AWS CloudFormationのススメ

# 0.はじめに

AWS CloudForamtionは、JSONやYAML形式で単一のサービスのみではなく、

複合したサービスを使用したサービスをテンプレートとして作成・共有が可能なAWSサービスです。

例えばですがAWS公式が用意している東京リージョンのサンプルテンプレートをいくつかご紹介します。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-sample-templates-ap-northeast-1.html

上のURLから、AWS 東京リージョンのサンプルテンプレートコレクションを閲覧できます。

実際に使っていただく前に、CloudFormationのメリットを紹介していきます。

# 1.CloudFormationのメリット

## 構成をテンプレート化することができる

・例えば同一の構成を複数リージョンに作成する必要がある
・障害時に同一の構成を即時に作成する必要がある
・構成自体のレビューをする必要があるが、記載通りの構成をコンソールから作成する際にヒューマンエラーが起きる可能性がある

上記の際に、事前にCloudFormationテンプレートを作成することで、
サービスの展開に対して、適切なソリューションとなる可能性があります。

CloudFormationで、既存、または新規で作成するAWSアーキテクチャの全体を保存しておくことができます。

また、サービス内のソースコードについてはコードレビューを行うことが多いですが、
インフラに関しては、レビューという概念はあまり行われてこなかったと思いますが、
（作業手順書のレビューのような文化はありますが）

CloudFormationを使うことで、テンプレートからサービスをアーキテクチャを起動する前に、
実際に起動するアーキテクチャをレビューすることができます。

## 構成をインプット・アウトプットすることができる

後ほど紹介しますが、AWS公式が作成したサンプルテンプレートや、
Qiitaやハンズオンなどで、複雑なアーキテクチャ構成が紹介されている箇所でも、

CloudFormationのテンプレートとしてテキスト化して紹介することで、
他のアカウントでも、即時に同様のアーキテクチャを展開することができます。

## CloudFormationデザイナーが利用できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661133/f34d51d3-cc00-3101-bd0b-5ec198e2da49.png)

CloudFormation デザイナーでは、体系的に構成を作成することができます。
左のメニューから、リソースを作業画面へ挿入することで、
自動的に画面下部のJSON、YAMLで記載されたテンプレートタブに、
デザインした通りのテンプレートが作成されていきます。

また右上のダウンロードボタンをクリックすることで、
現在作業画面に表示されている構成図を画像としてダウンロードすることもできます。

![template1-designer (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661133/6bff169a-379b-ea65-f67e-327208c92000.png)

# 2.CloudFormationテンプレートの内容

テンプレートに記載可能なプロパティは以下の通りです。

・AWSTemplateFormatVersion
・Description
・Metadata
・Parameters
・Mappings
・Resources
・Outputs

この中でResourcesだけは必須となっています。その他の記載は任意です。
例えばですが、以下のようなテンプレートがあります。

```
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  testVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
```

今回は、必須項目のResourcesと、任意項目のFormatVersionのみが記載してあります。

## Resources

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html

```
Resources:
  Logical ID:
    Type: Resource type
    Properties:
      Set of properties
```

Logical IDには、そのテンプレートの内で一意なIDを命名します。

例えば今回はVPCをtestVPCと命名しましたが、
同一テンプレート内で、このVPCと関連付けたリソースを作成する際に、Logical IDを用います。

Typeは、今回はVPCの作成テンプレートなので、AWS::EC2::VPCとなっています。
（IAMポリシーでも思いますが、AWS的にはVPCはEC2の１機能なのか・・・？）

Propertiesには、リソースに対して詳細なオプションを指定することができます。
これはリソースによっては、必須の項目もあります。

具体的には、EC2をテンプレートに組み込み際は、PropertiesでAMIを指定する必要があります。

## AWSTemplateFormatVersion

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/format-version-structure.html

これについては、今のところ`2010-09-09`以外の値は認められません。

ただ今後、新しいバージョンのテンプレートが作成される可能性を考えると、
未来に残す必要があるテンプレートについては、バージョンを指定していても問題ないかと思います。

## Description

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-description-structure.html


```
"Description" : "Here are some details about the template."
```

Descriptionには、リソースに関する説明を含めることができます。

## Mappings

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html

```
Mappings: 
  RegionMap: 
    us-east-1: 
      "HVM64": "ami-0ff8a91507f77f867"
    us-west-1: 
      "HVM64": "ami-0bdb828fd58c52235"
    eu-west-1: 
      "HVM64": "ami-047bb4163c506cd98"
    ap-southeast-1: 
      "HVM64": "ami-08569b978cc4dfa10"
    ap-northeast-1: 
      "HVM64": "ami-06cd52961ce9f0d85"
```

Mappingsでは上記のように、Mappings配列を作成しとくことで、別のプロパティで上記のマッピングを内容に含めることができます。

例えば、上の例でリージョン別のAMIを指定するMappingsを作成して、

```
Resources: 
  myEC2Instance: 
    Type: "AWS::EC2::Instance"
    Properties: 
      ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", HVM64]
      InstanceType: m1.small
```

こんな感じで、リージョン別に起動するAMIを切り替えることができます。

## Parameters

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html

```
Parameters:
  ParameterLogicalID:
    Type: DataType
    ParameterProperty: value
```

パラメーターでは、テンプレート作成の際に、インスタンスサイズなどをテンプレートにパラメーターとして持たせることができます。

また、デフォルト値を設定することで、指定がない際に選ばれるパラメーターの指定もできます。

```
Parameters:
  InstanceTypeParameter:
    Type: String
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - m1.small
      - m1.large
    Description: Enter t2.micro, m1.small, or m1.large. Default is t2.micro.
```

例えば上記の例では、InstanceTypeParameterというLogicalIDに、デフォルトでt2.microが設定されていることがわかります。

しかし、場合によっては、m1.small,m1.largeも指定することが可能であることがわかります。

例えば、検証環境では、最小サイズでインスタンスを指定して、

AllowedValuesに大きめのインスタンスサイズを含めておくことで、
そのままの内容でテンプレートを検証環境、本番環境で構成することができます。

## Metadata

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html

割愛しますが、テンプレートの詳細を記載することができます。

## Outputs

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html

テンプレート間での値のやりとりや、CloudForamtionコンソールへの出力を行うことができます。

ちょっと、汎用性が高いので、こちらも省略させていただきます。

# 3.まとめ

CloudFormationは起動・保存・共有と個人的には3つの使い方があると思っています。

構成を起動する前に、依存や影響を確認することができ、

作成したアーキテクチャを環境ごとに使い回すためにテンプレートとして保存することも可能で、

またJSONやYAML形式で共有することもできます。

そして紹介したように、CloudFormationデザイナーを使用して、
体型的なテンプレートの作成や、構成図の出力も可能です。

最初に紹介したように
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-sample-templates-ap-northeast-1.html

こちらのAWS公式のサンプルテンプレートを元に、サービスやサンプルソリューションを選択して、

デザイナーで表示、起動をクリックすることで、
実際に自身のAWSアカウントでテンプレートを表示、起動することができます。

サービスの展開に最適なソリューションのために、うまく使っていきましょう！