CloudFormationの超詳細解説 1/4 概要編

# はじめに
この記事はDevOps on AWS大全の一部です。
DevOps on AWS大全の一覧は[こちら](https://qiita.com/tech4anyone/items/b06f88035d27c6ef13b2)。

この記事ではCloudFomationのテンプレートに記載する内容を超詳細にまとめています。

具体的には以下流れで説明します。
- CloudFormationとは
- CLoudFormationの仕組み

AWSの区分でいう「Level 200：トピックの入門知識を持っていることを前提に、ベストプラクティス、サービス機能を解説するレベル」の内容です。

# この記事を読んでほしい人
- CloudFormationがどういうサービスか説明できるようになりたい人
- CloudFormationを採用するときのベストプラクティスを説明できるようになりたい人
- AWS Certified DevOps Engineer Professionalを目指している人

# CloudFormationとは
CloudFormationはIaCをAWSの世界で実現するためのサービスです。
CloudFormationを利用するとAWSで提供されている大半のリソースをYAMLまたはJSONのコードで管理できるようになります。

CloudFormationを用いてIaCを推し進めるとコードに定義した通りの環境がどこでも、いつでも、だれでも簡単に構築できるようになります。

結果として、人的ミスの減少やリリースにかかわる工数の削減、典型的なインフラストラクチャーの再利用が可能となり、よりビジネス価値につながる領域に人の力を集中されることが可能となります。

# CloudFormationの仕組み
CloudFormationはAWSのリソースをコード化し、そのコード化したものをCloudFormationテンプレート、と呼びます。
CloudFormationテンプレートはYAMLあるいはJSONで記述できますが、基本的には可読性の観点からYAMLで書くことがおすすめです。

テンプレートの構成要素は以下6つでこれらを組み合わせることでインフラストラクチャを定義していきます。
- Resources
- Parameters
- Mappings
- Outputs
- Conditions
- Metadata

それぞれの詳細は「CloudFormationの超詳細解説 2/4 テンプレート編」にまとめます。
そのため、ここではリソースは必須である、ということだけ述べておきます。

また、テンプレートヘルパーとしてReferencesとFunctionsが存在します。
こちらも詳細は「CloudFormationの超詳細解説 2/4 テンプレート編」にまとめます。

CloudFomationテンプレートにAWSリソースを書き起こしたら、S3にアップロードしてCloudFormationを実行することで環境の構築が実行されます。
CloudFormationの実行方法はマネジメントコンソールあるいはAWS CLIです。

CloudFormationを実行して構築されるリソース群をCloudFormationスタックと呼びます。
CloudFormationテンプレートを更新してリソースをアップデートしたり、リソースが不要になって削除する際にはCloudFormationスタック単位で操作することになります。

![](https://storage.googleapis.com/zenn-user-upload/bd3ab0763dca-20231111.png)

なお、スタック名は自アカウント内の各リージョン毎に一意である必要があります。
万が一、同じ名前にしてしまうと古いスタックが丸ごと上書きされてしまうので注意しましょう。
この点は試験でも聞かれますし、実プロジェクトのあるあるミスでもあります。

参考までにVPCの中に1台のEC2を起動するためのテンプレートをYAML版とJSON版で並べました。この短さでも読みやすさの観点からYAMLに軍配が上がるのがわかると思います。

YAML版CloudFormationテンプレート
```yaml
AWSTemplateFormatVersion: '2010-09-09'

Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: MyVPC

  MySubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: us-east-1a
      Tags:
        - Key: Name
          Value: MySubnet

  MySecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref MyVPC
      GroupDescription: Allow SSH and HTTP traffic
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-xxxxxxxxxxxxxxxxx  # あなたのAMIのIDに置き換えてください
      InstanceType: t2.micro
      KeyName: your-key-pair-name    # あなたのキーペアの名前に置き換えてください
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref MySubnet
          GroupSet:
            - !Ref MySecurityGroup
```


JSON版CloudFormationテンプレート
```json
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "MyVPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": "10.0.0.0/16",
        "EnableDnsSupport": true,
        "EnableDnsHostnames": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": "MyVPC"
          }
        ]
      }
    },
    "MySubnet": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": { "Ref": "MyVPC" },
        "CidrBlock": "10.0.0.0/24",
        "AvailabilityZone": "us-east-1a",
        "Tags": [
          {
            "Key": "Name",
            "Value": "MySubnet"
          }
        ]
      }
    },
    "MySecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "VpcId": { "Ref": "MyVPC" },
        "GroupDescription": "Allow SSH and HTTP traffic",
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 22,
            "ToPort": 22,
            "CidrIp": "0.0.0.0/0"
          },
          {
            "IpProtocol": "tcp",
            "FromPort": 80,
            "ToPort": 80,
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "MyEC2Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": "ami-xxxxxxxxxxxxxxxxx",
        "InstanceType": "t2.micro",
        "KeyName": "your-key-pair-name",
        "NetworkInterfaces": [
          {
            "DeviceIndex": 0,
            "SubnetId": { "Ref": "MySubnet" },
            "GroupSet": [{ "Ref": "MySecurityGroup" }]
          }
        ]
      }
    }
  }
}
```

# まとめ
この記事ではCloudFomationのテンプレートに記載する内容を超詳細にまとめました。

- CloudFormationとは
- CloudFormationの仕組み

次回はCloudFormationの超詳細解説 2/4 テンプレート編です。