AWS CDKでVPCピアリングを構築する

AWS CDKでVPCピアリング環境を作る機会があったので、TypeScriptのサンプルプログラムを共有します。
2021.01.22

AWS CDKでVPCピアリング環境を作る機会があったので、TypeScriptのサンプルプログラムを共有します。

AWS CDKでVPCピアリングのハイレベルConstructは用意されていませんが、 ローレベルConstructを使えばCloudFormationで構築できるものはだいたい構築できます。

次のブログのようにVPCピアリングはCloudFormationで構築できます。

よって、同じようにAWS CDKでもVPCピアリングは構築できます。それを試します。

構成図

ざっくりこんな感じの環境を作ります。

VPCを2つ構築してVPCピアリングで相互接続、ルートテーブルにVPCピアリングのルーティングを追加します。

AWS CDKのサンプルプログラム

TypeScriptのサンプルプログラムは次のとおりです。

#!/usr/bin/env node
import "source-map-support/register";
import * as Core from "@aws-cdk/core";
import * as Ec2 from "@aws-cdk/aws-ec2";

class TestStack extends Core.Stack {
  constructor(scope: Core.Construct, id: string, props?: Core.StackProps) {
    super(scope, id, props);

    // VPCを2つ構築する
    const peerVpc: Ec2.Vpc = new Ec2.Vpc(this, "PeerVPC", {
      cidr: '10.101.0.0/16',
      enableDnsHostnames: true,
      enableDnsSupport: true,
      maxAzs: 2,
      subnetConfiguration: [{
        name: 'PublicSubnet',
        subnetType: Ec2.SubnetType.PUBLIC,
        cidrMask: 24,
        reserved: false,
      },
      ],
    });
    const vpc: Ec2.Vpc = new Ec2.Vpc(this, "VPC", {
      cidr: '10.102.0.0/16',
      enableDnsHostnames: true,
      enableDnsSupport: true,
      maxAzs: 2,
      subnetConfiguration: [{
        name: 'PublicSubnet',
        subnetType: Ec2.SubnetType.PUBLIC,
        cidrMask: 24,
        reserved: false,
      },
      ],
    });

    // VPCピアリングで2つのVPCを相互接続する
    const vpcPeeringConnection = new Ec2.CfnVPCPeeringConnection(this, 'VpcPeeringConnection', {
      peerVpcId: Core.Token.asString(peerVpc.vpcId),
      vpcId: Core.Token.asString(vpc.vpcId),
    });

    // 各VPCのサブネットのルートテーブルにVPCピアリングへのルーティングを追加する
    peerVpc.publicSubnets.map((iSubnet: Ec2.ISubnet, index: number) => {
      new Ec2.CfnRoute(this, `PeerVpcRoute${index}`, {
        routeTableId: iSubnet.routeTable.routeTableId,
        destinationCidrBlock: vpc.vpcCidrBlock,
        vpcPeeringConnectionId: vpcPeeringConnection.ref,
      });
    });
    vpc.publicSubnets.map((iSubnet: Ec2.ISubnet, index: number) => {
      new Ec2.CfnRoute(this, `VpcRoute${index}`, {
        routeTableId: iSubnet.routeTable.routeTableId,
        destinationCidrBlock: peerVpc.vpcCidrBlock,
        vpcPeeringConnectionId: vpcPeeringConnection.ref,
      });
    });
  }
}

const app = new Core.App();
new TestStack(app, 'TestStack');

まず、11〜36行目で2つのVPCを作成しています。
AWS CDKではCIDRを指定しなくてもVPCの構築することは可能ですが、今回VPCピアリングする関係上、CIDRが被らないようにCIDRを指定しています。 また、検証用なのでPublic Subnetのみ構築するよう指定しています。

次に、39〜42行目で2つのVPCをVPCピアリングして相互接続しています。

最後に、45〜58行目でルートテーブルにVPCピアリングへのルーティングを追加しています。
これを理解するには、AWS CDKのVPCクラスがどういった構成になっているか知っておく必要があります。

クラス図にするとこんな感じで、VPCの中にSubnetのリストがあって、Subnet毎にルートテーブルがあります。

ですので、プログラム上では VPC の持つ publicSubnets に対して map して各 SubnetrouteTable にVPCピアリングへのルーティングを追加するようにしています。 VPC作成時にPublic SubnetだけでなくPrivate SubnetやIsolated Subnetを構築する場合は、あわせてそれらのSubnetが持つルートテーブルに対してもルーティングを追加する必要があります。

終わりに

AWS CDKでVPCピアリング環境を作るサンプルプログラムを紹介いたしました。

AWS環境の構築がコードできると何かと便利ですので、ハイレベルConstructとローレベルConstructどちらも使っていろいろな環境を作っていきたいと思います。