LoginSignup
4
3

More than 3 years have passed since last update.

CloudFormationをゼロから勉強する。(その9:クロススタックリファレンス)

Last updated at Posted at 2020-12-06

はじめに

その8ではスタックをネスト構成にしてテンプレートを分割しましたが、今回はクロススタックリファレンスで前回と同じようにテンプレートを分割してみようと思います。

クロススタックリファレンスとは

クロススタックリファレンスも前回のネスト同様、テンプレートを分割する方法の1つとなりますが、クロススタックリファレンスは他のテンプレートで使用する変数だけを共有させるようにする方法となります。

クロススタックリファレンスの書式

書式としては単純で、値を参照させる側のテンプレートのOutputsセクションで参照させたい値・変数をExportで指定して、参照する側はImportValue関数で他テンプレートでExportしている値・変数を読み込むだけです。簡単ですね!

参照させる側の書式例
Outputs:
  EC2VPC1:
    Value: !Ref EC2VPC1
    Export:
      Name: CrossStackVpcId
参照する側の書式例
Resources:
  EC2Subnet1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !ImportValue CrossStackVpcId

クロススタックリファレンスは、前回のネスト構成のように、親となるスタックを実行すれば、テンプレート内で定義されている子スタックがまとめて作成されるようなものではないため、展開する際は個々に実行する必要があります。

今回作成する構成

前回のテンプレートを手直しして以下のような構成を作ってみようと思います。

今回は親、子関係ないので、パラメータ入力・子テンプレート管理用のテンプレート(前回で言うと「cf.yaml」)は作成しません。

CrossStack.png

テンプレート、パラメータファイルの格納場所

今回は以下のファイル・ディレクトリ構成としようと思います。。

内容 VPCのパラメータ SUbnet1のパラメータ Subnet2のパラメータ EC2のパラメータ
スタック名 cross-stack-vpc cross-stack-subnet1 cross-stack-subnet2 cross-stack-ec2
テンプレートファイルのパス /home/ec2-user/vpc.yaml /home/ec2-user/subnet1.yaml /home/ec2-user/subnet2.yaml /home/ec2-user/ec2.yaml
パラメータファイルのパス /home/ec2-user/param1.json /home/ec2-user/param2.json /home/ec2-user/param3.json -

VPCスタック用テンプレートの作成

VPCのレンジを入力で受け取って、VPCIDExportで出力して他テンプレートから使用できるようにします。

テンプレートは個々に実行するため、入力用jsonファイルも作ります。

VPCスタック用テンプレート(vpc.yaml)
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  VPCRange:
    Type: String
Resources:
  EC2VPC1:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: !Ref VPCRange
      Tags:
        - Key: "Name"
          Value: "cf_VPC1"
Outputs:
  EC2VPC1:
    Value: !Ref EC2VPC1
    Export:
      Name: CrossStackVpcId
VPCレンジ入力用ファイル(param1.json)
[
  { "ParameterKey" : "VPCRange", "ParameterValue" : "172.24.0.0/16" }
]

Subnet1スタック用テンプレートの作成

Subnet1用のレンジを入力で受け取って、SubnetIDExportで出力して他テンプレートから使用できるようにします。

サブネット作成で必要なVPCIDImportValue関数で先ほどVPC作成でExportした名前を指定して取得します。

また、上記VPCと同様、入力用jsonファイルも作ります。

Subnet1スタック用テンプレート(subnet1.yaml)
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  SubnetRange1:
    Type: String
Resources:
  EC2Subnet1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !ImportValue CrossStackVpcId
      CidrBlock: !Ref SubnetRange1
      Tags:
        - Key: "Name"
          Value: "cf_Subnet1"
Outputs:
  EC2Subnet1:
    Value: !Ref EC2Subnet1
    Export:
      Name: CrossStackSubnet1Id
Subnet1レンジ入力用ファイル(param2.json)
[
  { "ParameterKey" : "SubnetRange1", "ParameterValue" : "172.24.0.0/24" }
]

Subnet2スタック用テンプレートの作成

パラメータ名の違いだけでSubnet1と同じなので説明割愛。

Subnet2スタック用テンプレート(subnet2.yaml)
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  SubnetRange2:
    Type: String
Resources:
  EC2Subnet2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !ImportValue CrossStackVpcId
      CidrBlock: !Ref SubnetRange2
      Tags:
        - Key: "Name"
          Value: "cf_Subnet2"
