1クリックでWordPressブログを構築する(CloudFormation)
背景
以下の記事で、AWSを使ってWordPressサイトを構築した。
こちらでは、AWSのマネージメントコンソールを使って環境を構築したが、マネージメントコンソールを使って構築すると以下のようなデメリットがある。
- 設定が複雑になってくると、セキュリティやルーティングの設定の関連性がわからなくなってくる可能性がある。
- 管理が面倒
- 一度削除すると、再度構築するのが面倒
上記の理由からも、近年ではコードでインフラを管理するInfrastructure as Code (IaC)が導入されてきている。
そこで今回は、上記記事で構築したWordPressブログの環境をAWSのIaCサービスであるCloudFormationを使って構築してみた。
CloudFormationとは
AWSのインフラ環境/リソースをコードで管理することができ、それを用いて一括でリソースを起動/削除が可能となるAWSのサービスである。
押さえておきたいポイントは以下。
- YAML/JSONで管理する。
- YAML/JSONで作成したテンプレートから、スタックを作成する。
- スタックとは、テンプレートによって起動されるリソースの集合のこと。
これくらいだろうか。
細かい話は以下にわかりやすくまとめってあったのでそちらを参照していただきたい。
構成
今回作成を目指す構成
今回作成を目指す構成は上記の図の通り。
簡単なAWSの構成で、WordPressをインストールしたEC2, RDS, Internet Gateway, Application Load Balancer (ALB) からなる。
設定を行うため、EC2へはインターネットからSSHで接続できるようにしておき、実際のブログへのアクセスはALB経由でHTTPで通信する。
※EC2へインターネットからSSH接続できることに関してセキュリティ面で問題はあるが今回は目を瞑ることにする。
ALBは実際なくても良いが、今後Multi-AZ構成を取ることを想定した場合に必要となるため利用する。
実際に構築してみる
0. 事前準備
- EC2へSSH接続するためのキーペアは事前に用意しておく。
詳細は割愛する。
1. テンプレートの作成
実際に作成したテンプレートは以下
AWSTemplateFormatVersion: '2010-09-09'
Description:
Create WordPress Blog Site
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-01748a72bed07727c
DatabaseName:
Description: Database Name
Type : String
Default: wordpress
DatabaseMasterName:
Description: Database Master User Namee
Type : String
Default: wordpress
DatabaseMasterPassword:
Description: Database Master User Password
Type : String
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
# ------------------------------------------------------------#
# Internet Gateway
# ------------------------------------------------------------#
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: My-InternetGateway
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# ------------------------------------------------------------#
# Route Table
# ------------------------------------------------------------#
RouteTable:
Type: AWS::EC2::RouteTable
DependsOn: AttachGateway
Properties:
VpcId: !Ref VPC
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 VPC
Tags:
- Key: Name
Value: PublicSubnetA
PublicRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref RouteTable
# ------------------------------------------------------------#
# Private Sunbet A
# ------------------------------------------------------------#
PrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: 10.0.2.0/24
MapPublicIpOnLaunch: 'false'
VpcId: !Ref VPC
Tags:
- Key: Name
Value: PrivateSubnetA
# ------------------------------------------------------------#
# Public Sunbet C
# ------------------------------------------------------------#
PublicSubnetC:
Type: AWS::EC2::Subnet
DependsOn: AttachGateway
Properties:
AvailabilityZone: "ap-northeast-1c"
CidrBlock: 10.0.3.0/24
MapPublicIpOnLaunch: 'true'
VpcId: !Ref VPC
Tags:
- Key: Name
Value: PublicSubnetC
# ------------------------------------------------------------#
# Private Sunbet C
# ------------------------------------------------------------#
PrivateSubnetC:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: "ap-northeast-1c"
CidrBlock: 10.0.4.0/24
MapPublicIpOnLaunch: 'false'
VpcId: !Ref VPC
Tags:
- Key: Name
Value: PrivateSubnetC
# ------------------------------------------------------------#
# ALB Security Group
# ------------------------------------------------------------#
AlbSG1:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: ALB-SG-1
GroupDescription: Allow HTTP access from internet
VpcId: !Ref VPC
SecurityGroupIngress:
# http
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: "0.0.0.0/0"
Tags:
- Key: Name
Value: ALB-SG-1
# ------------------------------------------------------------#
# ALB
# ------------------------------------------------------------#
ApplicationLoadBalancer:
Type : AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: My-ALB-1
Scheme: "internet-facing"
SecurityGroups:
- !Ref AlbSG1
# At least two subnet is needed
Subnets:
- !Ref PublicSubnetA
- !Ref PublicSubnetC
Tags:
- Key: Name
Value: My-ALB-1
# ------------------------------------------------------------#
# EC2 Security Group
# ------------------------------------------------------------#
WebSG1:
Type: AWS::EC2::SecurityGroup
DependsOn: AlbSG1
Properties:
GroupName: Web-SG-1
GroupDescription: Allow SSH from Internet
VpcId: !Ref VPC
SecurityGroupIngress:
# ssh
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
# HTTP
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref AlbSG1
Tags:
- Key: Name
Value: Web-SG-1
# ------------------------------------------------------------#
# 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:
- !Ref WebSG1
SubnetId: !Ref PublicSubnetA
Tenancy: default
Tags:
- Key: Name
Value: WebServer
UserData:
Fn::Base64: |
#!/bin/bash
echo "===========yum -y install httpd==========="
yum -y update
echo "===========amazon-linux-extras install php7.2 -y==========="
amazon-linux-extras install php7.2 -y
echo "===========yum -y install mysql httpd php-mbstring php-xml gd php-gd==========="
yum -y install mysql httpd php-mbstring php-xml gd php-gd
echo "===========systemctl enable/start httpd.service ==========="
systemctl enable httpd.service
systemctl start httpd.service
echo "=========== http://ja.wordpress.org/latest-ja.tar.gz ~/ ==========="
wget http://ja.wordpress.org/latest-ja.tar.gz
echo "=========== tar zxvf ~/latest-ja.tar.gz ==========="
tar zxvf latest-ja.tar.gz
echo "=========== cp -r wordpress/* /var/www/html/ ==========="
cp -r wordpress/* /var/www/html/
chown apache:apache -R /var/www/html
cd /var/www/html/
mkdir healthcheck
cd healthcheck
touch check
# ------------------------------------------------------------#
# Target Group
# ------------------------------------------------------------#
MyTG1:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
# Health check enabled must be true for target groups with target type 'instance'
HealthCheckPath: /healthcheck/check
HealthCheckEnabled: True
Name: My-TG-1
Port: 80
Protocol: HTTP
Tags:
- Key: Name
Value: My-TG-1
Targets:
# If the target type is instance, you cannot override the Availability Zone
- Id: !Ref WebServer
Port: 80
VpcId: !Ref VPC
# ------------------------------------------------------------#
# ALB Listner
# ------------------------------------------------------------#
ALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref MyTG1
Type: forward
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
# ------------------------------------------------------------#
# Database Subnet Group
# ------------------------------------------------------------#
DBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: My-SubnetGroup
DBSubnetGroupName: My-SubnetGroup
SubnetIds:
- !Ref PrivateSubnetA
- !Ref PrivateSubnetC
Tags:
- Key: Name
Value: My-SubnetGroup
# ------------------------------------------------------------#
# RDS Security Group
# ------------------------------------------------------------#
RDSSG1:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: RDS-SG-1
GroupDescription: Allow Request from WebServer
VpcId: !Ref VPC
SecurityGroupIngress:
# http
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !Ref WebSG1
Tags:
- Key: Name
Value: RDS-SG-1
# ------------------------------------------------------------#
# 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: !Ref DBSubnetGroup
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:
- !Ref RDSSG1
基本的には画面でポチポチと設定する内容を記入していけばよい。
公式のドキュメントを参考にした。
2. スタックの作成
① テンプレートの指定
- サービス > CloudFormationを選択し、「スタックの作成」を押下
- 以下の通りテンプレートをアップロードする。
② スタックの詳細を指定
- 以下のように設定
項目 | 設定値 |
---|---|
スタックの名前 | MyStack |
DatabaseMasterName | wordpress |
DatabaseMasterPassword | 任意のパスワード |
DatabaseName | wordpress |
EC2AMIId | ami-01748a72bed07727c |
KeyName | MyKeyPair |
※スタックの名前以外は、templateでParametersとして自分で設定できるものである。 |
③ スタックオプションの設定
- 何も記入せず「次へ」
④ レビュー
- 問題なければ「スタックの作成」
- 完了するまで5分くらいかかったが、以下のようにCREATE_COMPLETEと表示されれば完了
3. 動作確認
完了したら、さっそくサイトにアクセスしてみる。
-
サービス > EC2 のロードバランサーからDNS名をコピー
-
ブラウザに張り付け
上記のようにWordPressの画面が表示され、その後、画面の指示に従ってWordPressのインストールが完了した。
-
ちなみに、EC2へもSSHでログインが可能であった。
-
ユーザーデータで指定したApacheインストールやWordPressのダウンロード、ヘルスチェックファイルの作成もうまくいっているようだ。
なお、ユーザーデータで指定したコマンドのログは/var/log/cloud-init-output.logに出力されている。
テンプレートの詳細
簡単であるが、テンプレートについて解説する。
一個一個の設定を説明するのはAWSのドキュメントに任せて、ポイント/自分が悩んだところなどを記載する。
パラメータの設定
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-01748a72bed07727c
DatabaseName:
Description: Database Name
Type : String
Default: wordpress
DatabaseMasterName:
Description: Database Master User Namee
Type : String
Default: wordpress
DatabaseMasterPassword:
Description: Database Master User Password
Type : String
下記は、ユーザーが任意に作成できるパラメータであり、Parametersで作成が可能である。
ここで設定したパラメータは画面でスタックを作成するときに、入力できるようになる。
ここでは、EC2にSSH接続するためのキーペアやAMIのID、データベース名、データベースのマスターユーザー名、パスワードをパラメータとして設定した。
VPC
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
InstanceTenancy: default
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: MyVPC
- AWS::EC2::VPCでVPCを作成できる。
- CidrBlockさえ指定すれば構築できる。
Internet Gateway
# ------------------------------------------------------------#
# Internet Gateway
# ------------------------------------------------------------#
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: My-InternetGateway
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
- AWS::EC2::InternetGatewayで作成できる。特に設定値はなし。
- VPCGatewayAttachementで、VPCにInternet Gatewayをアタッチする、
プロパティでVPCのIDやInternet GatewayのIDを指定する。なお、!Refを使うとリソースのIDなどが参照できる。
Route Table
# ------------------------------------------------------------#
# Route Table
# ------------------------------------------------------------#
RouteTable:
Type: AWS::EC2::RouteTable
DependsOn: AttachGateway
Properties:
VpcId: !Ref VPC
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
- AWS::EC2::RouteTableでルートテーブルを作成する。
- Dependonにリソースを指定すると、そこで指定したリソースの作成直後にリソースを生成する。ここでは、Route TableはInternet GatewayがVPCにアタッチされた直後に作成されることを意味する。
- AWS::EC2::Routeでルーティングの設定を追加する。
ルーティングに関してはRouteTableのプロパティでは設定できないことに注意したい。
送信先のiPをDestinationCidrBlockプロパティで指定し、ターゲットをGatewayIdで指定した。送信元をIPv6にしたい場合は、DestinationIpv6CidrBlockで指定する。ターゲットをInternet Gateway以外にしたい場合は、InstanceId, NatGatewayIdプロパティなどを指定できる。
Subnet
# ------------------------------------------------------------#
# 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 VPC
Tags:
- Key: Name
Value: PublicSubnetA
PublicRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref RouteTable
- AWS::EC2::Subnetで作成する。プロパティでVPCやアベイラビリティゾーンを指定する。
- AWS::EC2::SubnetRouteTabelAssociationでサブネットとRoute Tableを紐づけるための設定を追加することができる。
# ------------------------------------------------------------#
# Private Sunbet A
# ------------------------------------------------------------#
PrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: "ap-northeast-1a"
CidrBlock: 10.0.2.0/24
MapPublicIpOnLaunch: 'false'
VpcId: !Ref VPC
Tags:
- Key: Name
Value: PrivateSubnetA
その他のSubnetについても同様に作成する。
ただし、Internet Gatewayへのルーティングは行わない。
AZ-Cは省略
Application Load Balancer
# ------------------------------------------------------------#
# ALB Security Group
# ------------------------------------------------------------#
AlbSG1:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: ALB-SG-1
GroupDescription: Allow HTTP access from internet
VpcId: !Ref VPC
SecurityGroupIngress:
# http
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: "0.0.0.0/0"
Tags:
- Key: Name
Value: ALB-SG-1
- 先に、ALBにアタッチするセキュリティグループを作成する。
- AWS::EC2::SecurityGroupで作成する。
- インターネットからのアクセスを許可するので、すべてのTCPの80番ポート通信を許可する設定とする。
# ------------------------------------------------------------#
# ALB
# ------------------------------------------------------------#
ApplicationLoadBalancer:
Type : AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: My-ALB-1
Scheme: "internet-facing"
SecurityGroups:
- !Ref AlbSG1
# At least two subnet is needed
Subnets:
- !Ref PublicSubnetA
- !Ref PublicSubnetC
Tags:
- Key: Name
Value: My-ALB-1
- AWS::ElasticLoadBalancingV2::LoadBalancerでALBを作成する。
- SecurityGroupプロパティで、先ほど作ったALBのセキュリティグループをアタッチする。
- SubnetはPublic Subnet A, Cの二つを指定する。(※2つないとダメ)
EC2
# ------------------------------------------------------------#
# EC2 Security Group
# ------------------------------------------------------------#
WebSG1:
Type: AWS::EC2::SecurityGroup
DependsOn: AlbSG1
Properties:
GroupName: Web-SG-1
GroupDescription: Allow SSH from Internet
VpcId: !Ref VPC
SecurityGroupIngress:
# ssh
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
# HTTP
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref AlbSG1
Tags:
- Key: Name
Value: Web-SG-1
- ALB同様、EC2にアタッチするセキュリティグループを作成する。
- SSHはインターネットからのアクセスを許可するので、TCPの22番ポートのCIDRは0.0.0.0/0。
- HTTPは、ALBからの通信のみ許可したいので、CidrIpではなくSourceSecurityGroupIdを設定する。
# ------------------------------------------------------------#
# 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:
- !Ref WebSG1
SubnetId: !Ref PublicSubnetA
Tenancy: default
Tags:
- Key: Name
Value: WebServer
UserData:
Fn::Base64: |
#!/bin/bash
echo "===========yum -y install httpd==========="
yum -y update
echo "===========amazon-linux-extras install php7.2 -y==========="
amazon-linux-extras install php7.2 -y
echo "===========yum -y install mysql httpd php-mbstring php-xml gd php-gd==========="
yum -y install mysql httpd php-mbstring php-xml gd php-gd
echo "===========systemctl enable/start httpd.service ==========="
systemctl enable httpd.service
systemctl start httpd.service
echo "=========== http://ja.wordpress.org/latest-ja.tar.gz ~/ ==========="
wget http://ja.wordpress.org/latest-ja.tar.gz
echo "=========== tar zxvf ~/latest-ja.tar.gz ==========="
tar zxvf latest-ja.tar.gz
echo "=========== cp -r wordpress/* /var/www/html/ ==========="
cp -r wordpress/* /var/www/html/
chown apache:apache -R /var/www/html
cd /var/www/html/
mkdir healthcheck
cd healthcheck
touch check
-
EC2インスタンスは、AWS::EC2::Instanceで作成する。
-
BlockDeviceMappingsプロパティで/dev/xvdaにEBSボリュームをアタッチできる。
-
KeyName: !Ref KeyNameで、Parametersで指定したKeyPairを設定する。
-
UserDataで、ユーザーデータを設定する。
ここで、apacheのインストールやwordpressのダウンロード、ヘルスチェックファイルの作成を子なっている。
なお、ユーザーデータを記載する際は、スクリプトをBase64エンコードする必要があるため、 Fn::Base64でエンコードする。 -
セキュリティグループを指定する際は、SecurityGroupIdsプロパティを利用する。
他にもSecurityGroupsなるプロパティがあるがこれを利用するとエラーとなった。
ドキュメントを参照すると以下が記載されている。
[EC2-Classic、デフォルト VPC] セキュリティグループの名前。デフォルト以外の VPC の場合は、代わりにセキュリティグループ ID を使用する必要があります。
上記のような、EC2-Classicや、デフォルトVPC以外はSecurityGroupIdsを利用する。
つまり、ほとんどの場合こっちでよいと思われる。
ALBとEC2の接続
# ------------------------------------------------------------#
# Target Group
# ------------------------------------------------------------#
MyTG1:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckPath: /healthcheck/check
HealthCheckEnabled: True
Name: My-TG-1
Port: 80
Protocol: HTTP
Tags:
- Key: Name
Value: My-TG-1
Targets:
- Id: !Ref WebServer
Port: 80
VpcId: !Ref VPC
- AWS::ElasticLoadBalancingV2::TargetGroupでターゲットグループを作成する。
- Targetプロパティで上記で作成したEC2インスタンスを登録する。
# ------------------------------------------------------------#
# ALB Listner
# ------------------------------------------------------------#
ALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref MyTG1
Type: forward
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
- AWS::ElasticLoadBalancingV2::ListenerでALBのリスナーを作成する。
- これによりALBが上記で作成したターゲットグループをListenするようになる。
RDS
# ------------------------------------------------------------#
# Database Subnet Group
# ------------------------------------------------------------#
DBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: My-SubnetGroup
DBSubnetGroupName: My-SubnetGroup
SubnetIds:
- !Ref PrivateSubnetA
- !Ref PrivateSubnetC
Tags:
- Key: Name
Value: My-SubnetGroup
- AWS::RDS::DBSubnetGroupでサブネットグループを作成する。
- RDSにおいては、冗長性の観点から、複数のAZに存在するサブネットをグルーピングしたサブネットグループ内に作成しなければならないという決まりがある。
# ------------------------------------------------------------#
# RDS Security Group
# ------------------------------------------------------------#
RDSSG1:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: RDS-SG-1
GroupDescription: Allow Request from WebServer
VpcId: !Ref VPC
SecurityGroupIngress:
# http
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !Ref WebSG1
Tags:
- Key: Name
Value: RDS-SG-1
- ALB, EC2同様、RDSにアタッチするセキュリティグループを作成する。
- TCPの3306番ポートをWebServerからのアクセスからのみ許可したいため、CidrIpではなくSourceSecurityGroupIdを設定する。
# ------------------------------------------------------------#
# 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: !Ref DBSubnetGroup
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:
- !Ref RDSSG1
- AWS::RDS::DBInstanceで実際にDBインスタンスを作成する。
- 基本的にはデフォルトのままで設定している。
- 上記で作成したサブネットグループをDBSubnetGroupNameプロパティで指定している。
- Parametersで設定していいるデータベース名、データベースマスターユーザー名、データベースマスターパスワードもそれぞれ、DBName, MasterUserName, MasterUserPasswordプロパティで指定している。
- セキュリティグループはVPCSecurityGroupsプロパティで指定する。
DBSecurityGroupsなるプロパティも存在するが、こちらはAWS::RDS::DBSecurityGroupで作成されたDBセキュリティグループなるものらしい。
DBセキュリティグループについては以下。
VPC セキュリティグループ – EC2-VPC プラットフォーム用。
DB セキュリティグループ – EC2-Classic プラットフォーム用。
つまり、EC2インスタンスの項で記載したように、EC2-Classicなる昔の環境のものなので、DBセキュリティグループヲ使うことはほとんどなさそう。
まとめ
WordPressブログサイトをCloudFormationを使って構築した。
準備には時間がかかってしまうが、一度作ってしまえばすぐに環境構築ができるし、削除もスタックを削除するだけで完了する。
本記事を書くにも、「あ、あそこのキャプチャとりたいからまた環境作りたい!」ってなった時にすぐにテンプレートから起動できるのはとても助かった。
ただ、CloudFormationのデメリットとしては、AWSでしか利用できないことである。
次回は様々なサービスに対応しているTerraformなども触ってみたいと思う。
Discussion