CFnでタグ付与をIf文を使用して複数付与する方法
背景・目的
開発環境ではタグ付与はなし
検証環境、本番環境では複数のタグを付与したいとの要望があった。
この場合、Conditionsを使用して開発環境の判定後にタグを付与したいが、そもそもIf文を使用したタグ付与の方法や、
タグを複数渡したいときのテンプレート記述方法の情報が見当たらなかった。
早く知りたい方向け
その場合、以下の記述で実現できた。(S3バケット作成)
AWSTemplateFormatVersion: 2010-09-09
Description: Add multi tag with condition
Parameters:
Env:
Type: String
AllowedValues:
- dev
- stg
- prod
Default: dev
Conditions:
IsDev: !Equals [!Ref Env, dev]
Resources:
S3Hosting:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "${Env}-s3-bucket-${AWS::Region}"
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
Tags:
!If
- IsDev
- - !Ref AWS::NoValue
- - Key: tag1
Value: value1
- Key: tag2
Value: value2
- Key: tag3
Value: value3
詳しく
どうしてその記述なのか知りたい方は以下参考にしてください。
まずは公式ドキュメント
公式ドキュメントを見るとCloudFormationテンプレートによるAWSリソースタグを付与したい場合は以下の記述で可能
公式ドキュメント:AWS::S3::Bucket
Tags:
- Key: String
Value: String
初めのハイフンがリスト形式で渡すことを表し、その後のKey,Valueのセットがオブジェクトを表す。
ちなみにJSONで見るとわかりやすい
"Tags" : [
{
"Key" : String,
"Value" : String
}
],
次にタグを複数渡したいときの実装
これは簡単ですね。いろいろな方が書かれています。
Tags:
- Key: String
Value: String
- Key: String2
Value: String2
- Key: String3
Value: String3
本題
ではこれにIf文による条件分岐があった場合どのように書けばいいでしょうか。
今回条件分岐含めて、1行での書き方もあるのでしょうが可読性のために改行して記述したいです。
そのためCFn上でIf文は以下のようになります
!If
- <条件>
- <trueの場合>
- <falseの場合>
この書き方を踏まえると以下のようにしてテンプレートに記述すると目的を達成できそうです!!
AWSTemplateFormatVersion: 2010-09-09
Description: Add multi tag with condition
Parameters:
Env:
Type: String
AllowedValues:
- dev
- stg
- prod
Default: dev
Conditions:
IsDev: !Equals [!Ref Env, dev]
Resources:
S3Hosting:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "${Env}-s3-bucket-${AWS::Region}"
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
Tags:
!If
- IsDev
- - !Ref AWS::NoValue
- - Key: tag1
Value: value1
- Key: tag2
Value: value2
- Key: tag3
Value: value3
長くなってしまったので必要な部分のみ取り出すと以下です。
Tags:
!If
- IsDev
- - !Ref AWS::NoValue
- - Key: tag1
Value: value1
- Key: tag2
Value: value2
- Key: tag3
Value: value3
Conditionsで記述した環境を判定するIsDev(開発環境)の場合は擬似パラメータ"!Ref AWS::NoValue"を使用します。
このときTagsプロパティにはリスト形式で渡す必要があるので-(ハイフン)を忘れないようにしましょう。
※もしかしたらハイフンいらないかもです。
またIsDevでない場合は複数のタグを渡す必要があります。
1つ目のハイフンはIf文の条件分岐を、2つめのハイフンはリストで渡すことを表しています。
もしかしたら以下のように記述するほうが見やすい方もいるかも知れません。
Tags:
!If
- IsDev
- - !Ref AWS::NoValue
-
- Key: tag1
Value: value1
- Key: tag2
Value: value2
- Key: tag3
Value: value3
ちなみにChatgptに1行で書いてとお願いすると以下のように返ってきました。
実際試していないので試した方は結果を教えて下さい。(個人的には見にくいです。。。)
Tags: !If [IsDev, [{Key: tag1, Value: value1}, {Key: tag2, Value: value2}], !Ref AWS::NoValue]
実際に実行してみると
簡単なテンプレートになりますが、実際にスタック作成してみました。
使用したテンプレートはこちら
開発環境想定
- パラメータにdevを指定して作成
- 作成されたS3バケット
タグが付与されていないことが確認できた。
本番環境想定
- パラメータにprodを指定して作成
- 作成されたS3バケット
タグが複数付与されていることが確認できた。
おわりに
いかがだったでしょうか
恥ずかしながら実務ではこんな簡単なことに苦しんでしまい、時間を溶かしてしまいました。
ハイフンつける場所をまちがえてエラー起こしたりと・・・
CFnでは記述するハイフンが何を意味しているのかをしっかり考える必要がありそうですね。
ちなみにLambda関数のSAM形式ではこちらの記述ではうまくいきませんでした。
こちらについてはまた別の記事で解説したいと考えています。
テンプレートに誤りありましたら、ご指摘をお願いいたします。
最後まで読んでくれてありがとうございました。
Discussion