【AWS】用語を整理しながら学ぶAWS - part5 Cloud Formation - 2

# はじめに

この記事では AWS Cloud Tech を通して Cloud Formation を学習して実践していく記事です。
主な内容としては実践したときのメモを中心に書きます。（忘れやすいことなど）
誤りなどがあれば書き直していく予定です。

https://aws-cloud-tech.com/

## 前回までのおさらい

Cloud Formation とは
IaC を利用して AWS のインフラ構築をコードで管理できるサービス

形式は YML(YAML Ain't a Markup Language)と呼ばれる形式であり

YAML の特徴としてはパレンティスといったカッコ書きで
ブロックを表すのではなくタブでブロックを表す。

単一のリソースは
論理 ID、Type、プロパティの 3 つで成立しており
Resources にまとめられることでスタックとして定義できる。
また、プロパティ内でリソースの細かい設定を行うことで
リソースを変更することができる。

[【AWS】用語を整理しながら学ぶ AWS - part5 Cloud Formation-1](https://qiita.com/ymd65536/items/f58f5504a37fc7d0a767)

### Resources 以外のオプション

## 前回のコード

前回のコードをもう一度見てみよう。

```yml:network.yml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  MyVPC2:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.8.0/21
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: MYVPC2fromCF
  subnetName:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: "ap-northeast-1a"
      VpcId: !Ref MyVPC2
      CidrBlock: 10.0.8.0/24
      Tags:
        - Key: Name
          Value: subnet1formCF
  secGroupName:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: GroupName-SG
      GroupDescription: GroupDescription-SG
      VpcId: !Ref MyVPC2
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: SGfromCF
Outputs:
  Subnet1:
    Value: !Ref subnetName
    Export:
      Name: Subnet1Name
  SG1:
    Value: !GetAtt secGroupName.GroupId
    Export:
      Name: SG1Name
```

## Outputs

AWS 公式ガイドにはこうある。

> オプションの Outputs セクションは、他のスタックにインポートする (クロススタック参照を作成)、
> 応答として返す (スタック呼び出しについて記述)
> または、AWS CloudFormation コンソールで表示する出力値を宣言します。

Outoputs はそのテンプレートから出力できるメタデータを出力(Export)することができる。
Export した値はクロススタック参照をするときに利用できる。

### ここでいうスタックとは

単一の AWS リソースのこと
すなわち、クロススタック参照とは AWS リソースが AWS リソースを参照することを指す。

### スタックのエクスポート名

今回のコードの場合
サブネットのキーは Subnet1 でエクスポート名は Subnet1Name
セキュリティグループのキーは SG1 でエクスポート名は SG1Name

クロススタック参照をする際に利用する名前はエクスポート名

### エクスポート名とは

他のスタックから Outputs を参照する際に利用する名前のこと

## 組み込み関数

AWS Cloud Formation にはいくつかの組み込み関数が存在する。

### Ref

AWS 公式ガイドにはこうある。

> 指定したパラメータまたはリソースの値を返します。

テンプレート内のリソース情報を参照する。
引数に論理 ID を取る。

### GetAtt

AWS 公式ガイドにはこうある。

> テンプレートのリソースから属性の値を返します。

secGroupName の属性「GroupId」を渡すと GroupId を返す。
今回はコンソール画面でいうところの「セキュリティグループ」の ID を
Outputs の SG1 に値として出力する。

引数に属性名を取る。

## クロススタック参照

前述の network.yml に対して
実際にクロススタック参照をやってみる。

前述の network.yml で構築したネットワークに EC2 を建てる。

```yml:ec2.yml

AWSTemplateFormatVersion: 2010-09-09
Resources:
  myEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      KeyName: Mykeypair
      ImageId: ami-0992fc94ca0f1415a
      InstanceType: t2.micro
      Monitoring: false
      SecurityGroupIds:
        - !ImportValue SG1Name
      SubnetId: !ImportValue Subnet1Name
      Tags:
        - Key: Name
          Value: CFec2

```

このとき組み込み関数「ImportValue」 を利用して
セキュリティグループとサブネットの ID をインポートする。
セキュリティグループとサブネットの ID は network.yml で出力したモノを使う。

### クロススタック参照の良いところ

コードを分割できる為、ネットワーク構築用やコンピューティングリソース用など
用途によってリソースを使い分けることができる。

今回の場合はネットワークとセキュリティグループを分けても良かったような気がする。

### クロススタック参照の悪いところ

その反面、分割ルールを決めておかないと管理が煩雑になりわかりにくくなる。

### プログラマー的な観点

しっかり用途ごとに分割できていれば
インフラの構成を変更した後に差分を取れるので
GitHub 連携したときにその効果をいかんなく発揮できる。

Outputs のキー名を設計の段階で明確にしておけば
スタック同士の結びつきがわかりやすくなり
構成変更時の影響範囲がわかる。

※できれば一度構築したら弄りたくはないんですけどね。

### これはと思うこと
任意の箇所だけ
スタックテンプレートを変更したいということができない。
例えば、ec2.yml にプライベート用の ec2 とパブリック用の ec2 を書いたときは
スタックを更新したときに変更のない箇所も更新対象になる。
※厳密にはテンプレートファイルを置き換える動作だから更新ではない？

疎結合に考えようとすると管理するファイルとクロススタック参照が多くなるのでは？

## まとめ

今回は network.yml と ec2.yml を使って簡単な環境構築をやりました。
Terrraform と比較するとチョット柔軟とは思えないところがありますが

書きやすさとわかりやすさはピカイチですし
日本語ドキュメントがしっかりしているので、かなり好きなサービスになりそうです。
今後のアップデートに期待ですね。

次回はもっとハッテンしていくぞ♂

## おわり