IaC っていいですよね。
ということで今回は CloudFormation を触ってみます。
記事目安...15 分
事前知識
CloudFormation とは
AWS リソースやサードパーティ製アプリケーションリソースをコードのように定義して作成するサービスです。 AWS 上で IaC を実現したい場合は欠かせないサービスとなります。
CloudFormation の利用料金はなんと無料です。 しかし、当然 CloudFormation を経由して構築されたリソースには、そのサービスごとに利用料金が掛かりますのでご注意ください。
ゴール
今回は前編・後編に分けてやっていきます。
前編では以下のリソースのテンプレートファイルを作成することに注力し、 後編では実際にデプロイしてみようと思います。
Resource | Number |
---|---|
VPC | 1 |
PublicSubnet | 1 |
InternetGW | 1 |
RouteTable | 1 |
最終的に出来上がる構成図イメージは以下です。
Cfn テンプレート作成の流れ
ここから Cfn テンプレート作成の流れと各ポイントを解説しながらすすめます。
最終的に出来上がる Cfn テンプレートは 本記事の 付録
> cfn-template_vpc-and-pubsub.yaml
をご参考ください。
セクションの定義
そもそもの前提として、CloudFormation テンプレートの記述は "セクション" という単位に分かれています。
今回は以下 2 セクションを扱います。
Key | Value |
---|---|
Parameters | ユーザが独自のパラメータを定義するセクション |
Resources | 各 AWS リソースを定義するセクション |
したがって、まずは Yaml に各セクションを記載します。
Parameters: Resources:
※作成過程をわかりやすくするためにあえてこのように書いてます。
これだけでは Yaml シンタックスとしては誤りなので注意してください。
VPC の定義
ここから各種 AWS リソースを定義します。
まずは、VPCを定義します。
以下ページに載っている VPC を定義するのに必要な項目を確認して、貼り付けましょう。 なお、値には許容される型が記述されています。
参考: AWS::EC2::VPC
Parameters: Resources: MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: String EnableDnsHostnames: Boolean EnableDnsSupport: Boolean InstanceTenancy: String Tags: - Tag
各Resourceには論理IDと呼ばれる一意の名前を付けることができます。
ここではMyVPCとしました。
Resources: MyVPC:
続いて各項目を編集します。
各項目と値の詳細については先ほどの AWS 公式ページ(AWS::EC2::VPC)をご確認ください。
Parameters: Resources: MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCidrBlock EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: !Ref VpcName
ここで突然でてきた "!Ref" に皆さん困惑されたのではないでしょうか。
Properties: CidrBlock: !Ref VpcCidrBlock ~省略~ Tags: - Key: Name Value: !Ref VpcName
これは CloudFormation で組み込み関数の一つ Ref 関数です。(※1)
機能は指定したパラメータの値を参照できます。
組み込み関数 Ref は、指定したパラメータまたはリソースの値を返します。
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html
ここでは、ユーザ定義のパラメータとして以下の値を参照させます。(このパラメータ自体の定義はのちほど定義します。)
- VPC の CIDR を格納する
VpcCidrBlock
- VPC の名前を格納する
VpcName
※1 CloudFormationにはたくさんの関数が用意されているので、気になった人は確認してみてください。
参考: 組み込み関数リファレンス
※2 Ref 関数の完全系は "Ref: xxx" であり、"!Ref" は短縮系となります。
短縮形の構文
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html
今回は、事前に用意されていない VpcName
を Ref 関数で参照したため、参照先を定義する必要があります。(※3)
この定義は、Parameter セクションにて行います。
パラメータ ドキュメントを参考に、以下値をそれぞれ記述します。
Key | Value |
---|---|
Description | パラメータの説明 |
Type | パラメータの型 |
Default | デフォルトで入力されるパラメータの値 |
Parameters: VpcCidrBlock: Description: Input a VPC IPv4 CidrBlock. ex) 192.168.2.0/24 Type: String VpcName: Description: Input a VPC name. This Parameter will be a Name tag. Type: String Default: "" Resources: MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCidrBlock EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: !Ref VpcName
※3 パラメータの中には事前に AWS により用意されたパラメータもございます。
擬似パラメータは、AWS CloudFormation によって事前定義されたパラメータです。
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html
これでVPCが完成です。
Public Subnet の定義
続いて Public Subnet を定義します。
以下ページにサブネットの定義パラメータがあるので、確認しながら進めてください。
今回は論理 ID を MyPublicSubnet で定義します。
Parameters: ~省略~ Resources: ~省略~ MyPublicSubnet: Type: AWS::EC2::Subnet Properties: AssignIpv6AddressOnCreation: Boolean AvailabilityZone: String CidrBlock: String Ipv6CidrBlock: String MapPublicIpOnLaunch: Boolean Tags: - Tag VpcId: String
先ほどの公式ドキュメントを確認しながら、各項目を編集します。
Parameters: ~省略~ Resources: ~省略~ MyPublicSubnet: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Ref AZ CidrBlock: !Ref PublicSubnetCidrBlock MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Ref PublicSubnetName VpcId: !Ref MyVPC
今回は、PublicSubnetCidrBlock
, PublicSubnetName
AZ
の 3 つのユーザ定義パラメータを追加しました。
ここで新しい Ref 関数の使い方が出てきたので解説します。
VpcId: !Ref MyVPC
Ref 関数はパラメータだけでなく、論理 ID を参照できます。この場合、リソースごとに決まった値を返します。
例えば、参照する論理 ID が VPC リソースの場合、 VPC ID
を返してくれます。
Return values Ref When you pass the logical ID of this resource to the intrinsic Ref function, Ref returns the ID of the VPC.
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html
リソースごとに、どんな値を参照するかは、各リソースドキュメントをご確認ください。
ユーザ定義パラメータを追加したので、Parameters セクションも変更します。
今回は、
PublicSubnetCidrBlock
,PublicSubnetName
AZ
の 3 つのユーザ定義パラメータを追加しました。
Parameters: ~省略~ AZ: Description: Input a AZ where Public Subnet will be created. Type: AWS::EC2::AvailabilityZone::Name PublicSubnetCidrBlock: Description: Input a Public Subnet IPv4 CidrBlock. ex) 192.168.2.0/25 Type: String PublicSubnetName: Description: Input a Public Subnet name. This Parameter will be a Name tag. Type: String Default: "" Resources: ~省略~ MyPublicSubnet: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Ref AZ CidrBlock: !Ref PublicSubnetCidrBlock MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Ref PublicSubnetName VpcId: !Ref MyVPC
ここでポイントとなるのは AWS::EC2::AvailabilityZone::Name です。
AZ: Description: Input a AZ where Public Subnet will be created. Type: AWS::EC2::AvailabilityZone::Name
AWS::EC2::AvailabilityZone::Name
は AWS 固有の型となります。
通常の String 型などとは異なり、アベイラビリティゾーンを表す型となります。
この型を宣言することで、対象のパラメータ値は、マネコンの現在のリージョンをもとにアベイラビリティゾーン一覧の中から選択が可能です。
AWS 固有の型は他にも色々あるため、利用してみてください。
AWS 固有のパラメータタイプ
引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#aws-specific-parameter-types)
これでサブネットの定義も完成です。
InternetGateway の定義
InternetGateway(以下 IGW)を定義します。
以下を参考に IGW に必要なパラメータ値を定義します。
今までと同じ流れなので詳細は割愛します。
Parameters: ~省略~ InternetGwName: Description: Input a IntenetGW name. This Parameter will be a Name tag. Type: String Default: "" Resources: ~省略~ MyInternetGW: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Ref InternetGwName
IGW を作成したので VPC と関連付けます。
IGW と VPC を関連付けるためには VPCGatewayAttachment
と呼ばれるリソースが必要です。(マネコンで構築する場合は暗黙的に作成されるリソースとなります。)
こちらも以下を参考に、今までと同様に定義します。
参考: AWS::EC2::VPCGatewayAttachment
Parameters: ~省略~ Resources: ~省略~ MyVPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref MyInternetGW VpcId: !Ref MyVPC
これで IGW まわりの定義は完了です。
RouteTable の定義
RouteTable を定義します。
こちらも以下を参考に、今までと同様に定義します。
Parameters: ~省略~ RouteTableName: Description: Input a RouteTable name. This Parameter will be a Name tag. Type: String Default: "" Resources: ~省略~ MyRouteTable: Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: !Ref RouteTableName VpcId: !Ref MyVPC
次にルートテーブルのルーティングを定義します。以下を参考に同様に定義してください。
※local ターゲットへのルーティングは自動で設定されます。明示的な定義は不要です。
参考: AWS::EC2::Route
~省略~ Resources: ~省略~ MyPublicRoute: Type: AWS::EC2::Route Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref MyInternetGW RouteTableId: !Ref MyRouteTable
さらに RouteTable と Subnet を関連付けます。
VPC と IGW を関連付けるリソースが必要だったのと同様、Subnet と RouteTable も関連付けるためのリソースが必要です。
以下を参考に定義します。
参考: AWS::EC2::SubnetRouteTableAssociation
~省略~ Resources: ~省略~ MySubnetRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref MyRouteTable SubnetId: !Ref MyPublicSubnet
これで RouteTable の定義も完了です。
確認
ということでテンプレートファイルができました。
完成版は本記事の 付録
> cfn-template_vpc-and-pubsub.yaml
をご確認ください。
まとめ
前編では CloudFormation で使うテンプレートファイルの書き方についてまとめました。
基本は AWS ドキュメントの見方さえわかってしまえば記述自体はすぐできそうですが、RouteTable のように複数にリソースに分割して定義するのはちょっと大変だなあという印象です。
後半では、実際に作ったテンプレート流していきます。
【初心者向け】VPC+PublicSubnet を CloudFormation を使って構築する 後編
ご覧いただきありがとうございました。
付録
cfn-template_vpc-and-pubsub.yaml
Parameters: # VPC VpcCidrBlock: Description: Input a VPC IPv4 CidrBlock. ex) 192.168.2.0/24 Type: String VpcName: Description: Input a VPC name. This Parameter will be a Name tag. Type: String Default: "" # Public Subnet AZ: Description: Input a AZ where Public Subnet will be created. Type: AWS::EC2::AvailabilityZone::Name PublicSubnetCidrBlock: Description: Input a Public Subnet IPv4 CidrBlock. ex) 192.168.2.0/25 Type: String PublicSubnetName: Description: Input a Public Subnet name. This Parameter will be a Name tag. Type: String Default: "" # Internet GW InternetGwName: Description: Input a IntenetGW name. This Parameter will be a Name tag. Type: String Default: "" # RouteTable for Public Subnet RouteTableName: Description: Input a RouteTable name. This Parameter will be a Name tag. Type: String Default: "" Resources: # VPC MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCidrBlock EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: !Ref VpcName # PublicSubnet MyPublicSubnet: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Ref AZ CidrBlock: !Ref PublicSubnetCidrBlock MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Ref PublicSubnetName VpcId: !Ref MyVPC # InternetGW MyInternetGW: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Ref InternetGwName MyVPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref MyInternetGW VpcId: !Ref MyVPC # RouteTable for Public Subnet MyRouteTable: Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: !Ref RouteTableName VpcId: !Ref MyVPC MyPublicRoute: Type: AWS::EC2::Route Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref MyInternetGW RouteTableId: !Ref MyRouteTable MySubnetRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref MyRouteTable SubnetId: !Ref MyPublicSubnet
菅谷 歩 (記事一覧)