背景
RDS MySQL + EC2接続環境をCloudFormationで自動構築しました。コンソール版ではParameter StoreにSecureString型でパスワードを保存していましたが、CloudFormationではこれができません。この制約と、RDS特有のDeletionPolicy設計について整理します。
1. AWS::SSM::ParameterはString/StringListのみサポート
DBPasswordParam:
Type: AWS::SSM::Parameter
Properties:
Type: String # SecureStringは指定できない
Value: !Ref DBPassword
AWS::SSM::ParameterリソースはStringとStringListのみサポートしており、SecureStringはKMSとの複雑な依存関係があるためサポート外です。本番運用でSecureStringを使いたい場合は、事前に手動またはカスタムリソースで作成し、{{resolve:ssm-secure:/path/to/param}}構文でテンプレートから参照する方法が推奨されます。
2. String型のため取得時に--with-decryptionが不要になる
aws ssm get-parameter \
--name "/my/rds/db-password" \
--query "Parameter.Value" \
--output text \
--region ap-northeast-1
コンソール版でSecureStringとして作成した場合と違い、CloudFormationで作成したString型パラメータは暗号化されていないため、--with-decryptionフラグなしでそのまま値を取得できます。裏を返せば、CloudFormationで機密情報をそのままSSM Parameterに書き込む設計は、コンソール版よりセキュリティレベルが一段落ちるという点は意識しておく必要があります。
3. NoEcho: trueでパラメータをコンソール表示からマスクする
Parameters:
DBPassword:
Type: String
Default: 'Handson1234!'
NoEcho: true
NoEcho: trueを設定すると、CloudFormationコンソール上でこのパラメータの値が****と表示されるようになります。値自体が暗号化されるわけではありませんが、画面共有時や誤操作での漏洩リスクを減らせる、手軽なマスキング手段です。
4. DeletionPolicy: DeleteでRDSの削除を確実にする
RDSInstance:
Type: AWS::RDS::DBInstance
DeletionPolicy: Delete
Properties:
BackupRetentionPeriod: 0
DeleteAutomatedBackups: true
DeletionPolicyにはDelete・Retain・Snapshot(RDS専用)の3種類があります。何も指定しないとRDSはデフォルトでスナップショット作成を求められる場合があり、それがdelete-stackの失敗要因になり得ます。DeletionPolicy: Deleteを明示し、BackupRetentionPeriod: 0で自動バックアップも無効にすることで、ハンズオンのような使い捨て環境の削除がスムーズになります。
5. RDS DBサブネットグループは2AZ必須という制約はCloudFormationでも変わらない
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select [1, !GetAZs '']
# RDS Subnet Group must span at least 2 AZs even for single-AZ deployments
RDSインスタンス自体はシングルAZで構築するにもかかわらず、DBサブネットグループの定義には2つ以上の異なるAZのサブネットが必要という制約は、コンソールでもCloudFormationでも同じです。IaC化してもAWSサービス自体の仕様は変わらない、という典型例です。
まとめ
CloudFormationがSecureStringを作成できないという制約と、DeletionPolicy: DeleteによるRDS削除の確実化が、このハンズオンでの核心でした。NoEcho: trueは表示のマスキングに過ぎず暗号化ではない、という点を理解しておくと、本番環境でのパスワード管理設計を誤らずに済みます。