はじめに
前回の記事では、Terraformを用いてAWSインフラのコード化を行いました。
本記事ではこれをCloudFormationに置き換え、同様の構成をコード化して自動的に構築する手順を解説します。
特に、CloudFormationではリソース間の依存関係やテンプレート構文の理解が重要で、初めて取り組む場合には注意が必要です。
ゴールは、パブリックサブネットに配置されたApacheがインストールされたEC2インスタンスを構築し、ブラウザからテストページを確認することです。
自動化する構成について
今回は、AWSのインフラを構築するために、以下の構成を自動化しました。
-
VPC(仮想プライベートクラウド):
10.0.0.0/16のCIDRを持つネットワークを構成します。 -
サブネット:
パブリックサブネット(10.0.1.0/24)を作成し、EC2インスタンスを配置します。 -
インターネットゲートウェイ(IGW):
インターネットとVPCを接続します。 -
ルートテーブル:
サブネットからインターネットへのルートを設定します。 -
セキュリティグループ:
HTTP(80番ポート)およびSSH(22番ポート)アクセスを許可します。 -
EC2インスタンス:
Amazon Linux 2を使用し、Apache HTTPサーバーをインストールします。
実際に作成したVPCのリソースマップは以下の通りです。パブリックサブネットにApacheがインストールされたEC2インスタンスが構築されます。
この構成を手動で作成するのは時間がかかり、管理も煩雑になります。
CloudFormationを使うことで、インフラをコードとして管理し、再現性のあるインフラを実現できます。
CloudFormationテンプレート
以下は、構成全体を自動化するためのCloudFormationテンプレートです。
AWSTemplateFormatVersion: '2010-09-09'
Description: Create VPC, Subnet, Internet Gateway, Security Group, and EC2 instance with Apache using CloudFormation.
Resources:
# VPC作成
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: cloudformation-main-vpc
# パブリックサブネット作成
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: cloudformation-public-subnet
# インターネットゲートウェイ作成
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: cloudformation-igw
# インターネットゲートウェイとVPCの関連付け
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MyVPC
InternetGatewayId: !Ref InternetGateway
# ルートテーブル作成
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: cloudformation-public-route-table
# インターネットへのルート設定
Route:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
# サブネットとルートテーブルの関連付け
SubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
# セキュリティグループ作成
PublicSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH
VpcId: !Ref MyVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: -1
FromPort: 0
ToPort: 0
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: cloudformation-public-sg
# EC2インスタンス作成
ApacheInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
SubnetId: !Ref PublicSubnet
SecurityGroupIds:
- !GetAtt PublicSecurityGroup.GroupId
ImageId: ami-0b6fe957a0eb4c1b9 # Amazon Linux 2 (Tokyo)
KeyName: <YourKeyName> # 必要に応じて設定
Tags:
- Key: Name
Value: cloudformation-apache-ec2
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<html><body><h1>Welcome to Apache Server powered by CloudFormation!</h1></body></html>" > /var/www/html/index.html
CloudFormationでは、サブネット単位でパブリックIPの割り当てを管理します。そのため、サブネット作成時に設定する MapPublicIpOnLaunch
に依存します。
一方、Terraformではインスタンス単位でパブリックIPの割り当てを管理し、インスタンス作成時に個別に設定する必要があります(associate_public_ip_address
)。
実際にスタックを実行してみた
CloudFormationのサービス画面からスタックの作成に進み、作成したyamlファイル
をアップロードします。
スタック名は任意で設定できます。ここでは私の名前「honda
」としています。
画面遷移後のスタックオプション設定は、個別の設定に依存するため、今回は設定せずに進めます。
最後に確認を行い、問題がなければ最下部までスクロールし、「送信
」をクリックして完了です。
スタックの実行後、イベントタブで成功を確認できました(実行には少し時間がかかります)。
検証結果の確認
作業が完了したので、実際にマネジメントコンソールで確認します。VPCが想定通りに作成されていることが確認できました。
また、コード内で作成したEC2インスタンスも確認できました。パブリックIPアドレスをブラウザに入力し、アクセスができるか確認します。
今回は検証のため、HTTPS通信ではなくHTTP通信でアクセスしています。
http://35.78.209.29/
実際に、cloudformation-apache-ec2
のindex.html
ファイルの内容が表示されていることを確認できました。
この確認をもって、検証は大成功です!
まとめ
今回は、CloudFormationを使用してAWSのEC2インスタンスを自動化する構成を作成しました。
Terraformとの構文の違いに悩まされながらも、無事にインフラをコード化することができました。
今後は、より複雑な構成に挑戦し、さらに自動化を進めていきたいと思います!
関連記事
CloudFormationによるインフラのコード化についても過去の記事で解説しているため、より深く知りたい方は読んでみてください!