AWS CloudFormationでWordPressを構築

内容
・趣旨目標
・CloudFormationとは
・参考サイト
・コードのテンプレートなど
・本記事で使用できるサービス
・ハンズオンで目指す構成
・ハンズオン開始！(Cloud9の導入)
・コーディングはYAML形式を使用するため、インデントの設定を変更(初期設定)
・ VPCの作成(CloudFormationの活用開始)
・テンプレートを更新して、適用させる。（コードの更新開始）
・テンプレを更新したので、AWS CLIでコードの検証
・チェックしたコードを更新（コードの更新完了）
・コードの構成を勝手に無理やり解釈してみたｗ
・EC2作成
・不足を設定(VPC,ユーザーデータ,セキュリティグループ)
・RDSとELBを同時に作成！
・完成
・撤収！！！

## 趣旨目標
AWSのCloudFormationをハンズオンに従って学習して、基礎力の向上と基礎知識の定着。テンプレートを多少編集することで、テンプレートの更新要領も理解します。
※本記事のコード記載は、ハンズオンのテンプレ資料に合わせた表記となっているので利用される場合は、お気をつけください。


## CloudFormationとは：

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html

## 参考サイト：
是非この動画を利用されてください。今までのハンズオンのなかで一番わかりやすく、勉強になりました。

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-cfn-2022-confirmation_810.html


## コードのテンプレートなど：

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html

https://github.com/awslabs/aws-cloudformation-templates/tree/master


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/6d090055-cc32-1d70-d08c-f40389307153.png)

## 本記事で使用できるサービス：
AWS CloudFormation,EC2,RDS,ELB,Cloud9


## ハンズオンで目指す構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/31f2ad36-4d91-4a3e-3bb3-4a5b38bb5b44.png)


## ハンズオン開始！(Cloud9の導入)
Cloud9を使用する。これも実はCloudFormation
の技術が裏で働いている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/3c466d7c-1085-6306-c31c-4e8f97fd1514.png)
EC2を動作させることでCloud9が動く。デフォルトで設定していく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/8ba70b2c-9309-efe6-6918-b611a15d828b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/1e48f5f9-6558-ce50-814b-328bdcf47c7c.png)

## コーディングはYAML形式を使用するため、インデントの設定を変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/201ffa02-8ee7-ce89-4181-b86faa3fd1c4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/a517c7a8-4d39-8513-c01c-afb56708de58.png)

AWS CLIのコマンド補完設定
```
echo "complete -C '/usr/local/bin/aws_completer' aws" >> ~/.bashrc
```
```
source ~/.bashrc
```





## VPCの作成
はじめにCloudFormationを開く。
先程作成したCloud9のジョブがある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/0a2fe429-da7b-9b88-80b1-6f6b55315d03.png)
新しいリソースの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/29032ccf-89f4-9c85-0a0f-7b6c431287b3.png)
ハンズオンで示されたファイルをアップロードする。
textにYAML形式で記載された各リソース毎のテンプレートコード。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/81dd0473-9c63-e2e4-d5dc-b4989e2624d2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/8247ebaf-6d5a-b6c9-2558-96047435ab75.png)
オプションはデフォルト
※なお、ClouFormationはタイムアウトを設定することで、課金額をコントロールすることができる。30秒を超える待機時間を設定した場合、エラー箇所の特定に時間を要すことや、課金額が増加します。
また、コマンドが失敗したときの挙動をここで設定できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/7e96087c-2d97-a94b-0c98-9065b70613ea.png)
【参考】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/33bf7e49-4234-96d1-3418-a61738695517.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/1eaeb077-ddba-e8c3-e1da-11084c36bd34.png)

作成完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/8d4a62b4-e025-db64-d7b2-b248829bf7c3.png)
実際にVPCが作成できている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/e783b552-505b-aad5-b7f0-5b3a1fb5142f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/0e3cbdd3-96e8-20df-c02e-9b9b3c4bc66e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/261306fd-fa93-96df-2903-1a9e7da2e71b.png)


