AWS CloudFormation に新しい言語拡張機能「AWS::LanguageExtensions」が追加されました

AWS

2022.9.12

Topics

アップデート内容

CloudFormation の Transform に新しくAWS::LanguageExtensionsが追加されました。

AWS CloudFormation announces new language extensions transform

オプションの Transform セクションで、AWS CloudFormation がテンプレートを処理するために使用するマクロを 1 つ以上指定します。Transform セクションは、強力なマクロシステムを持つ AWS CloudFormation のシンプルな宣言型言語を基盤にして構築されています。
トランスフォーム – AWS CloudFormation

その他の Transform には以下があります。

  • AWS::CodeDeployBlueGreen transform
  • AWS::Include transform
  • AWS::SecretsManager transform
  • AWS::Serverless transform
  • AWS::ServiceCatalog transform

一番有名どころだとAWS::Serverlessかなと思います。
SAM を使ったときに、CloudFormation テンプレートに追加されているものです。

Transform reference – AWS CloudFormation

何ができるのか

新しいAWS::LanguageExtensionsを追加してできるようになることは以下の3つです。

  • Fn::Length
  • Fn::ToJsonString
  • Intrinsic function references in DeletionPolicy and UpdateReplacePolicy attributes

各機能について詳しく解説していきます。

Fn::Length

組込み関数 Fn::Length は、配列または配列を返す組込み関数の中の要素数を返します。
Fn::Length – AWS CloudFormation

多くのプログラミング言語であるのでわかる方も多いのではないでしょうか。

例としては以下のように指定すると 3 が返ってきます。

"Fn::Length": [1, 2, 3]

配列の長さによって処理を切り分けるときに使えそうです。

Fn::ToJsonString

Fn::ToJsonString 組込み関数は、オブジェクトまたは配列をそれに対応する JSON 文字列に変換します。
Fn::ToJsonString – AWS CloudFormation

こちらも、よくプログラミング言語でもある JSON 形式への変換をする関数です。

Fn::ToJsonString:
- key1: value1
    key2: !Ref ParameterName

例としては上記のように指定すると 以下の JSON 文字列になって返ってきます。

"[{\"key1\":\"value1\"},{\"key2\":\"resolvedValue\"}]"

Intrinsic function references in DeletionPolicy and UpdateReplacePolicy attributes

AWS CloudFormation テンプレートに AWS::LanguageExtensions トランスフォームを追加すると、DeletionPolicy と UpdateReplacePolicy のリソース属性を定義するための組込み関数が使用できます。
Intrinsic function references in DeletionPolicy and UpdateReplacePolicy attributes – AWS CloudFormation

今までは組み込み関数を使用してDeletionPolicyUpdateReplacePolicyの値を変更することが出来ませんでした。
今回のアップデートによってFn:IfRefを使って定義することが可能になりました。

これによって、「本番環境では削除しない」や「検証環境なので削除する」といった環境の差分をパラメータを使って切り替えることができるようになりました。

AWSTemplateFormatVersion: 2010-09-09
Transform: "AWS::LanguageExtensions"
Parameters:
  DeletionPolicyParam:
    Type: String
    AllowedValues:
      - Delete
      - Retain
      - Snapshot
    Default: Delete
  UpdateReplacePolicyParam:
    Type: String
    AllowedValues:
      - Delete
      - Retain
      - Snapshot
    Default: Delete
Resources:
  Table:
    Type: "AWS::DynamoDB::Table"
    Properties:
      KeySchema:
        - AttributeName: primaryKey
          KeyType: HASH
      AttributeDefinitions:
        - AttributeName: primaryKey
          AttributeType: S
    DeletionPolicy: !Ref DeletionPolicyParam
    UpdateReplacePolicy: !Ref UpdateReplacePolicyParam

やってみる

実際にそれぞれの挙動について検証していきます。

Fn::Length

