💫

AWS Secrets MangerとParameter Storeに登録した公開鍵をTerraformで取得する

2022/05/13に公開

AWSにはシークレットを扱うサービスとして、 System Manager Parameter StoreSecrets 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_keyencoded_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