はじめに
AWS CloudFormation(CFn) テンプレートを記述する際、リソースの削除ポリシー(DeletionPolicy)を環境に応じて動的に変更したい要件がありました。
これを実現するために Parameters で値を渡し、 !Ref で参照する案が挙がりましたが、CloudFormationの仕様として許容されるのか疑問が生じました。
そこで、手元の生成AIに質問したところ、様々な回答が返ってきて混乱するという事態になりました。
結論
現在は CloudFormation の標準で 利用可能 です。 (2023年7月頃には利用可能になっていたようです)
検証に利用したテンプレート
AWSTemplateFormatVersion: "2010-09-09" Description: Template for SNS Topic Parameters: DeletionPolicy: Type: String Default: Retain AllowedValues: [Delete, Retain] Resources: SNSTopic: Type: AWS::SNS::Topic Properties: {} DeletionPolicy: !Ref DeletionPolicy UpdateReplacePolicy: !Ref DeletionPolicy
Transform: AWS::LanguageExtensions無し!Ref、!Subいずれでも正常に動作
経緯
生成AIによる回答の不一致
検証用のサンプルテンプレートも併せて出力してくれるだろうという期待のもと、軽い気持ちで質問しました。
「CloudFormationのDeletionPolicyで、!Refを使ってパラメータ値を指定することは可能か?」という問いに対し、得られた回答は以下のように分かれたものになりました。
- Gさん:「不可能」
- DeletionPolicy は静的な文字列(リテラル)である必要があります。
- Cさん:「一部例外的に可能」
- DeletionPolicy は Fn::If のみ例外的にサポートしています。
- Pさん:「条件付きで可能」
- Transform に AWS::LanguageExtensions を指定すれば、DeletionPolicy で !Ref や Fn::If などの組み込み関数を使えます。
どれが正しいのか判別がつかない状況となりました。
実機による検証結果
前述の結論に記載した通り、実際に検証用テンプレートを作成し、デプロイを行うと、特に問題なく動作しました。
結局のところ、実際に手を動かして検証するのが一番確実です。
裏取り
標準機能として実装された旨のニュースリリースなどは見つけられませんでした。 しかし、実際に利用可能であることと、公式ドキュメントに「不可」という明確な記述は無いようなので、ある時期を境に実装されたものと考えられます。
調査の過程で、まず 2022年9月29日 のニュースリリースが目に入りました。
この時点では Transform: 'AWS::LanguageExtensions' の宣言が必須でした。
上記ニュースリリース内で紹介されている cfn-language-discussion の Issue で実装完了のステータスとなっています。
この中で cfn-lint にチェック機能を実装する旨のコメントが確認できます。
We're also planning to add a rule to cfn-lint to check for this.
(また、cfn-lintにこのチェックを行うルールを追加する予定です。)
これを手掛かりに cfn-lint 側のリポジトリを探してみると、プルリクエスト(#2784)に該当するコメントが存在しました。
CloudFormation is implementing this feature within the core language processing, so the feature will be available even without the Language Extensions transform.
(CloudFormationはこの機能をコア言語処理内に実装しているため、Language Extensions変換がなくてもこの機能は利用可能です。)
上記の履歴から、2023年7月頃には既に標準機能で利用可能になっていた事が窺えます。
また、 2023年10月12日投稿のブログでも、この仕様に関する言及が見つかりました。
To retain, or not to retain resources in Cloudformation stacks | CarriageReturn.Nl
Ability to include functions in policies was introduced in AWS::LanguageExtensions transform, but it is now part of standard Cloudformation and transform is no longer required.
(ポリシーへの関数組み込み機能はAWS::LanguageExtensions変換で導入されましたが、現在は標準のCloudFormationの一部となり、変換は不要となりました。)
最初にこのような情報に辿り着けていれば、混乱することもなかったと思います。
おわりに
公式のアナウンスが目立たなかったためか、生成AIでも正確な回答を得ることが難しい状況でした。 このような「仕様がいつの間にか変わっている」ケースでは、こうした事態が起きやすいのかもしれません。
各生成AI(モデル)が異なる回答を提示してくる様子は、さながらエンジニア同士の雑談で意見が割れた際のようでもあり、情報の裏取りの重要性を痛感する良い機会となりました。