CloudFormationのDeletionPolicyを後から更新する

実はCloudFormationの属性には単体での更新に対応していないものがあります。 今回タイトルにしたDeletionPolicyもその一つで、これだけの更新といったことは出来ません。 今回はタグを使用して可能な限り副作用を抑えてこれを更新する方法を紹介します。
2022.08.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CloudFormationのDeletionPolicy属性とは

DeletionPolicyは端的に言ってしまえば、スタック削除時のリソースをどう取り扱うかの設定です。 以下の3つが選択可能です。

  • Delete(デフォルト)
  • Retain
  • Snapshot

各値の詳細については以下が参考になります。 特にSnapshotは対応しているリソースが限定されているので注意が必要です。

後からDeletionPolicyを変更したい

CloudFormationでAWSリソースを作成する場合、指定しなければDeletionPolicyはDeleteです。 なので、明示的にリソースの保持やスナップショットを指定しないとスタックの削除時にリソースも削除されてしまいます。

想定になかったリソースの再作成などでスタックの削除を行うときにDeletionPolicyが設定されていないと削除されてしまいます。 マネコン等で作業を行いスタックの削除を行わなければ済む話ですが、やはりスタックが残っているのは気持ちが悪いなーという気持ちはあると思います。 今回はそんな場合に後からDeletionPolicyを後から変更する方法を考えてみます。

問題

CloudFormationでスタックの設定変更を行う場合は、単にスタックのテンプレートを更新すればいいだけですが、いくつかの属性ではうまく行かない場合があります。 実は以下の3つの属性は単独での更新は出来ません。

  • CreationPolicy
  • DeletionPolicy
  • UpdatePolicy

スタックテンプレートの変更 - AWS CloudFormation

CreationPolicy、DeletionPolicy または UpdatePolicy 属性単独では更新できません。更新できるのは、リソースを追加、変更、または削除する変更を含める場合だけです。たとえば、リソースのメタデータ属性を追加または変更することはできます。

運良くリソースの変更があればそのタイミングで一緒に更新してもいいと思いますが、ない場合はどうすればよいでしょうか。

今回はタグを追加する方法でこれらのポリシーを更新する方法を検討します。

タグとは

AWSにおけるタグはリソースのメタデータの一つで、対応しているリソースであればキーとその値を設定可能です。 例えば以下のような形です。

タグ名: EC2Role タグ値: WebServer

本来はリソースの整理やコスト配分などに使われますが、今回はこのタグを変更したときにリソースの更新がかかるという仕様を利用して上記の属性の変更を行います。 他に影響のない無意味なタグを付与すれば副作用なく属性の更新が可能というわけです。

タグを利用した属性更新の例

DeletionPolicyなしでデプロイ

リソースは何でもいいので今回はVPCを対象に考えます。

vpc.yaml

AWSTemplateFormatVersion: 2010-09-09
Description: VPC Stack

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: this-is-sample-vpc

この状態で一度デプロイします。 DeletionPolicyは設定されていないのでスタックを削除するとVPCも削除されてしまいます。

DeletionPolicyの更新

本来であれば以下のような変更だけで良いはずです。

vpc.yaml

AWSTemplateFormatVersion: 2010-09-09
Description: VPC Stack

Resources:
  VPC:
    Type: AWS::EC2::VPC
    DeletionPolicy: Retain
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: this-is-sample-vpc

ですが、こちらを使用して変更スタックを作成すると以下のように変更なしと判定されてしまいます。

なので次のようにダミーのタグを追加します。 このとき、他で利用していないタグを使用してください。 コスト配分タグやEC2などの管理に使っているタグを使用しないでください。

AWSTemplateFormatVersion: 2010-09-09
Description: VPC Stack

Resources:
  VPC:
    Type: AWS::EC2::VPC
    DeletionPolicy: Retain
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: this-is-sample-vpc
        - Key: Dummy
          Value: this is dummy tag for update deletaion policy

こちらであれば以下のように変更が可能です。

ダミータグの削除

最後にダミータグの削除を行います。 以下のようにタグをテンプレートから削除すればよいだけです。

vpc.yaml

AWSTemplateFormatVersion: 2010-09-09
Description: VPC Stack

Resources:
  VPC:
    Type: AWS::EC2::VPC
    DeletionPolicy: Retain
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: this-is-sample-vpc

スタックの削除

スタックの削除を行います。

スタックの削除は完了しましたが、VPCは残っています。

無事にDeletionPolicyが更新されていたようです。

最後に

今回はタグを使用したDeletionPolicyの更新を行いました。 もちろんすべてのリソースがタグ付けに対応しているわけではありません。 なので、その場合はサービスに影響のないリソースの作成を同一テンプレートで行う必要があります。 ですが、タグ付に対応していればこちらの方法でサービスの作成といったことを行わなくても対応可能です。