はじめに
[前回の記事] kumagoro-95.hatenablog.com
前回の記事でCDKのプロジェクト作成までやったので、とりあえずEC2+RDS
の簡単な構成をCDKで書いてみたいと思います。
あんまりちゃんと考えてないので後から変わるかもですが、↓みたいな構成を考えてます。 ちょっと迷いましたが、VPCとサブネットはマネジメントコンソールから作りました。
既存のVPCを取得
EC2やらなんやらを作るために、作成済みのVPCの情報を取得します。
[test-stack.ts]
const vpc = ec2.Vpc.fromLookup(this, "existing-vpc" ,{ vpcId: "vpc-xxxxxxxxxx" //vpcIdを指定 });
これだけで取ってこれそうな感じでしたが、こんなエラーが。
Cannot retrieve value from context provider vpc-provider since account/region are not specified at the stack level. Either configure "env" with explicit account and region when you define your stack, or use the environment variables "CDK_DEFAULT_ACCOUNT" and "CDK_DEFAULT_REGION" to inherit environment information from the CLI (not recommended for production stacks) Subprocess exited with error 1
accountとregionの情報を持ってないのが問題みたい。envにaccountとregionの値を設定
するか、EnvironmentVariablesを使うよう言われている。
参考1:aws-cdkでvpc.fromLookupが動作しない - com4dc’s blog
参考2:cdk deploy 時に Cannot retrieve value from context provider vpc-provider ... と言われる - Qiita
今回は、スタック生成時にenvで渡してあげることにしました。
[cdk-test.ts]
const app = new cdk.App(); new CdkTestStack(app, 'CdkTestStack', { env: { account: 'xxxxxxxxxx', region: 'us-east-1' }
cdk synth
を叩いてみて、既存のVPCの情報を取ってこれることを確認。
VPCが取れたので、次はサブネットを取ってくる。
サブネットはサブネットIDを直接指定して取得しました。
const publicSubnet1 = ec2.Subnet.fromSubnetId(this, 'publicSubnet1', 'subnet-xxxx'); const publicSubnet2 = ec2.Subnet.fromSubnetId(this, 'publicSubnet2', 'subnet-yyyy');
ALB作成
全然覚えてなかったけど、ALBには下記のルールがある。(合ってる?)
外と通信できるALBを作るには、ALBを各AZのパブリックサブネットに紐づけてやる必要がある。
ALBに紐づけるAZは2つ以上でないといけない。
上記2点を踏まえて書いたらこんな感じに。
/** * ALB作成 */ const alb = new elb.ApplicationLoadBalancer(this, 'Alb', { vpc, internetFacing: true, // 外部と通信するためのalbなのでtrue loadBalancerName: "cdk-test-alb", securityGroup: albSecurityGroup, // 後述 vpcSubnets: { subnets: [publicSubnet1, publicSubnet2], } }) // port80からの通信を許可 const listener = alb.addListener('listener', { port: 80 }); listener.addTargets('target', { port: 80, });
参考:class ApplicationLoadBalancer (construct) · AWS CDK
ALBへ紐づけるセキュリティグループは、SSHと外からのHTTP通信を許可しておきます。
const albSecurityGroup = new ec2.SecurityGroup(this, "alb-security-group", { vpc, description: "Allow SSH and HTTP in", allowAllOutbound: true, }); // ssh接続を許可 albSecurityGroup.addIngressRule( ec2.Peer.anyIpv4(), ec2.Port.tcp(22), "Allow SSH Access" ); // http接続を許可 albSecurityGroup.addIngressRule( ec2.Peer.anyIpv4(), ec2.Port.tcp(80), "Allow http Access" );
参考:class SecurityGroup (construct) · AWS CDK
これでALBの設定は完了。
EC2作成
次はEC2インスタンスを作ります。
/** * EC2インスタンス作成 */ const machineImage = new ec2.AmazonLinuxImage() const ec2Instance = new ec2.Instance(this, 'ec2-instance', { vpc: vpc, instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO), machineImage: machineImage, securityGroup: ec2SecurityGroup, availabilityZone: 'us-east-1a', vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED, } }) const ec2Instance2 = new ec2.Instance(this, 'ec2-instance2', { vpc: vpc, instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO), machineImage: machineImage, securityGroup: ec2SecurityGroup, availabilityZone: 'us-east-1b', vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED, } })
参考: class Instance (construct) · AWS CDK
EC2のセキュリティグループでは、SSH接続とALBからのHTTP接続を許可します。
const ec2SecurityGroup = new ec2.SecurityGroup(this, "ec2-security-group", { vpc, description: "Allow SSH and HTTP in", allowAllOutbound: true, }); // ssh接続を許可 ec2SecurityGroup.addIngressRule( ec2.Peer.anyIpv4(), ec2.Port.tcp(22), "Allow SSH Access" ); // albからのhttp接続を許可 ec2SecurityGroup.addIngressRule( albSecurityGroup, ec2.Port.tcp(80), "Allow http Access from Alb" );
これで、ALBのdnsにアクセスするとEC2インスタンスに通信が通るようになりました。 次はRDS作ります。