サイトアイコン 協栄情報ブログ

AWS CDKによる【VPC】の構築

皆様こんにちは。
AWS CDKを利用してマルチAZ3層アーキテクチャ構築をしていきます。
この記事ではVPCの作成を行います。

目次はこちら

1.VPCとは

VPC(Virtual Private Cloud)は、AWS上で仮想的なプライベートネットワークを構築するためのサービスです。これにより、クラウド内で自分専用のネットワークを作り、リソースを安全に管理できます。

概要

2.目的

3.構成図

4.全体構築ソースコード

        # VPCの作成
        vpc = ec2.Vpc(self, "kitaya-vpc",
            ip_addresses=ec2.IpAddresses.cidr("192.168.1.0/24"),
            enable_dns_support=True,
            enable_dns_hostnames=True,
            subnet_configuration=[],
            nat_gateways=0
        )
        Tags.of(vpc).add("Name", "kitaya-vpc")

        # サブネットの作成
        public_subnet_az1 = ec2.CfnSubnet(self, "kitaya-subnet-public-2a",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.0/28",
            availability_zone="ap-northeast-2a"
        )
        Tags.of(public_subnet_az1).add("Name", "kitaya-subnet-public-2a")

        public_subnet_az2 = ec2.CfnSubnet(self, "kitaya-subnet-public-2b",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.16/28",
            availability_zone="ap-northeast-2b"
        )
        Tags.of(public_subnet_az2).add("Name", "kitaya-subnet-public-2b")

        private_subnet_az1 = ec2.CfnSubnet(self, "kitaya-subnet-private-web-2a",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.128/28",
            availability_zone="ap-northeast-2a"
        )
        Tags.of(private_subnet_az1).add("Name", "kitaya-subnet-private-web-2a")

        private_subnet_az2 = ec2.CfnSubnet(self, "kitaya-subnet-private-web-2b",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.144/28",
            availability_zone="ap-northeast-2b"
        )
        Tags.of(private_subnet_az2).add("Name", "kitaya-subnet-private-web-2b")

        protect_subnet_az1 = ec2.CfnSubnet(self, "kitaya-subnet-protect-db-2a",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.160/28",
            availability_zone="ap-northeast-2a"
        )
        Tags.of(protect_subnet_az1).add("Name", "kitaya-subnet-protect-db-2a")

        protect_subnet_az2 = ec2.CfnSubnet(self, "kitaya-subnet-protect-db-2b",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.176/28",
            availability_zone="ap-northeast-2b"
        )
        Tags.of(protect_subnet_az2).add("Name", "kitaya-subnet-protect-db-2b")

        # Elastic IP アドレスの作成
        eip_2a = ec2.CfnEIP(self, "kitaya-nat-eip-2a")
        Tags.of(eip_2a).add("Name", "kitaya-nat-eip-2a")

        eip_2b = ec2.CfnEIP(self, "kitaya-nat-eip-2b")
        Tags.of(eip_2b).add("Name", "kitaya-nat-eip-2b")

        # NATゲートウェイの作成
        nat_gw_2a = ec2.CfnNatGateway(self, "kitaya-nat-2a",
            subnet_id=public_subnet_az1.ref,
            allocation_id=eip_2a.attr_allocation_id
        )
        Tags.of(nat_gw_2a).add("Name", "kitaya-nat-2a")

        nat_gw_2b = ec2.CfnNatGateway(self, "kitaya-nat-2b",
            subnet_id=public_subnet_az2.ref,
            allocation_id=eip_2b.attr_allocation_id
        )
        Tags.of(nat_gw_2b).add("Name", "kitaya-nat-2b")

        # インターネットゲートウェイの作成
        igw = ec2.CfnInternetGateway(self, "kitaya-igw")
        ec2.CfnVPCGatewayAttachment(self, "AttachIgw",
            vpc_id=vpc.vpc_id,
            internet_gateway_id=igw.ref
        )
        Tags.of(igw).add("Name", "kitaya-igw")

        # ルートテーブル: kitaya-rtb-private-web-2a
        rtb_private_web_2a = ec2.CfnRouteTable(self, "kitaya-rtb-private-web-2a",
            vpc_id=vpc.vpc_id
        )
        Tags.of(rtb_private_web_2a).add("Name", "kitaya-rtb-private-web-2a")

        ec2.CfnRoute(self, "RoutePrivateWeb2A2",
            route_table_id=rtb_private_web_2a.ref,
            destination_cidr_block="0.0.0.0/0",
            nat_gateway_id=nat_gw_2a.ref
        )

        # ルートテーブル: kitaya-rtb-private-web-2b
        rtb_private_web_2b = ec2.CfnRouteTable(self, "kitaya-rtb-private-web-2b",
            vpc_id=vpc.vpc_id
        )
        Tags.of(rtb_private_web_2b).add("Name", "kitaya-rtb-private-web-2b")

        ec2.CfnRoute(self, "RoutePrivateWeb2B2",
            route_table_id=rtb_private_web_2b.ref,
            destination_cidr_block="0.0.0.0/0",
            nat_gateway_id=nat_gw_2b.ref
        )

        # ルートテーブル: kitaya-rtb-protect-db
        rtb_protect_db = ec2.CfnRouteTable(self, "kitaya-rtb-protect-db",
            vpc_id=vpc.vpc_id
        )
        Tags.of(rtb_protect_db).add("Name", "kitaya-rtb-protect-db")

        # ルートテーブル: kitaya-rtb-public
        rtb_public = ec2.CfnRouteTable(self, "kitaya-rtb-public",
            vpc_id=vpc.vpc_id
        )
        Tags.of(rtb_public).add("Name", "kitaya-rtb-public")

        ec2.CfnRoute(self, "RoutePublic2",
            route_table_id=rtb_public.ref,
            destination_cidr_block="0.0.0.0/0",
            gateway_id=igw.ref
        )

        # ルートテーブルの紐づけ
        ec2.CfnSubnetRouteTableAssociation(self, "AssocPublicSubnetAz1",
            subnet_id=public_subnet_az1.ref,
            route_table_id=rtb_public.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocPublicSubnetAz2",
            subnet_id=public_subnet_az2.ref,
            route_table_id=rtb_public.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocPrivateSubnetAz1",
            subnet_id=private_subnet_az1.ref,
            route_table_id=rtb_private_web_2a.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocPrivateSubnetAz2",
            subnet_id=private_subnet_az2.ref,
            route_table_id=rtb_private_web_2b.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocProtectSubnetAz1",
            subnet_id=protect_subnet_az1.ref,
            route_table_id=rtb_protect_db.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocProtectSubnetAz2",
            subnet_id=protect_subnet_az2.ref,
            route_table_id=rtb_protect_db.ref
        )

        # ネットワークACLの作成
        acl = ec2.CfnNetworkAcl(self, "kitaya-acl",
            vpc_id=vpc.vpc_id
        )
        Tags.of(acl).add("Name", "kitaya-acl")

        # ネットワークACLルールの追加: アクセスを全て許可
        ec2.CfnNetworkAclEntry(self, "AclEntryInboundAllowAll",
            network_acl_id=acl.ref,
            rule_number=100,
            rule_action="allow",
            egress=False,
            protocol=-1,
            cidr_block="0.0.0.0/0",
            port_range={"from": 0, "to": 65535}
        )

        ec2.CfnNetworkAclEntry(self, "AclEntryOutboundAllowAll",
            network_acl_id=acl.ref,
            rule_number=101,
            rule_action="allow",
            egress=True,
            protocol=-1,
            cidr_block="0.0.0.0/0",
            port_range={"from": 0, "to": 65535}
        )

        # ネットワークACLの紐づけ
        ec2.CfnSubnetNetworkAclAssociation(self, "AssocPublicSubnetAz1Acl",
            subnet_id=public_subnet_az1.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocPublicSubnetAz2Acl",
            subnet_id=public_subnet_az2.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocPrivateSubnetAz1Acl",
            subnet_id=private_subnet_az1.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocPrivateSubnetAz2Acl",
            subnet_id=private_subnet_az2.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocProtectSubnetAz1Acl",
            subnet_id=protect_subnet_az1.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocProtectSubnetAz2Acl",
            subnet_id=protect_subnet_az2.ref,
            network_acl_id=acl.ref
        )

