📡

CDKで作成したVPCネットワークのElastic IPを取得する

2021/03/30に公開1

この記事で紹介すること

この記事では、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アドレスであるって書いてなくて困ってました笑