よいユースケースが思いつかなかったので、AWS ドキュメントにあった例を参考にしてます。
AWS::LanguageExtensions 変換 – AWS CloudFormation

AWSTemplateFormatVersion: 2010-09-09
Transform: "AWS::LanguageExtensions"
Parameters:
  QueueList:
    Type: CommaDelimitedList
    Default: 1,2,3,4,5
  Prefix01:
    Type: String
    Default: Cold-Airflow
  Prefix02:
    Type: String
    Default: Length
Resources:
  Queue:
    Type: "AWS::SQS::Queue"
    Properties:
      QueueName: !Sub "${Prefix01}-${Prefix02}-Test"
      DelaySeconds:
        "Fn::Length": !Ref QueueList

DelaySeconds
キュー内のすべてのメッセージの配信を遅延させる時間を秒単位で指定します。0〜900(15分)の整数値で指定可能です。デフォルトは0です。
AWS::SQS::Queue – AWS CloudFormation

DelaySecondsは配信遅延を表している値となっています。
実際に作成して値を見ます。

SQSの詳細画面配信遅延5秒

[1,2,3,4,5]で長さは 5 になるので、配信遅延は 5 秒になっています。

Fn::ToJsonString

Secrets Manager の値で検証してみます。

AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::LanguageExtensions"
Description: json
Parameters:
  Prefix01:
    Type: String
    Default: Cold-Airflow
  Prefix02:
    Type: String
    Default: Json
Resources:
  Secret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub "${Prefix01}-${Prefix02}-Test"
      Description: "This is a shared secret."
      SecretString:
        Fn::ToJsonString:
          username: "test-user"

ToJsonStringを使わない場合は以下のようになります。

SecretString: '{"username":"test-user"}'

Secrets Managerに追加された値

CloudFormation を YAML 形式で書く場合、見栄えが統一されるのが良いですね。

DeletionPolicy and UpdateReplacePolicy

Stageの値がProdならRetainを、それ以外ならDeleteになるように設定します。

AWSTemplateFormatVersion: 2010-09-09
Transform: "AWS::LanguageExtensions"
Parameters:
  Stage:
    Type: String
    AllowedValues:
      - Prod
      - Staging
      - Dev
  Prefix01:
    Type: String
    Default: Cold-Airflow
  Prefix02:
    Type: String
    Default: Delete_Update
Conditions:
  IsProd: !Equals
    - !Ref Stage
    - Prod
Resources:
  Group:
    Type: AWS::IAM::Group
    Properties:
      GroupName: !Sub "${Prefix01}-${Prefix02}-Test"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEC2FullAccess
    DeletionPolicy: !If
      - IsProd
      - Retain
      - Delete
    UpdateReplacePolicy: !If
      - IsProd
      - Retain
      - Delete

この検証では、Stageの値がProdの場合とそれ以外で挙動について確認します。

まずはProdの場合

CloudFormationのパラメータ設定画面 Prodバージョン

IAM Group が作成されました。

CloudFormationのイベント画面リソースが作成されたことを確認

では、削除してみます。

Prodバージョンのリソースを削除

Group のステータスがスキップされています。
これは、DeletionPolicyRetainになっているからです。

CloudFormationのイベント画面スキャンされていることを確認
次はStagingの場合

CloudFormationパラメータ設定画面 Stagingバージョン

作成後削除してみます。

CloudFormationのイベント画面 Stagingバージョンでリソースが削除されたことを確認
今後は削除されていることが確認できました。

まとめ

Transform を使うことで使える関数が増えたりより環境に合わせたパラメータの活用が行えるようになりました。
個人的には、DeletionPolicy と UpdateReplacePolicy に Ref が使えるのは便利だなとおもいました。

Cold-Airflow

2021年新卒入社。インフラエンジニアです。RDBが三度の飯より好きです。 主にデータベースやAWSのサーバレスについて書く予定です。あと寒いのは苦手です。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら