LoginSignup
74
55

More than 5 years have passed since last update.

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

Posted at

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の方法もお試しください。

74
55
1

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
74
55