CloudFormationについて
CloudFormationとは、AWSのリソースを簡単に構築することができる機能のことです。
YAML/JSONファイルにリソースの設定を書き込んで、AWSコンソールのCloudFormationでファイルをアップロードすると、
設定したリソースが作成されていきます。
もちろんCLIでもアップロードができます。
これら一つのYAML/JSONファイルに設定された一連のリソース群のことをスタックと呼びます。
アップロードが完了すると、AWSコンソール上のCloudFormationではスタックの作成が始まります。
CloudFormationのテンプレートは単純にリソースを構築するだけではなく、
プロジェクトで利用されているAWSリソースの構成図としても役立ちます。
AWSコンソール上では把握しづらいリソース間の関係性も、
テンプレートファイル上で概要をつかむことができます(読める知識があれば)。
簡単にお試しできそうな記事がありました
【CloudFormation入門】5分と6行で始めるAWS CloudFormationテンプレートによるインフラ構築
CloudFormationの基本的なパラメーター
CloudFormationを始めるにあたって理解しておいた方が良いパラメーターは以下の3つです。
- Parameters
- Outputs
- Resources
まず、テンプレートの冒頭はこんな感じになると思います。
AWSTemplateFormatVersion: '2010-09-09'
Description: Your project name # 別に必須ではない
上に挙げているパラメーターはこのDescription
下に付け足して書いていきます。
ちなみにこのエントリーではYAMLでテンプレートを書いています。
Resources
ResourcesにはAWSリソースを定義していきます。
それぞれのリソースは機能役割が異なるので、各々の設定方法が存在します。
リソースの定義は想定している構成でどのリソースを使うべきかを判断し上で、
以下のリストから探して試していくと良いです。
設定方法
全てのリソースについて説明することは不可能なので、
ここにはVPCとInternetGatewayの組み合わせをサンプルで記載します。
Resources:
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: "10.0.0.0/16"
Tags:
-
Key: "Name"
Value: "MyVPC"
MyInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
-
Key: "Name"
Value: "MyInternetGateway"
AttachGatewayToVPC:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MyVPC
InternetGatewayId: !Ref MyIGW
IPv4 CIDR ブロックを指定してVPCを作成し、インターネットゲートウェイ(IGW)を関連づけています。
VPCとIGWの参照にはRef
組み込み関数(YAMLの短縮記法)を使います。
VPCとIGWを関連づけるためにはAWS::EC2::VPCGatewayAttachment
を利用します。
周知の通り、VPC内からインターネットへアクセスするにはIGWが必須です。
上記のサンプルでは基本的なVPCを設定しているだけです。
ここからサブネットやルートテーブル、EC2インスタンスをスタックに追加してあげると、
インスタンス内で開発を行えるところまでをCloudFormationで構築することができるようになります。
のリソースを設定すればできます。
AWS::EC2::Subnet サブネットの作成
AWS::EC2::Instance EC2インスタンスの作成
AWS::EC2::RouteTable ルートテーブルの作成
AWS::EC2::SubnetRouteTableAssociation サブネットとルートテーブルの関連付け
AWS::EC2::Route ルートテーブルとIGWの関連付け
Parameters
Parametersでは同じテンプレート内で利用する値を設定することができます。
設定方法
と言ってもはじめての人にはこの言葉では理解しづらいと思うので具体的に設定を見てみましょう。
Parameters:
S3BucketNameParameter:
Type: String # パラメーターの型
Default: 'Megalovania' # 初期値
AllowedPattern: ^[a-zA-Z0-9]*$ # 正規表現に合致するものを許容します。
AllowedValues: # enumのようにこの中の値を許容します。
- 'Megalovania'
- 'TheManWithTheMachineGun'
- 'BlueEyesWhiteDragon'
Default
ではCloudFormationでのスタック作成時に設定しなかった場合の初期値を設定します(AWSコンソール上からCFnスタック作成をするときにGUIで設定できる、けどしなかった場合の初期値)。
AllowedPattern
とAllowedValues
ではその初期値やあとで設定し直した時の値のルールを設定できます。
正規表現や想定されている値が数個しかない場合はこれらを使ってみると良いと思います。
参照方法
参照はResourcesおよびこのあと登場するOutputsで行えます。
組み込み関数のRef
を使って参照します。
# in case of Resources
Resources:
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref S3BucketNameParameter # 'Megalovania'
# in case of Outputs
Outputs:
ExportedBucket:
Description: "MyBucket"
Value: !Ref MyBucket
Export:
Name: "ExportedBucket"
Outputs
Outputsを使うと、同一リージョン内に作成された他のスタックで参照可能な値を設定したり、CloudFormationコンソール上にリリース担当者に参照してほしいリソースを表示したりすることができます。
設定方法
# スタックA
AWSTemplateFormatVersion: "2010-09-09"
Resources:
SampleVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: "10.0.0.0/16"
Tags:
-
Key: "Name"
Value: "SampleVPC"
Outputs:
ExportedVPC:
Description: "SampleVPC" # 説明
Value: !Ref SampleVPC # エクスポートする値
Export:
Name: "ExportedSampleVPC" # インポートするときに参照する名前
ここではVPCのVPC IDをエクスポートしています。
参照方法
次にエクスポートした値を参照しながら別のスタックを作成します。
上記ではVPCをエクスポートしたので、そのVPCに対してIGWをアタッチしてみます。
参照時にはFn::ImportValue
組み込みを利用します。
YAMLでは組み込み関数の短縮記法が使えるので、ここでは!ImportValue
としています。
# スタックB
AWSTemplateFormatVersion: "2010-09-09"
Resources:
MyInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
-
Key: "Name"
Value: "MyInternetGateway"
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !ImportValue ExportedSampleVPC # ExportのNameで指定した名前から値を参照します。
InternetGatewayId: !Ref MyInternetGateway
こうするとスタックAで作成されたVPCにスタックBで作成されたIGWが関連付きます。
スタック間を超えて参照したいリソースがあれば便利に使うことができます。
また、作成したスタックのOutputsはAWSコンソール上でも参照することができます。
例えば、
「ReactクライアントのビルドファイルをアップロードS3バケットはどれだったっけ?」
というようなときに、このCloudFormationコンソールのOutputsからバケット名が参照できればわざわざドキュメントにまとめる必要も無くなります。
せいぜい、「コンソールの出力を参照してください」と指示するくらいでしょう。
特に複雑に肥大したスタックなどには主要なものはOutputsにまとめておくと良いと思います。
テンプレートのアップロードとスタック作成
テンプレートが書けてもスタックの作り方がわからなければ意味がありません。
ただテンプレートを流し込むだけなので全く難しいことなどはありませんが。。。
一応ざっくりと手順に触れておきます。
1. CloudFormationコンソールへ入る
AWSコンソールでCloudFormationを開くとスタック一覧画面の上の方に「スタック作成」(Create stack)ボタンを見つけられると思います。
ドロップダウンになっているので「新しいスタック」(With new resources)を選択します。
2. テンプレートファイルを選択
スタック作成画面では「既存のテンプレート」(Template is ready)から「テンプレートをアップロード」(Upload a template file)を選択し、テンプレートファイルYAML/JSONを選択して「次へ」(Next)を押します。
3. スタック名を決める
スタック名を記入して「次へ」(Next)を押します。
4. 詳細設定(やりたい人だけ)
次のページの詳細設定等は省いて「次へ」(Next)を押します。
設定したいことがあればします。
5. 確認とスタックの作成実行
確認画面が表示されるので、確認ができたら下部の「スタック作成」(Create stack)を押します。
するとスタックの作成が始まってステータスがCREATE_IN_PROGRESS
となるのがわかると思います。
設定したリソースの量にもよりますが少しすればスタックがCREATE_COMPLETE
になります。
問題があればエラーも出ますが、基本的には以上がスタック作成の基本的な流れです。
コンソール上でリソースが作成されているのを確認できると思います。
おわり
以上の基本的なパラメーターについてとりあえず触れましたが、
CloudFormationを理解するには組み込み関数についても知る必要があります。
これは上でも触れた!Ref
とか!ImportValue
みたいなやつのことです。
組み込み関数には条件関数というものもあって、より柔軟にスタックテンプレートを作成することができるようになります。
今の職場では複数の環境(お客様が別々で要望も別々なので環境を分けている)がそれぞれの環境差異を持っているので各スタックテンプレートで組み立てているのですが、
そうは言っても類似した部分の共通簡略化は行いたくなるのでテンプレートの部分分岐をしたりします。
こういったときに条件関数が使えるので知っておいて損はないと思います。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
また、スタックはネスト化して表現することもできるので、「ネストされたスタック」についても知っておいた方が良いかもしれないです。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html