5.ソースコード詳細

5-1.VPCの作成

プロパティは下記

使用するプロパティ 設定値 説明
ip_addresses ec2.IpAddresses.cidr("192.168.1.0/24") 設定したいCIDRを入力
enable_dns_support True DNS解決を有効化
enable_dns_hostnames True DNSホスト名を有効化
subnet_configuration [] サブネットは後で明示的に構築するため"[]"
nat_gateways 0 NATゲートウェイは後で明示的に構築するため"0"
 # VPCの作成
        vpc = ec2.Vpc(self, "kitaya-vpc",
            ip_addresses=ec2.IpAddresses.cidr("192.168.1.0/24"),
            enable_dns_support=True,
            enable_dns_hostnames=True,
            subnet_configuration=[],
            nat_gateways=0
        )
        Tags.of(vpc).add("Name", "kitaya-vpc")

5-2.サブネットの作成

パブリックサブネット(NAT用)、プライベートサブネット(EC2用)、プロテクトサブネット(RDS用)をそれぞれのAZに構築します。

プロパティは下記

使用するプロパティ 設定値 説明
vpc_id vpc.vpc_id 作成するサブネットが所属するVPCのIDを指定
cidr_block 構成図参照 サブネットのCIDRを指定
availability_zone ・ap-northeast-2a
・ap-northeast-2b
配置するAZを指定
        # サブネットの作成
        public_subnet_az1 = ec2.CfnSubnet(self, "kitaya-subnet-public-2a",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.0/28",
            availability_zone="ap-northeast-2a"
        )
        Tags.of(public_subnet_az1).add("Name", "kitaya-subnet-public-2a")

        public_subnet_az2 = ec2.CfnSubnet(self, "kitaya-subnet-public-2b",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.16/28",
            availability_zone="ap-northeast-2b"
        )
        Tags.of(public_subnet_az2).add("Name", "kitaya-subnet-public-2b")

        private_subnet_az1 = ec2.CfnSubnet(self, "kitaya-subnet-private-web-2a",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.128/28",
            availability_zone="ap-northeast-2a"
        )
        Tags.of(private_subnet_az1).add("Name", "kitaya-subnet-private-web-2a")

        private_subnet_az2 = ec2.CfnSubnet(self, "kitaya-subnet-private-web-2b",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.144/28",
            availability_zone="ap-northeast-2b"
        )
        Tags.of(private_subnet_az2).add("Name", "kitaya-subnet-private-web-2b")

        protect_subnet_az1 = ec2.CfnSubnet(self, "kitaya-subnet-protect-db-2a",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.160/28",
            availability_zone="ap-northeast-2a"
        )
        Tags.of(protect_subnet_az1).add("Name", "kitaya-subnet-protect-db-2a")

        protect_subnet_az2 = ec2.CfnSubnet(self, "kitaya-subnet-protect-db-2b",
            vpc_id=vpc.vpc_id,
            cidr_block="192.168.1.176/28",
            availability_zone="ap-northeast-2b"
        )
        Tags.of(protect_subnet_az2).add("Name", "kitaya-subnet-protect-db-2b")

