Slide 1

Slide 1 text

CDKをCloudFormationテンプレートとして
 利用する際の注意点n選
 1 2024.2.21
 
 JAWS-UG CDK支部 #12


Slide 2

Slide 2 text

2 自己紹介 ★ ハンドルネーム ○ つくぼし ★ 所属 ○ AWS事業本部コンサルティング部 ○ ソリューションアーキテクト ★ 最近ハマっているAWSサービス ○ AWS Lambda ○ AWS CDK ★ SNS/ブログ ○ Twitter(@tsukuboshi0755) ○ DevelopersIO(つくぼし)

Slide 3

Slide 3 text

3 本LTのきっかけ ● 社内でTypeScriptを使用したアプリ開発チームに参加 ● AWSリソースについて、TypeScriptと相性の良いCDKコード に移行したいという要望が挙がる ● ただし諸事情により、一部のリソースをCFnテンプレートで もデプロイ可能にする必要があった

Slide 4

Slide 4 text

4 cdk synthで変換した後のCFnテンプレートは そのままでは使いにくい

Slide 5

Slide 5 text

5 今日話す事 1. CDK独自情報のトリミング 2. CFnパラメータの使用 3. 論理IDの上書き 4. 最後に

Slide 6

Slide 6 text

6 CDK独自情報のトリミング

Slide 7

Slide 7 text

7 cdk synthで出力したテンプレートには CFnだと通常使わない情報が含まれる

Slide 8

Slide 8 text

8 メタデータ(Metadata/CDKMetadata) # cdk synthでの出力テンプレート例 Resources: SampleRole: Type: AWS::IAM::Role # (中略) Metadata: aws:cdk:path: sample-stack/IAMRole/Resource # (中略) CDKMetadata: Type: AWS::CDK::Metadata Properties: Analytics: v2:deflate64:H4sIAAAAAAAA/1WPzWrDMBCEnyV3eWv7DYqgt9Jg917WkmyUSL tGPwlB+N2LbAztaT5mmVmmh67voLvgMzZK3xtnJyhjQnUXcqYrBvQmmSDwGX+ KRQ9lYGfqbddPJFyMvrKz6lXdf8YmcF1DJjIBipzpPSceFTpLi2Sa7ZIDJstUg6MJD6 vMJvSL0LOeoHzjdLzaYRMO/aQRykcmdcZO3oRynPXMwe+VIGeSOSb2g4mcQ20+ qea+clpz2nf8cSWTtkcdsTZwi2+PvoWuhfZyi9Y2IVOy3sBw6C+QtP6IPgEAAA== Metadata: aws:cdk:path: sample-stack/CDKMetadata/Default Condition: CDKMetadataAvailable Conditions: CDKMetadataAvailable: Fn::Or: - Fn::Or: - Fn::Equals: - Ref: AWS::Region - af-south-1 # 以下各リージョンの条件式が並ぶため省略 ● デフォルトでは、各リソースに対する aws:cdk:pathのMetadata、及び CDKMetadataがテンプレートに付与さ れる ● このメタデータを元にバージョンレポー トが生成され、CDK開発チームの改善 に使用されるとの事

Slide 9

Slide 9 text

9 メタデータのトリミング ● 各リソースのMetadataは、cdk.jsonで pathMetadataをfalseにするか、cdk synthコマンドに--no-path-metadataを つけて削除 ● CDKMetadataは、cdk.jsonで versionReportingをfalseにするか、cdk synthコマンドに--no-version-reporting をつけて削除 # cdk.jsonの例 { "app": "npx ts-node --prefer-ts-exts bin/sample.ts", "watch": { "include": [ "**" ], "exclude": [ # (中略) }, "context": { # (中略) } "pathMetadata": false, "versionReporting": false }

Slide 10

Slide 10 text

10 ブートストラップバージョン(CheckBootstrapVersion) # cdk synthでの出力テンプレート例 Parameters: BootstrapVersion: Type: AWS::SSM::Parameter::Value Default: /cdk-bootstrap/hnb659fds/version Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip] # (中略) Rules: CheckBootstrapVersion: Assertions: - Assert: Fn::Not: - Fn::Contains: - - "1" - "2" - "3" - "4" - "5" - Ref: BootstrapVersion AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI. ● CDK v2では、ブートストラップスタック バージョンを検証するルールがテンプ レートに付与される ● CheckBootstrapVersionは、SSMパラ メータのCDKブートストラップスタック バージョンが6未満の場合、エラーが出 力されるというルールになっている

Slide 11

Slide 11 text

11 ブートストラップバージョンのトリミング ● bin配下のCDKアプリで、 DefaultStackSynthesizerの generateBootstrapVersionRuleをfalseに 変更すれば削除可能 ● ちなみにStackSynthesizerとは、CDKの テンプレート生成方法やデプロイ方 法、差分確認方法、Asset格納場所を 定義するクラスとの事 # bin/sample.tsの例 import * as cdk from 'aws-cdk-lib'; import { CdkInterfaceStack } from '../lib/sample-stack'; const app = new cdk.App(); new CdkInterfaceStack(app, 'CdkInterfaceStack', { synthesizer: new cdk.DefaultStackSynthesizer({ generateBootstrapVersionRule: false }), });

Slide 12

Slide 12 text

