CloudFormationスタックセットをいい感じに削除する

ちょっと前にCloudFormationスタックセットを「いい感じ」に作ったので、今回はそれを「いい感じ」に削除します。


やりたいこと

  • 以下の記事で作った「いい感じ」に作ったCloudFormationスタックセットを、「いい感じ」に削除する

go-to-k.hatenablog.com


「いい感じ」に削除?

一括削除

今回の「いい感じに削除する」の「いい感じ」とはもうシンプルで、手動で何かをすることなく、作成したスタックセットを一括で削除することです。


前提

  • ここでいう一括とは、1つのスタックセット(複数のスタックインスタンス)を削除することです
  • スクリプト例では1アカウントに展開したスタックセットを前提にしています
  • 該当セットの全リージョンを削除するようにしています
    • 個別にリージョンを選択して削除する処理は本記事では対応しません
    • (こちらも少し変えれば簡単にできるかとは思います)


実装

GitHubにもあります。

github.com


スタックセット削除用関数

  • stack_sets_functions.sh
    • delete_stack_sets関数を呼び出せばスタックセットを削除できます
    • check_stack_set_operationは前回と同じコードです
    • 前回作成した、スタックセットをデプロイするdeploy_stack_setsは今回は省略しています
#!/bin/bash
set -eu

function check_stack_set_operation {
    local stack_set_name="$1"
    local operation_id="$2"
    local operation_region="$3"
    local profile="$4"

    if [ -z ${stack_set_name} ] \
        || [ -z ${operation_id} ] \
        || [ -z ${operation_region} ] \
        || [ -z ${profile} ]; then
        echo "Invalid options for check_stack_set_operation function"
        return 1
    fi

    while true;
    do
        local operation_status=$(aws cloudformation describe-stack-set-operation \
            --stack-set-name ${stack_set_name} \
            --operation-id ${operation_id} \
            --region ${operation_region} \
            --profile ${profile} \
            | jq -r .StackSetOperation.Status)

        echo "=== STATUS: ${operation_status} ==="

        if [ "${operation_status}" == "RUNNING" ]; then
            echo "Waiting for SUCCEEDED..."
            echo
            sleep 10
        elif [ "${operation_status}" == "SUCCEEDED" ]; then
            echo "SUCCESS."
            break
        else
            echo "!!!!!!!!!!!!!!!!!!!!!!!"
            echo "!!! Error Occurred. !!!"
            echo "!!!!!!!!!!!!!!!!!!!!!!!"
            return 1
        fi
    done
}

function delete_stack_sets {
    local stack_set_name="$1"
    local operation_region="$2"
    local profile="$3"

    if [ -z "${stack_set_name}" ] \
    || [ -z "${operation_region}" ] \
    || [ -z "${stack_set_type}" ] \
    || [ -z "${profile}" ]; then
        echo "Invalid options for delete_stack_sets function"
        return 1
    fi

    check_stack_exists=$(aws cloudformation describe-stack-set \
        --stack-set-name ${stack_set_name} \
        --region ${operation_region} \
        --profile ${profile} 2>&1 >/dev/null || true)

    if [ -n "${check_stack_exists}" ]; then
        echo "not exists stack sets!"
        echo
        return 1
    else
        stack_instances_regions=$(aws cloudformation list-stack-instances \
            --stack-set-name ${stack_set_name} \
            --region ${operation_region} \
            --query "Summaries[].Region" \
            --output text \
            --profile ${profile} \
            2>/dev/null \
            | sed -e "s/\t/ /g" \
            || true \
        )

        account_id=$(aws sts get-caller-identity --query "Account" --output text --profile ${profile})

        echo "delete stack instances..."
        echo

        operation_id=$(aws cloudformation delete-stack-instances \
            --stack-set-name ${stack_set_name} \
            --accounts ${account_id} \
            --regions ${stack_instances_regions} \
            --no-retain-stacks \
            --operation-preferences MaxConcurrentCount=1 \
            --region ${operation_region} \
            --query "OperationId" \
            --output text \
            --profile ${profile})
            
        check_stack_set_operation "${stack_set_name}" "${operation_id}" "${operation_region}" "${profile}"

        echo "delete stack sets..."
        echo

        aws cloudformation delete-stack-set \
            --stack-set-name ${stack_set_name} \
            --region ${operation_region} \
            --query "OperationId" \
            --output text \
            --profile ${profile}
    fi

    echo "Finished."
}


呼び出し元

  • サンプルシェル(delete_stack_sets.sh) -delete_stack_sets関数を呼び出す
#!/bin/bash
set -eu

cd $(dirname $0)
. ./stack_sets_functions.sh

PROFILE=""

while getopts p: OPT; do
    case $OPT in
        p)
            PROFILE="$OPTARG"
            ;;
    esac
done

if [ -z ${PROFILE} ]; then
    echo "required PROFILE"
    exit 1
fi

CFN_STACK_SET_NAME="SNSForStacksets"
OPERATION_REGION="us-east-1"

delete_stack_sets "${CFN_STACK_SET_NAME}" "${OPERATION_REGION}" "${PROFILE}" 


  • サンプルシェル実行
sh delete_stack_sets.sh -p my_profile


解説

基本的には前回の記事で作成したものをベースにしているので省略します。前回の記事にはしっかり解説を書いてありますのでそちらをご覧頂ければ幸いです。

※特徴としては、全スタックインスタンスの削除が終わるのを、waitに該当する処理を実装して待機することで、スクリプトで一括削除が可能になっています。


また、CloudFormation APIdelete-stack-instancesで、create-stack-instancesと同じく--operation-preferencesがありMaxConcurrentCountFailureToleranceCountなどを指定するのですが、詳細は公式ドキュメントをご覧下さい。

ざっくりいうと複数アカウントに展開したスタックセットに対する同時実行アカウント数の最大値、失敗時に終了する閾値のオプションです。

docs.aws.amazon.com


最後に

一括で「いい感じ」に作成するスクリプトを作ったので、削除するスクリプトも必要だなということで作ってみました。

展開したスタックセットを削除したくなったときには便利です。