## テンプレートを更新して、適用させる。（コードの更新開始）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/10d98fb7-5737-1e66-6f5d-892de8e39e49.png)
PublicSubnet1のnameタグを更新
「PublicSubnet1」に「update」を書き加える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/0c49d263-4677-6a16-ef7c-dbfe1c1bdeea.png)

## テンプレを更新したので、AWS CLIでコードの検証
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/0562ff0b-b308-6124-f06d-472112a684a2.png)
この「cfn」ディレクトリに先程のテンプレがあるので、次のコマンドで構文などが間違っていないか検証することができます。
```
aws cloudformation validate-template --template-body file://01_vpc.yml
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/dfc315c4-5899-bcd6-76d8-3be4d47aebdc.png)
「--template-body file://01_vpc.yml」このファイルの
「validate-template 」テンプレを検証します。
という意味。直感的なコマンドではない気がします( ;∀;)
parametersに何も記載がなく、問題ないことがわかります
チェックのみ完了！
続いて、実際にupdateをかまします。


## チェックしたコードを更新（コードの更新完了）
```
aws cloudformation update-stack --stack-name handson-cfn --template-body file://01_vpc.yml  
```
コマンドが長い(´;ω;｀)
アップデートできました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/dddfce96-539d-0ef7-71dd-1aa4ee947768.png)



## コードの構成を勝手に無理やり解釈してみたｗ
多分大きく４つの構成で、「決まり文句」「名前、イメージ決め。」「リソース」「他のリソースとの連携」なのかなと。リソースの項目が分厚くなりそうなイメージで大事なところかと。あと、テンプレートデータへは基本手を加えない。可読性とか確実性の面。
```
#決まり文句
AWSTemplateFormatVersion: 2010-09-09
Description: Hands-on template for EC2

#名前、イメージ決め。
Parameters:
  VPCStack:
    Type: String
    Default: handson-cfn
  EC2AMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

#リソース
Resources:
  EC2WebServer01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref EC2AMI
      InstanceType: t2.micro

#他のリソースとの連携
Outputs:
  EC2WebServer01:
    Value: !Ref EC2WebServer01
    Export:
      Name: !Sub ${AWS::StackName}-EC2WebServer01
```
※これは例示しているだけで、このまま使用できるコードではありません。
※他のリソースのコードと連携している例を次に示します。ELBのコードです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/9db92da6-cebd-dedf-f506-8292f3807565.png)




## EC2作成
Cloud9に移動、「cfn」ディレクトリに移動して次のコマンドを実行
```
aws cloudformation create-stack --stack-name handson-cfn-ec2 --template-body file://02_ec2.yml
```
このコマンドを実行することでEC2ができていることがわかりますが、不足があります。
現在デフォルトVPC、セキュリティグループもデフォルト、サブネットもデフォルトになっています。最終的にWordPressを構築するので、ユーザーデータも反映します。

## 不足を設定(VPC,ユーザーデータ,セキュリティグループ)
（今実施しているハンズオンのための設定になります。）
### まずVPCに追記していく。
Clou9のテンプレにSubnet欄を追加し、先程作成したVPCを割り当てるため、既作成のVPC、PublicSubnet1のSubnetidを記載していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/08d8d396-6e02-2103-ba72-9b2cc900a1fc.png)
検証
```
aws cloudformation validate-template --template-body file://02_ec2.yml
```
### 次はユーザーデータをセットします。
公式さんが作成しデータをペースト。WordPress,Apache,PHPをインストールするコマンド。
AWS公式のリファレンス内から「組み込み関数」を検索し、テキスト文字列「Base64」によって変換します。そして日本語が反映されるまで結構時間かかります|дﾟ)なお、本記事冒頭にサイトリンクがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/1a506cdf-bf68-3aac-14e1-2c225ac49367.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/e21c7e2b-9602-67f9-d1ca-9f86f507d5db.png)
※基本的なことだけれど、一言一句、大文字小文字、タイプミスでは先に進めません！

```
#! /bin/bash
yum update -y
amazon-linux-extras install php7.2 -y
yum -y install mysql httpd php-mbstring php-xml

wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
tar zxvf /tmp/latest-ja.tar.gz -C /tmp
cp -r /tmp/wordpress/* /var/www/html/
touch /var/www/html/.check_alive
chown apache:apache -R /var/www/html

systemctl enable httpd.service
systemctl start httpd.service
```
検証
```
aws cloudformation validate-template --template-body file://02_ec2.yml
```
更新
```
aws cloudformation update-stack --stack-name handson-cfn-ec2 --template-body file://02_ec2.yml
```


### 続いてセキュリティグループの設定
ここで構成を再確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/91ef630d-7f1e-6221-c311-c9dd243afd62.png)
どうやってセキュリティグループを設定するか確認(p_-)
リファレンスの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/a51b64ca-76c3-fa03-5d76-f5d9baa0d607.png)
。。。ここでは詳細な方法の記載がないようなので、EC2のリソースタイプを選択する画面に移動します。
見つけたぜ！(p_-)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/5d8b5c50-a05c-a31d-a94c-025b7a7c08f4.png)
ここ全部書くのか？ということはなくて、必要なものを記載します。参考となるのは、「Required」欄で必須であるか、また、「Required: Conditional」場合による。といった表記を参考に記載する。
この一連の行為は基本ですね！公式のドキュメントを確認する。(p_-)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/28ca589f-853a-bf97-13e8-94617e31a629.png)
今回は次のとおり。
・GroupDescription
・VpcId
・SecurityGroupIngress（インバウンド設定で必要）
これらをEC2を作成した時のResourcesのくくりに追記していく。


それぞれ必要な文字を公式ドキュメントからコピペで貼り付けますが、「SecurityGroupIngress」は、記載することが不明であるため、ドキュメントで追跡します|дﾟ)
するとさらに記載すべきものたちがわらわらと。
ひとまず必須は、「IpProtocol」ですね。これ以外にも、「ToPort」、「FromPort」と「CidrIp（VPCのネットワークアドレス）」を設定していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/f8a75413-28a8-4704-2852-eab3f2ef3213.png)

現状↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/4dcb0917-6fc0-4984-7fa5-1306b94addfd.png)

コードを保存して、検証→更新を行う。
検証
```
aws cloudformation validate-template --template-body file://02_ec2.yml
```
更新
```
aws cloudformation update-stack --stack-name handson-cfn-ec2 --template-body file://02_ec2.yml
```
結果、セキュリティグループが出来ています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/cb5bfb44-3cb4-c107-55cd-17b274b87794.png)
今はEC2に関連付けられていないため、関連付けます！

「SecurityGroupIds」という名前で関連付け。そして組み込み関数で、今設定してきたセキュリティグループを認識させる。
また、コードの保存をお忘れなく、検証、更新の順で更新を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/d2c06fbf-e716-2427-7fa4-7d19ac2c441e.png)
結果、関連付けることができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/aa4551e9-98f6-a41b-8e16-e51a68989293.png)

:::note
今基礎をおさえるために、わざと不足があるコードをテンプレで使用して、ハードコードの手法でコーディングしていますが、本来は、VPC用のスタックからデータをインポートするなどで対応しましょう！
:::



## RDSとELBを同時に作成！
RDSから
```
aws cloudformation create-stack --stack-name handson-cfn-rds --template-body file://03_rds.yml
```
ELBも作成
```
aws cloudformation create-stack --stack-name handson-cfn-elb --template-body file://04_elb.yml
```
## 完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/09c57ec3-b081-f028-b794-5194c0e24f44.png)

次にELBの出力の項目からURLをクリックします。三回目のWordPress|дﾟ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/b33cc9a6-efcf-a973-ea34-dc2525f2b69e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/77f31070-7850-c9af-f618-c9728969feae.png)


## 撤収！！！
次の学習に備えます！
うっしゃ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/7692d8b5-28d3-80ef-788b-95ef5879517f.png)
この５つのスタックを消すだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518951/12d14900-88dc-6e46-5499-7d8db990dfa8.png)

全般、CloudFormationを使いこなすことで、構築の確実性、迅速性が上がりそうですね。使いこなせばですが(p_-)

では！