【AWS】CloudFormationまとめ
背景・目的
近年ではWebアプリケーションを作成する際に必要となるサーバーやそれに対するセキュリティをコードで管理する、Infrastructure as Code (IaC)が利用されており、企業での導入も進んでいる。IaCを導入することで以下のようなメリットがある。
- インフラの変更を自動化できる
- コード化することにより、再利用が可能
- 構成管理しやすくなる
など様々な恩恵を受けることができる。
今回は、AWSでのIaCツールとして広く知られている、CloudFormationについてまとめてみたいと思う。
CloudFormationとは
AWSのインフラ環境/リソースをコードで管理することができ、それを用いて一括でリソースを起動/削除が可能となるAWSのサービスである。
押さえておきたいポイントは以下。
- YAML or JSONで管理する。
- YAML or JSONで作成したテンプレートから、スタックを作成する。
- スタックとは、テンプレートによって起動されるリソースの集合のこと。
- CloudFormation自体の利用料金は無料。使ったリソースに対して課金される。
細かい話は以下にわかりやすくまとめってあったのでそちらを参照していただきたい。
CloudFormationテンプレートを構成する要素
本章では、CloudFormaitonのテンプレートをYAMLで作成する例をとって、スタックを作成するためのテンプレートファイルの要素を述べる。
# バージョン(必須)
AWSTemplateFormatVersion: "2010-09-09"
# スタックの説明(任意)
Description:
# メタデータ(任意)
Metadata:
# パラメータ(任意)
Parameters:
# マッピング(任意)
Mappings:
# 条件(任意)
Conditions:
# 起動するAWSリソース(必須)
Resources:
# 出力
Outputs:
CloudFormationテンプレートは上記のような、AWSTemplateFormatVersion, Description, Metadata, Parameter, Mappings, Condition, Resouces, Outputsから構成される。
各項目は以下のような役割を果たしている。
項目 | 必須 | 説明 |
---|---|---|
AWSTemplateFormatVersion | 〇 | テンプレートが準拠している AWS CloudFormation テンプレートバージョン。 |
Description | × | テンプレートの説明。記述は任意。ただし、必ずテンプレートの Format Version セクションの後に記述する必要がある。 |
Metadata | × | CloudFormationに関するメタデータを定義することができる。 AWS::CloudFormation::Init EC2インスタンス内でパッケージのインストールやファイルの作成、サービスの開始などを実行するスクリプトを記述する。 AWS::CloudFormation::Interface Parameterセクションに記載したパラメータの順序を規定する。 AWS::CloudFormation::Designe AWS CloudFormation デザイナー (デザイナー) におけるリソースのレイアウトを記述する。 |
Parameters | × | スタック作成時にテンプレートに渡すことができる値。 |
Mappings | × | キーとそれに関連する値のマッピングを作成することができる。作成したMappingはCloudFormationのFn::FindInMap関数で呼び出すことができる。 |
Conditions | × | 条件式をここで定義することができる。例えば、スタックが本稼働用であるかテスト環境用であるかに依存する、条件付きのリソースを作成できる。 |
Resources | 〇 | 実際に起動するAWSリソースを記述するセクション。 |
Outputs | × | スタックのプロパティを確認すると返される値を記述する。テンプレートファイルを分けたときに、別ファイルのリソースのIDなどを参照するために使われる。 |
実際は、全項目が必須というわけではなく、AWSTemplateFormatVersion, Resourcesが記述されていればよい。
CloudFormationを使ってみる
実際にテンプレートを作って、VPCやSubnetを構築してみる。
テンプレートの記述
例えば、AWSのVPCとサブネットを構築するテンプレートは以下のようになる。
AWSTemplateFormatVersion: '2010-09-09'
Description:
Create VPC and Subnet
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: MyVPC
# ------------------------------------------------------------#
# Sunbet
# ------------------------------------------------------------#
MySubnet:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: 'true'
VpcId: !Ref VPC
Tags:
- Key: Name
Value: MySubnet
上記のように、構築するAWSリソースはResoucesセクションに記述される。Resoucesセクションには、論理ID, リソースタイプ、プロパティを記述する。
項目 | 説明 |
---|---|
論理ID | リソースを識別するIDのこと。テンプレート内で一意である必要がある。論理IDは、テンプレートの他の部分のリソースを参照するために使用される。 |
リソースタイプ | 宣言しているリソースの種類を表す。上記の例でいえば、AWS::EC2::VPCやAWS::EC2::Subnetである、 |
プロパティ | リソースに対して指定できる追加オプション。リソースによって指定できるオプションは異なる。 |
リソースタイプや、プロパティに何を指定できるかは、以下の公式ドキュメントを参照すると良い。
また、CloudFormationテンプレートでは組み込み関数が利用でき、上記例では、リソースの値を返すRef関数を利用している。ここでは、Subnetを作成するときに、どのVPCに紐づけるかを示すために使われている。
なお、Ref関数によって返ってくる値は、リソースごとに異なるので注意すること。
テンプレートでリソースを宣言するときに別のテンプレートリソースを名前で指定する必要がある場合は、Ref を使用して別のリソースを参照できます。一般的に、Ref はリソースの名前を返します。たとえば、AWS::AutoScaling::AutoScalingGroup の参照は、Auto Scaling グループリソースの名前を返します。
一部のリソースでは、リソースのコンテキストにおいて別の重要な意味を持つ識別子が返されます。たとえば、AWS::EC2::EIP リソースは IP アドレスを返し、AWS::EC2::Instance はインスタンス ID を返します。
なお、その他の組み込み関数は以下の公式ドキュメントを参照。
スタックの作成
次に、実際にAWSのコンソールにログインして、スタックを作成してみる。
-
サービス > CloudFormationを選択し、「スタックの作成」を押下
-
以下の通りテンプレートをアップロードし、「次へ」を押下。
-
スタック名を入力する画面に遷移するので、適当にスタック名を入力して「次へ」を押下。
-
スタックオプションの設定画面になるが、何も入力せずに「次へ」を押下。
-
レビュー画面で内容を確認したら、「スタックの作成」を押下。
-
以下の画面のようにCREATE_COMPLETEと表示されたら作成完了
-
サービス > VPC を確認すると、テンプレートに記載した、MyVPCやMySubnetが作成されていることがわかる。
-
作成されていることが確認できたら、今度はスタックを削除すれば、MyVPCやMySubnetが勝手に削除されることがわかる。
ここまでで、実際にCloudFormationでAWSリソースを構築するまでの流れを記載した。
次からは、テンプレートの作成するためのTipsについて記載する。
テンプレートを作成するときのTips
ここでは、CloudFormationテンプレートを作成するときのTipsについて記述する。
先述の「CloudFormationテンプレートを構成する要素」で記載した各セクションを記述することで、CloudFormationテンプレートをより見やすく、より再利用しやすくすることができる。
Parametersを利用して、パラメータを外出ししてみる
Parametersセクションを利用すると、パラメータを外だしできる。
例えば、CloudFormationでEC2インスタンスを構築する例で見てみる。
以下の例では、EC2インスタンスを作成するときに、AMIのIDやキーの名前といったものが直にテンプレートに記述されている。
これでは、起動したいテンプレートが変わった時などにテンプレートを修正しなければいけなくなる。
AWSTemplateFormatVersion: '2010-09-09'
Resources:
# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
WebServer:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: "ap-northeast-1a"
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 8
VolumeType: gp2
# AMIのIDを直書き
ImageId: ami-XXXXXXXXXXXXXXX
InstanceInitiatedShutdownBehavior: 'stop'
InstanceType: t2.micro
# キーペア名も直書き
KeyName: MyKeyPair
SecurityGroupIds:
- !Ref WebSG
SubnetId: !Ref SubnetA
Tenancy: default
Tags:
- Key: Name
Value: WebServer
そこで、以下のように、Parametersセクションにパラメータを記述することで、パラメータを外出しすることができる。パラメータには、論理IDとデータタイプを指定する。その他にもデフォルト値や、許容する値を配列で指定したりすることもできる。
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
KeyName:
Description: The EC2 Key Pair
Type: "AWS::EC2::KeyPair::KeyName"
EC2AMIId:
Description: AMI ID
Type : String
Default: ami-XXXXXXXXXXX
Resources:
# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
WebServer:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: "ap-northeast-1a"
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 8
VolumeType: gp2
# Parametersで作成した論理IDを指定
ImageId: !Ref EC2AMIId
InstanceInitiatedShutdownBehavior: 'stop'
InstanceType: t2.micro
# Parametersで作成した論理IDを指定
KeyName: !Ref KeyName
SecurityGroupIds:
- !Ref WebSG
SubnetId: !Ref SubnetA
Tenancy: default
Tags:
- Key: Name
Value: WebServer
上記のテンプレートを使ってスタックを作成しようとすると、以下のように、スタックの詳細画面でパラメータ入力のフォームが表示されるようになる。
これで、AMIのIDやキーペア名が変更されてもテンプレートを修正せずに、スタックを作成できる。
Metadataを利用して、パラメータを管理しやすくする
上記でパラメータを外出ししたものの、パラメータの数が増えてくると管理が煩雑になったり、スタック作成の際に見づらくなったりする。
例えば、以下のようにEC2とRDSを作成するテンプレートがあったとする。
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
KeyName:
Description: The EC2 Key Pair to allow SSH access to the instance
Type: "AWS::EC2::KeyPair::KeyName"
EC2AMIId:
Description: AMI ID
Type : String
Default: ami-XXXXXXXXXXXX
DatabaseName:
Description: Database Name
Type : String
Default: UserName
DatabaseMasterName:
Description: Database Master User Namee
Type : String
Default: MasterName
DatabaseMasterPassword:
Description: Database Master User Password
Type : String
Resources:
# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
WebServer:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: "ap-northeast-1a"
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 8
VolumeType: gp2
ImageId: !Ref EC2AMIId
InstanceInitiatedShutdownBehavior: 'stop'
InstanceType: t2.micro
KeyName: !Ref KeyName
SecurityGroupIds:
- test
SubnetId: test
Tenancy: default
Tags:
- Key: Name
Value: WebServer
# ------------------------------------------------------------#
# RDS
# ------------------------------------------------------------#
Database:
Type: AWS::RDS::DBInstance
Properties:
AllocatedStorage: 20
AllowMajorVersionUpgrade: false
AutoMinorVersionUpgrade: false
AvailabilityZone: ap-northeast-1a
BackupRetentionPeriod: 0
DBInstanceClass: db.t3.micro
DBInstanceIdentifier: database-1
DBName: !Ref DatabaseName
DBSubnetGroupName: test
DeleteAutomatedBackups: false
DeletionProtection: false
Engine: mysql
EngineVersion: 8.0.20
MasterUsername: !Ref DatabaseMasterName
MasterUserPassword: !Ref DatabaseMasterPassword
MaxAllocatedStorage: 1000
MultiAZ: false
PubliclyAccessible: false
StorageEncrypted: false
StorageType: gp2
Tags:
- Key: Name
Value: My-RDS-1
VPCSecurityGroups:
- test
このテンプレートを使ってスタックを作成しようとすると、以下のようにパラメータの入力順がバラバラになったりして管理しずらい。
そこで以下のように、Metadataセクションに、AWS::CloudFormation::Interfaceキーを記述して、パラメータのグループを作成する。
AWSTemplateFormatVersion: '2010-09-09'
# Metadataセクション
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: EC2 Configuration
Parameters:
- EC2AMIId
- KeyName
-
Label:
default: RDS Configuration
Parameters:
- DatabaseName
- DatabaseMasterName
- DatabaseMasterPassword
Parameters:
KeyName:
Description: The EC2 Key Pair to allow SSH access to the instance
Type: "AWS::EC2::KeyPair::KeyName"
EC2AMIId:
Description: AMI ID
Type : String
Default: ami-XXXXXXXXXXXX
DatabaseName:
Description: Database Name
Type : String
Default: UserName
DatabaseMasterName:
Description: Database Master User Namee
Type : String
Default: MasterName
DatabaseMasterPassword:
Description: Database Master User Password
Type : String
Resources:
# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
WebServer:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: "ap-northeast-1a"
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 8
VolumeType: gp2
ImageId: !Ref EC2AMIId
InstanceInitiatedShutdownBehavior: 'stop'
InstanceType: t2.micro
KeyName: !Ref KeyName
SecurityGroupIds:
- test
SubnetId: test
Tenancy: default
Tags:
- Key: Name
Value: WebServer
# ------------------------------------------------------------#
# RDS
# ------------------------------------------------------------#
Database:
Type: AWS::RDS::DBInstance
Properties:
AllocatedStorage: 20
AllowMajorVersionUpgrade: false
AutoMinorVersionUpgrade: false
AvailabilityZone: ap-northeast-1a
BackupRetentionPeriod: 0
DBInstanceClass: db.t3.micro
DBInstanceIdentifier: database-1
DBName: !Ref DatabaseName
DBSubnetGroupName: test
DeleteAutomatedBackups: false
DeletionProtection: false
Engine: mysql
EngineVersion: 8.0.20
MasterUsername: !Ref DatabaseMasterName
MasterUserPassword: !Ref DatabaseMasterPassword
MaxAllocatedStorage: 1000
MultiAZ: false
PubliclyAccessible: false
StorageEncrypted: false
StorageType: gp2
Tags:
- Key: Name
Value: My-RDS-1
VPCSecurityGroups:
- test
上記のテンプレートを使ってスタックを作成しようとすると、以下のようにテンプレートで定義したグループと順番でパラメータ入力フォームが現れる。
これで、パラメータの入力も見やすくなる!
Metadataキーは他にもあるがここでは割愛する。
Mappingsを記述してテンプレートを再利用しやすくしてみる
Mappingsを利用すると、キーとそれに関連する値のマッピングを作成することができる。
そして、それと合わせてFindInMap関数を使うと、同じテンプレートも場合によって設定を変えることができるようになる。
例えば以下の例のように、検証環境と本番環境で作成するサブネットのCIDRブロックを変える場合などに、MappingsとFindInMap関数が有効である。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Environment:
Description: Type of this environment.
Type: String
Default: prd
AllowedValues:
- prd
- stg
Mappings:
SubnetMap:
prd:
Subnet: 10.0.1.0/24
stg:
Subnet: 10.0.2.0/24
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: MyVPC
# ------------------------------------------------------------#
# Public Sunbet A
# ------------------------------------------------------------#
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: !FindInMap [SubnetMap, !Ref Environment, Subnet]
MapPublicIpOnLaunch: 'true'
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: PublicSubnetA
あらかじめ、Paramtersセクションで入力パラメータを決めておく。今回は"stg"(検証環境)と"prd"(本番環境)のどちらかを入力できるようにする。
そして、Mappingセクションで、キー名stg or prdに対するサブネットの値をそれぞれ定義しておく。Mappingセクションは以下のように記載する。
Mappings:
Mapping01:
Key01:
Name: Value01
Key02:
Name: Value02
Key03:
Name: Value03
そしてFindInMap関数で呼び出すと、入力パラメータ値(stg or prd)に応じて作成されるサブネットのCIDR値を変えることができる。
Fn::FindInMapは以下のように使用する。
!FindInMap [ MapName, TopLevelKey, SecondLevelKey ]
項目 | 説明 |
---|---|
MapName | Mappings セクションで宣言された、キーと値を含むマッピングの論理名。 |
TopLevelKey | 最上位のキー名。この値は、キーと値のペアのリスト。 |
SecondLevelKey | 2番目のレベルのキー名で、TopLevelKey に割り当てられたリストのキーの1つに設定される。 |
戻り値 | SecondLevelKeyに割り当てられた値。 |
ちなみに上記テンプレートを使ってスタックを作成すると、以下のようになる。
-
スタックの詳細を指定画面で、Environmentパラメータをprdにして、スタックを作成する。
-
実際に作成されたサブネットを見ると、prd用のサブネットになっていることがわかる。
Conditionsを利用して条件によって挙動を変えてみる
Mappingsセクションで、本番環境と検証環境で設定値を変えてみたが、条件分岐など複雑な動作は記述できなかった。そこで、CloudFormationの条件関数を使ってConditionsセクションに条件を記述し、本番環境だけ、追加でEC2インスタンスを構築するといった動きを記述してみる。
Conditions
条件関数
先ほどのMappingsセクションを記述したテンプレートを修正して、以下のようにする。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Environment:
Description: Type of this environment.
Type: String
Default: prd
AllowedValues:
- prd
- stg
Mappings:
SubnetMap:
prd:
Subnet: 10.0.1.0/24
stg:
Subnet: 10.0.2.0/24
Conditions:
IsPrd: !Equals [!Ref Environment, "prd"]
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: MyVPC
# ------------------------------------------------------------#
# Public Sunbet A
# ------------------------------------------------------------#
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: !FindInMap [SubnetMap, !Ref Environment, Subnet]
MapPublicIpOnLaunch: 'true'
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: PublicSubnetA
# ------------------------------------------------------------#
# EC2 Instance
# ------------------------------------------------------------#
myEC2Instance:
Type: AWS::EC2::Instance
Condition: IsPrd
Properties:
KeyName: MyKeyPair
ImageId: ami-XXXXXXXXXX
InstanceType: t2.micro
今回はConditionsセクションに、本スタックが本番環境かどうかを判定する条件式IsPrdを作成した。
Conditions:
IsPrd: !Equals [!Ref Environment, "prd"]
それを、EC2インスタンスを作成する際にConditionプロパティに指定することで、本番環境のとき(入力パラメータがprdのとき)のみにEC2インスタンスを作成するという挙動を記述できる。
myEC2Instance:
Type: AWS::EC2::Instance
Condition: IsPrd
実際にスタックを作成してみる。
- 入力パラメータを"stg"にしてみる。
- VPCとサブネットのみが作成された。
- 次に作成されたスタックに対して、更新を行い、次は"prd"を選択
- 今度はEC2インスタンスが作成された。
Outputsを利用して、レイヤーごとにテンプレートを分ける
構築するリソースが多くなってくると、テンプレートの行数が膨大になってくるため、AWSはCloudFormationテンプレートを複数に分け、スタックを分割することを推奨している。
AWSで推奨しているスタック分割の仕方は以下の通り。
レイヤー名 | 説明 | 代表例 |
---|---|---|
Application Layer | システムが直接利用するアプリケーションを記述する。 | EC2, RDS, ELBなど |
Security Layer | ネットワークリソースのうち、ネットワークレイヤーに依存するセキュリティ関連のリソースを記述する。IAMは特に他のリソースに依存しないが、個々のレイヤーに記述する。 | Security Group, IAMなど |
Network Layer | ネットワークレイヤーのリソースを記述する。ネットワークレイヤーは最も依存性の低いリソースであり、外部のリソースを必要としない。 | VPC, Subnet, Internet Gatewayなど |
スタックを分割すると、1つ問題が発生する。それは、Ref関数で同じテンプレート内のリソースを参照できなくなることである。
そこで登場するのがOutputセクションと、ImportValue関数である。Outputセクションで、リソースの情報を出力し、ImportValue関数で、他のテンプレートで作成されたリソースの情報を参照することができる。
以下でVPC, サブネット, セキュリティグループ、EC2を作成する具体例を見てみる。
AWSTemplateFormatVersion: 2010-09-09
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: MyVPC
# ------------------------------------------------------------#
# Internet Gateway
# ------------------------------------------------------------#
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: My-InternetGateway
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MyVPC
InternetGatewayId: !Ref InternetGateway
# ------------------------------------------------------------#
# Route Table
# ------------------------------------------------------------#
RouteTable:
Type: AWS::EC2::RouteTable
DependsOn: AttachGateway
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: My-RouteTable
Route:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref RouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
# ------------------------------------------------------------#
# Public Sunbet A
# ------------------------------------------------------------#
PublicSubnetA:
Type: AWS::EC2::Subnet
DependsOn: AttachGateway
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: 'true'
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: PublicSubnetA
PublicRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref RouteTable
Outputs:
VPC1:
Value: !Ref MyVPC
Export:
Name: VPCName
SubnetA:
Value: !Ref PublicSubnetA
Export:
Name: SubnetName
詳細な説明は割愛するが、ここでのポイントは、OutputsセクションでVPCのリソース情報と、サブネットのリソース情報をエクスポートしている点である。Outputsセクションは以下のように記述する。
Outputs:
# 論理ID
Logical ID:
Description: Information about the value
# 返り値
Value: Value to return
Export:
# エクスポート時に出力する名前
Name: Value to export
このように、上記のテンプレートをCloudFormationで作成すると以下の画像ように出力タブで作成されたリソース情報を確認することができる。
キーの欄に指定した論理ID、値欄には出力されたVPCのIDやサブネットのIDが表示されている。さらに、エクスポート名の欄には指定したエクスポート名が表示されている。実際に他のテンプレートから参照する際にはこのエクスポート名を指定することになる。
次に、これらの情報を使ってセキュリティレイヤーを構築してみる。
WSTemplateFormatVersion: 2010-09-09
Resources:
MySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !ImportValue VPCName
GroupDescription: Allow SSH from Internet
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: WebServerSG
Outputs:
MySecurityGroup:
Value: !Ref MySecurityGroup
Export:
Name: SecurityGroupName
ここで重要なのは、
VpcId: !ImportValue VPCName
の行であり、VPC IDを指定するときに、ImportValue関数を使っている点である。
この組み込み関数を利用することで、他のテンプレートで作成されたリソースを参照することができる。
そして、Newworkレイヤー同様、Outputsで作成したセキュリティグループIDを出力している。
さらにこれを使ってApplicationレイヤーを作成する。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
KeyName:
Description: The EC2 Key Pair
Type: "AWS::EC2::KeyPair::KeyName"
EC2AMIId:
Description: AMI ID
Type : String
Default: ami-XXXXXXXXXXXXX
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
KeyName: !Ref KeyName
ImageId: !Ref EC2AMIId
InstanceType: t2.micro
SubnetId: !ImportValue SubnetName
SecurityGroupIds:
- !ImportValue SecurityGroupName
Tags:
- Key: Name
Value: WebServer
Securityレイヤー同様に、ImportValue関数でサブネットIDとセキュリティグループIDを参照している。
このように、OutputsセクションとImportValue関数を使うことで、CloudFormationのスタック分割を実現することができる。
まとめ
今回はAWSでIaCを実現できるサービスであるCloudFormationの基本的な活用方法ついて記載した。
ただ、Resourcesセクションに起動するAWSサービスを記述するだけでなく、より管理しやすい形でコードを記述する工夫がとても大事であることを学んだ。
最後に、
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
ありがとうございました。
以上です。
Discussion