Outputs:
  EC2Subnet2:
    Value: !Ref EC2Subnet2
    Export:
      Name: CrossStackSubnet2Id
Subnet2レンジ入力用ファイル(param3.json)
[
  { "ParameterKey" : "SubnetRange2", "ParameterValue" : "172.24.1.0/24" }
]

EC2スタック用テンプレートの作成

ImportValue関数でSubnet1のIDを取得します。

EC2スタック用テンプレート(ec2.yaml)
AWSTemplateFormatVersion: 2010-09-09
Resources:
  EC2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: ami-0cc75a8978fbbc969
      InstanceType: t2.micro
      KeyName: staging_key
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          SubnetId: !ImportValue CrossStackSubnet1Id
          DeviceIndex: 0
      Tags:
        - Key: "Name"
          Value: "cf_EC2"

スタックの作成

作成したテンプレートをいつも通り実行してスタックを作成すれば完成です。

但し、今回の場合、Export値を参照するので、Export対象のスタックが先に完成していなければ、値が引けずに失敗します。

そのため、一斉にcreate-stackで実行するのではなく、スタック作成の成功を待ってから順に作成するようにしましょう。

スタックの作成
aws cloudformation create-stack --template-body file:///home/ec2-user/vpc.yaml     --stack-name cross-stack-vpc     --parameters file:///home/ec2-user/param1.json
aws cloudformation create-stack --template-body file:///home/ec2-user/subnet1.yaml --stack-name cross-stack-subnet1 --parameters file:///home/ec2-user/param2.json
aws cloudformation create-stack --template-body file:///home/ec2-user/subnet2.yaml --stack-name cross-stack-subnet2 --parameters file:///home/ec2-user/param3.json
aws cloudformation create-stack --template-body file:///home/ec2-user/ec2.yaml     --stack-name cross-stack-ec2

削除について

ネスト構成の時と異なり、個々にスタック作成しているので、削除する場合も個々に削除する必要があります。

但し、Exportしている値は依存関係があるため、もし他のスタックでExportしている値を使用していた場合は削除できません。

例えば、「vpc.yaml」を削除しようとすると「Export CrossStackVpcId cannot be deleted as it is in use by cross-stack-subnet1 and cross-stack-subnet2」といった理由により削除ができません。

スタックの削除と状態確認
aws cloudformation delete-stack --stack-name cross-stack-vpc
aws cloudformation describe-stacks --stack-name cross-stack-vpc
describe-stacksの表示例
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/cross-stack-vpc/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", 
            "EnableTerminationProtection": false, 
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }, 
            "Parameters": [
                {
                    "ParameterValue": "172.24.0.0/16", 
                    "ParameterKey": "VPCRange"
                }
            ], 
            "Tags": [], 
            "Outputs": [
                {
                    "ExportName": "CrossStackVpcId", 
                    "OutputKey": "EC2VPC1", 
                    "OutputValue": "vpc-xxxxxxxxxxxxxxxxx"
                }
            ], 
            "StackStatusReason": "Export CrossStackVpcId cannot be deleted as it is in use by cross-stack-subnet1 and cross-stack-subnet2", 
            "CreationTime": "YYYY-MM-DDThh:mm:ss.xxxZ", 
            "StackName": "cross-stack-vpc", 
            "NotificationARNs": [], 
            "StackStatus": "CREATE_COMPLETE", 
            "DisableRollback": false, 
            "RollbackConfiguration": {}
        }
    ]
}

もし全てを削除したい場合は、以下の順番で削除するようにしましょう。

すべてのスタックの削除
aws cloudformation delete-stack --stack-name cross-stack-ec2
aws cloudformation delete-stack --stack-name cross-stack-subnet2
aws cloudformation delete-stack --stack-name cross-stack-subnet1
aws cloudformation delete-stack --stack-name cross-stack-vpc

おわりに

今回のクロススタックリファレンスは前回のネストによるテンプレート呼び出しと比較し、簡単に値の共有ができると感じました。

ネストは多段構成になると、各スタックごとの繋がりを意識して作成する必要がありましたが、クロススタックリファレンスではスタックは個々に分離されているので、連携するテンプレート数が多くなっても書式があまり変わらずに書けるのは良いですね。

次回は今までやってきたTransformネストクロススタックリファレンスの使い分けについて私なりに考察してみようと思います。

4
3
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
3