Cloud Formationテンプレートをはじめて書く人へ

# Cloud Formationとは
AWS CloudFormationはAWSのインフラストラクチャをコードで管理するサービスです。JSONやYAML形式でリソース情報を記述し、CloudFormationに読み込ませると自動的にリソースを構築することができます。このコードによって構築されたリソースの管理を行うため、リソースの変更・削除が容易にできるというメリットがあります。さらに、同じリソースを横展開する際には既存のコードをそのまま利用できるため、複製の効率化も図れます。


### テンプレートとは
テンプレートとはAWS上に構築するリソースの情報を記述したコードのことを指します。CloudFormationではJSONまたはYAML形式をサポートしています。このテンプレートを使ってAWSリソースを自動で作成・変更・削除することができます。


### スタックとは
スタックとはテンプレート（インフラを定義するコード）によって作成されるリソースの集まりを指します。スタックを作成する際はテンプレートで定義されたリソースが一括で作成されます。その際、リソースの構築順はCloudFormationが自動的に判断してくれるため、我々でコードの記述順を考える必要はありません。


# EC2を作成してみる
###  テンプレートの書き方
ここからは、EC2を作成するテンプレートをもとにコードの要素を説明していきます。
以下のテンプレートでは、EC2とセキュリティグループを作成しています。
#### セキュリティグループの詳細設定
* `SecurityGroupIngress`でインバウンドルールを設定
* `FromPort`及び`ToPort`を0に設定すると、インバウンド通信を全て拒否

#### EC2の詳細設定
* インスタンスタイプはt2.microを選択
* ImageID (AMI ID)はAMIカタログにある最新のAmazon Linux2マシンイメージを取得
* VPC及びSubnetは任意のIDをそれぞれ選択

```yaml:EC2.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Create EC2Instance and security group.

## ::PARAMETERS::
## ユーザーが指定するテンプレートのパラメータ
Parameters:
  stackInstanceType:
    Type: String
    Description: Specify the instance type.
    Default: t2.micro

  stackImageId:
    Type: AWS::SSM::Parameter::Value<String>
    Description: Specify the image id.
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  stackVpcId:
    Type: AWS::EC2::VPC::Id
    Description: Specify the VPC id.
    
  stackPrivateSubnet1:
    Type: AWS::EC2::Subnet::Id
    Description: Specify the private subnet id.


## ::RESOURCES::
## Resources used in this solution
## このテンプレートで作成するAWSリソース
Resources:
  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: EC2securityGroup
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 0
          ToPort: 0
      VpcId: !Ref stackVpcId

  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref stackInstanceType
      SubnetId: !Ref stackPrivateSubnet1
      ImageId: !Ref stackImageId
      SecurityGroupIds:
        - !Ref EC2SecurityGroup

## ::OUTPUTS::
## 他のスタックにインポート可能な出力値
Outputs:
  InstanceId:
    Description: Instance Id
    Value: !Ref EC2Instance

  EC2SecurityGroupId:
    Description: Security Group Id
    Value: !Ref EC2SecurityGroup
```
* **AWSTemplateFormatVersion**
テンプレートの機能を識別します。現時点では**2010-09-09**が最新かつ唯一有効な値です。このセクションを省略すると最新バージョンが適用されます。
* **Description**
テンプレートに関するコメントを記述することができます。
* **Parameters**
スタックを作成・更新する際に作成者側で任意のパラメータを設定することができます。上記コードを例にすると、`stackInstanceType`というパラメータをこのセクションで宣言し、Resourcesセクションの`InstanceType:`に`!Ref stackInstanceType`という形で代入します。このように記述することで、AWSマネジメントコンソールからインスタンスタイプを指定することができます。
* **Resources**
テンプレートの中で唯一**必須**となるセクションです。このセクションではAWSリソースを宣言します。Resourcesセクションで指定が必要なパラメータは[Resourcesのパラメータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html "リソース")を参照してください。
また、Resourcesセクションの中の**Properties**においてAWSリソースの詳細なパラメータを設定することができます。EC2であればインスタンスタイプやイメージIDなどを指定することができます。EC2を作成する際に指定可能なパラメータは[EC2作成時に指定可能なパラメータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-instance.html "AWS::EC2::Instance")を参照してください。


* **Outputs**
AWS CloudFormationコンソールで表示する出力値を宣言する際にこのセクションを使用します。スタックで作成されたリソースの名前やIDを出力させることが一般的です。また、出力した値はほかのスタックにインポートすることが可能です。



### スタックの作成方法(AWS マネジメントコンソール)
続いて上記のテンプレートを使用して実際にスタックを作成していきます。

1. AWSマネジメントコンソールにログインし、CloudFormationコンソールへ移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622083/2347d152-153a-41a1-1837-bf1670c90c0e.png)

1. 左のメニューバーにあるスタックをクリックし、スタック作成画面に移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622083/c3f88c90-c15d-279a-aa32-23aa6af5ba6e.png)

1. 「スタックの作成」→「新しいリソースを使用」の順に選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622083/a21fed6b-258c-a060-59b8-cba33c22b13c.png)

1. 「テンプレートファイルのアップロード」を選択し、テンプレートファイルをアップロードします。
※テンプレートファイルをアップロードすると「cf-templates-xxxxx」という名前のS3バケットが作成され、このバケットの中にファイルが格納されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622083/276ed4f6-5a59-f7f4-8920-9b163b12df18.png)

1. 次の画面でスタック作成に必要なパラメータを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622083/2f0f46df-e923-3f55-3642-c60a3a03c642.png)

1. 「スタックオプションの設定」画面では何も設定を変更せず「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622083/2d7be31f-1771-959e-dce0-a52ca1e0fc3c.png)

1. 「確認して作成」画面でパラメータを確認し、「送信」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622083/c70be133-c549-4e3c-bf3c-a1bae79ac3f7.png)

1. しばらくして、スタックのステータスが「CREATE_IN_PROGRESS」から「CREATE_COMPLETE」になったらスタック作成は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622083/ebebebb5-1b66-7702-55fe-17a757f651c3.png)

1. リソースタブからEC2のリンクに飛ぶと作成されたEC2を確認することが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622083/e389b0c2-2593-300f-fcde-1d9c69461e3f.png)

# おわりに
今回はCloudFormationの基本的な使い方を説明しました。テンプレートには、今回紹介しなかったセクションやオプションが多数存在します。セクションを追加することで、条件分岐なども可能になります。必要に応じて調査してみてください。
この情報がどなたかのお役に立てば幸いです。