スタック間の前にコンストラクト間試した
コード全体
cdk.ts
import { App } from "aws-cdk-lib";
import { CdkStack } from '../lib/cdk-stack';
const app = new App();
new CdkStack(app, 'Cdk', {
});
cdk-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { VpcStack } from './resource/vpc-stack';
export class CdkStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const vpcStack = new VpcStack(this, 'VpcStack', {
env: {
account: '123456789012',
region: 'ap-northeast-1',
},
});
this.addDependency(vpcStack);
}
}
vpc-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { SubnetType, Vpc } from 'aws-cdk-lib/aws-ec2';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as ssm from 'aws-cdk-lib/aws-ssm';
export class VpcStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const vpc = new Vpc(this, 'Vpc', {
ipAddresses: ec2.IpAddresses.cidr('192.168.0.0/16'),
maxAzs: 2,
subnetConfiguration: [
{
cidrMask: 24,
name: 'public',
subnetType: SubnetType.PUBLIC,
},
],
});
const securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
vpc,
allowAllOutbound: true,
});
securityGroup.addIngressRule(
ec2.Peer.ipv4('54.x.x.x/32'),
ec2.Port.tcp(22)
)
securityGroup.addIngressRule(
ec2.Peer.ipv4('52.x.x.x/16'),
ec2.Port.tcp(22)
)
const ami = new ec2.AmazonLinuxImage({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
cpuType: ec2.AmazonLinuxCpuType.ARM_64
});
const instanceRole = new iam.Role(this, 'InstanceRole', {
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName(
'AmazonSSMManagedInstanceCore',
),
],
});
new ssm.StringParameter(this, 'VPCID', {
parameterName: '/cdk/vpcid',
stringValue: vpc.vpcId,
});
const ec2instance = new ec2.Instance(this, 'Instance', {
vpc: ec2.Vpc.fromLookup(this, 'VPC', {
vpcId: ssm.StringParameter.valueFromLookup(this, '/cdk/vpcid'),
}),
keyName: 'RESEARCH',
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T4G,
ec2.InstanceSize.NANO),
machineImage: ami,
securityGroup: securityGroup,
role: instanceRole,
blockDevices: [
{
deviceName: `/dev/xvda`,
volume: ec2.BlockDeviceVolume.ebs(8, {
volumeType: ec2.EbsDeviceVolumeType.GP3,
})
},
],
});
ec2instance.node.addDependency(vpc);
}
}
肝
- CdkStackからVpcStackをコールするときにenvを渡す。envを渡さないとVpcStack内でEC2コンストラクトを作成するところのssm.StringParameter.valueFromLookupが動作しない
const vpcStack = new VpcStack(this, 'VpcStack', {
env: {
account: '123456789012',
region: 'ap-northeast-1',
},
- VPCIDをSSMパラメータストアに出す
new ssm.StringParameter(this, 'VPCID', {
parameterName: '/cdk/vpcid',
stringValue: vpc.vpcId,
});
- EC2作成コンストラクトでVPCを指定するときに以下のようにする
const ec2instance = new ec2.Instance(this, 'Instance', {
vpc: ec2.Vpc.fromLookup(this, 'VPC', {
vpcId: ssm.StringParameter.valueFromLookup(this, '/cdk/vpcid'),
}),
- EC2作成コンストラクトの直後にVPCコンストラクトへの依存関係をセットする
const ec2instance = new ec2.Instance(this, 'Instance', { //上記と同じブロック
...
});
ec2instance.node.addDependency(vpc);
コメント
CDKでクロススタック参照がつらいので(リソース名変えたいなと思うときに依存性解決エラー)、パラメータストア参照を試したがここまでやっときた。
うまくいかなかった理由はec2.InstanceでVPCを渡すときの型が分かってなかったから。
まだまだだけどおぼろげにどういう指定が必要なのか見えてきた。
追記
セキュリティグループもvpcを参照してたのでパラメータストア参照にしてみた
(VPC名変えるときにセキュリティグループも毎度再作成試みられて依存関係エラーでがちだったのでパラメータストア参照にするとよいかもしれない)
const securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
vpc: ec2.Vpc.fromLookup(this, 'VPC', {
vpcId: ssm.StringParameter.valueFromLookup(this, '/cdk/vpcid'),
}),
allowAllOutbound: true,
});
追記2
vpc-stack.tsは以下の方が良い
securityGroupとec2コンストラクトで、都度fromLookupしてた部分を、ssmvpcにまとめることができた
(+ついでにVPCIDをスネークケースにしたVpcId)
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { SubnetType, Vpc } from 'aws-cdk-lib/aws-ec2';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as ssm from 'aws-cdk-lib/aws-ssm';
export class VpcStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const vpc = new Vpc(this, 'Vpc', {
ipAddresses: ec2.IpAddresses.cidr('192.168.0.0/16'),
maxAzs: 2,
subnetConfiguration: [
{
cidrMask: 24,
name: 'public',
subnetType: SubnetType.PUBLIC,
},
],
});
...
new ssm.StringParameter(this, 'VpcId', {
parameterName: '/cdk/vpcid',
stringValue: vpc.vpcId,
});
const ssmvpc = ec2.Vpc.fromLookup(this, 'SsmVpc', {
vpcId: ssm.StringParameter.valueFromLookup(this, '/cdk/vpcid'),
});
const securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
vpc: ssmvpc,
allowAllOutbound: true,
});
...
const ec2instance = new ec2.Instance(this, 'Instance', {
vpc: ssmvpc,
keyName: 'RESEARCH',
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T4G,
ec2.InstanceSize.NANO),
machineImage: ami,
securityGroup: securityGroup,
role: instanceRole,
blockDevices: [
{
deviceName: `/dev/xvda`,
volume: ec2.BlockDeviceVolume.ebs(8, {
volumeType: ec2.EbsDeviceVolumeType.GP3,
})
},
],
});
ec2instance.node.addDependency(vpc);
}
}