5-3.Elastic IP アドレスの作成

それぞれのAZにNATゲートウェイを作成するので2つ作成します。

 # Elastic IP アドレスの作成
        eip_2a = ec2.CfnEIP(self, "kitaya-nat-eip-2a")
        Tags.of(eip_2a).add("Name", "kitaya-nat-eip-2a")

        eip_2b = ec2.CfnEIP(self, "kitaya-nat-eip-2b")
        Tags.of(eip_2b).add("Name", "kitaya-nat-eip-2b")

5-4.NATゲートウェイの作成

作成したElastic IP アドレスを使用して各AZにNATゲートウェイを作成します。

プロパティは下記

使用するプロパティ 設定値 説明
subnet_id ・public_subnet_az1.ref
・public_subnet_az2.ref
配置するサブネットを指定
allocation_id ・eip_2a.attr_allocation_id
・eip_2b.attr_allocation_id
使用するElastic IP アドレスを指定
Tags.of(vpc).add() "Name", "ソースコード参照" タグとキーの値を設定
        # NATゲートウェイの作成
        nat_gw_2a = ec2.CfnNatGateway(self, "kitaya-nat-2a",
            subnet_id=public_subnet_az1.ref,
            allocation_id=eip_2a.attr_allocation_id
        )
        Tags.of(nat_gw_2a).add("Name", "kitaya-nat-2a")

        nat_gw_2b = ec2.CfnNatGateway(self, "kitaya-nat-2b",
            subnet_id=public_subnet_az2.ref,
            allocation_id=eip_2b.attr_allocation_id
        )
        Tags.of(nat_gw_2b).add("Name", "kitaya-nat-2b")

