CDKで作成したVPCネットワークのElastic IPを取得する
この記事で紹介すること
この記事では、AWS CDKで、一般的な冗長構成をとったVPCを作成した際に、
自動的に作成されるNAT Gatewayに付与されるElastic IPの値(アドレス)を取得する方法をご紹介します。
背景
AWS CDKを利用すると、VPC内に、2つのAZにまたがるパブリックサブネット x 2、プライベートサブネット x 2、NAT Gateway、NAT GatewayにアタッチするElastic IP、セキュリティグループで構成される一般的な冗長構成のネットワークを簡単に記述することができます。
import * as ec2 from '@aws-cdk/aws-ec2';
const vpc = new ec2.Vpc(this, "vpc", {
natGateways: 1
});
CloudFormationテンプレートで同じ構成のネットワークを記述する場合と比べると、めちゃめちゃ簡単です。
今回、このように作成したネットワーク内のElastic IPをパラメータストアに格納したく、その取得方法を色々と調べてみたので、記事にして紹介します。
結論
結論からいうと、こんな感じの実装で作成したElastic IPの値を取得しました。
const vpc = new ec2.Vpc(this, "vpc", {
natGateways: 1
});
const eips: string[] = [];
vpc.publicSubnets.forEach((subnet, index) => {
const eip = subnet.node.children.find(child => child.node.id == 'EIP') as ec2.CfnEIP;
if (!eip) return;
eips.push(eip.ref);
});
前半の3行は既出のコードで、色々なリソースをもつVPCを作っており、後半のコードでElastic IPの値を取得しています。
Elastic IPは、VPCの中のパブリックサブネットの子ノード(リソース)として管理されています。
今回は、VPC内に2つのパブリックサブネットが作成されるため、まずはパブリックサブネットの個数分forループします。
forループの中では、パブリックサブネットの子ノードにあるElastic IPを、ノードIDがEIP
のものとして探します。
AWS CDKは、CloudFormationを利用してリソースの作成を行うため、それぞれのリソースもCloudFormation上のリソースとして管理されます。
そのため、CloudFormationのリソースのReturn values(Elastic IPの例)で取得できる値は、CDKでも取得することができます。
今回は、eip.ref
とすることで、作成したElastic IPのIPアドレスを取得することができました。
最後に、取得したIPアドレスをパラメータストアに格納するには、下記のように実装します。
import * as ssm from '@aws-cdk/aws-ssm';
new ssm.StringListParameter(this, "ssm-eip", {
parameterName: '/eips',
stringListValue: eips
});
注意点
今回、このような実装をするにあたり、パラメータストアにIPアドレスを格納する前に、ちゃんとIPアドレスが取得できているかを確認しようとしていました。
そのため、下記のように、取得したElastic IPのIPアドレスをコンソール出力していたのですが、この方法だと、${Token[TOKEN.134]}
というような値が出力され、期待した値が取れないと試行錯誤していました。
const eips: string[] = [];
vpc.publicSubnets.forEach((subnet, index) => {
const eip = subnet.node.children.find(child => child.node.id == 'EIP') as ec2.CfnEIP;
if (!eip) return;
eips.push(eip.ref);
});
console.log(eips[0])
Elastic IPのIPアドレスは、実際にCloudFormationスタックが作成されないと確定しないため、今回のようにスタック作成前に利用しようとすると、仮の値が出力されてしまいます。
しかし、これをパラメータストアに格納するなどすると、実際に割り当てられたIPアドレスが確認できます。
おまけ
ついでなので、作成したVPC内のリソースの値を取得し、パラメータストアに格納する方法を紹介します。
-
VPC IDをパラメータストアに格納する方法
new ssm.StringParameter(this, "ssm-vpc-id", { parameterName: '/vpc_id', stringValue: vpc.vpcId });
-
(プライベート)サブネットのIDをパラメータストアに格納する方法
const subnetIds = vpc.privateSubnets.map( subnet => subnet.subnetId ); new ssm.StringListParameter(this, "ssm-subnet-ids", { parameterName: '/subnet_ids', stringListValue: subnetIds });
-
セキュリティグループのIDをパラメータストアに格納する方法
new ssm.StringParameter(this, "ssm-security-group-ids", { parameterName: '/security_group_id', stringValue: vpc.vpcDefaultSecurityGroup });
Discussion
refだったとは...
公式にもこれがIPアドレスであるって書いてなくて困ってました笑