新サービス AWS Secrets Manager のシークレットを CLI から更新し、その動作を理解する
こんにちは、菊池です。
AWS Summit 2018 San Francisco で発表された新サービス、Secrets Managerを触ってます。
- 【完全新機能】DB認証情報やOAuthキーを一元管理可能なAWS Secrets Managerが発表されました!
- 機密管理サービス AWS Secrets Manager で RDS のパスワードローテーションを試す
今回は、シークレットに保存される値がどのように管理されているのか、AWS CLIを使って、その構成要素であるバージョン、ステージラベルを色々と操作しながら理解してみたいと思います。
シークレットの構成
シークレットを構成する要素は、公式ドキュメントに記載の以下の図がわかりやすいでしょう。
シークレットはメタデータと、シークレットの値を格納する各バージョンで構成されます。
- メタデータ
- ARN
- 名前
- 説明
- KMSキー
- ローテション設定
- 最終利用日
- タグ
- バージョン
- ID
- ステージングラベル
- シークレットの値
1つのシークレットには、複数のバージョンを持つことでシークレットの値を使い分けることができます。そのバージョンを管理するための要素が、ステージングラベルです。ステージングラベルに付与するラベルによって、シークレットの複数バージョンを管理します。
ステージングラベル:AWSCURRENT
デフォルトのバージョンに付与されるラベルです。このラベルが付与されたバージョンのシークレットの値を、通常は利用します。明示的にステージングラベルを指定しなければ、このバージョンが取得されます。
ステージングラベル:AWSPREVIOUS
1つ前のバージョンに付与されるラベルです。新しいバージョンにAWSCURRENT
を付与すると、それまでAWSCURRENT
が付与されていたバージョンにAWSPREVIOUS
が付与されます。
この他にも、任意の文字列のラベルをバージョンに付与することができます。1つのバージョンには最大で20個までのラベルが付与可能です。ただし、同時に複数のバージョンに同じラベルを付与することはできません。例えば、AWSCURRENT
をもつラベルは1つのバージョンのみで、他のバージョンに付与する場合には、それまで付与されていたバージョンからは削除する必要があります。
シークレットのバージョンを操作してみる
実際にシークレットのバージョンを操作して、その挙動を確認していきます。まずは単純なシークレットをコンソールから登録しました。
この状態で、AWS CLIからシークレットを取得してみます。get-secret-value
コマンドでシークレットの値が取得できます。
$ aws secretsmanager get-secret-value --secret-id test { "Name": "test", "VersionId": "56301bf3-21f9-4ce5-a42b-dd9667d63151", "SecretString": "{\"password\":\"version1\"}", "VersionStages": [ "AWSCURRENT" ], "CreatedDate": 1523092005.303, "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
{password:version1}
が取得できました。また、ステージングラベル(VersionStages
)にAWSCURRENT
が設定されています。
次に、コンソールからシークレットをversion2
に更新します。
これで再度取得してみると、{password:version2}
が取得できます。
$ aws secretsmanager get-secret-value --secret-id test { "Name": "test", "VersionId": "f03f988d-1658-4b54-b825-eb98992e6d41", "SecretString": "{\"password\":\"version2\"}", "VersionStages": [ "AWSCURRENT" ], "CreatedDate": 1523092141.428, "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
ここで、保存されたバージョンをlist-secret-version-ids
コマンドで確認してます。
$ aws secretsmanager list-secret-version-ids --secret-id test { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG", "Versions": [ { "VersionId": "f03f988d-1658-4b54-b825-eb98992e6d41", "VersionStages": [ "AWSCURRENT" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092141.428 }, { "VersionId": "56301bf3-21f9-4ce5-a42b-dd9667d63151", "VersionStages": [ "AWSPREVIOUS" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092005.303 } ] }
すると、{password:version1}
を保存していた"VersionId": "56301bf3-21f9-4ce5-a42b-dd9667d63151"
には、AWSPREVIOUS
のラベルが保存されていることがわかります。1つ前のバージョンには、AWSPREVIOUS
が付与されて保存されるということです。
ラベルを指定せずに新しいバージョンを作成するとAWSCURRENTが指定される
続いて、CLIからput-secret-value
で新しいバージョンを作成します。特にラベルは指定していませんが、レスポンスにAWSCURRENT
のラベルが付与されています。
$ aws secretsmanager put-secret-value \ > --secret-id test \ > --secret-string "{\"password\":\"version3\"}" { "VersionId": "e9ec4d8f-3012-48ae-a5f8-dc0b249f574e", "VersionStages": [ "AWSCURRENT" ], "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
シークレットの値を取得しても、新しいバージョンが取得できます。
$ aws secretsmanager get-secret-value --secret-id test { "Name": "test", "VersionId": "e9ec4d8f-3012-48ae-a5f8-dc0b249f574e", "SecretString": "{\"password\":\"version3\"}", "VersionStages": [ "AWSCURRENT" ], "CreatedDate": 1523092732.549, "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
ラベルが空になったバージョンは削除される
保存されているバージョンを取得すると、AWSCURRENT
、AWSPREVIOUS
が1つずつ進んでいます。一方で、1つ前にAWSPREVIOUS
が付与されていたバージョン({password:version1}
)は削除されました。
$ aws secretsmanager list-secret-version-ids --secret-id test { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG", "Versions": [ { "VersionId": "f03f988d-1658-4b54-b825-eb98992e6d41", "VersionStages": [ "AWSPREVIOUS" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092643.074 }, { "VersionId": "e9ec4d8f-3012-48ae-a5f8-dc0b249f574e", "VersionStages": [ "AWSCURRENT" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092732.549 } ] }
ラベルを指定してバージョンを作成するとAWSCURRENTは付与されない
続いて、明示的にラベルを指定してバージョンを作成してみます。put-secret-valueに--version-stages "NEXT"
を付与して作成します。
$ aws secretsmanager put-secret-value \ > --secret-id test \ > --secret-string "{\"password\":\"version4\"}" \ > --version-stages "NEXT" { "VersionId": "87b38f9f-5422-4e7f-8fa3-0857c0905b22", "VersionStages": [ "NEXT" ], "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
この場合、シークレットの値を取得しても、AWSCURRENT
は変わらずに以前のバージョンが取得できます。
$ aws secretsmanager get-secret-value --secret-id test { "Name": "test", "VersionId": "e9ec4d8f-3012-48ae-a5f8-dc0b249f574e", "SecretString": "{\"password\":\"version3\"}", "VersionStages": [ "AWSCURRENT" ], "CreatedDate": 1523092732.549, "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
ラベル--version-stages "NEXT"
を指定して取得すれば、作成したバージョンを取得できます。
$ aws secretsmanager get-secret-value \ > --secret-id test \ > --version-stage "NEXT" { "Name": "test", "VersionId": "87b38f9f-5422-4e7f-8fa3-0857c0905b22", "SecretString": "{\"password\":\"version4\"}", "VersionStages": [ "NEXT" ], "CreatedDate": 1523092955.717, "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
バージョンのリストを取得すると、AWSCURRENT
、AWSPREVIOUS
は変わらないまま、新しいバージョンが保存されたことがわかります。
$ aws secretsmanager list-secret-version-ids --secret-id test { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG", "Versions": [ { "VersionId": "f03f988d-1658-4b54-b825-eb98992e6d41", "VersionStages": [ "AWSPREVIOUS" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092643.074 }, { "VersionId": "e9ec4d8f-3012-48ae-a5f8-dc0b249f574e", "VersionStages": [ "AWSCURRENT" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092732.549 }, { "VersionId": "87b38f9f-5422-4e7f-8fa3-0857c0905b22", "VersionStages": [ "NEXT" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092955.717 } ] }
ラベルAWSCURRENTを変更するとAWSPREVIOUSも変更される
AWSCURRENT
を新しく保存したバージョンに付与してみます。update-secret-version-stage
コマンドで、以前のバージョンからAWSCURRENT
をremove
し、新しいバージョンにmove
します。
$ aws secretsmanager update-secret-version-stage \ > --secret-id test \ > --version-stage AWSCURRENT \ > --remove-from-version-id e9ec4d8f-3012-48ae-a5f8-dc0b249f574e \ > --move-to-version-id 87b38f9f-5422-4e7f-8fa3-0857c0905b22 { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
AWSCURRENT
の変更と共に、AWSPREVIOUS
も1つ前のバージョンに移動しました。AWSPREVIOUS
が外されたバージョンは削除されています。
$ aws secretsmanager list-secret-version-ids --secret-id test { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG", "Versions": [ { "VersionId": "87b38f9f-5422-4e7f-8fa3-0857c0905b22", "VersionStages": [ "AWSCURRENT", "NEXT" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092955.717 }, { "VersionId": "e9ec4d8f-3012-48ae-a5f8-dc0b249f574e", "VersionStages": [ "AWSPREVIOUS" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092732.549 } ] }
ステージラベルがあれば古いバージョンも保持可能
以下のように、現在3つのバージョンを保持しています。ラベルVERSION4
のバージョンがAWSCURRENT
です。
$ aws secretsmanager list-secret-version-ids --secret-id test { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG", "Versions": [ { "VersionId": "87b38f9f-5422-4e7f-8fa3-0857c0905b22", "VersionStages": [ "AWSCURRENT", "VERSION4" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092955.717 }, { "VersionId": "2625bf18-971d-44ec-abc9-46a600a85673", "VersionStages": [ "VERSION5" ], "CreatedDate": 1523094151.125 }, { "VersionId": "422a96da-9790-4081-819c-4d123c3c96ed", "VersionStages": [ "VERSION6" ], "CreatedDate": 1523094223.278 } ] }
AWSCURRENT
をVERSION5
に移動します。
$ aws secretsmanager update-secret-version-stage \ > --secret-id test \ > --version-stage AWSCURRENT \ > --remove-from-version-id 87b38f9f-5422-4e7f-8fa3-0857c0905b22 \ > --move-to-version-id 2625bf18-971d-44ec-abc9-46a600a85673 { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
VERSION5
がAWSCURRENT
、VERSION4
がAWSPREVIOUS
に変更されました。
$ aws secretsmanager list-secret-version-ids --secret-id test { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG", "Versions": [ { "VersionId": "87b38f9f-5422-4e7f-8fa3-0857c0905b22", "VersionStages": [ "VERSION4", "AWSPREVIOUS" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092955.717 }, { "VersionId": "2625bf18-971d-44ec-abc9-46a600a85673", "VersionStages": [ "AWSCURRENT", "VERSION5" ], "CreatedDate": 1523094151.125 }, { "VersionId": "422a96da-9790-4081-819c-4d123c3c96ed", "VersionStages": [ "VERSION6" ], "CreatedDate": 1523094223.278 } ] }
ここからさらに、VERSION6
をAWSCURRENT
に指定します。
$ aws secretsmanager update-secret-version-stage \ > --secret-id test \ > --version-stage AWSCURRENT \ > --remove-from-version-id 2625bf18-971d-44ec-abc9-46a600a85673 \ > --move-to-version-id 422a96da-9790-4081-819c-4d123c3c96ed { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
VERSION6
がAWSCURRENT
、VERSION5
がAWSPREVIOUS
に変更されました。AWSPREVIOUS
が取り外されたバージョンも、ラベルVERSION4
が残ってますので削除されずに保持されたままになります。
$ aws secretsmanager list-secret-version-ids --secret-id test { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG", "Versions": [ { "VersionId": "87b38f9f-5422-4e7f-8fa3-0857c0905b22", "VersionStages": [ "VERSION4" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092955.717 }, { "VersionId": "2625bf18-971d-44ec-abc9-46a600a85673", "VersionStages": [ "VERSION5", "AWSPREVIOUS" ], "CreatedDate": 1523094151.125 }, { "VersionId": "422a96da-9790-4081-819c-4d123c3c96ed", "VersionStages": [ "AWSCURRENT", "VERSION6" ], "CreatedDate": 1523094223.278 } ] }
バージョン作成時に複数ラベルを同時に指定
バージョン作成時に複数のラベルを同時に指定できます。AWSCURRENT
とVERSION7
を同時に指定して作成します。
$ aws secretsmanager put-secret-value \ > --secret-id test \ > --secret-string "{\"password\":\"version7\"}" \ > --version-stages VERSION7 AWSCURRENT { "VersionId": "cc824ce3-e79b-44ad-bd15-83f03d06d364", "VersionStages": [ "AWSCURRENT", "VERSION7" ], "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG" }
VERSION7
がAWSCURRENT
として作成されました。以前のバージョン、VERSION4/5
も残っています。
$ aws secretsmanager list-secret-version-ids --secret-id test { "Name": "test", "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:test-1O5wUG", "Versions": [ { "VersionId": "87b38f9f-5422-4e7f-8fa3-0857c0905b22", "VersionStages": [ "VERSION4" ], "LastAccessedDate": 1523059200.0, "CreatedDate": 1523092955.717 }, { "VersionId": "2625bf18-971d-44ec-abc9-46a600a85673", "VersionStages": [ "VERSION5" ], "CreatedDate": 1523094151.125 }, { "VersionId": "422a96da-9790-4081-819c-4d123c3c96ed", "VersionStages": [ "VERSION6", "AWSPREVIOUS" ], "CreatedDate": 1523094223.278 }, { "VersionId": "cc824ce3-e79b-44ad-bd15-83f03d06d364", "VersionStages": [ "AWSCURRENT", "VERSION7" ], "CreatedDate": 1523094955.779 } ] }
まとめ
以上です。
新しいサービスであるAWS Secrets Managerのシークレットを手動で更新していくことで、その管理の仕組みを理解できました。ステージラベルをうまく使うことで、世代の管理や以前の情報をコントロールしていくことができそうです。
なお、実運用上は利用するアプリケーションと管理対象のシステムのパスワード変更などが同期して動作する必要があります。そのため、変更管理には提供されるLambdaを使ったローテーションをベースに使っていくのがよいでしょう。