🌧️
AWS CDKのARN文字列に対するreplaceに失敗した話
結論
CDKのデプロイ時に確定するような値(ARNやリソース名)に対してreplaceは実行できない。
CloudFormationテンプレートが合成されるまでは内部的に${TOKEN[XXXX]}
という文字列形式で取り扱われている。
公式ドキュメント:https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/tokens.html
失敗例
サンプルコード
.
├── bin
│ └── cdk.ts
├── lib
│ ├── sampleStack.SampleFunction.ts
│ └── sampleStack.ts
(略)
bin/cdk.ts
import * as cdk from 'aws-cdk-lib';
import { SampleStack } from '../lib/sampleStack';
const app = new cdk.App();
new SampleStack(app, 'SampleStack');
lib/sampleStack.SampleFunction.ts
export const handler = () => {
console.log(process.env.queueArn)
};
lib/sampleStack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
export class SampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const queue = new sqs.Queue(this, 'SampleQueue', {
queueName: 'sampleQueue',
visibilityTimeout: cdk.Duration.seconds(300),
});
new NodejsFunction(this, 'SampleFunction', {
functionName: 'sampleFunction',
environment: {
queueArn: queue.queueArn.replace('ap-northeast-1', 'us-east-1'),
}
});
}
}
cdk deployを実行する
Lambdaの環境変数を確認すると、replace処理が実行されていないことが確認できる。
コンソールに出力して確認する
確認のため、エラーを吐かせてコンソールにqueue.queueArn
を出力する。
lib/sampleStack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sqs from 'aws-cdk-lib/aws-sqs';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
export class SampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const queue = new sqs.Queue(this, 'SampleQueue', {
queueName: 'sampleQueue',
visibilityTimeout: cdk.Duration.seconds(300),
});
new NodejsFunction(this, 'SampleFunction', {
functionName: 'sampleFunction',
environment: {
queueArn: queue.queueArn.replace('ap-northeast-1', 'us-east-1'),
}
});
throw new Error(queue.queueArn);
}
}
出力結果は以下のようになった。
queueのARNが${Token[TOKEN.16]}
という文字列で扱われていることが確認できる。
/home/cdk-sample/lib/sampleStack.ts:22
throw new Error(queue.queueArn);
^
Error: ${Token[TOKEN.16]}
at new SampleStack (/home/cdk/lib/sampleStack.ts:22:11)
at Object.<anonymous> (/home/cdk/bin/cdk.ts:5:1)
at Module._compile (node:internal/modules/cjs/loader:1376:14)
at Module.m._compile (/home/cdk/node_modules/ts-node/src/index.ts:1618:23)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Object.require.extensions.<computed> [as .ts] (/home/cdk/node_modules/ts-node/src/index.ts:1621:12)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Function.Module._load (node:internal/modules/cjs/loader:1023:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
at phase4 (/home/cdk/node_modules/ts-node/src/bin.ts:649:14)
Subprocess exited with error 1
補足
文字列のreplace処理は失敗するが、連結処理は実行できる。
以下、公式ドキュメントより抜粋。
次の例に示すように、通常の文字列のように渡したり、連結したりできます。
const functionName = bucket.bucketName + 'Function';
また、次の例に示すように、使用している言語で文字列補間も使用できます。
const functionName = `${bucket.bucketName}Function`;
Discussion