この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
今回作成するリソース
今回は2個のAZにまたがってVPCを定義します。
各AZにはpublic
、private
、isolated
の三つのサブネットを用意します。
図にすると以下のようになります。
public
サブネット
public
サブネットではインターネットゲートウェイへのルーティングが設定されており、直接インターネットとのやり取りが可能です。ElasticIPを割り振ることでEC2インスタンス、ELB、NATゲートウェイが外部からの通信を受け入れることが可能です。
private
サブネット
private
サブネットでは外部との通信はNATゲートウェイを介して行われます。インターネットゲートウェイへのルーティングがなく、基本的にはインターネットからのアクセスはありません。なので、public
サブネットを介して通信が行われることがあります。
isolated
サブネット
isolated
サブネットはローカルとの通信しかできません。ここではpublic
、private
との相互通信が可能です。
DBなど外部への通信が不要で、ローカルなマシンとののみ通信が必要なリソースがしばしば設置されます。
準備
CDKの準備
まずはCDKの準備をします。 今回はPythonを使用します。
PythonのCDKのパッケージのバージョンはaws-cdk-lib==2.9.0
です。
CDKの準備
$ npm init
$ npm install aws-cdk
$ mkdir three-tier
$ cd three-tier
$ npx cdk init --language python
つぎにCDKで使用するPythonパッケージをインストールします。
CDKでPythonを使用する場合はvenv
が用意されているので、それを使うと便利です。
依存関係のインストール
$ source .venv/bin/activate
$ pip3 install -r requirements.txt
以降では常にsource .venv/bin/activate
を行ったあとのvenv
の環境で作業を行います。
コードの準備
まずはスタックを定義します。
three_tier_stack.py
from aws_cdk import (
Stack,
aws_ec2 as ec2
)
from constructs import Construct
VCP_CIDR = '192.168.0.0/16'
class ThreeTierStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
self.vpc = ec2.Vpc(
self,
'three-tier',
cidr=VCP_CIDR,
max_azs=2,
subnet_configuration=[
ec2.SubnetConfiguration(
name='public',
subnet_type=ec2.SubnetType.PUBLIC
),
ec2.SubnetConfiguration(
name='private',
subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT
),
ec2.SubnetConfiguration(
name='isolated',
subnet_type=ec2.SubnetType.PRIVATE_ISOLATED
),
]
)
ここではVPCの定義を行っています。ec2.Vpc
はリソースを作成するためのハイレベルなインターフェイスで、少ない手順でVPCで使用するインターネットゲートウェイや、NATゲートウェイ、サブネットなどの設定ができます。
ここではmax_azs
を2とすることで以下でサブネットが各AZ毎に作成されます。
subnet_configuration
ではサブネットの設定を行っています。CIDRの分割はVPCに設定されたCIDRから自動で行ってくれます。このときsubnet_type
を指定することで先述のpublic
、private
、isolated
の設定ができます。
一緒にapp.py
も書き換えます。
app.py
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from vpc.vpc_stack import ThreeTierStack
app = cdk.App()
vpc_stack = ThreeTierStack(app, "ThreeTierVPC")
cdk.Tags.of(vpc_stack).add('Project', 'three-tier')
app.synth()
ここではStackにタグをつけています。こうすることで、スタック内で作成されるリソースにタグが自動てつけられます。
タグのキーはProject
で値はthree-tier
です。
デプロイする
最初にブートストラップを行い初期化を行ったのち、デプロイします。 デプロイには10分ぐらいの時間がかかります。
デプロイ
$ npx cdk bootstrap
$ npx cdk deploy
結果を確認する
サブネットのAZとCIDRを確認する
まずはサブネットの一覧を確認してみます。(見やすいように適宜開業を入れてあります。)
サブネット一覧
$ aws ec2 describe-subnets \
--filter "Name=tag:Project,Values=three-tier" \
--query 'Subnets[].[Tags[?Key==`Name`].Value,[AvailabilityZone,CidrBlock]] | reverse(sort_by(@, &[0][0]))' \
--output text
ThreeTierVPC/three-tier/publicSubnet2
ap-northeast-1c 192.168.32.0/19
ThreeTierVPC/three-tier/publicSubnet1
ap-northeast-1a 192.168.0.0/19
ThreeTierVPC/three-tier/privateSubnet2
ap-northeast-1c 192.168.96.0/19
ThreeTierVPC/three-tier/privateSubnet1
ap-northeast-1a 192.168.64.0/19
ThreeTierVPC/three-tier/isolatedSubnet2
ap-northeast-1c 192.168.160.0/19
ThreeTierVPC/three-tier/isolatedSubnet1
ap-northeast-1a 192.168.128.0/19
ap-northeast-1a
とap-northeast-1a
にそれぞれサブネットが作られています。
ルートテーブルの確認
続いてルートテーブルの設定を見てみます。
ルートテーブル
$ aws ec2 describe-route-tables \
--filter "Name=tag:Project,Values=three-tier"\
--query 'RouteTables[].[Tags[?Key==`Name`].Value,Routes[].[DestinationCidrBlock,GatewayId,NatGatewayId]] | reverse(sort_by(@, &[0][0]))' \
--output text
ThreeTierVPC/three-tier/publicSubnet2
192.168.0.0/16 local None
0.0.0.0/0 igw-XXXXXX None
ThreeTierVPC/three-tier/publicSubnet1
192.168.0.0/16 local None
0.0.0.0/0 igw-XXXXXX None
ThreeTierVPC/three-tier/privateSubnet2
192.168.0.0/16 local None
0.0.0.0/0 None nat-XXXXXX
ThreeTierVPC/three-tier/privateSubnet1
192.168.0.0/16 local None
0.0.0.0/0 None nat-YYYYYY
ThreeTierVPC/three-tier/isolatedSubnet2
192.168.0.0/16 local None
ThreeTierVPC/three-tier/isolatedSubnet1
192.168.0.0/16 local None
public
サブネットにはインターネットゲートウェイ(igw-XXXXXX)へのルーティングが設定されています。
同様にprivate
サブネットではNATゲートウェイ(nat-XXXXXX、nat-YYYYYY)へのルーティングが定義されています。
isolated
サブネットではローカル以外のルーティングが定義されていません。
また、private
サブネットではサブネット毎に異なったNATゲートウェイが指定されています。
これは各AZのpublic
サブネットに展開されたNATゲートウェイを参照しているためです。
つまりは、同一AZのNATゲートウェイを使用するようになっています。
削除する
最後に削除して終わります。
スタックの削除
$ npx cdk destroy
最後に
CDKを使用することで簡単に複雑な構造のVPCを定義することができました。 細かい設定をしない場合はこのようにハイレベルのインターフェイスを使用することで手順を省くことができます。