[CloudFormation] UpdateReplacePolicy等の適用タイミングについて

1 min読了の目安(約1700字TECH技術記事

例えばDynamoDBの定義がしてあって、あらかじめcreate-stackでリソースがap-northeast-1とeu-central-1に作成されているとする

テンプレート1
Resources:
  DynamoDBResource:
    Type: AWS::DynamoDB::Table
    Properties: 
      # 以下略

そして以下のようにテンプレートを更新する

テンプレート2
Conditions:
  IsAn1: !Equals [ !Ref 'AWS::Region', 'ap-northeast-1' ]

Resources:
  Condition: IsAn1
  DynamoDBResource:
    Type: AWS::DynamoDB::Table
    Properties: 
      # 以下略

↑のテンプレートでp-northeast-1とeu-central-1のスタックに対してupdate-stackにすると、"Condition"の条件に基づいてeu-central-1からテーブルが削除される
この時スタックは更新するがeu-central-1のテーブル自体は削除したくない場合、テンプレートの定義に'UpdateReplacePolicy'を指定することが考えられる

テンプレート3
Conditions:
  IsAn1: !Equals [ !Ref 'AWS::Region', 'ap-northeast-1' ]

Resources:
  Condition: IsAn1
  # Retainにするとスタックが更新されてもリソースが残る
  UpdateReplacePolicy: Retain
  # DeletionPolicyも一緒に指定する必要がある
  DeletionPolicy: Delete
  DynamoDBResource:
    Type: AWS::DynamoDB::Table
    Properties: 
      # 以下略

しかしテンプレート2の代わりにテンプレート3でスタックを更新してもUpdateReplacePolicyは反映されない。従ってeu-centaral-1のテーブルは消えてしまう。

対策として次の順序でスタックを更新するとeu-central-1のテーブルが消えない

  1. テンプレート1 で create-stack (ap-northeast-1とeu-central-1)
  2. テンプレート4 で update-stack (eu-central-1だけでいい)
    テンプレート4
    Resources:
      DynamoDBResource:
        Type: AWS::DynamoDB::Table
        UpdateReplacePolicy: Retain
        # DeletionPolicyも一緒に指定する必要がある
        DeletionPolicy: Delete
        Properties: 
          # 以下略
    
  3. テンプレート2 で update-stack (ap-northeast-1とeu-central-1)
    • 「UpdateReplacePolicy: Retain」を全体のポリシーとするなら別に残したテンプレートにしてもいい
    • あくまで一度作成したテンプレートから条件が変わる際に不本意にテーブルが消えるのを防ぐためのUpdateReplacePolicyなので不要ならここで指定しなくてもいい

結論

UpdateReplacePolicy、DeletionPolicyを始めて指定する際に合わせてリソースの置換/削除が生じると、設定したポリシーが反映されないので、
置換/削除が生じる前に一度Policyを設定する必要がある