新サービス 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
コマンドでシークレットの値が取得できます。
1 2 3 4 5 6 7 8 9 10 11 | $ 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}
が取得できます。
1 2 3 4 5 6 7 8 9 10 11 | $ 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
コマンドで確認してます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $ 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
のラベルが付与されています。
1 2 3 4 5 6 7 8 9 10 11 | $ 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" } |
シークレットの値を取得しても、新しいバージョンが取得できます。
1 2 3 4 5 6 7 8 9 10 11 | $ 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}
)は削除されました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $ 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"
を付与して作成します。
1 2 3 4 5 6 7 8 9 10 11 12 | $ 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
は変わらずに以前のバージョンが取得できます。
1 2 3 4 5 6 7 8 9 10 11 | $ 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"
を指定して取得すれば、作成したバージョンを取得できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ 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
は変わらないまま、新しいバージョンが保存されたことがわかります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | $ 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
します。
1 2 3 4 5 6 7 8 9 | $ 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
が外されたバージョンは削除されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | $ 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
です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | $ 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
に移動します。
1 2 3 4 5 6 7 8 9 | $ 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
に変更されました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | $ 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
に指定します。
1 2 3 4 5 6 7 8 9 10 | $ 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
が残ってますので削除されずに保持されたままになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | $ 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
を同時に指定して作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ 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
も残っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | $ 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を使ったローテーションをベースに使っていくのがよいでしょう。