インフラエンジニアの皆さん、こんにちは。
IaC(Infrastructure as Code)の現場で、「テンプレートの中にパスワードを書いてしまった」という、SREとして最も背筋が凍るミスを犯したことはありませんか? Gitの履歴に機密情報が残れば、それはもう事故です。
今日は、AWS CloudFormationの奥義の一つ、「動的リファレンス(Dynamic References)」を使い、機密情報をコードから完全に分離する最高にクールな手法を伝授します。これを使えば、セキュリティ強度は劇的に向上し、環境ごとのパラメータ管理も驚くほどスマートになります。
—
1. なぜ「動的リファレンス」なのか?
通常、CloudFormationで値を扱う際は `Parameters` セクションを使いますが、これだとテンプレートを見る権限がある人全員に、機密情報が丸見えになってしまいます。
そこで登場するのが 動的リファレンス です。これは、デプロイの「実行タイミング」でAWS Systems Manager (SSM) Parameter StoreやSecrets Managerから値を直接「フェッチ」してくる仕組みです。テンプレートの静的ファイルには、機密情報が1バイトも残りません。
2. 準備:SSM Parameter Storeへの機密情報の格納
まずは土台作りです。AWS CLIで、データベースのパスワードをセキュアな領域に保存しましょう。
SSMのSecureStringとしてパスワードを保存
aws ssm put-parameter \
–name “/myapp/prod/db-password” \
–value “SuperSecretPassword123!” \
–type “SecureString” \
–region ap-northeast-1
これで、機密情報はAWSの管理下に入りました。これ以降、誰かがテンプレートを覗いても、見えるのは「参照先のパス」だけです。
—
3. 実践:動的リファレンスを用いたテンプレート設計
では、RDSのインスタンスを作成するテンプレートで、この値を呼び出してみましょう。
AWSTemplateFormatVersion: ‘2010-09-09’
Description: “Secure RDS Deployment using Dynamic References”
Resources:
MyDatabase:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceClass: db.t3.micro
Engine: mysql
MasterUsername: admin
# 【重要】ここが動的リファレンスの真髄!
# {{resolve:ssm-secure:パラメータ名:バージョン}} の構文を使います
MasterUserPassword: ‘{{resolve:ssm-secure:/myapp/prod/db-password:1}}’
AllocatedStorage: ’20’
Outputs:
DatabaseEndpoint:
Value: !GetAtt MyDatabase.Endpoint.Address
ここが技術のポイント:
- `{{resolve:ssm-secure:パス:バージョン}}`: これが魔法の構文です。CloudFormationのエンジンがスタック作成時に内部的にAPIを叩き、値をメモリ上に展開します。
- ハードコーディングの完全排除: テンプレートをGitで管理しても、中身はクリーンそのもの。これがSREの理想形です。
—
4. 動作確認:HelloWorldを安全に届ける
このテンプレートをデプロイして、実際にリソースが作成されるか確認します。
1. スタック作成: AWSコンソールかCLIで実行してください。
2. イベントの確認: 「CREATE_COMPLETE」になれば成功です。
3. セキュリティの確認: AWSコンソールでスタックのパラメータタブを見てください。入力値は見えないか、参照先パスだけが表示されているはずです。
もしエラーが出る場合は、IAMロールの権限を確認してください。CloudFormationを実行するロールには、`ssm:GetParameters` や `kms:Decrypt` の権限が必須です。
—
5. 先輩エンジニアからのアドバイス:さらなる高みへ
この手法をマスターしたら、次は AWS Secrets Manager への移行を検討しましょう。
- SSM Parameter Store: シンプルなキーバリューストア。
- Secrets Manager: パスワードの自動ローテーション(定期的な変更)に対応。
本番環境であれば、Secrets Managerを使うのがベストプラクティスです。構文も `{{resolve:secretsmanager:シークレット名:SecretString:キー名}}` と少し拡張するだけでOK。
「コードの中に秘密を隠さない」。
これを徹底するだけで、あなたのインフラ構築スキルは一段階上のレベルに到達します。面倒なパスワード管理から解放され、より本質的なアーキテクチャ設計に時間を使いましょう。
何か詰まったら、いつでも聞いてくださいね。皆さんのデプロイが常に安全で、冪等性が保たれていますように!