AWS Secrets Managerでシークレットが正常にローテーションできなかった時の対応方法
シークレットのローテーションに失敗するのだが
こんにちは、のんピ(@non____97)です。
皆さんはAWS Secrets ManagerでDBのシークレットが正常にローテーションできなかった時はありますか? 私はあります。
シークレットをローテーションするLambda関数のログを確認してもイマイチ分かりにくかったりするので、勘所と対応方法をまとめます。
AWS公式ドキュメントにもSecrets Managerのローテーションのトラブルシューティング方法が記載されているので、併せてご覧ください。
いきなりまとめ
- シークレットのローテーションが上手く動作しない場合は、まずLambda関数とDBのセキュリティグループを確認
- Lambda関数のセキュリティグループで、DBとAWS Secrets Managerにエンドポイントにアクセスを許可するルールがあるか
- DBのセキュリティグループで、Lambda関数からのアクセスを許可するルールがあるか
- シークレットをローテーションするLambda関数にAWS Secrets Managerのエンドポイントへのルートがあるかを確認
- NAT Gatewayへのルーティング or AWS Secrets ManagerのVPCエンドポイントがあるか
- 上述の内容を実施しても正常にローテーションされない場合は、シークレットの各バージョンのラベルを確認して対応する
AWSPENDING
のラベルのバージョンにAWSCURRENT
のラベルが付いていない場合AWSPENDING
のラベルのバージョンを削除する
AWSPENDING
のラベルのバージョンにAWSCURRENT
のラベルも付いている場合AWSPENDING
とAWSCURRENT
のラベルが付与されているバージョンのシークレットでDBに接続できるか確認AWSPENDING
とAWSCURRENT
のラベルが付与されているバージョンのシークレットでDBに接続できない場合、AWSPREVIOUS
のラベルが付与されているバージョンのシークレットでDBに接続できるか確認AWSPREVIOUS
のラベルが付与されているバージョンのシークレットでDBに接続できる場合、AWSPREVIOUS
ラベルが付いているバージョンにAWSCURRENT
ラベルを付与するAWSPENDING
とAWSCURRENT
のラベルが付与されているバージョンのシークレットでDBに接続できる場合、AWSPENDING
とAWSCURRENT
のラベルが付与されているバージョンでAWSPENDING
のラベルのみを外す
ローテーション失敗時に確認すること
ローテーションに失敗したかどうかの判断はシークレットをローテーションするLambda関数のログを確認します。シークレットのローテーションに失敗すると、以下のようなログが出力されます。
START RequestId: 24ce3d1b-e194-482c-b33a-5d879e5d15d5 Version: $LATEST [INFO] 2022-03-28T05:33:50.860Z 24ce3d1b-e194-482c-b33a-5d879e5d15d5 Found credentials in environment variables. [INFO] 2022-03-28T05:33:52.139Z 24ce3d1b-e194-482c-b33a-5d879e5d15d5 createSecret: Successfully put secret for ARN arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx and version 4bcc57ad-6901-489f-88cf-c5b56f14cbca. END RequestId: 24ce3d1b-e194-482c-b33a-5d879e5d15d5 REPORT RequestId: 24ce3d1b-e194-482c-b33a-5d879e5d15d5 Duration: 1548.10 ms Billed Duration: 1549 ms Memory Size: 128 MB Max Memory Used: 73 MB Init Duration: 318.95 ms START RequestId: f312a4c3-3d5f-45f2-aa67-a95e1985f993 Version: $LATEST [ERROR] 2022-03-28T05:34:07.568Z f312a4c3-3d5f-45f2-aa67-a95e1985f993 setSecret: Unable to log into database with previous, current, or pending secret of secret arn arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx [ERROR] ValueError: Unable to log into database with previous, current, or pending secret of secret arn arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx Traceback (most recent call last): File "/var/task/lambda_function.py", line 76, in lambda_handler set_secret(service_client, arn, token) File "/var/task/lambda_function.py", line 169, in set_secret raise ValueError("Unable to log into database with previous, current, or pending secret of secret arn %s" % arn) END RequestId: f312a4c3-3d5f-45f2-aa67-a95e1985f993 REPORT RequestId: f312a4c3-3d5f-45f2-aa67-a95e1985f993 Duration: 15393.85 ms Billed Duration: 15394 ms Memory Size: 128 MB Max Memory Used: 73 MB
START RequestId: 74fc027b-8dc0-4da4-b618-239b54b95247 Version: $LATEST [INFO] 2022-03-28T02:38:08.558Z 74fc027b-8dc0-4da4-b618-239b54b95247 Found credentials in environment variables. END RequestId: 74fc027b-8dc0-4da4-b618-239b54b95247 REPORT RequestId: 74fc027b-8dc0-4da4-b618-239b54b95247 Duration: 30032.43 ms Billed Duration: 30000 ms Memory Size: 128 MB Max Memory Used: 71 MB Init Duration: 372.84 ms 2022-03-28T02:38:38.338Z 74fc027b-8dc0-4da4-b618-239b54b95247 Task timed out after 30.03 seconds
マネージメントコンソールの場合、シークレット「シークレット名」をローテーションできませんでした。 A previous rotation isn't complete. That rotation will be reattempted.
と表示されたりもします。
このようにシークレットを正しくローテーションできない場合は、まずシークレットをローテーションするLambda関数とDBのセキュリティグループを確認します。
ポイントは以下の2つです。
- Lambda関数のセキュリティグループで、DBとAWS Secrets Managerにエンドポイントにアクセスを許可するルールがあるか
- DBのセキュリティグループで、Lambda関数からのアクセスを許可するルールがあるか
もし、両方のポイントを満たせていない場合は、こちらを満たすようなルールを追加します。意外とLambda関数のアウトバウンドルールで、AWS Secrets Managerにエンドポイントにアクセスを許可するルールがなかったりするので注意して確認しましょう。
加えて、シークレットをローテーションするLambda関数にAWS Secrets Managerのエンドポイントへのルートがあるかも確認します。Lambda関数が動作するサブネットにNAT Gatewayへのルーティングがあるか、もしくはVPCにAWS Secrets ManagerのVPCエンドポイントがあるかを確認します。
どちらも存在しない場合は、Lambda関数のサブネットのルートテーブルにNAT Gatewayへのルーティングを追加するなど、Lambda関数からAWS Secrets Managerのエンドポイントへのルートを用意します。
上述の確認ポイントはAWS公式ドキュメントでも紹介されています。
以上の対応をすれば、基本的に次回から正しくローテーションされます。
それでもローテーションが上手くいかない場合
それでもローテーションが上手くいかない場合もあります。
例えば、新しいシークレットは生成したが、DBに新しいシークレットを反映できていない場合です。
そのような場合は、シークレットをローテーションするLambda関数のCloudWatch Logsに以下のようなエラーが出力されます。
START RequestId: 24ce3d1b-e194-482c-b33a-5d879e5d15d5 Version: $LATEST [INFO] 2022-03-28T05:33:50.860Z 24ce3d1b-e194-482c-b33a-5d879e5d15d5 Found credentials in environment variables. [INFO] 2022-03-28T05:33:52.139Z 24ce3d1b-e194-482c-b33a-5d879e5d15d5 createSecret: Successfully put secret for ARN arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx and version 4bcc57ad-6901-489f-88cf-c5b56f14cbca. END RequestId: 24ce3d1b-e194-482c-b33a-5d879e5d15d5 REPORT RequestId: 24ce3d1b-e194-482c-b33a-5d879e5d15d5 Duration: 1548.10 ms Billed Duration: 1549 ms Memory Size: 128 MB Max Memory Used: 73 MB Init Duration: 318.95 ms START RequestId: f312a4c3-3d5f-45f2-aa67-a95e1985f993 Version: $LATEST [ERROR] 2022-03-28T05:34:07.568Z f312a4c3-3d5f-45f2-aa67-a95e1985f993 setSecret: Unable to log into database with previous, current, or pending secret of secret arn arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx [ERROR] ValueError: Unable to log into database with previous, current, or pending secret of secret arn arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx Traceback (most recent call last): File "/var/task/lambda_function.py", line 76, in lambda_handler set_secret(service_client, arn, token) File "/var/task/lambda_function.py", line 169, in set_secret raise ValueError("Unable to log into database with previous, current, or pending secret of secret arn %s" % arn) END RequestId: f312a4c3-3d5f-45f2-aa67-a95e1985f993 REPORT RequestId: f312a4c3-3d5f-45f2-aa67-a95e1985f993 Duration: 15393.85 ms Billed Duration: 15394 ms Memory Size: 128 MB Max Memory Used: 73 MB
エラーが発生しても、しばらくは自動でローテーションをリトライしてくれますが、原因を解消せずに10分ほど経つとリトライもされなくなります。
このような状態で手動でローテーションをしようとしてもシークレット「シークレット名」をローテーションできませんでした。 A previous rotation isn't complete. That rotation will be reattempted.
と表示されてしまいます。
このような場面に遭遇したら、シークレットの各バージョンのラベルを確認します。
シークレットのバージョン一覧は、AWS CLIでlist-secret-version-idsを実行して確認します。
実行結果は以下の通りです。
$ aws secretsmanager list-secret-version-ids \ > --secret-id prd-db-cluster/AdminLoginInfo { "Versions": [ { "VersionId": "dfe186d3-7399-4f46-873a-a4f7078aa77f", "VersionStages": [ "AWSPENDING" ], "LastAccessedDate": "2022-03-28T00:00:00+00:00", "CreatedDate": "2022-03-28T09:59:44.672000+00:00", "KmsKeyIds": [ "DefaultEncryptionKey" ] }, { "VersionId": "c7264842-7f5d-407a-9b8e-24e63385e62a", "VersionStages": [ "AWSCURRENT" ], "LastAccessedDate": "2022-03-28T00:00:00+00:00", "CreatedDate": "2022-03-28T09:50:12.998000+00:00", "KmsKeyIds": [ "DefaultEncryptionKey" ] }, { "VersionId": "8db5d941-83e3-48bc-b63c-adcb714da48d", "VersionStages": [ "AWSPREVIOUS" ], "LastAccessedDate": "2022-03-28T00:00:00+00:00", "CreatedDate": "2022-03-28T09:50:06.006000+00:00", "KmsKeyIds": [ "DefaultEncryptionKey" ] } ], "ARN": "arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx", "Name": "prd-db-cluster/AdminLoginInfo" }
この状態は以下AWS公式ドキュメントで言うところのステップ 2: データベースまたはサービスの認証情報を変更する (setSecret)
が上手くいっていない状態です。
ステップ 1: シークレットの新しいバージョンを作成する (createSecret)
ローテーションの最初のステップでは、シークレットの新しいバージョンが作成されます。ローテーション戦略に基づき、この新しいバージョンには新しいパスワード、新しいユーザー名とパスワード、またはそれ以上の秘密情報を含めることができます。Secrets Manager は、この新しいバージョンに対し、ステージングラベル AWSPENDING をラベル付けします。ステップ 2: データベースまたはサービスの認証情報を変更する (setSecret)
次に、AWSPENDING バージョンのシークレットと一致するよう、データベースまたはサービス内の認証情報が、ローテーションにより変更されます。このステップでは、ローテーション戦略に応じて、既存のユーザーと同じアクセス許可を付与しながら、新しいユーザーを作成できます。
そのため、DBには新しいバージョンのシークレット(AWSPENDING
)は適用されていない状態です。
このバージョンのシークレット(AWSPENDING
)はDBに適用されていない不要なバージョンであるため削除をします。シークレットのラベルの操作をする場合は、AWS CLIでupdate-secret-version-stageを実行します。
コマンドの実行結果は以下の通りです。
# AWSPENDING のラベルが付いているバージョンを削除 $ aws secretsmanager update-secret-version-stage \ --secret-id prd-db-cluster/AdminLoginInfo \ --version-stage AWSPENDING \ --remove-from-version-id dfe186d3-7399-4f46-873a-a4f7078aa77f { "ARN": "arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx", "Name": "prd-db-cluster/AdminLoginInfo" } # シークレットのバージョン一覧を表示 $ aws secretsmanager list-secret-version-ids \ > --secret-id prd-db-cluster/AdminLoginInfo { "Versions": [ { "VersionId": "c7264842-7f5d-407a-9b8e-24e63385e62a", "VersionStages": [ "AWSCURRENT" ], "LastAccessedDate": "2022-03-28T00:00:00+00:00", "CreatedDate": "2022-03-28T09:50:12.998000+00:00", "KmsKeyIds": [ "DefaultEncryptionKey" ] }, { "VersionId": "8db5d941-83e3-48bc-b63c-adcb714da48d", "VersionStages": [ "AWSPREVIOUS" ], "LastAccessedDate": "2022-03-28T00:00:00+00:00", "CreatedDate": "2022-03-28T09:50:06.006000+00:00", "KmsKeyIds": [ "DefaultEncryptionKey" ] } ], "ARN": "arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx", "Name": "prd-db-cluster/AdminLoginInfo" }
この状態で手動でローテーションをすると、マネージメントコンソール上ではローテーションのスケジュールが設定されたシークレット。
と表示されます。
シークレットをローテーションするLambda関数のCloudWatch Logsでは以下のようなログが出力されており、シークレットが正しくローテーションされていることを確認できます。
START RequestId: da9f8651-3e4f-41bd-9413-36a979df433f Version: $LATEST [INFO] 2022-03-28T10:44:37.078Z da9f8651-3e4f-41bd-9413-36a979df433f Found credentials in environment variables. [INFO] 2022-03-28T10:44:38.551Z da9f8651-3e4f-41bd-9413-36a979df433f createSecret: Successfully put secret for ARN arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx and version 7ba9c7e1-0531-4248-b37e-9b9073aa9fd3. END RequestId: da9f8651-3e4f-41bd-9413-36a979df433f REPORT RequestId: da9f8651-3e4f-41bd-9413-36a979df433f Duration: 1772.00 ms Billed Duration: 1772 ms Memory Size: 128 MB Max Memory Used: 73 MB Init Duration: 426.19 ms START RequestId: 8e10fce2-5019-4d7e-90e0-cbd9eda8a99b Version: $LATEST [INFO] 2022-03-28T10:44:39.192Z 8e10fce2-5019-4d7e-90e0-cbd9eda8a99b setSecret: Successfully set password for user postgresAdmin in PostgreSQL DB for secret arn arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx. END RequestId: 8e10fce2-5019-4d7e-90e0-cbd9eda8a99b REPORT RequestId: 8e10fce2-5019-4d7e-90e0-cbd9eda8a99b Duration: 618.21 ms Billed Duration: 619 ms Memory Size: 128 MB Max Memory Used: 75 MB START RequestId: e2408615-4feb-4d8b-812c-286d8812a56f Version: $LATEST [INFO] 2022-03-28T10:44:39.522Z e2408615-4feb-4d8b-812c-286d8812a56f testSecret: Successfully signed into PostgreSQL DB with AWSPENDING secret in arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx. END RequestId: e2408615-4feb-4d8b-812c-286d8812a56f REPORT RequestId: e2408615-4feb-4d8b-812c-286d8812a56f Duration: 321.87 ms Billed Duration: 322 ms Memory Size: 128 MB Max Memory Used: 75 MB START RequestId: cdd11f74-6b58-4564-94ef-3321862ab631 Version: $LATEST [INFO] 2022-03-28T10:44:39.897Z cdd11f74-6b58-4564-94ef-3321862ab631 finishSecret: Successfully set AWSCURRENT stage to version 7ba9c7e1-0531-4248-b37e-9b9073aa9fd3 for secret arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx. END RequestId: cdd11f74-6b58-4564-94ef-3321862ab631 REPORT RequestId: cdd11f74-6b58-4564-94ef-3321862ab631 Duration: 355.55 ms Billed Duration: 356 ms Memory Size: 128 MB Max Memory Used: 76 MB
対応方法は以上です。のんピでした!
と締めたいところではありますが、上述の「AWSPENDING
のラベルのバージョンを削除する」をしてはいけない場合もあります。
それは、以下のように「AWSPENDING
のラベルのバージョンにAWSCURRENT
のラベルも付いている場合」です。
$ aws secretsmanager list-secret-version-ids \ --secret-id prd-db-cluster/AdminLoginInfo { "Versions": [ { "VersionId": "11c46614-f0fb-4695-9fd9-7792cac5aa32", "VersionStages": [ "AWSPREVIOUS" ], "LastAccessedDate": "2022-03-28T00:00:00+00:00", "CreatedDate": "2022-03-28T04:13:43.587000+00:00", "KmsKeyIds": [ "DefaultEncryptionKey" ] }, { "VersionId": "4bcc57ad-6901-489f-88cf-c5b56f14cbca", "VersionStages": [ "AWSCURRENT", "AWSPENDING" ], "LastAccessedDate": "2022-03-28T00:00:00+00:00", "CreatedDate": "2022-03-28T05:33:52.125000+00:00", "KmsKeyIds": [ "DefaultEncryptionKey" ] } ], "ARN": "arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx", "Name": "prd-db-cluster/AdminLoginInfo" }
この状態だと、DBに新しいバージョンのシークレットが反映されているのかどうか判断できません。
そのため、このような場合はAWSPENDING
とAWSCURRENT
のラベルが付与されているバージョンのシークレットでDBに接続できるかどうかをまず確認します。
AWSPENDING
とAWSCURRENT
のラベルが付与されているバージョンのシークレットでDBに接続できないことを確認できた場合は、続けてAWSPREVIOUS
のラベルが付与されているバージョンのシークレットでDBに接続できるかを確認します。
AWSPREVIOUS
のラベルが付与されているバージョンのシークレットでDBに接続できる場合、DBには新しいバージョンのシークレットは反映されてなかったと判断できます。
そのため、前のバージョンを示すAWSPREVIOUS
のラベルが付いているバージョンをデフォルトのバージョン(AWSCURRENT
)となるようにラベルの貼り替えを行います。
ラベルの貼り替えも以下のようにAWS CLIでupdate-secret-version-stageを実行して行います。
# ラベルの貼り替え $ aws secretsmanager update-secret-version-stage \ --secret-id prd-db-cluster/AdminLoginInfo \ --version-stage AWSCURRENT \ --remove-from-version-id 4bcc57ad-6901-489f-88cf-c5b56f14cbca \ --move-to-version-id 11c46614-f0fb-4695-9fd9-7792cac5aa32 { "ARN": "arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx", "Name": "prd-db-cluster/AdminLoginInfo" } # シークレットのバージョン一覧を表示 $ aws secretsmanager list-secret-version-ids \ --secret-id prd-db-cluster/AdminLoginInfo { "Versions": [ { "VersionId": "11c46614-f0fb-4695-9fd9-7792cac5aa32", "VersionStages": [ "AWSCURRENT" ], "LastAccessedDate": "2022-03-28T00:00:00+00:00", "CreatedDate": "2022-03-28T04:13:43.587000+00:00", "KmsKeyIds": [ "DefaultEncryptionKey" ] }, { "VersionId": "4bcc57ad-6901-489f-88cf-c5b56f14cbca", "VersionStages": [ "AWSPREVIOUS" ], "LastAccessedDate": "2022-03-28T00:00:00+00:00", "CreatedDate": "2022-03-28T05:33:52.125000+00:00", "KmsKeyIds": [ "DefaultEncryptionKey" ] } ], "ARN": "arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:prd-db-cluster/AdminLoginInfo-vXO5yx", "Name": "prd-db-cluster/AdminLoginInfo" }
これでローテーションできる状態になりました。
もし、AWSPENDING
とAWSCURRENT
のラベルが付与されているバージョンのシークレットでDBに接続できた場合は、ローテーションは正常に行えているが、ラベルの貼り替えが正常に行われていない状態なので、AWSPENDING
のラベルのみを削除します。その際のコマンドは以下の通りです。
$ aws secretsmanager update-secret-version-stage \ --secret-id <シークレット名> \ --version-stage AWSPENDING \ --remove-from-version-id <AWSPENDING と AWSCURRENTのラベルが付いているバージョンのID>
AWS Secrets Managerのローテーションの仕組みを理解することが重要
AWS Secrets Managerでシークレットが正常にローテーションできなかった時の対応方法を紹介しました。
見慣れないエラーが出ても、AWS Secrets Managerのローテーションの仕組みを理解し、落ち着いてポイントを確認すれば対処できます。
そのためには自分の手で触ってみることが一番の近道だと感じました。
また、今回登場したラベルの操作は以下記事が参考になります。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!