5-5.インターネットゲートウェイの作成

VPCを構築する上で作成必須の項目となります。
インターネットゲートウェイを作成し、VPCにアタッチします。

アタッチに使用したプロパティは下記です。

使用するプロパティ 設定値 説明
vpc_id vpc.vpc_id インターネットゲートウェイをアタッチするVPCを指定
internet_gateway_id igw.ref アタッチするインターネットゲートウェイを指定
# インターネットゲートウェイの作成
        igw = ec2.CfnInternetGateway(self, "kitaya-igw")
        ec2.CfnVPCGatewayAttachment(self, "AttachIgw",
            vpc_id=vpc.vpc_id,
            internet_gateway_id=igw.ref
        )
        Tags.of(igw).add("Name", "kitaya-igw")

5-6.ルートテーブルの作成

サブネットが使用するルートテーブルを作成します。
また、ルートテーブルが使用するルートも併せて作成します。
その後、ルートテーブルと各サブネットを紐づけます。

プロパティは下記

使用するプロパティ 設定値 説明
vpc_id vpc.vpc_id ルートテーブルが関連付けられるVPCを指定

プロパティは下記

使用するプロパティ 設定値 説明
route_table_id vpc.vpc_id ルートを追加する対象のルートテーブルを指定
destination_cidr_block 構成図参照 ルートの宛先 CIDR ブロックを指定
nat_gateway_id ソースコード参照 ルートがトラフィックを送信するためのNATゲートウェイを指定
gateway_id igw.ref ルートがトラフィックを送信するためのゲートウェイを指定
※今回はインターネットゲートウェイ

プロパティは下記

使用するプロパティ 設定値 説明
subnet_id ソースコード参照 紐づけるサブネットを指定
route_table_id ソースコード参照 紐づけるルートテーブルを指定
        # ルートテーブル: kitaya-rtb-private-web-2a
        rtb_private_web_2a = ec2.CfnRouteTable(self, "kitaya-rtb-private-web-2a",
            vpc_id=vpc.vpc_id
        )
        Tags.of(rtb_private_web_2a).add("Name", "kitaya-rtb-private-web-2a")

        ec2.CfnRoute(self, "RoutePrivateWeb2A2",
            route_table_id=rtb_private_web_2a.ref,
            destination_cidr_block="0.0.0.0/0",
            nat_gateway_id=nat_gw_2a.ref
        )

        # ルートテーブル: kitaya-rtb-private-web-2b
        rtb_private_web_2b = ec2.CfnRouteTable(self, "kitaya-rtb-private-web-2b",
            vpc_id=vpc.vpc_id
        )
        Tags.of(rtb_private_web_2b).add("Name", "kitaya-rtb-private-web-2b")

        ec2.CfnRoute(self, "RoutePrivateWeb2B2",
            route_table_id=rtb_private_web_2b.ref,
            destination_cidr_block="0.0.0.0/0",
            nat_gateway_id=nat_gw_2b.ref
        )

        # ルートテーブル: kitaya-rtb-protect-db
        rtb_protect_db = ec2.CfnRouteTable(self, "kitaya-rtb-protect-db",
            vpc_id=vpc.vpc_id
        )
        Tags.of(rtb_protect_db).add("Name", "kitaya-rtb-protect-db")

        # ルートテーブル: kitaya-rtb-public
        rtb_public = ec2.CfnRouteTable(self, "kitaya-rtb-public",
            vpc_id=vpc.vpc_id
        )
        Tags.of(rtb_public).add("Name", "kitaya-rtb-public")

        ec2.CfnRoute(self, "RoutePublic2",
            route_table_id=rtb_public.ref,
            destination_cidr_block="0.0.0.0/0",
            gateway_id=igw.ref
        )

        # ルートテーブルの紐づけ
        ec2.CfnSubnetRouteTableAssociation(self, "AssocPublicSubnetAz1",
            subnet_id=public_subnet_az1.ref,
            route_table_id=rtb_public.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocPublicSubnetAz2",
            subnet_id=public_subnet_az2.ref,
            route_table_id=rtb_public.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocPrivateSubnetAz1",
            subnet_id=private_subnet_az1.ref,
            route_table_id=rtb_private_web_2a.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocPrivateSubnetAz2",
            subnet_id=private_subnet_az2.ref,
            route_table_id=rtb_private_web_2b.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocProtectSubnetAz1",
            subnet_id=protect_subnet_az1.ref,
            route_table_id=rtb_protect_db.ref
        )

        ec2.CfnSubnetRouteTableAssociation(self, "AssocProtectSubnetAz2",
            subnet_id=protect_subnet_az2.ref,
            route_table_id=rtb_protect_db.ref
        )

