movee(モビー) オノデラのブログ

(株)movee代表。週末は自社サービスを作っています。

CloudFormationと5つのsection(Parameters、Resouces、Mappings、Conditions、Outputs)

CloudFormationの理解が弱いのでまとめてみる。

CloudFormationはJSON型式か、YAML型式で記述されたテンプレートをもとにスタック(AWSリソースの集合体)を自動構築する。JSONYAMLファイルを作成してコンパネからファイルをアップロードして読み込んで使っていく。

sampletemplate.yaml

AWSTemplateFormatVersion: "2010-09-09"

Parameters:

  AmazonLinux AMIID:
    Type: AWS::SSM::Parameter::Value <AWS::EC2::Image::Id> //SSM::Parameter::Valueを使ってSystems ManagerパラメータストアのSSMパラメータを使って最新のAmazon Linux2 AMIを仕様
    Default: /aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2

Resources:

  EC2Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      Instance Type: t2.micro //EC2.t2.microタイプを指定
      Imageld: !Ref AmazonLinuxAMIID //!Refという組み込み関数でparametersに設定したAmazon linux 2を参照
      Tags:
        - Key: Name
          Value: Demo Server

Parametersはスタック作成画面上で入力・選択できるParameterを設定できる。 Resoucesはスタックに含めるリソースと設定プロパティを書く。サンプルはEC2だけだがLambdaやRDS、S3なども定義できるはず。

Mappings: 独自に作成したAMIから起動するEC2を構築する場合。 AMIはregion単位で使えるため東京regionのAMIをバージニアregionで使うことはできないのでAMIをcross region copyしてEC2を起動する。複数regionで使う場合、regionごとにテンプレートを作るのは煩雑なのでMappingsを使う。

mappings.yaml

AWSTemplateFormatVersion: "2010-09-09"

Mappings:
  RegionMap:
    ap-southeast-1: //東京region
      "AMI": "ami-08569b978cc4dfa10" 
    ap-northeast-1: //シンガポールregion
      "AMI": "ami-06cd52961ce9f0d85"

Resources:

EC2Instance:
  Type: "AWS::EC2::Instance"
  Properties:
    Instance Type: t2.micro
    Imageld: !FindInMap [Region Map, !Ref "AWS::Region", AMI] //FindMap関数でスタックを作成してるregionをキーにしてAMIのIDを参照する
    Tags:
      -Key: Name
       Value: Demo Server

FindMapは今アクセスしているregionが東京なら東京regionのAMIのIDを参照する、のだと思う。

Conditions:テスト環境と本番環境が異なるときに条件を変更したいとき。例えば本番だけEBSのボリュームを増やしたいなど。そんなときはConditionsで条件を設定する。

Outputs:出力を定義するsection。2つのuse caseを提示する。

EC2でWebServerを起動後、自動割当のURLをすぐに知りたい場合、Outputsにhttp://${EC2Instance.PublicDnsName}を定義すれば実行後の出力でURLが表示される。

outputsample.yml

Outputs:
  URL:
    Description: URL of the sample website
    Value: !Sub 'http://${EC2Instance.PublicDnsName}'

networkスタックとapplicationスタックが別々の場合でnetworkスタックの定義をapplicationで参照する場合など。 以下のPublicSubnetのIDを${AWS::StackName}-SubnetIDとしてexportに定義してapplicationではImportValue関数でnetworkスタックのサブネットIDの参照ができる。

sample.yaml

Outputs:
  PublicSubnet:
    Description: The subnet ID to use for public web servers
    Value: !Ref PublicSubnet
    Export:
      Name: ! Sub '${AWS::StackName}-SubnetID'

Resources:
  EC2Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType: t2.micro
      Imageld: !Ref AmazonLinuxAMIID
      NetworkInterfaces:
        Subnetld:
          Fn::ImportValue:
            !Sub ${NetworkStackName}-SubnetID

最後のOutputsの例だが、OutputsとResoucesを同じsample.yaml内で定義しているが、別々のyamlじゃないとダメなのかな。試してない。 以上、Parameters、Resouces、Mappings、Conditions、Outputsの5つのsectionの使い方の紹介。