【CloudFormation】AWS CLIで変更セットを作成してマネジメントコンソールで確認・展開する

2024.02.05

CloudFormationスタックを新規作成または更新する際は、 変更セットを事前に作成して、確認したいケースが多いと思います。 この一連の流れを AWS CLI で全て実現しようと思うと、create-change-set および、describe-change-set を使うことになります。

ただ、変更セットの確認(describe-change-set) を ターミナル上で見るには辛く、見やすくするために作り込みが必要です(※)。 できれば変更セットの確認は、マネジメントコンソール上で確認したいです。

そこで今回は「変更セットの作成」までをAWS CLIで実施して、 「変更セットの確認(〜展開)」をマネジメントコンソールで実施する方法を 考えてみます。

※ ちなみに rain というツールを使うと 作り込み無く、変更セットの確認もターミナル上で見やすく実施できます。

AWS CLI で変更セットを作成する

変更セットの作成は aws cloudformation create-change-set コマンドで実施します。

以下 3パターン、それぞれでサンプルコマンドを紹介します。

  • 新規スタックを作成する前の変更セット
  • 既存スタックを更新する前の変更セット(パラメータ更新のみ)
  • 既存スタックを更新する前の変更セット(テンプレート更新含む)

新規スタックを展開する前の変更セット

例としてSNSトピックを作成するCFnテンプレートを使って、 スタックを展開していきます。

以下のようなコマンドを実行します。 --change-set-type CREATE 指定が必要です。

### ファイルのパス、スタック名
file_path="./example-sns-topic.yaml"
stack_name="example-sns-topic"

### パラメータ
SNSTopicName="example-sns-topic"
EmailAddress="example@example.com"

### 変更セットの作成
change_set_name="change-set-$(date +%Y%m%d-%H%M%S)"
aws cloudformation create-change-set --output json \
  --stack-name "${stack_name}" \
  --change-set-name "${change_set_name}" \
  --change-set-type "CREATE" \
  --template-body "file://${file_path}" \
  --parameters \
    ParameterKey=SNSTopicName,ParameterValue="${SNSTopicName}" \
    ParameterKey=EmailAddress,ParameterValue="${EmailAddress}"
# {
#     "Id": "arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/change-set-20240204-095158/ab6943d1-0a71-4cda-ab40-a5109fa32fb2",
#     "StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/example-sns-topic/99d41db0-c2f7-11ee-9619-0ad70eb931c9"
# }

マネジメントコンソール上で "change-set-xxxx" が作成されていることを確認しました。

img

img

既存スタックを更新する前の変更セット(パラメータ更新のみ)

既存スタックを更新する際は create-change-set にて --change-set-type UPDATE を指定します。

パラメータ更新のみの場合は、以下のようなコマンドになります。

### ファイルのパス、スタック名
stack_name="example-sns-topic"

### 更新したいパラメータ
EmailAddress="example-ver2@example.com"

### 変更セットの作成
change_set_name="change-set-$(date +%Y%m%d-%H%M%S)"
aws cloudformation create-change-set --output json \
  --stack-name "${stack_name}" \
  --change-set-name "${change_set_name}" \
  --change-set-type "UPDATE" \
  --use-previous-template \
  --parameters \
    ParameterKey=SNSTopicName,UsePreviousValue=true \
    ParameterKey=EmailAddress,ParameterValue="${EmailAddress}"

# {
#     "Id": "arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/change-set-20240204-100114/f4a0d669-5e16-438c-a37d-7ee03c833c99",
#     "StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/example-sns-topic/99d41db0-c2f7-11ee-9619-0ad70eb931c9"
# }

こちらも変更セットが確認できましたね。

img

既存スタックを更新する前の変更セット(テンプレート更新)

最後にテンプレート更新のコマンド例です。 --change-set-type UPDATE に加えて、 --no-use-previous-template オプションを指定します。

### ファイルのパス、スタック名
file_path="./example-sns-topic-ver2.yaml"
stack_name="example-sns-topic"

