この記事
以前、VPC作ってEC2にひとまずWebサーバ用意するまで、という記事を書きましたが
https://qiita.com/shinon_uk/items/04e86115c7dd96018ec1
こういった基本的なVPC+PublicSubnet+Routetable...のセットをCFnで作るものを
ずっと記事連携させたかったので書きます。
対象は、いつもマネジメントコンソールで個別に構築してるけど
AWSのDevOpsとかインフラ自動化とか、手を伸ばしてみようかなーという方になると思います。
コードを短くしたいので、EC2+SecuriyGroupは別回にして、構築作業はGUIから行います。
#やること
今回は「あとはEC2を立てるだけ」の状態にしたいので
以下最低限のリソースをCloudFormationで作成します。
・VPC
・Subnet(Public + Private)
・RouteTable(Route含む)
・InternetGateway
#知る
###CloudFormationとは
どんなAWSサービスでも、大体Blackbeltを見れば用途は理解できます。
※下記資料:Published on Nov 28, 2018
https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-aws-cloudformation?ref=https://aws.amazon.com/jp/blogs/news/webinar-bb-cfn-update-2018/
・JSON/YAMLのテキストファイルで、あらゆるリージョンのAWSリソースをプロビジョニングできる
対応リソース:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html
・プロビジョニングしたAWSリソースの変更/削除が可能で、ソフトウェアに対して行うのと同じように、AWSインフラを管理できる
・CloudFormation自体の料金は発生しない、作成したリソース分のみ
###CloudFormationのセクション
抜粋して記載します。
-
AWSTemplateFormatVersion
フォーマットのバージョンを指定する。2020/02現時点では、 たった一つのバージョン2010-09-09が最新である。 -
Description
作成するテンプレートの説明を記載する。 -
Parameters
カスタマイズが必要なパラメータを、CFn流すときに渡すためのもの。例えば、作成する環境名、ドメイン名など。 -
Resources
必須である、リソース記載部分。テンプレートで説明できる最も小さなブロックである。 -
Outputs
テンプレートを作成した際に値を返す物を定義する。
尚、テンプレートはJSON、YAMLで定義できる。YAMLが使用可能ということは、例えばIAM RoleをYAMLで定義することも可能というメリットもある。
以降、YAMLで記載
#作る
###ドキュメント
AWSが公開しているブループリントを見てもいいんですが、
ドキュメントを参照して行きます。
例えば、VPCリソース
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html
各プロパティの必須項目が
必須: はい
となっている場合は、記載が必要です。
あとは例を見て作成。
1 Resources:
2 VPC:
3 Type: AWS::EC2::VPC
4 Properties:
5 CidrBlock: !Ref VpcCidr
6 InstanceTenancy: default
7 EnableDnsSupport: true
8 EnableDnsHostnames: true
9 Tags:
10 - Key: Name
11 Value: !Sub '${AppName}-${Environment}-vpc'
2行目、リソースIDは一意であれば自由に決められます。
3行目、Typeでリソースを実際に指定しています。
あとは該当するリソース(Type)のドキュメントを見ながら作成するイメージですね。(先述)
また、11行目のValueに !Sub がありますが、組込関数で同一コード内のIDを参照しています。
!Sub, !Ref は参照によく使う組み込み関数です。
他にも組み込み関数はたくさんありますが、必要になったら使う、などでいいと思います。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
####何はともかくやってみる
###テンプレート
作成したテンプレートは下記です。
適宜日本語コメントも入れています。
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC Template'
#このセクションはCFn流す際に与えるパラメータの定義
Parameters:
#サービス名など
AppName:
Description: Please specify the application name.
Type: String
Default: "example"
#環境名
Environment:
Description: Please specify the target environment.
Type: String
Default: "dev"
AllowedValues:
- prod
- stg
- dev
#VPCのIP指定
VpcCidr:
Description: Please specify the VPC IP
Type: String
Default: '10.0.0.0/16'
AllowedPattern: '((\d{1,3})\.){3}\d{1,3}/\d{1,2}'
#各SubnetのIP指定
Public1SubnetCidr:
Description: Please specify the Subnet IP for Public1
Type: String
Default: '10.0.0.0/20'
Private1SubnetCidr:
Description: Please specify the Subnet IP for Public1
Type: String
Default: '10.0.64.0/20'
リソース定義
Resources:
#VPCを定義
VPC:
Type: AWS::EC2::VPC
Properties:
#Parameters参照
CidrBlock: !Ref VpcCidr
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
#複数のParameters参照して繋げて作成
#defaultの値で指定だと example-dev-vpc というValueになる
Value: !Sub '${AppName}-${Environment}-vpc'
#IGWを定義
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub '${AppName}-${Environment}-igw'
#IGWをVPCにアタッチ
#マネジメントコンソールでやっている作業を定義しているだけ
VPCInternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
#アタッチしたいVPCを参照
VpcId: !Ref 'VPC'
InternetGatewayId: !Ref 'InternetGateway'
#Subnetを定義する
#Public Subnetを定義
SubnetPublic1:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref Public1SubnetCidr
AvailabilityZone: !Select [ 0, !GetAZs ]
MapPublicIpOnLaunch: true
VpcId: !Ref 'VPC'
Tags:
- Key: Name
Value: !Sub '${AppName}-${Environment}-Public1'
#Private Subnetを定義
SubnetPrivate1:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref Private1SubnetCidr
AvailabilityZone: !Select [ 0, !GetAZs ]
VpcId: !Ref 'VPC'
Tags:
- Key: Name
Value: !Sub '${AppName}-${Environment}-Private1'
#RouteTableを定義
#Route Table for Publicを定義
RouteTablePublic:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref 'VPC'
Tags:
- Key: Name
Value: !Sub '${AppName}-${Environment}-rt-public'
#Route Table for Privateを定義
RouteTablePrivate:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref 'VPC'
Tags:
- Key: Name
Value: !Sub '${AppName}-${Environment}-rt-private'
#RouteTableにRouteを定義する
#Route Table for PublicにRouteを1つ定義
RoutePublic:
Type: AWS::EC2::Route
DependsOn: VPCInternetGatewayAttachment
Properties:
DestinationCidrBlock: 0.0.0.0/0
RouteTableId: !Ref 'RouteTablePublic'
GatewayId: !Ref 'InternetGateway'
#各Subnetを、各RouteTableに関連づける
#Route Table for PublicにPublic Subnetを関連づける
SubnetRouteTableAssociationPublic1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref 'RouteTablePublic'
SubnetId: !Ref 'SubnetPublic1'
#Route Table for PrivateにPrivate Subnetを関連づける
SubnetRouteTableAssociationPrivate1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref 'RouteTablePrivate'
SubnetId: !Ref 'SubnetPrivate1'
最後に、Outputセクションで値を出力しておきます。
今回は使わないんですが、例えば他のテンプレートに値を渡したい時に使用したりします。
その話はスタック構成含めて別記事で出します。
Outputs:
VpcId:
Description: VPC ID
Value: !Ref 'VPC'
Export:
Name: !Sub '${AWS::StackName}-VpcId'
SubnetPublic1:
Description: Public subnet 1
Value: !Ref 'SubnetPublic1'
Export:
Name: !Sub '${AWS::StackName}-PublicSubnet1'
SubnetPrivate1:
Description: Private subnet 1
Value: !Ref 'SubnetPrivate1'
Export:
Name: !Sub '${AWS::StackName}-PrivateSubnet1'
###実際に流す作業
テンプレート(コード)はローカルに保存してもS3でも、ひとまずは大丈夫です。
以下はアップロードするパターン。
①みんな大好きマネジメントコンソールで、CloudFormationを開く。
②スタックの作成へ
↓↓
直接アップロードなのでこっち(S3にファイルは保存されます。)
ファイルを指定して次に進みます。
この時点で文法エラーなどあれば、画面上にエラー出力してくれます。修正。
(大文字小文字とか自分あるある)
③パラメータ指定
始めはdefaultで指定した値が入っています。
テンプレート内で扱う名前がある場合は、アプリ名やサービス名などをここで指定します。
↓
次へを押していく。
↓
最後にパラメータで指定した値を確認
↓
スタックの作成を押して、流します。
CREATE IN PROGRESSになれば作成が始まっています。
仮に問題があって一つでも作成ができなかった場合は、デフォルトでロールバックされます。
※設定は作成時に設定変更可能
↓
右上のボタンを押して更新できます。
最終的に、左のスタック画面で以下のように表示されれば完成です。
リソースタブからもみることができますが、作成したリソースを確認してください。
各リソースの変更は、各サービスの変更画面から可能ですが、
テンプレートを修正して更新する事もできます。
削除する際は、スタックの削除を押せば、テンプレートのリソースが一括で削除されるのでとても便利です。
Github
https://github.com/shinon-uk/CloudFormation/tree/master/vpc-sample
#最後に
久しぶりの記事になりました。
まだまだCloudFormationでやれることはあるので、
後日またスタック構成にしたCLIベース構築の話を記載する予定です。