CDK の Vpc.fromLookup では StringParameter.valueFromLookup を使う
CDK で既存 VPC とのピアリング設定等を行う場合、Vpc.fromLookup
を用いて VPC を参照する事になると思います。
VPC ID のハードコーディングを避けるには、SSM(Systems Manager)のパラメータストアから値を取得する方法が考えられます。
CDK で SSM パラメータストアの値を参照するには、以下のような方法が用意されていますが、Vpc.fromLookup
の vpcId へ指定できたのは (b) で (a) は駄目でした。
- (a) StringParameter.valueForStringParameter ※
- (b) StringParameter.valueFromLookup
※ valueForTypedStringParameter や new StringParameter(・・・).stringValue でも同じ
(a) の戻り値を Vpc.fromLookup
の vpcId へ設定すると、All arguments to Vpc.fromLookup() must be concrete (no Tokens)
というエラーが発生しました。
これは、(a) が返すのは実際の値ではなく、実際の値を参照するためのトークンだという事が原因のようです。
一方、(b) は cdk synth 時にパラメータストアから値を取得して cdk.context.json
ファイルにキャッシュするようになっており、パラメータストアから取得した実際の値が返ってきます。
ただし、cdk.context.json にキャッシュした後は、パラメータストアから再取得しないようで、パラメータストア側の値を更新しても反映してくれませんでした。※
※ cdk context --clear で cdk.context.json をクリアすると反映されましたが
スタック定義例
import { App, Stack } from '@aws-cdk/core' import { StringParameter } from '@aws-cdk/aws-ssm' import * as ec2 from '@aws-cdk/aws-ec2' const vpcIdParamName = '/sample/vpcid' const app = new App() const stack = new Stack(app, 'VPCPeeringSample', { env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION } }) const vpc = new ec2.Vpc(stack, 'Vpc', { cidr: '192.168.0.0/16', subnetConfiguration: [ { name: 'sample', subnetType: ec2.SubnetType.PUBLIC } ] }) const peerVpc = ec2.Vpc.fromLookup(stack, 'PeerVpc', { vpcId: StringParameter.valueFromLookup(stack, vpcIdParamName) // 以下のようにするとエラーになる // vpcId: StringParameter.valueForStringParameter(stack, vpcIdParamName) }) // VPC ピアリング const vpcPeering = new ec2.CfnVPCPeeringConnection(stack, 'VpcPeering', { vpcId: vpc.vpcId, peerVpcId: peerVpc.vpcId }) vpc.publicSubnets.map((s, i) => { new ec2.CfnRoute(stack, `src-peering-${i}`, { routeTableId: s.routeTable.routeTableId, destinationCidrBlock: peerVpc.vpcCidrBlock, vpcPeeringConnectionId: vpcPeering.ref }) }) ・・・
今回のソースは http://github.com/fits/try_samples/tree/master/blog/20210926/