### 変更セットの作成
change_set_name="change-set-$(date +%Y%m%d-%H%M%S)"
aws cloudformation create-change-set --output json \
  --stack-name "${stack_name}" \
  --change-set-name "${change_set_name}" \
  --change-set-type "UPDATE" \
  --no-use-previous-template \
  --template-body "file://${file_path}" \
  --parameters \
    ParameterKey=SNSTopicName,UsePreviousValue=true \
    ParameterKey=EmailAddress,UsePreviousValue=true
# {
#     "Id": "arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/change-set-20240204-100630/0e92f7ca-53ef-4ba0-af00-27dd7ad96b64",
#     "StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/example-sns-topic/99d41db0-c2f7-11ee-9619-0ad70eb931c9"
# }

こちらも同じく変更セット作成を確認できました。

img

マネジメントコンソールで変更セットを確認する

変更セットURLの形式について

変更セットのURLは以下のような形式です。(見やすくするために改行で区切っています)

https://ap-northeast-1.console.aws.amazon.com/cloudformation/home
?region=ap-northeast-1#/stacks/changesets/changes
?stackId=${スタックIDをURLエンコードしたもの}
&changeSetId=${変更セットIDをURLエンコードしたもの}

スタックIDおよび変更セットIDは以下のような形式です。

  • スタックID: arn:aws:cloudformation:ap-northeast-1:123456789012:stack/example-sns-topic/11aa22bb-1111-2222-3333-0ha1example
  • 変更セットID: arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/change-set-xxxx/aa11bb22-1111-2222-3333-a510example

URLエンコードする場合、以下変換が必要になります。

  • :%3A へ変換
  • /%2F へ変換

CLI結果からURLを作成してブラウザへアクセス

create-change-set の返り値に スタックID( StackId ) および 変更セットID( Id ) が含まれます。 それらIDを使ってコマンドラインから マネジメントコンソールへアクセスします。

例えば「新規スタックを作成する前の変更セット」にて、 変更セット作成後にマネジメントコンソールへアクセスするには 以下のようなコマンドを実行します。

### ファイルのパス、スタック名
file_path="./example-sns-topic.yaml"
stack_name="example-sns-topic"

### パラメータ
SNSTopicName="example-sns-topic"
EmailAddress="example@example.com"

### 変更セットの作成
change_set_name="change-set-$(date +%Y%m%d-%H%M%S)"
cli_response=$(aws cloudformation create-change-set --output json \
  --stack-name "${stack_name}" \
  --change-set-name "${change_set_name}" \
  --change-set-type "CREATE" \
  --template-body "file://${file_path}" \
  --parameters \
    ParameterKey=SNSTopicName,ParameterValue="${SNSTopicName}" \
    ParameterKey=EmailAddress,ParameterValue="${EmailAddress}")

### マネジメントコンソールで変更セットを確認
# 変更セットIDのURLエンコード
change_set_id_encoded=$(echo "${cli_response}" \
  | jq -r ".Id"      | sed -e 's/:/%3A/g' | sed -e 's/\//%2F/g')
# スタックIDのURLエンコード
stack_id_encoded=$(echo "${cli_response}" \
  | jq -r ".StackId" | sed -e 's/:/%3A/g' | sed -e 's/\//%2F/g')
# コンソールURLを生成
console_url="https://ap-northeast-1.console.aws.amazon.com/cloudformation/home\
?region=ap-northeast-1#/stacks/changesets/changes\
?stackId=${stack_id_encoded}\
&changeSetId=${change_set_id_encoded}"
# コンソールURLをブラウザで開く(macOSの場合 open コマンド)
open "${console_url}"

img

コードのハイライト部分が主な追記点です。 コンソールURLを create-change-set 結果から組み立てて ブラウザで開きます。

Tips: mac環境であれば、 open "URL" を使って楽にブラウザを開けます。 (PowerShell の場合は Start-Process "URL" )

おわりに

以上、変更セットを手早くマネコンで確認するための試みでした。

個人的には rain がイケているので、可能であればこちらを使いたいです。 制約がありrainを活用できない場合は、本記事が参考になるかもしれません。

参考