LoginSignup
4
2

More than 1 year has passed since last update.

はじめてのCloudFormation

Posted at

はじめに

CloudFormationを学習し始めて、エラーラッシュに見舞われながら覚えたことを書いています。
対象読者は同じにようにテンプレートエラーに悩んでいる方AWS初学者です。
qita初投稿ですので、何か不備等があればご指摘いただけると助かります。

参考

この記事はAWS初学者を導く体系的な動画学習サービス
AWS CloudTechの課題カリキュラムで作成しました。
https://aws-cloud-tech.com

CloudFormationについて

構成したいAWSリソースやその細かい設定をJSON、YAMLといった記述方式に則ってファイル(テンプレート)に記述し、それを読み込ませることで複数のAWSリソースを同時に起動できるしくみ。ひとつのテンプレートで生成されるAWSリソース群をスタックと呼ぶ。

テンプレートの型は複数のセクションからなるが(以下template.yml)、記述が必須なのは、AWSTemplateFormatVersionResourceの部分のみ。前者はテンプレートのバージョンを表しているだけなので、ユーザーは後者のResourceセクションに構築したいAWSサービスを書式に則って定義していく。

template.yml
AWSTemplateFormatVersion: 2010-09-09 #記載必須
Description: ---
Metadata:

Parameters:

Mappings:

Conditions:

Resources: #記載必須

Outputs:

Resourceセクションの書式について

application.yml
Resources:  #以下のセクションではAWSリソースを定義する宣言
  Logical ID:  #テンプレート内で使う固有の名前。他のリソースを定義するときに参照したい場合などに使う。
    Type: Resource type   #AWSリソース名をここに定義する。 
    Properties:        #AWSリソースの細かい設定をPropertiesとして個々に指定。
      Set of properties   #どんなPropertyがあるかは公式ドキュメントTemplate Referenceを参照する。

例) VPCを定義する場合

AWS公式ドキュメントのTemplate Reference上でVPCのテンプレートを探す。
VPCのテンプレートはEC2 resource type referenceタブ内にあるAWS::EC2::VPCページ内にある。これを元に自分の設定したい値を定義していく。本例のようにリソース名「VPC」として探すとで他のリソースと関連して定義されている点に注意。

network.yml
Type: AWS::EC2::VPC  
Properties: 
  CidrBlock: String  #セミコロンの後は半角スペース開けてValueを記述
  EnableDnsHostnames: Boolean
  EnableDnsSupport: Boolean
  InstanceTenancy: String
  Tags: 
    - Tag

Propertiesセクションについて

Propertyは全てKey: Value形式で記述。
Propertyの設定の仕方はTemplate referencePropertiesのセクションで確認できる。
Valueの前は半角スペース開けないとエラーになるので注意

Propertiesを記述する際は、Template referenceで定義されているRquiredTypeUpdate_requiresの3つに気を付ける。

Rquired
Propertyには設定が必須のものと、そうでないものがあり、それを以下の3パターンとして定義している。

  • Required: Yes 設定しないとエラーになるProperty
  • Required: No 設定しないとなんらかのデフォルト値が勝手に設定されるProperty
  • Required: Conditional 他の設定との兼ね合いで必須だったり不要だったりするProperty。ただ、具体的にどの 設定と関連しているかは明示されていないこともあるので注意。

Type
PropertyValueをどのデータ型で記述するか。基本はType、String、Boolean、List of Tag、integerなどだが、特定のIDや入れ子で何か指定する場合がある。
List of Tagの場合は以下のようにリスト形式で記述する必要がある。

  Tags: 
    - ListItem1
    - ListItem2

Update requires
スタックを更新したとき、このPropertyを変更した場合にどうなるか

  • Update requires: No interruption リソース自体はそのままでProperty部分のみ変更
  • Update requires: Replacement リソースごと交換

データベースなどにおいてリソースごと交換が必要なPropertyを変更した場合は、保存したデータごとResourceが一旦削除されて作り直しになるので注意。

予め設定できるValueが限定されているものは以下のようにAllowed valuesとして明記されている。
例)EC2インスタンスのテナンシーを 専用|デフォルト(共有)|専有 から選択する例
InstanceTenancy: 
Allowed values: dedicated | default | host

定義が必要なResourceについて

マネジメントコンソール上ではウィザード内の一連の流れの中で一緒に作成しているリソースでも個別に定義する必要がある。
例:ロードバランサーの起動には、最低限、以下のResourceを個別で定義する必要がある。

  • Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
  • Type: "AWS::ElasticLoadBalancingV2::Listener"-
  • Type: "AWS::ElasticLoadBalancingV2::TargetGroup"

組み込み関数について

Propertiesの値を記述する際に、直接、値を入力するのではなく、外部から参照した情報を値としたい場合に使用する。

Ref関数

テンプレート内の他のリソースを参照に使う関数
書式
 !Ref 論理ID 
例)同テンプレート内で定義した別のResource MyVpcのIdを取得する例

network.yml
  PublicSubnet:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone: "ap-northeast-1a"
      VpcId: !Ref MyVpc 
       ~ ~ 略 ~ ~

GetAtt関数

他のリソースの属性を取得する場合に使う関数。
書式
 !GetAtt 論理ID.属性名

その他の関数

参考:https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html

OutputとImportValue

通常は一つのテンプレートに構築したいリソースを全てまとめて記述することはせず、ライフサイクルやアプリケーション、ネットワーク、セキュリティなどのレイヤーごとにテンプレートを分ける。よって、別ファイルで定義した値を参照したい場合は、OutputImportValueを使う。

Ouputsセクションの書式 (出力元)
network.yml
Outputs:  #以下に出力したいリソースを定義
  PublicSubnet1: #任意の論理ID。Resourceセクションで定義したものと同じでもOK 
    Description: PublicSubnet-AZ1a #説明書き
    Value: !Ref PublicSubnet1 #出力したいリソースを記載。
    Export:
      Name: MyPublicSubnet1 #出力した時の名前(任意)
ImportValueの書式(出力した値を使う時)
application.yml
  WebServer1:
    Type: AWS::EC2::Instance
    Properties:
      ImageId:
        "ami-0ca38c7440de1749a"
       #  ~~~~~ 中略 ~~~~~~ #
      SubnetId: !ImportValue PublicSubnet1 #Outputsで出力した名前

Parameterの活用
Propertyの値を固定値ではなく変数として定義するようなもの。Parametersセクションで定義した値をPropertyValueとしてRef関数で代入する。テンプレートをアップロードする際に、任意の値に都度変更できる。

application.yml
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.

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

エラーについて

まずはVSCodeの拡張機能を使って、エディター上でエラーを自動検出できる体制を作るのが大事。ただ、VSCode上でエラーが出てなくても以下のようなエラーに出くわすこともあるので注意。何れの場合も、エラーメッセージをちゃんと読んでテンプレートの該当箇所をTemplate referenceの規則に従って修正することが大事。

  • マネジメントコンソールでテンプレートファイルをアップロードした際にエラーメッセージがでる。
  • マネジメントコンソールでアップロード後、「デザイナーで表示」を実施する。記述に不備がでるとエラーが出る。
  • 「デザイナー」で表示した際にエラーがなくても「スタックを作成」するとエラーになることがある。
  • 無事テンプレートに従ってResourceの作成が始まるも途中でエラー。イベントタブにエラー内容が表示される。
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2