CloudFormation入門① VPC / Subnet / Internet Gateway
はじめに
今回はVPC周りの構築をやっていきます。(初めてCloudFormationを使いますが、何回か書けば少しは慣れてくるだろうということで5回連載していきます。)
目標
今回は以下のような構成を作成します。
VPCの中にパプリックサブネットとプライベートサブネットが1つずつある構成で、パブリックサブネットのルートテーブルでインターネットゲートウェイを指定します。
最終的なコード
先に最終的なコードをお見せします。
AWSTemplateFormatVersion: 2010-09-09
# VPC
Resources:
TestVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
-
Key: Name
Value: TestVPC
# サブネット
## パブリックサブネット
TestPublicSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: 10.0.10.0/24
MapPublicIpOnLaunch: true
VpcId: !Ref TestVPC
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: ""
Tags:
-
Key: Name
Value: TestPublicSubnet
## プライベートサブネット
TestPrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: 10.0.20.0/24
MapPublicIpOnLaunch: false
VpcId: !Ref TestVPC
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: ""
Tags:
-
Key: Name
Value: TestPrivateSubnet
# インターネットゲートウェイ
## 作成
TestInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
-
Key: Name
Value: TestInternetGateway
## VPCにアタッチ
AttachInternetGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref TestInternetGateway
VpcId: !Ref TestVPC
# ルートテーブル(パブリック)
## 作成
TestRouteTableForPublicSubnet:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref TestVPC
Tags:
-
Key: Name
Value: TestRouteTableForPublicSubnet
## インターネットゲートウェイを指定
RouteTableForPublicSubnet:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref TestRouteTableForPublicSubnet
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref TestInternetGateway
## ルートテーブルとパブリックサブネットを紐付け
AssociateRouteTableForPublicSubnet:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref TestRouteTableForPublicSubnet
SubnetId: !Ref TestPublicSubnet
# ルートテーブル(プライベート)
## 作成
TestRouteTableForPrivateSubnet:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref TestVPC
Tags:
-
Key: Name
Value: TestRouteTableForPrivateSubnet
## ルートテーブルとプライベートサブネットを紐付け
AssociateRouteTableForPrivateSubnet:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref TestRouteTableForPrivateSubnet
SubnetId: !Ref TestPrivateSubnet
解説
ここからいくつかのパートに分けて解説していきます。
フォーマットバージョン
AWSTemplateFormatVersion: 2010-09-09
テンプレートの機能を識別するフォーマットバージョンになります。最新のバージョンが出てこない限りは脳死で書きます。
【補足】リソース定義の基本構文
今回の基本構文はこのようになっています。
Resources:
Logical ID:
Type: Resource type
Properties:
Set of properties
Resources
セクションの基本構文は、Resources
をキー名とします。Logical ID
で論理ID
を指定します。論理IDはテンプレート内で一意である必要があり、他のリソースの関連付けに使用することができます。
Type
ではリソースのタイプを定義します。CloudFormationで使用できるリソースタイプは公式に記載されています。
Properties
ではリソースに対して指定できる追加オプションを定義します。プロパティを宣言する必要のないリソースの場合は、省略できます。
VPC
# VPC
Resources:
TestVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
-
Key: Name
Value: TestVPC
リソースタイプはType: AWS::EC2::VPC
とします。PropertiesでVPCのCidrBlockを定義する必要があります。TagsにKeyとValueを設定していますが、必須ではありません。コンソール上で識別しやすいように名前をつけました。作成後は以下のようにコンソール上で表示されます。
サブネット
# サブネット
## パブリックサブネット
TestPublicSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: 10.0.10.0/24
MapPublicIpOnLaunch: true
VpcId: !Ref TestVPC
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: ""
Tags:
-
Key: Name
Value: TestPublicSubnet
## プライベートサブネット
TestPrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: 10.0.20.0/24
MapPublicIpOnLaunch: false
VpcId: !Ref TestVPC
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: ""
Tags:
-
Key: Name
Value: TestPrivateSubnet
パブリックサブネット、プライベートサブネットの作成時はどちらもType: AWS::EC2::Subnet
のリソースタイプを設定します。CidrBlockはVPCで設定した値に含まれる範囲に設定します。
サブネット作成時のポイントの一つとしてMapPublicIpOnLaunch
の設定があり、trueであればパブリックサブネット、falseあればプライベートサブネットでの指定となります。
VpcId: !Ref TestVPC
の指定では、先述した論理IDがTestVPC
となっているVPCを参照させています。ここで組み込み関数と呼ばれるものが使用されているので説明します。VpcIdを指定する際、VPC IDが事前に分かっている状態であれば、
VpcId: vpc-0ec2ad5f8a6ed592c
というように直接ID指定することも可能です。しかし今回のようにCloudFormationで一度に作成する際は、まだVPCが作成されておらず、VPC IDが分からないためRefを使用した指定をしています。Refは組み込み関数の一つで、指定したパラメータまたはリソースの値を返すことができます。
アベイラリティゾーン(AZ)の指定では、Fn::Select
やFn::GetAZs
を使用しています。これは、使用可能なAZはアカウントごとに異なるということを考慮して、CloudFromationを使用するアカウントのAZに依存させないようにしています。
- Fn::GetAZs: 指定されたリージョンで使用可能なAZの配列を返す
- Fn::Select: インデックスによってオブジェクトのリストから1つのオブジェクトを返す
簡単にこのあたりの挙動を説明します。
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: ""
この場合、Fn::GetAZs: ""
でリージョンを指定していないため、デプロイされたリージョン(今回だと東京リージョン)が暗黙的に指定されたことになります。
AvailabilityZone:
Fn::Select:
- 0
- ["ap-northeast-1a", "ap-northeast-1c"]
東京リージョンを指定することで、AZの配列が返されることになり、Fn::Select
で配列の0番目であるap-northeast-1a
を指定できることになります。
インターネットゲートウェイ
## 作成
TestInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
-
Key: Name
Value: TestInternetGateway
## VPCにアタッチ
AttachInternetGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref TestInternetGateway
VpcId: !Ref TestVPC
インターネットゲートウェイの作成にはリソースタイプAWS::EC2::InternetGateway
を使用します。作成後にAWS::EC2::VPCGatewayAttachment
でVPCのアタッチを行います。アタッチする際には、プロパティで作成したインターネットゲートウェイとVPCのIDを指定します。
ルートテーブル(パブリック)
## 作成
TestRouteTableForPublicSubnet:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref TestVPC
Tags:
-
Key: Name
Value: TestRouteTableForPublicSubnet
## インターネットゲートウェイを指定
RouteTableForPublicSubnet:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref TestRouteTableForPublicSubnet
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref TestInternetGateway
## ルートテーブルとパブリックサブネットを紐付け
AssociateRouteTableForPublicSubnet:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref TestRouteTableForPublicSubnet
SubnetId: !Ref TestPublicSubnet
ルートテーブルを作成する時点ではパブリックでもプライベートでもAWS::EC2::RouteTable
を使用します。作成後に、AWS::EC2::Route
でルーティングの指定を行います。今回はパブリックのためインターネットゲートウェイを指定します。最後にルートテーブルとサブネットの紐付けをAWS::EC2::SubnetRouteTableAssociation
を行います。
ルートテーブル(プライベート)
# ルートテーブル(プライベート)
## 作成
TestRouteTableForPrivateSubnet:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref TestVPC
Tags:
-
Key: Name
Value: TestRouteTableForPrivateSubnet
## ルートテーブルとプライベートサブネットを紐付け
AssociateRouteTableForPrivateSubnet:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref TestRouteTableForPrivateSubnet
SubnetId: !Ref TestPrivateSubnet
パブリックと基本的には同じです。こちらはインターネットゲートウェイとは繋ぎません。
おわりに
こちらのコードでスタックを作成した結果がこちらです。
想定通りできていそうですね!
Discussion