【CloudFormation入門編】CloudFormation Templateで値を省略した場合はどうなる?【第二回_別紙】

CloudFormation Templateを書いていると、

「この設定は書かなくてもいいの?」

という場面が出てきます。

例えば、S3バケットを作るだけなら、

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket

だけでも作成できます。

では、Templateに書いていない設定はどうなるのでしょうか?

結論から言うと、省略した項目の扱いは、その項目によって異なります。

大きく分けると、以下の4パターンがあります。

① CloudFormation側でデフォルト値が設定される
② AWSリソース側のデフォルト動作になる
③ 任意項目なので設定されない
④ 必須項目なのでエラーになる

この違いを理解しておくことが重要です。


1. Templateで省略したからといって「空」になるわけではない

例えば、以下のTemplateを考えてみます。

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket

このTemplateには、S3バケットの名前を指定するBucketNameがありません。

だからといって、

BucketName = 空

になるわけではありません。

CloudFormationは、S3バケット名を明示的に指定しなかった場合、物理リソース名を自動生成します。

そのため、実際には、

SampleBucket
      ↓
CloudFormation
      ↓
ランダムな名前を持つS3 Bucket

という動きになります。

つまり、

Templateに書いていない = 値が空

ではありません。


2. AWSリソース側のデフォルト値が使われる場合

CloudFormationのResourceには、さまざまなPropertiesがあります。

例えばEC2の場合、

Resources:
  SampleInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-xxxxxxxx

としたとします。

InstanceTypeを指定していません。

この場合、

InstanceType:

が空になるわけではありません。

CloudFormationのResource仕様でデフォルト値が定義されている場合、そのデフォルト値が使用されます。

ただし、ここで注意したいのが、

「デフォルト値が存在するかどうかは、ResourceのPropertyによって異なる」

ということです。

そのため、

「省略したらいつもこの値になる」

と暗記するのではなく、使用するResourceのCloudFormationドキュメントを確認することが重要です。


3. Optionalな項目は設定されない

CloudFormationのResourceには、必須ではないPropertiesもたくさんあります。

例えばS3 Bucketには、さまざまな設定があります。

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: sample-example
      VersioningConfiguration:
        Status: Enabled

この場合、

VersioningConfiguration:

を指定しなければ、バージョニングを有効化する設定そのものをTemplateから指定していないことになります。

つまり、

Template
   ↓
指定した設定だけをCloudFormationへ伝える
   ↓
指定していないOptionalな設定は
そのResourceの仕様に従う

というイメージです。


4. 必須項目を省略するとエラーになる

一方で、必須の項目を省略するとStackの作成に失敗します。

例えば、

Resources:
  SampleInstance:
    Type: AWS::EC2::Instance

のように、EC2 Instanceを作成するために必要な情報を何も指定しない場合、必要な情報が不足しているため作成できません。

Resourceによっては、必須のPropertiesがあります。

そのため、

「ResourcesにTypeを書けば、あとは全部自動で設定される」

というわけではありません。


Parametersを省略した場合

ここからは、Templateの各セクションごとに見てみます。

まずParametersです。

例えば、

Parameters:
  Environment:
    Type: String
    Default: dev

とした場合、Stack作成時にEnvironmentを指定しなければ、

Environment = dev

が使われます。

これはDefaultを指定しているからです。


Defaultを指定しない場合

では、次のようにしたらどうでしょうか。

Parameters:
  Environment:
    Type: String

この場合、Defaultがありません。

そのため、Stack作成時に値を指定する必要があります。

Environment
    ↓
Stack作成時に入力

値を指定しないとStackの作成時に問題になります。

つまりParametersでは、

Defaultあり
    ↓
指定しなければDefault値

Defaultなし
    ↓
Stack作成時に値を指定

と考えると分かりやすいです。


Resourcesを省略した場合

CloudFormation Templateで最も重要なのがResourcesですが、Resourcesそのものは実質的に中心となるセクションです。

例えば、

Description: Sample Template

だけのTemplateでは、作成するAWSリソースがありません。

CloudFormationでは、Stack自体は作成できても、作成対象となるResourceがなければ意味のあるインフラは構築されません。

基本的には、

Resources:
  ...

を中心にTemplateを考えます。


ResourceのPropertiesを省略した場合

ここが一番重要です。

例えば、

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket

のようにPropertiesそのものを省略できます。

これは、

「S3 BucketのPropertiesが全部空になる」

という意味ではありません。

CloudFormationは、指定されたResource Typeに基づいてリソースを作成します。

Propertiesを指定しなければ、指定していない項目については、そのResourceの仕様に従ったデフォルト動作になります。

例えば、

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket

