この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS CDKでElastic IPを使った固定IPなNLB環境を作る機会があったので、TypeScriptのサンプルプログラムを共有します。
簡単にできるかなー?と、思っていたんですが、現状(2022/03/30)、cdkでNLBを作成するNetworkLoadBalancerクラスに、 Elastic IPを付与するパラメーターがありません。 正攻法では、NLBにEIPを設定することができないです。
CloudFormationであれば、以下ブログのようにEIPを使った固定IPなNLBを構築できます。
CloudFormationでできることは、ローレベルConstructを使えばだいたいcdkでもできるので、それを試します。
前提条件
AWS CDKはv2を使用しています
$ cdk --version
2.18.0 (build 75c90fa)
構成図
ざっくりこんな感じの環境を作ります。
AWS CDKのサンプルプログラム
TypeScriptのサンプルプログラムは次の通りです。
#!/usr/bin/env node
import "source-map-support/register"
import { Construct } from 'constructs'
import { App, Stack, StackProps, Token } from 'aws-cdk-lib'
import * as ec2 from 'aws-cdk-lib/aws-ec2'
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2'
import * as elbv2Targtes from 'aws-cdk-lib/aws-elasticloadbalancingv2-targets'
class TestStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const vpc = new ec2.Vpc(this, 'VPC', {
maxAzs: 2,
natGateways: 0,
subnetConfiguration: [{
name: 'PublicSubnet',
subnetType: ec2.SubnetType.PUBLIC,
}],
})
// EC2作成
const securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
vpc,
allowAllOutbound: true,
})
securityGroup.addIngressRule(
ec2.Peer.anyIpv4(),
ec2.Port.tcp(80),
)
const bastion = new ec2.BastionHostLinux(this, 'EC2', {
vpc,
securityGroup,
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.BURSTABLE4_GRAVITON,
ec2.InstanceSize.MICRO,
),
})
// NLB作成
const nlb = new elbv2.NetworkLoadBalancer(this, 'NLB', {
vpc,
internetFacing: true,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
},
})
const nlbListener = nlb.addListener(
'NLBListener',
{
port: 80
},
)
nlbListener.addTargets('NLBTargets', {
protocol: elbv2.Protocol.TCP,
port: 80,
targets: [
new elbv2Targtes.InstanceTarget(
bastion.instance,
80
)
]
})
// NLBにEIPを付与する
const cfnLoadBalancer = nlb.node.defaultChild as elbv2.CfnLoadBalancer
cfnLoadBalancer.subnetMappings = vpc.publicSubnets.map((subnet, i) => {
// パブリックサブネットのAZの数だけ、EIPを構築する
const eip = new ec2.CfnEIP(this, `EIP${i}`,{
domain: 'vpc',
})
nlb.node.addDependency(eip)
// EIPを設定したNLBのSubnetMappingPropertyを作成する
return {
subnetId: subnet.subnetId,
allocationId: Token.asString(eip.getAtt('AllocationId')),
} as elbv2.CfnLoadBalancer.SubnetMappingProperty
})
// NLBのSubnet設定を削除する
if (cfnLoadBalancer.subnetMappings !== undefined) {
cfnLoadBalancer.subnets = undefined
}
}
}
const app = new App();
new TestStack(app, 'TestStack');
解説
CloudFormationでNLBにEIPを設定して構築する場合は SubnetMappings
パラメーターを使って、EIPを設定します。
なので、cdkでも同じようにCloudFormationの SubnetMappings
パラメーターを設定してやります。
66行目で、NLBのdefaultChildから、CloudFormationと1:1になるL1コンストラクタのCfnLoadBalancerを取り出しています。
67〜79行目で、VPCのパブリックサブネットのAZの数だけSubnetMappingPropertyを作って、subnetMappingsに設定しています。
81〜83行目で、subnetMappingsを設定したので、重複しているとエラーとなるsubnetsのパラメーターを undefined
にして設定を削除しています。
この様に、subnetMappingsにElastic IPを設定して、デフォルトで設定されるsubnetsを無効にすることで、固定IPなNLBをAWS CDKで構築することができます。