AWS Secrets MangerとParameter Storeに登録した公開鍵をTerraformで取得する
AWSにはシークレットを扱うサービスとして、 System Manager Parameter Store と Secrets Manager の2種類あり、TerraformではData Sourcesを使用することでどちらの方法でも動的にパラメータを取得することができます。
今回はTerraform上で両者を同じように扱おうとして半日溶かしました、という注意喚起の記事です。
TL;DR
Secrets Managerにキーペアを登録した時、改行が全てスペースに変換されてしまう仕様上、公開鍵のような改行を含むシークレットを登録するためには、バイナリで登録する必要があります。シークレット作成はAWS CLIから行います。(2022年5月13日現在、AWSマネコンからバイナリ形式での作成はできません。)
$ aws secretsmanager create-secret --name public_key --secret-binary fileb://public_key.pem
Terraformでは data.aws_secretsmanager_secret.public_key
で対象のシークレットIDを取得し、data.aws_secretsmanager_secret_version.public_key
で値を取得した後、secret_binary
で出力できます。
data "aws_secretsmanager_secret" "public_key" {
name = "cloudfront/key_group/public_key"
}
data "aws_secretsmanager_secret_version" "public_key" {
secret_id = data.aws_secretsmanager_secret.public_key.id
}
output "sm" {
value = data.aws_secretsmanager_secret_version.public_key.secret_binary
}
文字列で出力されているため、base64decode()
は不要です。
$ terraform output sm
<<EOT
-----BEGIN PUBLIC KEY-----
XXXXX
XXXXX
XXXXX
-----END PUBLIC KEY-----
EOT
環境
- macOS Monterey: v12.3.1
- Terraform: v1.1.7
- hashicorp/aws: v4.11.0
- aws-cli: v2.6.1
エラーの状況
Parameter Storeでは改行も含めてパラメータを登録できるため、data.aws_ssm_parameter.public_key
で取得した値を value
で出力できます。
data "aws_ssm_parameter" "public_key" {
name = "/cloudfront/key_group/public_key"
}
output "ps" {
value = data.aws_ssm_parameter.public_key.value
}
$ terraform output ps
<<EOT
-----BEGIN PUBLIC KEY-----
XXXXX
XXXXX
XXXXX
-----END PUBLIC KEY-----
EOT
一方、Secrets Managerでは勝手に改行がスペースに変換されてしまうため、それに気づかずシークレットをリソースに渡しているとInvalidエラーが発生します。私の時はaws_cloudfront_public_key
のencoded_key
に渡す際に以下のエラーに当たりました。
╷
│ Error: error creating CloudFront PublicKey: InvalidArgument: Your request contains empty/invalid/out of limits RSA Encoded Key
│ status code: 400, request id: 6254fb9d-7d22-4ff3-b062-f64b6d60f813
│
│ with module.cognito.aws_cloudfront_public_key.static,
│ on ../shared/modules/cognito/cloudfront.tf line 71, in resource "aws_cloudfront_public_key" "static":
│ 71: resource "aws_cloudfront_public_key" "static" {
│
╵
Terraform側ではなく、Secrets Manager側の仕様に原因があったが気付きづらかった…。
Discussion