Help us understand the problem. What is going on with this article?

CloudFormationテンプレート間で値を渡す3つの方法

More than 1 year has passed since last update.

CloudFormationテンプレート間でリソースIDなどを渡す方法について紹介します。
簡単のため、2つのテンプレートで以下を実施する例で示します。

  • VPCを作りVpcIdを渡す
  • 渡されたVpcId内にSubnetを作る

1. AWS::CloudFormation::Stack を使って !GetAtt *.Outputs.* で受け取る

親となるテンプレート(base.yml)を用意して、2つのテンプレートを呼び出す形になります。
値を渡すテンプレート(vpc.yaml)ではOutputsに値を出力し、
親テンプレートのParametersで!GetAtt ResourceName.Outputs.OutputNameを使って渡します。
受け取るテンプレート(subnet.yaml)はParametersにパラメータを用意しておきます。

なお、vpc.yaml, subnet.yamlは事前にS3にアップしておき、base.yamlのみをCloudFormationで作成します。
(2, 3の方法はvpc.yaml, subnet.yamlをCFで作成します。)

base.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  VPC:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/***/vpc.yaml
  Subnet:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/***/subnet.yaml
      Parameters:
        VpcId: !GetAtt VPC.Outputs.VpcId # !GetAtt で受け渡す
vpc.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.250.250.0/24
Outputs:
  VpcId: # 渡す値を出力する
    Value: !Ref VPC
subnet.yaml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  VpcId: # 受け取る値を定義する
    Type: AWS::EC2::VPC::Id
Resources:
  Subnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VpcId
      CidrBlock: 10.250.250.0/28

参考: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html

テンプレートを更新する場合は、S3にアップ、親テンプレートの更新、という流れになります。

この方法はここで使われています。
https://github.com/awslabs/ecs-refarch-continuous-deployment/blob/master/ecs-refarch-continuous-deployment.yaml

2. ImportValueを使う(cross reference)

値を渡すテンプレート(vpc.yaml)ではOutputsにExport属性付きで値を出力し、
受け取るテンプレート(subnet.yaml)は!ImportValueで取得します。

vpc.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.250.251.0/24
Outputs:
  VpcId:
    Value: !Ref VPC
    Export: # 渡す値をExportで出力する
      Name: VpcId
subnet.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  Subnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !ImportValue VpcId
      CidrBlock: 10.250.251.0/28

参考:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/walkthrough-crossstackref.html

この方法の注意点として、テンプレートを更新してExportする値が変わるような場合、更新する前にImportValueしたリソースを必ず削除する必要があります。

3. Parameter Storeを使う

値を渡すテンプレート(vpc.yaml)ではParamter Storeに値を保存し、
受け取るテンプレート(subnet.yaml)はParametersで取得します。
このとき、TypeはAWS::SSM::Parameter::Value、Value(テンプレート上はDefault)はParameter StoreのNameになります。

vpc.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.250.252.0/24
  SSMVpcId: # 渡す値をParameter Storeに保存する
    Type: AWS::SSM::Parameter
    Properties:
      Name: /cf-values/VpcId
      Type: String
      Value: !Ref 'VPC'
subnet.yaml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  VpcId: # 受け取る値を定義する
    Type: AWS::SSM::Parameter::Value<AWS::EC2::VPC::Id>
    Default: /cf-values/VpcId # Parameter StoreのNameを指定
Resources:
  Subnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VpcId
      CidrBlock: 10.250.252.0/28

参考:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#aws-ssm-parameter-types

記述は多くなりますが、Parameter Storeをこのように使うこともできます。

まとめ

個人的な希望は、2の方法でExportする値を更新するとImportValueしたリソースも自動で更新するようになるとありがたいのですが。
是非、3の方法もお試しください。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away