目次Category
はじめに
今回は、AWS CloudFormationを利用して、デフォルトVPCへEC2インスタンスを構築します。
TerraformとCloudFormationでは、どちらもコードでAWSリソースを構築できますが、記述方法や管理方法には違いがあります。
本記事では、Terraformで構築したものと同じ構成のEC2インスタンスをCloudFormationで作成し、それぞれの違いを確認していきます。
Terraformでの構築手順については、こちらの記事をご覧ください。
【Systems Manager パラメータストアの値を Lambda から取得する】
なお、今回はCloudFormationの基本的な使い方を理解することを目的としているため、デフォルトVPCを利用します。
今回構築する全体像

CloudFormationのテンプレートを実行し、デフォルトVPC内にEC2インスタンスとSecurity Groupを作成します。
作成したEC2では、UserDataを利用してApacheをインストールし、ブラウザからWebページを表示できる状態にします。
各サービスの役割
| サービス | 役割 | 家づくりで例えると |
|---|---|---|
| AWS CloudFormation | AWSリソースをまとめて作成・管理する | 設計図 |
| Amazon EC2 | 仮想サーバを作成する | 家 |
| Security Group | EC2への通信を制御する | 家の門や鍵 |
家づくりで例えると、CloudFormationは設計図、EC2は設計図をもとに建てる家、Security Groupは家への出入りを制限する門や鍵の役割を持ちます。
設計図には、どのようなEC2を作成するか、どの通信を許可するか、起動時にどの処理を行うかなどを記載します。
CloudFormationでテンプレートを実行すると、記載された内容をもとに必要なAWSリソースがまとめて作成されます。
CloudFormationを利用するメリット
- ・AWSリソースの構成をテンプレートとして管理できる
- ・同じ構成の環境を繰り返し作成できる
- ・複数のAWSリソースをスタック単位でまとめて管理できる
- ・テンプレートを更新することで、リソースの変更を反映できる
- ・スタックを削除することで、作成したリソースをまとめて削除できる
AWSコンソールから手作業でリソースを作成する場合、設定内容を別の環境で再現するには、同じ操作をもう一度行う必要があります。
CloudFormationでは、構成をテンプレートとして残せるため、同じテンプレートを利用して同じ構成を再作成できます。
CloudFormationの主な用途
- ・開発環境、検証環境、本番環境を同じ構成で作成する
- ・複数人で同じAWS環境を再現する
- ・EC2、Security Group、VPCなどの関連リソースをまとめて管理する
- ・環境の変更履歴をテンプレートとして残す
- ・不要になった環境をスタック単位でまとめて削除する
構築手順
Step1 CloudFormationの準備をする
はじめに、CloudFormationで使用するテンプレートファイルを作成します。
この手順では、以下の準備を行います。
- ・VSCodeで作業フォルダを作成する
- ・
template.ymlを作成する - ・AWSコンソールでCloudFormationを開く
① 作業フォルダを作成する
設定手順
- VSCodeを開きます。
- 任意の場所にCloudFormation用の作業フォルダを作成します。
- 作成したフォルダをVSCodeで開きます。
template.ymlを作成します。
ポイント
- ・CloudFormationでは、YAMLまたはJSON形式でAWSリソースを定義します。
- ・今回は、YAML形式を利用します。
- ・Terraformでは
.tfファイルを利用しますが、CloudFormationではYAMLまたはJSONのテンプレートファイルを利用します。
Step2 EC2とSecurity Groupをテンプレートに定義する
次に、CloudFormationテンプレートへEC2インスタンスとSecurity Groupを定義します。
この手順では、Step1で作成したtemplate.ymlへ、以下の構成をまとめて記述します。
- ・デフォルトVPCとサブネットを選択できるようにする
- ・インスタンスタイプを候補から選択できるようにする
- ・Amazon Linux 2023のAMIをSystems Managerの公開パラメータから取得する
- ・HTTP通信の80番ポートを許可するSecurity Groupを作成する
- ・EC2へパブリックIPv4アドレスを割り当てる
- ・EC2起動時にApacheをインストールし、動作確認用のWebページを作成する
- ・作成後にEC2のID、パブリックIP、WebページのURLを出力する
① template.ymlを作成する
Step1で作成したtemplate.ymlへ、以下の内容を記述して保存します。
注意
コード内の[name]は、ご自身の名前など、リソースを識別できる任意の文字列へ書き換えてください。
AWSTemplateFormatVersion: '2010-09-09'
Description: Create an EC2 web server in the default VPC
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: Select the default VPC
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Select a subnet in the default VPC
InstanceType:
Type: String
Default: t3.micro
Description: Select the EC2 instance type
AllowedValues:
- t3.nano
- t3.micro
- t3.small
- t3.medium
LatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
Description: Latest Amazon Linux 2023 AMI ID
Resources:
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP access to the web server
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: Allow HTTP access
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
Description: Allow all outbound traffic
Tags:
- Key: Name
Value: sgp-[name]-01
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref LatestAmiId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref SubnetId
AssociatePublicIpAddress: true
GroupSet:
- !Ref WebSecurityGroup
UserData:
Fn::Base64: |
#!/bin/bash
dnf update -y
dnf install -y httpd
systemctl enable httpd
systemctl start httpd
echo "<h1>Hello from CloudFormation</h1>" > /var/www/html/index.html
Tags:
- Key: Name
Value: ec2-[name]-01
Outputs:
InstanceId:
Description: EC2 instance ID
Value: !Ref EC2Instance
PublicIp:
Description: Public IPv4 address of the EC2 instance
Value: !GetAtt EC2Instance.PublicIp
WebUrl:
Description: URL of the web server
Value: !Sub "http://${EC2Instance.PublicIp}"ポイント
- ・YAMLでは、インデントによって項目の階層を表します。
- ・インデントがずれているとテンプレートを正しく読み込めないため、位置を揃えて記述します。
テンプレートの構成
ここからは、作成したテンプレートを項目ごとに分けて解説します。
| 項目 | 役割 |
|---|---|
AWSTemplateFormatVersion | CloudFormationテンプレートの形式バージョンを指定する |
Description | テンプレートの概要を記載する |
Parameters | スタック作成時に利用する値を定義する |
Resources | 作成するAWSリソースを定義する |
Outputs | スタック作成後に確認したい値を出力する |
Parametersの解説
Parametersでは、スタック作成時に利用するVPC、サブネット、インスタンスタイプ、およびAMIを定義しています。
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: Select the default VPC
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Select a subnet in the default VPC
InstanceType:
Type: String
Default: t3.micro
Description: Select the EC2 instance type
AllowedValues:
- t3.nano
- t3.micro
- t3.small
- t3.medium
LatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
Description: Latest Amazon Linux 2023 AMI ID設定内容の意味
- ・VpcId:EC2とSecurity Groupを作成するVPCを指定する
- ・SubnetId:EC2を配置するサブネットを指定する
- ・InstanceType:作成するEC2のインスタンスタイプを指定する
- ・Default:値を変更しなかった場合に使用する初期値を指定する
- ・AllowedValues:選択可能なインスタンスタイプを制限する
- ・LatestAmiId:Systems Managerの公開パラメータからAmazon Linux 2023のAMI IDを取得する
ポイント
- ・VPC IDとサブネットIDをテンプレートへ直接記述せず、スタック作成時に選択できるようにしています。
- ・インスタンスタイプは候補から選択でき、初期値には
t3.microが設定されています。 - ・VpcIdとSubnetIdには、同じVPCに所属する組み合わせを指定します。
Security Groupの解説
WebSecurityGroupでは、EC2への通信を制御するSecurity Groupを定義しています。
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP access to the web server
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: Allow HTTP access
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
Description: Allow all outbound traffic
Tags:
- Key: Name
Value: sgp-[name]-01設定内容の意味
- ・Type:Security Groupを作成する
- ・VpcId:Parametersで選択したVPCへSecurity Groupを作成する
- ・SecurityGroupIngress:EC2へ入ってくる通信のルールを定義する
- ・FromPort/ToPort:HTTP通信で使用する80番ポートを許可する
- ・CidrIp:すべてのIPv4アドレスからの通信を対象にする
- ・SecurityGroupEgress:EC2から外部へ出ていく通信を定義する
- ・IpProtocol: -1:すべてのプロトコルによる送信を許可する
- ・Description:通信ルールの内容を説明する
ポイント
- ・今回はブラウザからWebページを確認するため、HTTP通信で利用する80番ポートだけを許可しています。
- ・
0.0.0.0/0はすべてのIPv4アドレスを示すため、実際の業務では用途に応じて接続元を制限します。
EC2の解説
EC2Instanceでは、作成するEC2のAMI、インスタンスタイプ、ネットワーク設定を定義しています。
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref LatestAmiId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref SubnetId
AssociatePublicIpAddress: true
GroupSet:
- !Ref WebSecurityGroup設定内容の意味
- ・ImageId:LatestAmiIdで取得したAmazon Linux 2023のAMIを利用する
- ・InstanceType:Parametersで選択したインスタンスタイプを利用する
- ・NetworkInterfaces:EC2へ割り当てるネットワークインターフェイスを定義する
- ・DeviceIndex: 0:EC2の主要なネットワークインターフェイスとして設定する
- ・SubnetId:Parametersで選択したサブネットへEC2を配置する
- ・AssociatePublicIpAddress:EC2へパブリックIPv4アドレスを割り当てる
- ・GroupSet:作成したSecurity Groupをネットワークインターフェイスへ関連付ける
ポイント
- ・
!Refは、Parametersの値や同じテンプレート内で作成したリソースを参照するときに使用します。
UserDataの解説
UserDataでは、EC2の初回起動時に実行する処理を定義しています。
UserData:
Fn::Base64: |
#!/bin/bash
dnf update -y
dnf install -y httpd
systemctl enable httpd
systemctl start httpd
echo "<h1>Hello from CloudFormation</h1>" > /var/www/html/index.html実行する処理
- ・システムパッケージを更新する
- ・Apacheをインストールする
- ・EC2再起動後もApacheが自動起動するように設定する
- ・Apacheを起動する
- ・
Hello from CloudFormationと表示するWebページを作成する
ポイント
- ・UserDataを利用することで、EC2作成後に手作業でApacheを設定する必要がなくなります。
- ・EC2の作成だけでなく、サーバの初期設定と動作確認用ページの配置まで自動化できます。
- ・同じテンプレートを利用することで、同じ初期状態のWebサーバを再作成できます。
Outputsの解説
Outputsでは、スタック作成後に確認したいEC2の情報を出力します。
Outputs:
InstanceId:
Description: EC2 instance ID
Value: !Ref EC2Instance
PublicIp:
Description: Public IPv4 address of the EC2 instance
Value: !GetAtt EC2Instance.PublicIp
WebUrl:
Description: URL of the web server
Value: !Sub "http://${EC2Instance.PublicIp}"設定内容の意味
- ・InstanceId:作成したEC2のインスタンスIDを表示する
- ・PublicIp:
!GetAttを使い、EC2のパブリックIPv4アドレスを取得する - ・WebUrl:
!SubでパブリックIPをURLへ組み込み、アクセス用URLを作成する
ポイント
- ・スタック作成後、CloudFormationの[出力]タブから各値を確認できます。
- ・WebUrlを利用すると、EC2コンソールでパブリックIPを探さずに動作確認できます。
Step3 CloudFormationスタックを作成する
テンプレートが完成したら、AWS CloudFormationコンソールからスタックを作成します。
スタックとは、CloudFormationテンプレートから作成したAWSリソースをまとめて管理する単位です。
① テンプレートをアップロードする
設定手順
- AWSマネジメントコンソールを開きます。
- CloudFormationコンソールを開きます。
- [スタックの作成]をクリックします。
- [新しいリソースを使用(標準)]を選択します。
- テンプレートの指定で[テンプレートファイルのアップロード]を選択します。
- [ファイルの選択]をクリックします。
- 作成した
template.ymlを選択します。 - [次へ]をクリックします。
ポイント
- ・テンプレートをアップロードすると、CloudFormationが構文を読み取り、定義されているパラメータやリソースを確認します。
- ・YAMLのインデントに誤りがある場合は、テンプレートを正しく読み込めないことがあります。
② スタックの詳細を設定する
設定内容
- ・スタック名:stack-[name]-01(任意の名前)
- ・VpcId:デフォルトVPC
- ・SubnetId:デフォルトVPC内のサブネット
- ・InstanceType:利用するEC2のインスタンスタイプ(初期値はt3.micro)
- ・LatestAmiId:初期値のSystems Manager公開パラメータを利用する
設定手順
- スタック名にstack-[name]-01を入力します。
- VpcIdの一覧からデフォルトVPCを選択します。
- SubnetIdの一覧から、デフォルトVPCに所属するサブネットを選択します。
- InstanceTypeを確認します。今回は初期値の
t3.microを利用します。 - LatestAmiIdは初期値のまま進めます。
- [次へ]をクリックします。
- スタックオプションはデフォルトのまま進めます。
- 設定内容を確認します。
- [送信]をクリックします。
ポイント
- ・VpcIdとSubnetIdは、同じVPCに所属する組み合わせを選択します。
- ・サブネットIDが存在しない場合や、別リージョンのサブネットを指定した場合はスタック作成に失敗します。
- ・AWSコンソール右上のリージョンと、AMI・VPC・サブネットのリージョンを揃える必要があります。
- ・Terraformでは
terraform applyでリソースを作成しますが、CloudFormationではスタックを作成することでリソースを構築します。
③ スタックの作成状態を確認する
スタックを作成すると、CloudFormationのイベント画面にリソースの作成状況が表示されます。
確認する内容
- ・スタックのステータスが
CREATE_IN_PROGRESSになっている - ・Security Groupが作成されている
- ・EC2インスタンスが作成されている
- ・最終的にスタックのステータスが
CREATE_COMPLETEになっている
ポイント
- ・CloudFormationは、テンプレート内の参照関係をもとに作成順序を判断します。
- ・今回はEC2からSecurity Groupを参照しているため、Security Groupが作成された後にEC2へ関連付けられます。
- ・作成に失敗した場合は、イベント画面のステータス理由から原因を確認できます。
Step4 EC2の動作を確認する
スタックの作成が完了したら、EC2インスタンスとWebサーバが正常に作成されていることを確認します。
① EC2インスタンスを確認する
確認手順
- Amazon EC2コンソールを開きます。
- [インスタンス]を開きます。
ec2-[name]-01が作成されていることを確認します。- インスタンスの状態が[実行中]になっていることを確認します。
- ステータスチェックが正常になっていることを確認します。
ポイント
- ・CloudFormationで作成したEC2も、通常のEC2と同様にEC2コンソールから確認できます。
- ・EC2コンソールから直接作成した場合との違いは、CloudFormationスタックによって管理されている点です。
② Security Groupを確認する
確認手順
- EC2コンソールの[セキュリティグループ]を開きます。
sgp-[name]-01が作成されていることを確認します。- インバウンドルールを開きます。
- HTTPの80番ポートが許可されていることを確認します。
- EC2インスタンスにSecurity Groupが関連付けられていることを確認します。
ポイント
- ・Security Groupで80番ポートが許可されていない場合、Apacheが起動していてもブラウザからアクセスできません。
- ・Webページが表示されない場合は、EC2の状態だけでなくSecurity Groupの設定も確認します。
③ ブラウザからアクセスする
確認手順
- CloudFormationコンソールで作成したスタックを開きます。
- [出力]タブを開きます。
WebUrlに表示されたURLを開きます。- Webページが表示されることを確認します。
Hello from CloudFormationと表示されることを確認します。
想定される結果
Hello from CloudFormation表示されない場合の確認ポイント
- ・EC2インスタンスが実行中になっているか
- ・EC2にパブリックIPv4アドレスが付与されているか
- ・Security Groupで80番ポートが許可されているか
- ・選択したサブネットがインターネットへ接続できる構成になっているか
- ・UserDataの処理が完了しているか
- ・Apacheが正常にインストール、起動されているか
ポイント
- ・Webページが表示されれば、EC2、Security Group、UserDataが正常に設定されています。
- ・EC2の作成直後は、UserDataの処理が完了するまで少し時間がかかる場合があります。
Step5 CloudFormationスタックを削除する
動作確認が完了したら、不要な利用料金が発生しないようにCloudFormationスタックを削除します。
スタックを削除すると、今回のテンプレートから作成したEC2インスタンスとSecurity Groupもまとめて削除されます。
① スタックを削除する
削除手順
- CloudFormationコンソールを開きます。
- 今回作成したスタックを選択します。
- [削除]をクリックします。
- 確認画面で[削除]をクリックします。
- スタックのステータスが
DELETE_IN_PROGRESSになることを確認します。 - スタックが一覧から削除されるまで待ちます。
ポイント
- ・CloudFormationでは、スタックを削除することで、スタック内のリソースをまとめて削除できます。
- ・EC2とSecurity Groupを一つずつ個別に削除する必要がありません。
- ・Terraformでいう
terraform destroyに近い処理です。
② リソースが削除されたことを確認する
確認手順
- Amazon EC2コンソールを開きます。
- EC2インスタンスが終了済み、または一覧から削除されていることを確認します。
- [セキュリティグループ]を開きます。
- 作成したSecurity Groupが削除されていることを確認します。
ポイント
- ・スタックを削除した後は、作成したリソースが残っていないことを各サービスのコンソールから確認します。
- ・不要なEC2が残っていると利用料金が発生する可能性があるため、削除後の確認まで行います。
家づくりで例えると
AWSコンソールから手作業でリソースを作成した場合、家、門、鍵を一つずつ確認しながら撤去する必要があります。
一方、CloudFormationでは、設計図から作成した家や門をスタック単位で管理しています。
そのため、スタックを削除することで、設計図から作成した家(EC2)や門(Security Group)をまとめて撤去するイメージになります。
Terraformとの主な違い
| 項目 | Terraform | CloudFormation |
|---|---|---|
| 定義ファイル | .tfファイル | YAMLまたはJSON |
| 作成前の確認 | terraform plan | 変更セット |
| リソース作成 | terraform apply | スタック作成・更新 |
| リソース管理 | Stateファイル | CloudFormationスタック |
| リソース削除 | terraform destroy | スタック削除 |
TerraformとCloudFormationは、どちらもコードで管理するIaCツールです。
同じ構成をそれぞれのツールで作成することで、記述方法や管理方法の違いを比較しやすくなります。
まとめ
今回は、AWS CloudFormationを利用して、デフォルトVPCへEC2インスタンスを構築しました。
今回の構築では、
- ・CloudFormationのYAMLテンプレートでAWSリソースを定義する
- ・スタックを利用して複数のAWSリソースをまとめて管理する
- ・スタック削除によって、作成したリソースをまとめて削除する
というCloudFormationの基本的な構築・管理方法を確認しました。
CloudFormationを利用すると、EC2やSecurity GroupなどのAWSリソースをテンプレートとして管理でき、同じ構成を繰り返し作成できます。
また、スタックを単位として作成・更新・削除できるため、複数のリソースを個別に操作する場合と比べて管理しやすくなります。
TerraformとCloudFormationで同じ構成を作成して比較することで、それぞれのIaCツールにおける記述方法やリソース管理の違いも確認できました。
同じカテゴリーの記事
同じカテゴリの記事を読む