12 CFnパラメータの使用

Slide 13

Slide 13 text

13 CFnパラメータはCDKパラメータとは別で 考える必要がある

Slide 14

Slide 14 text

14 CFnパラメーターの使用 ● CFnParameterのdefaultオプションに対 して、cdk.jsonやconfig.tsで定義した変 数を渡す ● ただしこのままだと、スタック作成時に パラメータ順序が論理IDのアルファ ベット順でソートされてしまう # lib/sample-stack.tsの例 export class SampleStack extends cdk.Stack { constructor(scope: Construct, id: string, props: SampleStackProps) { super(scope, id, props); const sysName = new cdk.CfnParameter(this, "SysName", { type: "String", default: props.sysName, description: "System name for this stack.", }); const envName = new cdk.CfnParameter(this, "EnvName", { type: "String", default: props.envName, description: "Environment for this stack.", }); const appName = new cdk.CfnParameter(this, "AppName", { type: "String", default: props.appName, description: "Application for this stack.", }); # (中略) };

Slide 15

Slide 15 text

15 AWS::CloudFormation::Interfaceの使用 ● stack.templateOptions.metadataに対し てAWS::CloudFormation::Interfaceを定 義し、想定する順番でパラメータを並 べ替える ● paramGroups配列に対してaddTo ParamGroupsメソッドを使用し、ソートし たい順番で変数のlogicalIdを各々指定 # lib/sample-stack.tsの例 export class SampleStack extends cdk.Stack { constructor(scope: Construct, id: string, props: SampleStackProps) { super(scope, id, props); private paramGroups: ParameterGroup[] = []; private addToParamGroups(label: string, ...param: string[]) { this.paramGroups.push({ Label: { default: label }, Parameters: param, }); } # (各パラメーターは省略) this.addToParamGroups( "Sample Configuration", sysName.logicalId, envName.logicalId, appName.logicalId, ); this.templateOptions.metadata = { "AWS::CloudFormation::Interface": { ParameterGroups: this.paramGroups, }, }; };

Slide 16

Slide 16 text

16 論理IDの上書き

Slide 17

Slide 17 text

17 コンストラクト別の論理ID生成 # cdk synthでの出力テンプレート例(L2コンストラクト使用) Resources: SampleRole6CE32B88: Type: AWS::IAM::Role # (中略) SamplePolicyC8B10014: Type: AWS::IAM::ManagedPolicy Properties: # (中略) Roles: - Ref: SampleRole6CE32B88 ● L1コンストラクトを使用すると、出力さ れるテンプレートの論理IDはコンストラ クト IDそのまま ● L2/L3コンストラクトを使用すると、出力 されるテンプレートの論理IDは「コンス トラクト ID + ランダムなハッシュ値」とな る

Slide 18

Slide 18 text

18 論理IDがランダム生成される事による問題 ● CFnで運用すると、コンソールから作成リソースを確認する 時に見た目が気になる ● L1コンストラクトからL2コンストラクトにリファクタリングする 時に、論理IDを維持できず困る

Slide 19

Slide 19 text

19 論理IDの上書き ● defaultChildを用いて、デフォルトの子 要素からL1コンストラクトを取得 ● overrideLogicalIdメソッドを使用し強制 的に上書きする事で、出力後テンプ レートの論理IDを意図的に制御できる ● ただしやりすぎるとCDKのコード量が多 くなってしまうので注意 # lib/sample-stack.tsの例 export class SampleStack extends cdk.Stack { constructor(scope: Construct, id: string, props: SampleStackProps) { super(scope, id, props); const SampleRole = new iam.Role( this, "SampleRole", # (中略) }, ); const cfnSampleRole = accessRoleforAppRunner.node .defaultChild as iam.CfnRole; cfnSampleRole.overrideLogicalId("SampleRole"); };

Slide 20

Slide 20 text

20 最後に

Slide 21

Slide 21 text

21 まとめ ● cdk synthで出力したテンプレートをCloudFormationとして運用するに は、いくつか考慮するべき点があるので注意 ● 特に以下3点に気をつけると良さそう ○ CDK独自情報のトリミング ○ CFnパラメータの使用 ○ 論理IDの上書き ● CDKはCloudFormationの弱点をカバーできる便利な技術である

Slide 22

Slide 22 text

22 参考文献 ● AWS CDKはじめてのアプリ - AWS CloudFormationテンプレートを合成 する ● AWS CDKツールキット (cdkコマンド) - 構成 (cdk.json) ● ブートストラッピング - 合成のカスタマイズ ● AWS CDKでAWS::CloudFormation::Interfaceを設定してみた ● CDK L1 ConstructのリソースをL2 Constructにリファクタリングする

Slide 23

Slide 23 text

23

Slide 24

Slide 24 text

24 templateOptionsの使い道 ● stack.templateOptions.templateFormat Versionを使用する事で、フォーマット バージョンを指定可能 ● stack.templateOptions.descriptionを使 用する事で、テンプレートの説明を記 述可能 # lib/sample-stack.tsの例 export class SampleStack extends cdk.Stack { constructor(scope: Construct, id: string, props: SampleStackProps) { super(scope, id, props); this.templateOptions.templateFormatVersion = '2010-09-09'; this.templateOptions.description = 'This will appear in the AWS console'; };