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

CloudFormationでクロススタック参照(YAML版)

More than 3 years have passed since last update.

はじめに

今回はCloudFormationのクロススタック参照を試してみたいと思います。
前回作成したVPCテンプレートを修正し、S3&VPCエンドポイントのテンプレートから参照できるようにいたします。

AWS CloudFormation で YAML テンプレートとクロススタックリファレンスをサポート

テンプレートファイル

VPC作成テンプレートでOutputsセクションを追加し、
ルートテーブルとサブネットをエクスポートするように記載しております。
※Exportする名前はAWSアカウントおよびリージョンで一意にする必要があるので
 被らないように命名規則を作ってください。
 今回はリソース同様、<環境>-<システム名>-<リソース名>という形にしてます。

以下、VPC作成テンプレート

CFn_CreateVPCsubnet.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description:
  VPC & subnet create
Parameters:
  EnvType:
    Description: Environment type.
    Default: dev
    Type: String
    AllowedValues:
      - dev
      - mnt
      - prd
    ConstraintDescription: must specify dev or mnt or prd.
  ProjectId:
    Description: Project name id.
    Type: String
    MinLength: "3"
    MaxLength: "3"
    AllowedPattern: "[a-zA-Z0-9]*"
    ConstraintDescription: must specify Project id.

Resources:
# Create VPC
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/24
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"vpc" ] ]

# Create Public RouteTable
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"pub-route" ] ]

# Create Private RouteTable
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"pri-route" ] ]

# Create Public Subnet A
  PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.0.0/27
      AvailabilityZone: "ap-northeast-1a"
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"PublicSunetA" ] ]
  PubSubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetA
      RouteTableId: !Ref PublicRouteTable

# Create Public Subnet C
  PublicSubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.0.32/27
      AvailabilityZone: "ap-northeast-1c"
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"PublicSunetC" ] ]
  PubSubnetCRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetC
      RouteTableId: !Ref PublicRouteTable

# Create Private Subnet A
  PrivateSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.0.64/27
      AvailabilityZone: "ap-northeast-1a"
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"PrivateSubnetA" ] ]
  PriSubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnetA
      RouteTableId: !Ref PrivateRouteTable

# Create Private Subnet C
  PrivateSubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.0.96/27
      AvailabilityZone: "ap-northeast-1c"
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"PrivateSubnetC" ] ]
  PriSubnetCRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnetC
      RouteTableId: !Ref PrivateRouteTable

# Create InternetGateway
  myInternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"igw" ] ]
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref myInternetGateway

# Create VPNGateway
  myVPNGateway:
    Type: "AWS::EC2::VPNGateway"
    Properties:
      Type: ipsec.1
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"vgw" ] ]
  AttachVpnGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyVPC
      VpnGatewayId: !Ref myVPNGateway

# Route for InternetGateway or VPNGateway
  myRoute:
    Type: AWS::EC2::Route
    DependsOn: myInternetGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref myInternetGateway
      #GatewayId: !Ref myVPNGateway

Outputs:
  StackVPC:
    Description: The ID of the VPC
    Value: !Ref MyVPC
    Export:
      Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId" , "vpcid"]]

  PublicRouteTable:
    Description: The ID of the PublicRouteTable
    Value: !Ref PublicRouteTable
    Export:
      Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PublicRouteTable"]]

  PrivateRouteTable:
    Description: The ID of the PrivateRouteTable
    Value: !Ref PrivateRouteTable
    Export:
      Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PrivateRouteTable"]]

  StackPubSubnetA:
    Description: The ID of the VPC Subnet
    Value: !Ref PublicSubnetA
    Export:
      Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PublicSubnetA"]]

  StackPubSubnetB:
    Description: The ID of the VPC Subnet
    Value: !Ref PublicSubnetC
    Export:
      Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PublicSubnetC"]]

  StackPriSubnetA:
    Description: The ID of the VPC Subnet
    Value: !Ref PrivateSubnetA
    Export:
      Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PrivateSubnetA"]]

  StackPriSubnetB:
    Description: The ID of the VPC Subnet
    Value: !Ref PrivateSubnetC
    Export:
      Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PrivateSubnetC"]]

"Fn::ImportValue"の箇所で、上記のエクスポートした情報をインポートしています。
VPCとルートテーブルを利用しています。

以下、S3&VCPエンドポイント作成

CFn_CreateS3.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description:
  S3 & VPC Endpoint create
Parameters:
  EnvType:
    Description: Environment type.
    Default: dev
    Type: String
    AllowedValues:
      - dev
      - mnt
      - prd
    ConstraintDescription: must specify dev or mnt or prd.
  ProjectId:
    Description: Project name id.
    Type: String
    MinLength: "3"
    MaxLength: "3"
    AllowedPattern: "[a-zA-Z0-9]*"
    ConstraintDescription: must specify Project id.

Resources:
# Create S3 by log
  LogS3:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"logbucket" ] ]
      Tags:
      - Key: Name
        Value: !Join [ "-", [ "Ref":"EnvType" , "Ref":"ProjectId" ,"LogBucket" ] ]

  LogS3Endpoint:
    Type: "AWS::EC2::VPCEndpoint"
    Properties:
      RouteTableIds:
        - { "Fn::ImportValue": !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PublicRouteTable"]] }
        - { "Fn::ImportValue": !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "PrivateRouteTable"]] }
      ServiceName:
        !Sub "com.amazonaws.${AWS::Region}.s3"
      VpcId: { "Fn::ImportValue": !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId" , "vpcid"]] }

Outputs:
  LogS3:
    Description: Log S3 Bucket
    Value: !Ref LogS3
    Export:
      Name: !Join [ "-", [ "Ref":"EnvType", "Ref":"ProjectId", "LogBucket"]]

ちなみに短縮形多用しておりますが、ImportValueのところは以下のエラーがでたため、短縮形の利用を諦めました。
```
Template validation error: Template format error: YAML not well-formed. (line 36, column 26)

まとめ

組み込み関数の組み合わせでエラーが多発して手こずりましたが、なんとかできました。
次はEC2インスタンスに挑戦したいと思います!

ちなみにエンドポイント作成はクロススタック参照せず、
VPC作成テンプレートに入れたほうがよいと後から思いました笑

shinko-1930
1930年創業のIT企業。人間力と確かな技術で、お客さまの期待を超えるサービスを提供し続けます。
http://www.shinko-1930.co.jp/
Why not register and get more from Qiita?
  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
No 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
ユーザーは見つかりませんでした