HCP Vault Secretsを使って複数AWSアカウントのSecrets Managerを同期させてみる
複数AWSアカウント間でSecrets ManagerのSecretを共有は、KMSのキーポリシーやIAMポリシーを設定すれば可能です。
アカウント間で Secrets Manager のシークレットを共有する | AWS re:Post
HCP Vault Secretsを使えばより簡単にSecretsを複数AWSアカウント間で共有できるかもと思い、試してみました。
HCP Vault Secretsとは
シークレット管理のサービスです。2023年6月にパブリックベータとして発表されました。
HCP Vault Secretで管理しているシークレットをAWS Secrets Manager等と同期することも可能です。
Valultのマネージドサービスとして、HCP Vaultが以前から存在していました。
以下の表を見ると違いが分かりやすいです。
What is HCP Vault Secrets | Vault | HashiCorp Developerより引用
HCP VaultはSecrets管理の他に暗号化や証明書の管理も可能です。
HCP Vaultはクラスターを作成する必要がありますが、HCP Vault Secretsは作成不要です。
HCP Vault Secretではクラスターサイズを気にすること無く、よりシンプルにSecrets管理ができます。
- Announcing HCP Vault Secrets public beta
- What is HCP Vault Secrets? | HashiCorp Cloud Platform | HashiCorp Developer
- AWS Secrets Manager
やってみる
HCP Vault SecretsはAWS Secrets ManagerとSecretsを同期したりできます。
今回は複数AWSアカウントで同じSecretsを利用したいケースを想定して、HCP Vault Secretsと2つのAWSアカウントのSecrets Managerを同期させてみます。
Applicationの作成
HCP ポータルにログインして、Vault Secretsを選択します。
Create new application
でアプリケーションを作成します。
今回はTestApplication
という名前で作成します。
Secretsの作成
TestApplication
にリダイレクトされるため、Add new secret
でSecretsを作成します。
Key ValutでSecretsを作成できます。今回は以下の値でSecretsを作成します。
- Name: username
- Valut: test-user
ちなみにActivity LogsからSecrets作成等のログを確認できます。
AWS Secrets Manager統合・同期
Secretsを用意できたので、Secrets Managerと同期させます。
Integrations
からAWS Secrets Manager
を選択します。
Add new sync destination
を選択して、同期先の情報を入力します。
今回はaccount-a
とaccount-b
の2つの同期先を作成します。
上記のRole ARNには、HCP Vault SecretsがAWS Secrets Managerを操作するためのRoleを指定します。
RoleはTerraformで作成します。
公式ドキュメントの方でRole作成用のTerraformを用意してくれているので、それを使ってterraformを実行します。(terraform init -> terraform apply)
Integrate with AWS Secrets Manager | HashiCorp Cloud Platform | HashiCorp Developer
provider "aws" { // See https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration // for options on how to configure this provider. The following parameters or environment // variables are typically used. // Parameters: // access_key = "" // secret_key = "" // region = "" // Environment variables: // AWS_ACCESS_KEY_ID // AWS_SECRET_ACCESS_KEY // AWS_REGION } variable "external_id" { type = string description = "External ID to securely delegate access to HCP Vault Secrets" sensitive = true } resource "aws_iam_role" "hashicorp_vault_secrets_role" { name = "HCPVaultSecrets" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { AWS = "arn:aws:iam::879554817125:role/HCPVaultSecrets_Sync" } Condition = { StringEquals = { "sts:ExternalId" = var.external_id } } } ] }) inline_policy { name = "HCPVaultSecrets" policy = data.aws_iam_policy_document.hashicorp_vault_secrets_policy.json } } data "aws_iam_policy_document" "hashicorp_vault_secrets_policy" { statement { effect = "Allow" actions = [ "secretsmanager:DescribeSecret", "secretsmanager:GetSecretValue", "secretsmanager:CreateSecret", "secretsmanager:PutSecretValue", "secretsmanager:UpdateSecret", "secretsmanager:UpdateSecretVersionStage", "secretsmanager:DeleteSecret", "secretsmanager:RestoreSecret", "secretsmanager:TagResource", "secretsmanager:UntagResource" ] resources = ["*"] } } output "role_arn" { description = "Role ARN to configure the AWS Secrets Manager Integration" value = aws_iam_role.hashicorp_vault_secrets_role.arn }
external_id="<HCP Vault Secretsの画面で表示されている、External ID>"
TerraformのOutputにRole ARNが表示されるため、Add new sync destination
のRole ARN
に貼り付けます。
任意のリージョンを選択します。(今回は、us-east-1を選択、2023/7時点では東京リージョンは対応していない)
Save and sync Secrets
で同期設定を完了させます。
これで1アカウント分の設定が完了しました。
2つ目のアカウントでも同様の設定を行います。
External Id
は同期先ごとに変わらないため、tfvarsの内容はそのままで問題ありません。
同期が完了すると、以下のようにStatusがSynced
になります。
実際に各アカウントでSecrets Managerが作成されて、Secretsが保存されているか見てましょう。
# アカウントAの認証情報をセット $ aws secretsmanager get-secret-value --secret-id TestApplication/username --region us-east-1 { "ARN": "arn:aws:secretsmanager:us-east-1:<アカウントAのアカウントID>:secret:TestApplication/username-3LwKPy", "Name": "TestApplication/username", "VersionId": "0C324B40-A6ED-4CC9-93AC-4E71E5A10D0A", "SecretString": "test-user", "VersionStages": [ "AWSCURRENT" ], "CreatedDate": "2023-07-05T18:30:25.413000+09:00" }
# アカウントBの認証情報をセット $ aws secretsmanager get-secret-value --secret-id TestApplication/username --region us-east-1 { "ARN": "arn:aws:secretsmanager:us-east-1:<アカウントBのアカウントID>:secret:TestApplication/username-NANMmZ", "Name": "TestApplication/username", "VersionId": "AA70D0E1-3299-4D29-8ACC-DC6D4BA12A19", "SecretString": "test-user", "VersionStages": [ "AWSCURRENT" ], "CreatedDate": "2023-07-05T18:30:34.805000+09:00" }
アカウントAとアカウントBでSecrets ManagerTestApplication/username
が作成されていることが確認できました。
HCP Vault SecretsのSecrets値を更新してみる
HCP Vault Secrets側でSecretsを更新して、Secrets Managerに反映されるか確認してみます。(test-user
-> test-user-2
に変更)
Secrets Managerを確認すると、test-user-2
に変更されていました。
アクティビティログとSecrets Managerのログを見た感じ、変更後即時に反映されていました。
$ aws secretsmanager get-secret-value --secret-id TestApplication/username --region us-east-1 { "ARN": "arn:aws:secretsmanager:us-east-1:<アカウントBのアカウントID>:secret:TestApplication/username-NANMmZ", "Name": "TestApplication/username", "VersionId": "49173D5C-4F9A-4F50-82B6-266250CB0DD3", "SecretString": "test-user-2", "VersionStages": [ "AWSCURRENT" ], "CreatedDate": "2023-07-06T10:45:05.229000+09:00" }
HCP Vault SecretsのSecretsを削除してみる
Secretsを削除して、Secrets Managerも削除されるか確認します。
再度コマンドでSecrets Managerを確認してみます。
以下のようにSecretsは削除対象としてマークされているため、値が表示できない旨を確認できました。
HCP Vault Secretsで削除時にSecrets Manager側も削除されるみたいですね。
$ aws secretsmanager get-secret-value --secret-id TestApplication/username --region us-east-1 An error occurred (InvalidRequestException) when calling the GetSecretValue operation: You can't perform this operation on the secret because it was marked for deletion.
おわりに
HCP Vault Secretsを使ってみました。簡単に複数AWSアカウントのSecrets同期ができました。
覚える必要がある概念が、ApplicationとSecretsだけでシンプルで使いやすいです。
現状(2023/7時点)統合先がAWS Secrets Managerのみですが、今後Google CloudやAzureのシークレット管理サービスと統合できるようになったら、マルチクラウドでのシークレット管理が捗りそうです。
ベータ版のためいくつか制約や問題点もありますので、使用の際は注意ください。
HCP Vault Secrets constraints and limitations | HashiCorp Cloud Platform | HashiCorp Developer
今後のアップデートに期待です。
以上、AWS事業本部の佐藤(@chari7311)でした。