DeletionPolicy 属性で解決：CloudFormationでRDSをコード化した際、スタック削除時にスナップショットが削除されず困っていた件

## はじめに
今回は、AWS上でインフラ構築をCloudFormationを使って自動化する中で、スタックを削除した際にRDSのスナップショットが削除されないという事象が発生しました。

:::note warn
**通常、RDSインスタンスを削除する際には、最終スナップショットを取得する必要があります。
※CloudFormationでも、デフォルトでこの設定が適用される仕様です。**
:::

しかし、DeletionPolicy属性を使用することで、この問題を解消できたため、備忘録として簡単にまとめます。

## 補足：今回ご紹介する一部のコードについて
現在、受講しているITスクールのハッカソンでチーム開発を進めており、その中でRDSインスタンスの無料利用枠を構築する作業を行っていました。

今回ご紹介するのは、RDSインスタンスの部分のみとなります。この箇所で困っていたため、取り上げています。

**コード全体を知りたい方は、以下の記事も参考にしてみてください。**

https://qiita.com/free-honda/items/68e06a33a942e02fbc85

## 困っていたこと
CloudFormationでスタックを作成した場合、使い終わった際にスタックを削除することで環境全体が削除されます。

:::note alert
***しかし、今回使用したCloudFormationのコードでは、RDSについてスナップショットが削除されずに残り続けるという問題が発生していました。***
:::

これにより、気づかないうちに小額ながら課金が発生し、スナップショットが大量に溜まることで小さなストレスを感じる状況となりました...。

## 実際の解決方法について
`AWS::RDS::DBInstance` の部分に「`DeletionPolicy: Delete`」を付与することで、この問題を解決できました。

**公式ドキュメント：**

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html

**修正後のファイルについて**

```test.yaml
  # RDSインスタンス
  RDSInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Delete
    Properties:
      AllocatedStorage: "20" 
・・・（省略）
        - Key: Name
          Value: "CloudFormation-rds-instance"
      DeletionProtection: false
```

## DeletionPolicy 属性について
DeletionPolicy 属性を使用すると、スタックが削除された際にリソースを保持したり、バックアップを作成したりすることが可能です。

:::note info
**各リソースに対して明示的に指定しない場合、AWS CloudFormation はデフォルトでリソースを削除します。**
:::

また、この属性はスタックの更新操作にも適用され、テンプレートからリソースを削除して更新する際にリソースを保持することができます。

***ただし、スタック更新中にリソースのプロパティ変更などで物理インスタンスが置き換えられる場合には、この属性は適用されません。***

## 各オプションの簡単なまとめ

以下は、公式ドキュメントを基に自分なりに箇条書きで簡単にまとめた内容です。***詳細について知りたい方は、公式ドキュメントをご参照ください。***

**公式ドキュメント：**

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html

なお、インターネット上の文献を確認したところ、このあたりの情報は頻繁にアップデートが行われるようです。

**そのため、今回記載した内容も将来的に古くなる可能性があります。最新情報については公式ドキュメントや信頼できる情報源をご確認ください。**

**参考リンク：**

https://dev.classmethod.jp/articles/cloudformation-retain-except-on-create/

### Delete

- **動作**  
  CloudFormation は、スタック削除時にリソースとそのすべてのコンテンツを削除します。

- **適用範囲**  
  すべてのリソースタイプに追加可能です。DeletionPolicy を指定しない場合、デフォルトでこの動作が適用されます。

- **注意点**  
  - **RDS**  
    - `AWS::RDS::DBCluster` の場合、デフォルトは `Snapshot` です。  
    - `AWS::RDS::DBInstance` に `DBClusterIdentifier` プロパティを指定しない場合も、デフォルトは `Snapshot` です。  
  - **S3**  
    - S3バケットを削除する際は、バケット内のすべてのオブジェクトを事前に削除する必要があります。

### Retain

- **動作**  
  CloudFormation はスタック削除時にリソースやコンテンツを削除せず保持します。スタックの状態は `Delete_Complete` になりますが、保持されたリソースは課金対象となります。

- **適用範囲**  
  すべてのリソースタイプに追加可能です。

- **注意点**  
  - **更新オペレーション**  
    - リソースが削除された場合、`DeletionPolicy` により物理リソースは保持されますが、CloudFormation のスコープからは削除されます。  
    - リソースが更新され、古いリソースが新しいリソースに置き換えられる場合、古いリソースは完全に削除されます。


### RetainExceptOnCreate

- **動作**  
  スタック操作では基本的に `Retain` と同様に動作しますが、リソースを作成したスタック操作がロールバックされた場合はリソースを削除します。

- **結果**  
  - 新しいリソース、空のリソース、未使用のリソースは削除されます。  
  - 使用中のリソースとそのデータは保持されます。

- **補足**  
  この削除ポリシーをAPIパラメータとして使用する場合は、[UpdateStack API ドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/APIReference/API_UpdateStack.html) を参照してください。

### Snapshot

- **動作**  
  スナップショットをサポートするリソースの場合、CloudFormation は削除前にリソースのスナップショットを作成します。

- **結果**  
  - スタック削除後もスナップショットは保持され、課金対象となります。  
  - スタックの状態は `Delete_Complete` になりますが、スナップショットは削除されません。

## まとめ
正直なところ、CloudFormationのスタックを削除した後に手動でスナップショットを削除する方法でも対応可能でしたが、その作業に少しストレスを感じていました。

:::note warn
**しかし、この属性を追加することで問題が解決し、とても助かりました。**
:::

今回の解決は、私自身が発見したというよりも、AWSに詳しい方から教えていただいたおかげで達成できたものです。***こうした技術を共有し合う文化の重要性を改めて感じることができました。***