AWS CloudFormation のクロススタック参照(Output Export と Fn::ImportValue)のメリットと設定方法

クロススタック参照というものがよくわからない。普通に Parameters から指定して参照させるだけではダメなの?……というわけで調べてみた。いくつかメリットがあるみたいだ。

メリット

削除保護ができる

スタック B がスタック A に依存している(A がエクスポートしたものを B から参照している)場合、スタック A を管理コンソール上から削除しようとしても削除されない

B ---> A
       ^^
       こっちを先に削除すると……?
       → 「いや B が参照してますよ」と怒ってくれる

管理コンソール上では以下のようなメッセージが出る。

CREATE_COMPLETE Export export-environment-xxxx-vpcid cannot be deleted as it is in use by (スタック B のスタック名)

より詳しく言えば(削除すると普通は DELETE PROGRESS になるところを、それがキャンセルされる、でもそれだけだと見た目わからんから再び)CREATE COMPLETE と表示している……という感じ。

Parameters を介さずに参照できる

スタック A でつくった環境にスタック B でリソースを注入したい(A のサブネットに B で定義したインスタンスをつくる等)場合、A のどのリソースに注入するかは Parameters から指定させるのが普通(たぶん)だと思う。

しかしクロススタック参照を使えば、エクスポートした名前をお互いに使うだけで渡せる。いちいちパラメーターを指定する画面を介さなくて良い。

書き方

参照される側、する側両方のテンプレに修正が必要。

1: 参照される側のリソースを Output Export する

肝心部分は Outputs.XXXX.Export.Name に「エクスポートしたい名前」を指定する ところ。

続く Import では、この名前をそのまま指定することになる。

Outputs:
  VpcId:
    Value: !Ref VPC
    Export:
      Name: "export-environment-xxxx-vpcid"

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      InstanceTenancy: default
      CidrBlock: 10.192.0.0/16

2: 参照する側のリソースから ImportValue する

Export されてる名前をそのまま指定する。

この例では 1 でエクスポートしてる VPC export-environment-xxxx-vpcid を参照したいので、これを Import する。

Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: "Dummy security group to test cross stack."
      SecurityGroupIngress:
      - CidrIp: 0.0.0.0/0
        FromPort: 22
        ToPort: 22
        IpProtocol: tcp
      VpcId: !ImportValue "export-environment-xxxx-vpcid"

参考