AWS CDK v2.91.0 で、Fn::FindInMap(Mappings)の既定値がサポートされました

2023.08.12

こんにちは、CX事業本部 Delivery部の若槻です。

本日リリースされた AWS CDK v2.91.0 で、Fn::FindInMap(Mappings)の既定値がサポートされました。

core: Fn.findInMap supports default value (#26543) (8526feb), closes #26125

Mappings とは

そもそも Fn::FindInMap(Mappings)とは、CloudFormation で利用できる組み込み関数の一つで、Mapping と呼ばれるキーと値のペアの集合から、指定したキーに対応する値を取得することができます。これにより単一の CloudFormation テンプレートでアカウントやリージョンなどの環境ごとに異なる値をデプロイ時に注入することができます。

そして、AWS CDK でも CfnMapping コンストラクトクラスを利用して、Mappings を利用できます。

そもそも CDK で環境ごとに異なるパラメーターを使用したい場合は App 層でスタックを初期化する際に注入できるので不要ですが、CloudFormation テンプレートを Mapping 付きで生成して別途利用したい場合などは Mappings を利用することになります。

そして今回の AWS CDK のアップデートで、CfnMapping コンストラクトクラスで Mappings を利用する際の既定値を指定できるようになったので試してみます。

試してみた

モジュールのアップデート

AWS CDK のモジュールを v2.91.0 以上にアップグレードします。

npm i aws-cdk@latest aws-cdk-lib@latest

CDK コード

AWS CDK スタックで CfnMapping コンストラクトクラスを利用して Mappings を作成し、参照してみます。

lib/cdk-sample-stack.ts

import { CfnMapping, Stack, StackProps, CfnOutput } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkSampleStack extends Stack {
  public readonly myFileObjectKey: string;

  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    // Mapping の作成
    const regionTable = new CfnMapping(this, 'RegionTable', {
      mapping: {
        'us-east-1': {
          regionName: 'Hello, US East (N. Virginia)',
        },
        'ap-northeast-1': {
          regionName: 'Hello, Asia Pacific (Tokyo)',
        },
      },
    });

    // Mapping の参照
    const regionName1 = regionTable.findInMap(
      this.region,
      'regionName',
      'Region not found'
    );
    const regionName2 = regionTable.findInMap(
      'not-exist-region',
      'regionName',
      'Region not found'
    );

    // デバッグ用に出力
    new CfnOutput(this, 'RegionName1', {
      value: regionName1,
    });
    new CfnOutput(this, 'RegionName2', {
      value: regionName2,
    });
  }
}

CfnMapping コンストラクトクラスから作成された CfnMapping オブジェクトでは、findInMapメソッドを使用して Mapping を解決して値を取得できます。その時に第三引数で既定値を指定できるようになっています。

CDK Synth してみる

スタックを合成してテンプレートを生成すると、以下のように CfnMapping により Mappings が生成されます。また Outputs には findInMap メソッドで指定した既定値が示されています。ただし Synth 時はまだ値は決定していません。

$ cdk synth 
Transform:
  - AWS::LanguageExtensions
Mappings:
  RegionTable:
    us-east-1:
      regionName: Hello, US East (N. Virginia)
    ap-northeast-1:
      regionName: Hello, Asia Pacific (Tokyo)
Outputs:
  RegionName1:
    Value:
      Fn::FindInMap:
        - RegionTable
        - Ref: AWS::Region
        - regionName
        - DefaultValue: Region not found
  RegionName2:
    Value:
      Fn::FindInMap:
        - RegionTable
        - not-exist-region
        - regionName
        - DefaultValue: Region not found

CDK Deploy してみる

そして実際にデプロイを行うと、Mappings の値が決定され、スタックのデプロイ時に使用されます。

$ cdk deploy
Outputs:
CdkSampleStack.RegionName1 = Hello, Asia Pacific (Tokyo)
CdkSampleStack.RegionName2 = Region not found

キーとして ap-northeast-1this.region)を指定した RegionName1 では、Mappings の値が取得できています。一方でキーとして not-exist-region を指定した RegionName2 では、Mappings にキーが無いので既定値が出力されています。

おわりに

AWS CDK v2.91.0 で、Fn::FindInMap(Mappings)の既定値がサポートされたので試してみました。

CDK を使うようになってから CloudFormation の組み込み関数を意識して使うことはめっきり減っていたので、今回久しぶりにちゃんと触りました。

ただし、下記の「デプロイ時ではなく、合成時に決定する」にもある通り、スタックの挙動の決定はデプロイ時ではなく合成時に App 層で行うことが推奨されています。

CfnMapping のような CloudFormation の組み込み関数は、冒頭でも少し書いた通り、生成したテンプレートを別途利用する用途がある場合などに限って利用するのが良いと思います。

参考

以上