Python3でAWS Secrets Managerシークレットを即時削除してみました。


この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。

前提

・スクリプトの実行環境をAWS CloudShellとします。
・Secretの作成及び削除権限を持つユーザでスクリプトを実行すること

背景

以前、AWSコンソール上でAWS Secrets Managerシークレットを削除し、同じAWS シークレット名で作成しようとすると、下記のエラーメッセージが表示され、作成できませんでした。
error: An error occurred (InvalidRequestException) when calling the CreateSecret operation: You can’t create this secret because a secret with this name is already scheduled for deletion.

理由:(AWS Secrets Managerシークレットを即時削除できるようになりましたから引用)

1.AWS Secrets Managerのシークレットが即座削除に対応
2.AWS SDK/CLI は対応。管理コンソールは未対応
3.即時削除されたシークレットは復旧できない

今回、AWS Secrets ManagerシークレットをPython3で即時したいと思います。
新規でAWS Secrets Managerシークレットを作成する場合、ブログ
Python3でパスワードを生成してSecretを作成してみました。を参照

Secretの即時削除スクリプト

aws_del_secret_force.py

# -*- coding: utf-8 -*-

import boto3
import sys

if(len(sys.argv) <= 1):
    print('Please enter arguments!')
    print('Example:filename.py "user_name"')
    sys.exit()
# ここに到達できていれば sys.argv[1]は必ず存在するので、安全にアクセスできます。
first_argv = str(sys.argv[1])
print('input first argument is', first_argv)

def aws_del_secret_force(user_name):
    """シークレット削除"""

    try:
        print('シークレット:[' + user_name +']の削除を行います。')
        rt = None

        secret_name = 'username = ' + '"' + user_name + '"'
        print(f'secret_name: {secret_name}')

        # シークレット作成
        secretsmanager_client = boto3.client('secretsmanager')

        response = secretsmanager_client.delete_secret(
            SecretId=user_name,
            ForceDeleteWithoutRecovery=True
        )
        print('response:')
        print(response)

    # except Exception:
    except Exception as e:
        print ('[secretsmanager_DelSecret] del secret exception error.')
        print("error: " + str(e))
        rt=None
    print('シークレット:[' + user_name +']の削除を完了しました。')

    return rt        

# 呼び出しのテスト
rt_aws_del_secret_force = aws_del_secret_force(first_argv)
print('rt_aws_del_secret_force:')
print(rt_aws_del_secret_force)

動作確認

1.Pythonのバージョン確認

Python3のバージョン確認コマンド:
python3 –version或いはpython3 -V

実行例:

[cloudshell-user@ip-10-0-50-90 ~]$ python3 –version
Python 3.7.10
[cloudshell-user@ip-10-0-50-90 ~]$ python3 -V
Python 3.7.10
[cloudshell-user@ip-10-0-50-90 ~]$

2.PythonのスクリプトをCloudShellにアップロードする

AWS CloudShell画面右上の「Actions」⇒「Uplodad file」より.Pythonのスクリプト(aws_del_secret_force.py)をアップロードする

3.Pythonのスクリプトを実行してみる

実行例:
python3 aws_del_secret_force.py "test3"

Secret名が既に存在する場合の例:

cloudshell-user@ip-10-0-50-90 ~]$ python3 aws_del_secret_force.py "test3"
input first argument is test3
シークレット:[test3]の削除を行います。
secret_name: username = "test3"
response:
{'ARN': 'arn:aws:secretsmanager:ap-northeast-1:268673644828:secret:test3-aRm17s', 'Name': 'test3', 'DeletionDate': datetime.datetime(2022, 7, 9, 9, 22, 32, 97000, tzinfo=tzlocal()), 'ResponseMetadata': {'RequestId': '2988ab1c-326b-4c1b-b366-35ee6cd2e731', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '2988ab1c-326b-4c1b-b366-35ee6cd2e731', 'content-type': 'application/x-amz-json-1.1', 'content-length': '127', 'date': 'Sat, 09 Jul 2022 09:22:31 GMT'}, 'RetryAttempts': 0}}
シークレット:[test3]の削除を完了しました。
rt_aws_del_secret_force:
None
[cloudshell-user@ip-10-0-50-90 ~]$ 

Secret名が存在しない場合の例:
※Secret名が存在しない場合でも削除コマンドが成功します。

[cloudshell-user@ip-10-0-50-90 ~]$ python3 aws_del_secret_force.py "test3"
input first argument is test3
シークレット:[test3]の削除を行います。
secret_name: username = "test3"
response:
{'ARN': 'arn:aws:secretsmanager:ap-northeast-1:268673644828:secret:test3-WEHRtt', 'Name': 'test3', 'DeletionDate': datetime.datetime(2022, 7, 9, 9, 28, 51, 292000, tzinfo=tzlocal()), 'ResponseMetadata': {'RequestId': '65a5c132-21aa-4335-abc5-4b7d2a005afe', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '65a5c132-21aa-4335-abc5-4b7d2a005afe', 'content-type': 'application/x-amz-json-1.1', 'content-length': '127', 'date': 'Sat, 09 Jul 2022 09:28:51 GMT'}, 'RetryAttempts': 0}}
シークレット:[test3]の削除を完了しました。
rt_aws_del_secret_force:
None
[cloudshell-user@ip-10-0-50-90 ~]$ 

同じ名で作成してみる

[cloudshell-user@ip-10-0-50-90 ~]$ python3 aws_create_secret.py "test3"
input first argument is test3
シークレット:[test3]の作成を行います。
RandomPassword:
uU0w29K=
{'ARN': 'arn:aws:secretsmanager:ap-northeast-1:268673644828:secret:test3-SgRZH3', 'Name': 'test3', 'VersionId': 'b226573b-2479-49be-8922-d3f512cfa77a', 'ResponseMetadata': {'RequestId': '65a3f55c-14dc-477c-be49-19fae9a96078', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '65a3f55c-14dc-477c-be49-19fae9a96078', 'content-type': 'application/x-amz-json-1.1', 'content-length': '146', 'date': 'Sat, 09 Jul 2022 09:30:42 GMT'}, 'RetryAttempts': 0}}
シークレット:[test3]の作成を完了しました。
[cloudshell-user@ip-10-0-50-90 ~]$ 

まとめ

Python3でAWS Secrets Managerシークレットを即時削除するスクリプトを紹介しました。

Secret名が既に存在し、同じSecret名で作成したい場合、このスクリプトを使って削除してから、
作成するスクリプト(Python3でパスワードを生成してSecretを作成してみました。を参照)を使って検証できました。

お役に立てれば幸いです。

参考

AWS Secrets Managerシークレットを即時削除できるようになりました

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/secretsmanager.html#SecretsManager.Client.delete_secret

Last modified: 2022-07-09

Author