LoginSignup
0
0

More than 1 year has passed since last update.

インフラ設計者がAWS CDKに入門してみる②~構築編~

Posted at

前提など

構築の前提や準備などは前回の記事を参照してください。

作成したコード

ひとまず完成したコードがこちらです。
L1コンストラクトで書いてます。コンストラクトについては後日書きたいと思います。
細かく設定したいのでL1を利用しましたが、L2、L3と抽象度が上がるにつれて記載するコードが少なくなっていきます。
(ファイル名は構成とずれてます、、、)

lib/aws-1vpc-3private-subnet-stack.ts
import * as cdk from '@aws-cdk/core';
import {
   CfnVPC,
   CfnSubnet,
   CfnInternetGateway,
   CfnVPCGatewayAttachment,
   CfnRouteTable,
   CfnRoute,
   CfnSubnetRouteTableAssociation, 
   VpcEndpoint
  } from '@aws-cdk/aws-ec2';

export class Aws1Vpc3PrivateSubnetStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const systemName = this.node.tryGetContext('systemName');
    const envType = this.node.tryGetContext('envType');

    //VPC
    const vpc = new CfnVPC(this, 'Vpc', {
      cidrBlock: '10.0.0.0/16',
      tags: [{ key: 'Name', value: `${systemName}-${envType}-vpc` }]
    });

    //InternetGateway
    const igw = new CfnInternetGateway(this, 'igw', {
    })
    new CfnVPCGatewayAttachment(this, 'igwAttachment', {
      internetGatewayId: igw.ref,
      vpcId: vpc.ref
    })

    //PublicSubnet
    const subnetPublic1a = new CfnSubnet(this, 'SubnetPublic1a', {
      cidrBlock: '10.0.0.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1a',
      mapPublicIpOnLaunch: true,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-public-subnet-1a-1` }]
    })
    const subnetPublic1c = new CfnSubnet(this, 'SubnetPublic1c', {
      cidrBlock: '10.0.1.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1c',
      mapPublicIpOnLaunch: true,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-public-subnet-1c-1` }]
    })
    const subnetPublic1d = new CfnSubnet(this, 'SubnetPublic1d', {
      cidrBlock: '10.0.2.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1d',
      mapPublicIpOnLaunch: true,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-public-subnet-1d-1` }]
    })

    //PrivateSubnet
    const subnetPrivate1a1 = new CfnSubnet(this, 'SubnetPrivate1a1', {
      cidrBlock: '10.0.10.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1a',
      mapPublicIpOnLaunch: false,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1a-1` }]
    })
    const subnetPrivate1a2 = new CfnSubnet(this, 'SubnetPrivate1a2', {
      cidrBlock: '10.0.20.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1a',
      mapPublicIpOnLaunch: false,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1a-2` }]
    })
    const subnetPrivate1c1 = new CfnSubnet(this, 'SubnetPrivate1c1', {
      cidrBlock: '10.0.11.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1c',
      mapPublicIpOnLaunch: false,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1c-1` }]
    })
    const subnetPrivate1c2 = new CfnSubnet(this, 'SubnetPrivate1c2', {
      cidrBlock: '10.0.21.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1c',
      mapPublicIpOnLaunch: false,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1c-2` }]
    })
    const subnetPrivate1d1 = new CfnSubnet(this, 'SubnetPrivate1d1', {
      cidrBlock: '10.0.12.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1d',
      mapPublicIpOnLaunch: false,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1d-1` }]
    })
    const subnetPrivate1d2 = new CfnSubnet(this, 'SubnetPrivate1d2', {
      cidrBlock: '10.0.22.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1d',
      mapPublicIpOnLaunch: false,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-private-subnet-1d-2` }]
    })

    //RouteTable
    const publicRouteTable = new CfnRouteTable(this, 'PublicRouteTable', {
      vpcId: vpc.ref,
      tags: [{
        key: 'Name',
        value: `${systemName}-${envType}-Public-RouteTable`,
      }]
    })
    new CfnRoute(this, 'PublicRoute', {
      routeTableId: publicRouteTable.ref,
      destinationCidrBlock: '0.0.0.0/0',
      gatewayId: igw.ref,
    })
    new CfnSubnetRouteTableAssociation(this, 'PublicSubnet1aRouteTableAssociation', {
      routeTableId: publicRouteTable.ref,
      subnetId: subnetPublic1a.ref
    })
    new CfnSubnetRouteTableAssociation(this, 'PublicSubnet1cRouteTableAssociation', {
      routeTableId: publicRouteTable.ref,
      subnetId: subnetPublic1c.ref
    })
    new CfnSubnetRouteTableAssociation(this, 'PublicSubnet1dRouteTableAssociation', {
      routeTableId: publicRouteTable.ref,
      subnetId: subnetPublic1d.ref
    })

    const privateRouteTable = new CfnRouteTable(this, 'privateRouteTable', {
      vpcId: vpc.ref,
      tags: [{
        key: 'Name',
        value: `${systemName}-${envType}-Private-RouteTable`,
      }]
    })
    new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1a1RouteTableAssociation', {
      routeTableId: privateRouteTable.ref,
      subnetId: subnetPrivate1a1.ref
    })
    new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1c1RouteTableAssociation', {
      routeTableId: privateRouteTable.ref,
      subnetId: subnetPrivate1c1.ref
    })
    new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1d1dRouteTableAssociation', {
      routeTableId: privateRouteTable.ref,
      subnetId: subnetPrivate1d1.ref
    })
    new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1a2RouteTableAssociation', {
      routeTableId: privateRouteTable.ref,
      subnetId: subnetPrivate1a2.ref
    })
    new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1c2RouteTableAssociation', {
      routeTableId: privateRouteTable.ref,
      subnetId: subnetPrivate1c2.ref
    })
    new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1d2dRouteTableAssociation', {
      routeTableId: privateRouteTable.ref,
      subnetId: subnetPrivate1d2.ref
    })
  }
}

細かく見ていきます。

インポート

各種パッケージをインポートしています。
ここでインポートするためには、事前にディレクトリ内でnpm installします。ここでは、npm install @aws-cdk/aws-ec2が必要です。

import * as cdk from '@aws-cdk/core';
import {
   CfnVPC,
   CfnSubnet,
   CfnInternetGateway,
   CfnVPCGatewayAttachment,
   CfnRouteTable,
   CfnRoute,
   CfnSubnetRouteTableAssociation, 
   VpcEndpoint
  } from '@aws-cdk/aws-ec2';

スタック定義

ここからがスタック定義になります。
cdk.Stackを継承したAws1Vpc3PrivateSubnetStackクラスに構築したいリソースを定義していきます。
デプロイするとAws1Vpc3PrivateSubnetStackというCfnスタックが作成されます。
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {super(scope, id, props);でコンストラクトの定義をしていますが、基本的にはそのままでも問題ないです。
最後の2行は変数を定義しています。ここで参照されるsystemNameenvTypecdk.jsoncontext内で定義します。

export class Aws1Vpc3PrivateSubnetStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const systemName = this.node.tryGetContext('systemName');
    const envType = this.node.tryGetContext('envType');

VPC

VPCリソースはCidrBlockとTagを指定しています。

    const vpc = new CfnVPC(this, 'Vpc', {
      cidrBlock: '10.0.0.0/16',
      tags: [{ key: 'Name', value: `${systemName}-${envType}-vpc` }]
    });

InternetGateway

igwインスタンスを作成して、VPCにアタッチします。

    const igw = new CfnInternetGateway(this, 'igw', {
    })
    new CfnVPCGatewayAttachment(this, 'igwAttachment', {
      internetGatewayId: igw.ref,
      vpcId: vpc.ref
    })

Subnet

基本的にパブリックもプライベートも同じ定義ですが、mapPublicIpOnLaunchのみtrueがパブリック、falseがプライベートです。指定しないとfalseが設定されます。

    const subnetPublic1a = new CfnSubnet(this, 'SubnetPublic1a', {
      cidrBlock: '10.0.0.0/24',
      vpcId: vpc.ref,
      availabilityZone: 'ap-northeast-1a',
      mapPublicIpOnLaunch: true,
      tags: [{ key: 'Name', value: `${systemName}-${envType}-public-subnet-1a-1` }]
    })

RouteTable

RouteTableの作成には、RouteTable、Route、Associationの3つの要素があります。

    const publicRouteTable = new CfnRouteTable(this, 'PublicRouteTable', {
      vpcId: vpc.ref,
      tags: [{
        key: 'Name',
        value: `${systemName}-${envType}-Public-RouteTable`,
      }]
    })
    new CfnRoute(this, 'PublicRoute', {
      routeTableId: publicRouteTable.ref,
      destinationCidrBlock: '0.0.0.0/0',
      gatewayId: igw.ref,
    })
    new CfnSubnetRouteTableAssociation(this, 'PublicSubnet1aRouteTableAssociation', {
      routeTableId: publicRouteTable.ref,
      subnetId: subnetPublic1a.ref
    })

localへのRoute定義以外が必要な場合はRoute定義が必要ですが、必要ない(プライベートサブネットにアタッチする)場合は、Route定義は不要です。

    const privateRouteTable = new CfnRouteTable(this, 'privateRouteTable', {
      vpcId: vpc.ref,
      tags: [{
        key: 'Name',
        value: `${systemName}-${envType}-Private-RouteTable`,
      }]
    })
    new CfnSubnetRouteTableAssociation(this, 'PrivateSubnet1a1RouteTableAssociation', {
      routeTableId: privateRouteTable.ref,
      subnetId: subnetPrivate1a1.ref
    })

最後に

今回作成したリソースはデプロイしても料金のかからないものばかりなので、CDKの勉強にはちょうど良いかなと思っています。
実際は疎通確認用のEC2やNATGatewayを含んだスタックにする方が、利用用途は多くなると思います。

今後はそういったリソースもチャレンジしていきたいと思います。TypeScript初心者なので、コードが汚いのはご容赦ください。

今回作成したコードはこちらです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0