と、

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: sample-example

では、どちらもS3 Bucketを作成します。

違いは、

1つ目
↓
BucketNameをCloudFormationに任せる

2つ目
↓
BucketNameを自分で指定する

という点です。


Outputsを省略した場合

Outputsも必須ではありません。

例えば、

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket

だけでもStackは作成できます。

Outputsがないからといって、作成したS3 Bucketが削除されたり、利用できなくなったりするわけではありません。

単純に、

StackのOutputsとして外部に値を表示しない

というだけです。


「省略」と「空の値」は違う

ここは特に注意したいポイントです。

例えば、

Properties:
  BucketName:

と書いた場合と、

Properties:

そのものを省略した場合では、同じ意味になるとは限りません。

さらに、

BucketName: ""

のように空文字を明示的に指定する場合もあります。

これらは、

① プロパティそのものを指定しない

② プロパティは指定するが値を空にする

③ プロパティに具体的な値を指定する

という異なる状態です。

例えば、

# ① 省略
Resources:
  SampleBucket:
    Type: AWS::S3::Bucket
# ② 空の値
Resources:
  SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: ""
# ③ 値を指定
Resources:
  SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: sample-example

この3つは同じ意味になるとは限りません。

特に②のような書き方は、Resourceによってはエラーになることもあります。

そのため、

「値を設定しないなら、とりあえず空文字にする」

という考え方は避けたほうが安全です。

不要な設定は、基本的には記述しないという考え方が分かりやすいです。


CloudFormationで省略した値を考えるときの順番

Templateを書くときに、

「このPropertyを書かなくても大丈夫かな?」

と思ったら、以下の順番で確認するとよいです。

① このPropertyは必須?
        ↓
   Yes → 値を指定する
        ↓
   No
        ↓
② デフォルト値がある?
        ↓
   Yes → デフォルト値が使われる
        ↓
   No
        ↓
③ 省略した場合のResourceの仕様を確認

つまり、

「省略したらどうなるか」を自分で推測しない

ことが重要です。

CloudFormationではResource Typeごとに仕様が決まっているため、AWS公式ドキュメントで確認します。


Templateをシンプルにするために省略する

では、なぜわざわざ設定を省略するのでしょうか?

理由の一つは、Templateをシンプルにできるからです。

例えば、

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket

と、

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      # ここに大量の設定を書く

では、前者のほうが何をしているのか分かりやすい場合があります。

AWSのデフォルト動作で問題ないのであれば、無理にすべての設定を書く必要はありません。


ただし「明示的に書く」ことにも意味がある

一方で、本番環境などでは、

「AWSのデフォルト値に任せるのではなく、設定を明示したい」

という場合もあります。

例えば、

Resources:
  SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      VersioningConfiguration:
        Status: Enabled

のように、

「このS3バケットではバージョニングを有効にする」

ことをTemplate上で明示できます。

これには、

  • Templateを見れば設定が分かる
  • AWS側のデフォルト動作に依存しにくい
  • コードレビューしやすい
  • 環境構成を再現しやすい

というメリットがあります。


「全部書く」と「全部省略する」のどちらが正解?

どちらか一方が正解というわけではありません。

考え方としては、

AWSのデフォルト動作で問題ない
        ↓
省略する

環境として明確に指定したい
        ↓
明示する

と考えるとよいでしょう。

特に、

セキュリティに関係する設定

本番環境で重要な設定

チームとして明確にしておきたい設定

などは、デフォルトに任せずTemplate上で明示することを検討します。


まとめ

CloudFormation Templateでは、設定を省略した場合でも、必ずしも「空」になるわけではありません。

省略した設定は、大きく分けると、

Templateで省略
      ↓
┌──────────────────────┐
│ 必須項目?             │
└──────────┬───────────┘
           │
      Yes  │  No
           │
           ↓
        エラー       Resourceの仕様へ
                         ↓
              ┌──────────┴──────────┐
              ↓                     ↓
        デフォルト値あり        デフォルトなし
              ↓                     ↓
        デフォルト値を使用      指定されない

というように考えられます。

そして、もう一つ重要なのが、

「省略する」ことと「空の値を設定する」ことは違う

ということです。

そのため、Templateを書くときは、

この設定は必要?
      ↓
必須なら書く
      ↓
任意なら
      ↓
デフォルトで問題ない?
      ↓
Yes → 省略
No  → 明示的に設定

という考え方をすると整理しやすくなります。

CloudFormationを使い始めたばかりのうちは、「全部の設定を書く」のではなく、「何をAWSのデフォルトに任せ、何をTemplateで明示するのか」を考えることが重要です。

コメント

タイトルとURLをコピーしました