5-6.ネットワークACLの作成

VPCを構築する上で作成必須の項目となります。
今回はサブネット単位でセキュリティの管理をおこないません。
※セキュリティグループで管理

そのためインバウンドアウトともに全トラフィックを許可します。
ネットワークACL、ネットワークACLルールを作成し、すべてのサブネットにアタッチします。

プロパティは下記

使用するプロパティ 設定値 説明
vpc_id vpc.vpc_id ネットワークACLを作成するVPCを指定

プロパティは下記

使用するプロパティ 設定値 説明
network_acl_id acl.ref ルートを追加する対象のルートテーブルを指定
rule_number 100 ACL内でのルールの優先順位で番号が小さいほど優先度が高い
rule_action allow 許可か拒否(今回は許可)
egress False インバウンドトラフィックを意味する
egress True アウトバウンドトラフィックを意味する
protocol -1 全てのプロトコルを対象
cidr_block 0.0.0.0/0 全トラフィックを許可
port_range "from": 0, "to": 65535 プロトコル番号の指定(全ポート)

プロパティは下記

使用するプロパティ 設定値 説明
subnet_id ソースコード参照 ネットワークACL を関連付ける対象のサブネットを指定
network_acl_id acl.ref 関連付けるネットワークACLを指定
        # ネットワークACLの作成
        acl = ec2.CfnNetworkAcl(self, "kitaya-acl",
            vpc_id=vpc.vpc_id
        )
        Tags.of(acl).add("Name", "kitaya-acl")

        # ネットワークACLルールの追加: アクセスを全て許可
        ec2.CfnNetworkAclEntry(self, "AclEntryInboundAllowAll",
            network_acl_id=acl.ref,
            rule_number=100,
            rule_action="allow",
            egress=False,
            protocol=-1,
            cidr_block="0.0.0.0/0",
            port_range={"from": 0, "to": 65535}
        )

        ec2.CfnNetworkAclEntry(self, "AclEntryOutboundAllowAll",
            network_acl_id=acl.ref,
            rule_number=100,
            rule_action="allow",
            egress=True,
            protocol=-1,
            cidr_block="0.0.0.0/0",
            port_range={"from": 0, "to": 65535}
        )

        # ネットワークACLの紐づけ
        ec2.CfnSubnetNetworkAclAssociation(self, "AssocPublicSubnetAz1Acl",
            subnet_id=public_subnet_az1.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocPublicSubnetAz2Acl",
            subnet_id=public_subnet_az2.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocPrivateSubnetAz1Acl",
            subnet_id=private_subnet_az1.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocPrivateSubnetAz2Acl",
            subnet_id=private_subnet_az2.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocProtectSubnetAz1Acl",
            subnet_id=protect_subnet_az1.ref,
            network_acl_id=acl.ref
        )

        ec2.CfnSubnetNetworkAclAssociation(self, "AssocProtectSubnetAz2Acl",
            subnet_id=protect_subnet_az2.ref,
            network_acl_id=acl.ref
        )

6.感想

AWS CDKでの構築は初めてでエラーの解読にかなり時間を要しました。
今後のリソース構築で少しづつ慣れていこうと思います。

モバイルバージョンを終了