【初心者向け】CloudFormationテンプレートの作成：VPC編

今は担当していないのですが、
最近までCloudFormatonを触る機会があったので、備忘録もかねて書きました。

大前提になりますが、テンプレートを書くときは必ず公式ドキュメントを読みましょう！
頻繁にアップデートや変更が入る可能性ありです！
使用するリソースごとにルールがあります。
[ここ！公式リファレンス](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)

# はじめに

CloudFormationを使ってAWSのインフラを簡単に管理する方法を紹介します。今回は初心者の方向けにVPC（仮想プライベートクラウド）を作成するための基本的なテンプレートの書き方について解説します。また、ちょっと便利なスタック間でリソースをやり取りする方法も説明しますので、ぜひ最後まで読んでみてください。
# 基本的なテンプレートの書き方

まずは、VPCを作成するための基本的なCloudFormationテンプレートを見てみましょう。このテンプレートを使えば、VPCとサブネットを簡単に作成できます。

```
AWSTemplateFormatVersion: '2010-09-09'
Description: VPCの基本的な書き方

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.1.0/24'
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: MySubnet

```

まずは宣言しましょう。

```
AWSTemplateFormatVersion: '2010-09-09'
Description: VPCの基本的な書き方
```
これを書かないと始まりません。

次はResourcesを宣言します。

```
Resources:
  MyVPC:
    Type: 'AWS::EC2::VPC'
```
AWSリソースを宣言するセクションResourcesを定義します。
他にも必須ではないんですが、Parametersやoutputなどもよく使用します。

<br>
このテンプレートでは、以下のリソースを定義しています：

<strong>・VPC (MyVPC):</strong> 

10.0.0.0/16のCIDRブロックを持ち、DNSサポートとDNSホスト名を有効にしています。

<strong>・サブネット (MySubnet):</strong> 

10.0.1.0/24のCIDRブロックを持ち、VPC内に配置されます。サブネット内のインスタンスには自動でパブリックIPが割り当てられます。

# 要素について
そもそも、要素について理解しないと初心者の私には難しかったので、ここで紹介しておきます。

##### Type
Typeはリソースの種類を指定します。CloudFormationでは、AWSリソースのタイプごとに固有のタイプ名があります。

例えばこんなやつです。

<strong>・AWS::EC2::VPC: VPCを作成するためのタイプ。
・AWS::EC2::Subnet: サブネットを作成するためのタイプ。
・AWS::S3::Bucket: S3バケットを作成するためのタイプ。<strong>

これらのtypeは[公式リファレンス](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)で確認できます。

##### Properties
Propertiesはリソースの具体的な設定を行う部分です。各リソースタイプには特定のプロパティがあり、それを設定することでリソースの動作を制御します。

例えばAWS::EC2::VPCのプロパティには以下のようなものがあります。

<strong>・CidrBlock: VPCのCIDRブロックを指定します。
・EnableDnsSupport: VPC内でDNSサポートを有効にするかどうかを指定します。
・EnableDnsHostnames: VPC内でDNSホスト名を有効にするかどうかを指定します。
・VpcId: サブネットが属するVPCのIDを指定します。これは他のリソースを参照するために使用されます。
・MapPublicIpOnLaunch: サブネット内のインスタンスに自動でパブリックIPアドレスを割り当てるかどうかを指定します。

##### 属性について

CloudFormationリソースには、他のリソースから参照できる属性（Attributes）があります。例えば、VPCのIDやサブネットのIDなどです。これらの属性はテンプレート内で!Refや!GetAttを使用して参照します。

これ結構大事です。
<strong>・!Ref: リソースのIDを返します。
例：!Ref MyVPCはMyVPCリソースのIDを返します。
・!GetAtt: 特定の属性を取得します。
例：!GetAtt MyVPC.CidrBlockはMyVPCリソースのCIDRブロックを返します。

```
Outputs:
  VPCId:
    Value: !Ref MyVPC
    Export:
      Name: MyVPCId

  VPCBlock:
    Value: !GetAtt MyVPC.CidrBlock

```
この例では、VPCのIDを!Refで、CIDRブロックを!GetAttで取得しています。
※これらの属性を使用するときはスタックの作成順序に注意しましょう。参照する値がない場合、スタックがうまく展開できません。
これらを使用するとVPCIDをわざわざ指定しなくても、動的に必要な情報を取得できます。

##### myVPCとかMySubnetってやつ
```
Resources:
  MyVPC:
    Type: 'AWS::EC2::VPC'
・
・
・
 MySubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
```
これですね。
これは<strong>論理ID</strong>といってユーザーが自分で命名するものです。リソースやサービス、用途にあったわかりやすい名前をつけましょう。

# 要素のエクスポートとインポート

CloudFormationでは、1つのスタックから別のスタックへリソースをエクスポートし、それをインポートすることができます。これにより、異なるテンプレート間でリソースを共有できます。以下に、VPC IDをエクスポートして他のスタックでインポートする例を示します。

<strong>エクスポート側のテンプレート：<strong>
```
AWSTemplateFormatVersion: '2010-09-09'
Description: エクスポートの仕方

Resources:
  MyVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: '10.0.0.0/16'

Outputs:
  VPCId:
    Value: !Ref MyVPC
    Export:
      Name: MyVPCId

```
このテンプレートでは、VPCのIDをOutputsセクションでエクスポートしています。エクスポートされた値は、他のテンプレートでインポート可能です。

<strong>インポート側のテンプレート：<strong>
```
AWSTemplateFormatVersion: '2010-09-09'
Description: インポートの仕方

Resources:
  MySubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !ImportValue MyVPCId
      CidrBlock: '10.0.1.0/24'
      MapPublicIpOnLaunch: true

```
このテンプレートでは、先ほどエクスポートされたVPC IDをインポートして使用しています。!ImportValueを使って他のテンプレートからエクスポートされた値を取り込むことができます。

# まとめ

この記事では、CloudFormationを使ってVPCを作成する基本的な方法、要素のエクスポートとインポートの方法について紹介しました。これらの技術を駆使して、効率的にAWSリソースを管理し、インフラの構築を自動化してみてください。ほかにもループ処理など便利な使い方はありますので、また紹介できればと思います。CloudFormationを使いこなせるようになると、インフラ構築が格段に楽になりますよ！