[AWS][boto3][delete_stack] CloudFormationスタックをシリアルに削除するサンプルスクリプト

## 概要

- 以前作ったスクリプト(*1)の反対でCloudFormationスタックを順次削除するboto3スクリプト
    - (*1) [[AWS][boto3][create_stack] CloudFormationスタックをシリアルに実行するサンプルスクリプト](https://qiita.com/suo-takefumi/items/2bbcc3fd9af02acbeb26)
- スクリプト概要
    - 削除中のスタックが完了するまで次のスタックは削除しない
    - 削除するスタックは、スタック名の前方一致でフィルタ
    - 複数のスタックを削除する場合、作成日が新しいスタックから順に削除する
    - Dry-run 機能あり
    - Dry-runとは別に誤削除の防止機能（ブロックリスト）を搭載
- **※注意※ AWSリソースを削除するスクリプトなので、利用する際は自己責任でお願いします**

## 環境

Windows 10 の以下バージョンの環境にて動作を確認

```
PS C:\> python3 --version
Python 3.8.10
PS C:\> aws --version
aws-cli/2.2.3 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
PS C:\> python3
Python 3.8.10 (tags/v3.8.10:3d8993a, May  3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import boto3
>>> import botocore
>>> print(f'boto3 version: {boto3.__version__}')
boto3 version: 1.14.43
>>> print(f'botocore version: {botocore.__version__}')
botocore version: 1.17.43
>>>
PS C:\> aws configure
AWS Access Key ID [****************XXXX]:
AWS Secret Access Key [****************XXXX]:
Default region name [ap-northeast-1]:
Default output format [json]:
```

AWS Cloud9でも動作することを確認

```console
user01:~/environment $ python --version
Python 3.9.4
user01:~/environment $ aws --version
aws-cli/1.19.102 Python/2.7.18 Linux/4.14.232-177.418.amzn2.x86_64 botocore/1.20.102
user01:~/environment $ python
Python 3.9.4 (default, Jul  5 2021, 12:39:18) 
[GCC 7.3.1 20180712 (Red Hat 7.3.1-13)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import boto3
>>> import botocore
>>> print(f'boto3 version: {boto3.__version__}')
boto3 version: 1.17.105
>>> print(f'botocore version: {botocore.__version__}')
botocore version: 1.20.105
```

## スクリプト

スクリプトはgithubに格納しました。

https://github.com/zgw426/AWS-SDK_Delete_CloudFormationStacks


## ファイル構成

ファイルは2つあります。

|ファイル名|概要|
|---|---|
|deleteCfnStacks.py|スクリプト本体|
|deleteCfnStacks_BlockList.json|ブロックリスト<BR />削除しないスタックの条件を設定|

## スクリプトの実行方法

スクリプトの実行方法はこちらです。

```
PS C:\Users\user01\test> python deleteCFnStacks.py -f {削除するスタックのName(前方一致)} -d False|True
```

`-f`, `-d` オプションの2つあります。

|オプション|概要|
|---|---|
|`-f`|スタックの絞り込みオプション。削除するスタックのNameの値を指定(前方一致)|
|`-d`|Falseを指定するとDry-runが無効になりスタック削除処理が実行される。<BR />指定しない場合は、Dry-runが有効になる|

スクリプト実行例）Nameが test から始まるスタックを削除します

```powershell
PS C:\Users\user01\test> python deleteCfnStacks.py -f test -d False
```

スクリプト実行例）Nameが test から始まるスタックを確認します（スタック削除しない）

```powershell
PS C:\Users\user01\test> python deleteCfnStacks.py -f test
```

## ブロックリストの設定方法

`deleteCfnStacks_BlockList.json`に、削除しないスタックを設定します。
`deleteCfnStacks_BlockList.json`は、`StackName`,`Date`の2通りの設定方法があります。
`StackName`は`Name`タグの文字列に対し、前方一致するスタックが削除不可になります。
`Date`は、スタックの作成時刻が `Start`,`End`の日時の期間内にあるスタックが削除不可になります。

以下は`deleteCfnStacks_BlockList.json`の記載例


```json:deleteCfnStacks_BlockList.json
{
    "StackName" : 
        [
            "hoge",
            "fuga"
        ],
    "Date" : 
        [
            {"Start":"2021-07-05 09:35:00","End":"2021-07-05 09:35:59","note":"メモ１"},
            {"Start":"2020-07-04 00:00:00","End":"2020-08-04 23:59:59","note":"メモ２"}
        ]
}
```

上記の場合、以下条件のスタックが削除不可になります。

- スタック名が`hoge`から始まるスタック
- スタック名が`fuga`から始まるスタック
- 【2021-07-05 09:35:00 ～ 2021-07-05 09:35:59】 の期間内に作成したスタック
- 【2020-07-04 00:00:00 ～ 2020-08-04 23:59:59】 の期間内に作成したスタック


## 実行時に表示されるメッセージ例

例１）

```
PS C:\Users\user01\test> python deleteCfnStacks.py -f test
Python Version Check [OK] : sys.version_info(major=3, minor=9, micro=5, releaselevel='final', serial=0)
[BLOCK(Date)] test001-subnet1 は、ブロックリストによりブロックされました
[BLOCK(StackName)] test001-vpc は、ブロックリストによりブロックされました
[Dry-run:ON] スタック削除は実行しません
■-- 選定されたスタック --■
2021-07-04 09:36:27 test001-sg
■----------------------■
PS C:\Users\user01\test>
```

- 説明
    - `test`から始まるスタック名が対象になる
    - `-d False`オプションが無いためスタック削除しない(Dry-run有効)
    - ブロックリスト(Date)により、`test001-subnet1`スタックは削除しない
    - ブロックリスト(StackName)により、`test001-vpc`スタックは削除しない
    - スタック名 `test001-sg`が削除対象として選定された(Dry-run有効のため削除しない)


例２）

```
PS C:\Users\user01\test> python deleteCfnStacks.py -f test -d False
Python Version Check [OK] : sys.version_info(major=3, minor=9, micro=5, releaselevel='final', serial=0)
[BLOCK(Date)] test001-subnet1 は、ブロックリストによりブロックされました
[BLOCK(StackName)] test001-vpc は、ブロックリストによりブロックされました
[Dry-run:OFF] スタック削除を実行します
2021-07-04 09:36:27 test001-sg
{'ResponseMetadata': {'RequestId': 'aaaaaaaa-7777-7777-7777-777777777777', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'aaaaaaaa-7777-7777-7777-777777777777', 'content-type': 'text/xml', 'content-length': '212', 'date': 'Sun, 04 Jul 2021 12:08:34 GMT'}, 'RetryAttempts': 0}}
[LOG] CFn Delete Stack [test001-sg] start.
[LOG] CFn Delete Stack [test001-sg] end.
PS C:\Users\user01\test>
```

- 説明
    - 例１に`-d False`オプションを追記して実行
    - `-d False`オプションが有るためスタック削除する(Dry-run無効)