前回の続きです。

Former2でリソースをインポートできましたが、生成されるCDKはL1 Constructを使っています。
L2 Constructを使ったほうがCDKのメリットを活かせます。
L2に自動でリファクタリングすることは現在できないため、手動にはなりますがリファクタリングしていきます。
結論から書くと、普通にリファクタリングすると生成されるCFnテンプレートの論理IDが変わってリソース再作成が発生します。
そのため、overrideLogicalId
メソッドを使って論理IDを変更しないようにする必要があります。
スナップショットテスト導入
リファクタリング時、意図しない変更を検知できるようにスナップショットテストを導入します。
Amazon Web Services ブログ あらゆる言語でのCDKアプリケーションのテスト
# test/import-cdk.test.ts
import * as cdk from 'aws-cdk-lib';
import { Template } from 'aws-cdk-lib/assertions';
import { ImportCdkStack } from '../bin/import-cdk'
test('SQS Queue Snapshot', () => {
const app = new cdk.App();
const stack = new ImportCdkStack(app, 'ImportCdkStack', { env: { region: 'ap-northeast-1' } });
expect(Template.fromStack(stack)).toMatchSnapshot();
});
テストを実行して、スナップショットを生成します。
$ npm run test
> import-cdk@0.1.0 test /Users/satomasaki/work/src/github.com/msato0731/import-cdk
> jest
PASS test/import-cdk.test.ts
✓ SQS Queue Snapshot (16 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 1 passed, 1 total
Time: 3.293 s, estimated 4 s
生成されるCFnテンプレートに変更がなければ、2回目以降の実行時も同様にテストが成功します。
既存のL1 ConstructをL2にリファクタリング
スナップショットテストを導入できたところで、リファクタリングしていきます。
L2に置き換えた結果は以下です。
#!/usr/bin/env node
import 'source-map-support/register';
// cdk v2に変更
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';
export class ImportCdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// L1 Construct
// const SQSQueue = new sqs.CfnQueue(this, 'SQSQueue', {
// delaySeconds: 0,
// maximumMessageSize: 262144,
// messageRetentionPeriod: 345600,
// receiveMessageWaitTimeSeconds: 0,
// visibilityTimeout: 40,
// queueName: "import-test",
// });
// L2 Construct
const SQSQueue = new sqs.Queue(this, 'SQSQueue', {
deliveryDelay: cdk.Duration.seconds(0),
maxMessageSizeBytes: 262144,
retentionPeriod: cdk.Duration.days(4),
receiveMessageWaitTime: cdk.Duration.seconds(0),
visibilityTimeout: cdk.Duration.seconds(40),
queueName: "import-test",
});
// L2 Constructにすると論理IDにランダムな文字列が入るため上書き
(SQSQueue.node.defaultChild as sqs.CfnQueue).overrideLogicalId("SQSQueue")
SQSQueue.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY)
}
}
const app = new cdk.App();
new ImportCdkStack(app, 'ImportCdkStack', { env: { region: 'ap-northeast-1' } });
app.synth();
テスト結果も問題なさそうです。
$ npm run test
> import-cdk@0.1.0 test /Users/satomasaki/work/src/github.com/msato0731/import-cdk
> jest
PASS test/import-cdk.test.ts (8.89 s)
✓ SQS Queue Snapshot (23 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 1 passed, 1 total
Time: 8.939 s, estimated 9 s
diffの結果は、Metadataの変更のみです。
npm run cdk diff ImportCdkStack (git)-[master]
> import-cdk@0.1.0 cdk /Users/satomasaki/work/src/github.com/msato0731/import-cdk
> cdk "diff" "ImportCdkStack"
Stack ImportCdkStack
Resources
[~] AWS::SQS::Queue SQSQueue SQSQueue
└─ [~] Metadata
└─ [~] .aws:cdk:path:
├─ [-] ImportCdkStack/SQSQueue
└─ [+] ImportCdkStack/SQSQueue/Resource
overrideLogicalId
メソッドを使って論理IDを固定する
上記コードの以下の記述についてです。
(SQSQueue.node.defaultChild as sqs.CfnQueue).overrideLogicalId("SQSQueue")
L2とL1で生成されるCFnテンプレートの論理IDが変わることに対する対策です。
リソース名が変わると、既存のリソースが削除されて置き換わるような動きになります。
CDKのConstruct IDをもとに、CFnの論理IDが設定されます。
L1とL2で以下のような違いがあります。
- L1: Construct Id (例 SQSQueue
- L2: Construct Id + ランダムな文字列 (例 SQSQueue7674CD17
※例はConstruct IdにSQSQueueを設定した場合
# 論理ID上書きしなかった場合の「cdk diff」
$ npm run cdk diff ImportCdkStack
> import-cdk@0.1.0 cdk /Users/satomasaki/work/src/github.com/msato0731/import-cdk
> cdk "diff" "ImportCdkStack"
Stack ImportCdkStack
Resources
[-] AWS::SQS::Queue SQSQueue destroy
[+] AWS::SQS::Queue SQSQueue SQSQueue7674CD17
# スナップショットテストも失敗
$ npm run test
> import-cdk@0.1.0 test /Users/satomasaki/work/src/github.com/msato0731/import-cdk
> jest
FAIL test/import-cdk.test.ts
✕ SQS Queue Snapshot (21 ms)
● SQS Queue Snapshot
expect(received).toMatchSnapshot()
Snapshot name: `SQS Queue Snapshot 1`
- Snapshot - 1
+ Received + 1
@@ -5,11 +5,11 @@
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]",
"Type": "AWS::SSM::Parameter::Value",
},
},
"Resources": Object {
- "SQSQueue": Object {
+ "SQSQueue7674CD17": Object {
overrideLogicalIdメソッドを使って、上書きすることでL1で作ったときと同様の論理IDにすることができます。
参考 How to Override Logical IDs of Resources in AWS CDK


