VPCIDをサブネット作成用にSSMパラメータストアに出力するものがあったとして
#vpc.yaml
Resources:
Vpc:
Type: AWS::EC2::VPC
...
SSMVpcId:
Type: AWS::SSM::Parameter
Properties:
Name: !Sub "/${Prefix}/vpc-id"
Type: String
Value: !Ref Vpc
#subnet.yaml
Resources:
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Sub "{{resolve:ssm:/${Prefix}/vpc-id}}"
...
SSMVpcIdをなんとなくVpcIdに変更したくなってupdate-stackすると、「/cf/vpc-id already exists in stack」エラーになる。これは、元々「SSMVpcId」で作成したSSMパラメータが削除/再作成される動作がないため、既存で「/${Prefix}/vpc-id」パラメータが存在するところに「VpcId」というCFn内部の概念で同じパラメータを作成しようとしてなる。
やってみる前は、なんとなくそこらへんうまくやってくれると思ってた(SSMVpcIdの記述はなくなったのだから削除されて、VpcIdでSSMパラメータが再作成されるか、SSMパラメータはVpcIdの概念で再利用されるか)
で、これを修正するには、SSMVpcIdのブロックをいったんまるっとコメントアウトしてupdate stackする。そうすると、SSMパラメータが削除される。
でも良いところは、既存でそのSSMパラメータを参照して作成したサブネットに影響はないこと。まあそうだよね。サブネットとしては、作成時だけSSMパラメータから値を取り出してセットしてるわけで。いったん作成したサブネットはそれ自体にVPCIDを保持してるので、作成時に参照したSSMパラメータを削除しても影響がない。マネコンとかでやる場合と近いイメージ。
でも、これがImportValueのクロススタック参照だと、実際のリソースはともかくCFn的にサブネット用スタックから参照してるとなれば、参照元のSSMパラメータの削除ってできないんじゃないかな?あとで検証してみたい。
(※検証した)
で、いったんSSMVpcIdブロックを削除してSSMパラメータ削除されたら、VpcIdとして再度記述してupdate-stack
VpcId:
Type: AWS::SSM::Parameter
Properties:
Name: !Sub "/${Prefix}/vpc-id"
Type: String
Value: !Ref Vpc
これで正常にUPDATE_COMPLETE。
SSMパラメータを介したスタック間リソース参照は、疎結合で良いかもしれない
参考
動的参照(resolve:ssm:)