CloudFormation を AWS CLI で操作するときの基本は、「aws cloudformation deploy でスタックの作成と更新を1つのコマンドにまとめ、中身を先に確かめたいときだけ変更セット(change set)を挟む」ことです。スタックとは、テンプレートから作られたリソースのまとまりのことです。

この記事では、deploy / create-stack / update-stack / create-change-set の違いを比較表にしたうえで、検証 → 作成 → 変更セットの確認 → 実行 → 削除を、コマンドと出力つきで順番に通します。あわせて、スタックの状態ごとに「次に打つコマンド」を一覧にし、よく出会う3つのエラー文への対処もまとめます。

確認環境:Ubuntu 24.04、AWS CLI 1.46.1(Python 3.11)。AWS の API をローカルで再現するツール(moto 5.2.3)で実行しました。掲載するコマンドは、接続先の指定を外して、AWS でそのまま使える形にしています。

CloudFormation CLI の早見表

4つのコマンドの違い

項目 deploy create-stack update-stack create-change-set
できること 作成と更新の両方 作成だけ 更新だけ 変更内容の下書きを作る
スタックが無いとき 新しく作る 新しく作る エラーになる --change-set-type CREATE で作成用の下書き
スタックが有るとき 更新する エラーになる 更新する 更新用の下書き(既定は UPDATE)
完了まで待つか 待つ(進み具合を表示) 待たない(StackId を返してすぐ戻る) 待たない 待たない
リソースが変わる時点 コマンドの中で変更セットを作って実行した時点 受け付けた直後から 受け付けた直後から execute-change-set を打つまで変わらない
テンプレートの渡し方 --template-file パス --template-body file://パス または --template-url 同左、または --use-previous-template create-stack と同じ
パラメータの渡し方 --parameter-overrides Key=Value --parameters ParameterKey=K,ParameterValue=V 同左(UsePreviousValue=true も可) create-stack と同じ
指定しなかったパラメータ(更新時) いまの値を引き継ぐ ― 明示が必要 明示が必要
向いている場面 日常の反映、CI からの反映 作成だけを厳密に行いたいとき 更新だけを厳密に行いたいとき 反映前に差分を確かめたいとき

迷ったら deploy、差分を見てから反映したいときは deploy --no-execute-changeset か create-change-set と覚えておくと選びやすくなります。

やりたいこと別のコマンド

やりたいこと コマンド
テンプレートの文法を確かめる aws cloudformation validate-template --template-body file://queue.yaml
作成または更新する aws cloudformation deploy --template-file queue.yaml --stack-name task-stack
差分だけ作って止める aws cloudformation deploy ... --no-execute-changeset
変更セットを自分で作る aws cloudformation create-change-set --stack-name task-stack --change-set-name 名前 ...
変更セットの中身を見る aws cloudformation describe-change-set --stack-name task-stack --change-set-name 名前
変更セットを実行する aws cloudformation execute-change-set --stack-name task-stack --change-set-name 名前
状態を見る aws cloudformation describe-stacks --stack-name task-stack --query "Stacks[0].StackStatus"
うまくいかなかった理由を見る aws cloudformation describe-stack-events --stack-name task-stack --query "StackEvents[?ends_with(ResourceStatus,'_FAILED')].[LogicalResourceId,ResourceStatusReason]" --output text
完了まで待つ aws cloudformation wait stack-create-complete --stack-name task-stack
削除する aws cloudformation delete-stack --stack-name task-stack

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CloudFormationをAWS CLIで操作|deployと変更セット」

一連の流れを図で見る

flowchart LR
  A[validate-template<br>文法を確かめる] --> B[deploy<br>スタックを作る]
  B --> C[create-change-set<br>変更の下書き]
  C --> D[describe-change-set<br>中身を確かめる]
  D --> E[execute-change-set<br>反映する]
  E --> F[delete-stack<br>片付ける]

以降は、この順番で実際に動かしていきます。

準備:サンプルのテンプレート

SQS のキューを1つ作るテンプレートです。queue.yaml という名前で保存します。パラメータは環境名(Env)と可視性タイムアウト(Timeout)の2つです。

AWSTemplateFormatVersion: "2010-09-09"
Description: Task queue sample
Parameters:
  Env:
    Type: String
    Default: dev
  Timeout:
    Type: Number
    Default: 30
Resources:
  TaskQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: !Sub "task-queue-${Env}"
      VisibilityTimeout: !Ref Timeout
Outputs:
  QueueUrl:
    Value: !Ref TaskQueue

手順1:validate-template でテンプレートを検証する

スタックを作る前に、テンプレートが読み取れる形になっているかを確かめます。--query Description を付けると、説明文だけが返るので、通ったことがひと目で分かります。

aws cloudformation validate-template --template-body file://queue.yaml --query Description
"Task queue sample"

ローカルのファイルを渡すときは file:// を付けます。付け忘れると、ファイル名そのものがテンプレートの中身として送られます。

validate-template が確かめるのは、テンプレートの書式です。リソースのプロパティの値が受け付けられるかどうかは、実際に作成するときに決まります。

手順2:deploy でスタックを作成する

aws cloudformation deploy \
  --template-file queue.yaml \
  --stack-name task-stack \
  --parameter-overrides Env=dev \
  --tags Team=platform
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - task-stack

出力から分かるとおり、deploy は内部で変更セットを作り、それを実行し、完了まで待ちます。スタックが無ければ作成、有れば更新になるので、同じコマンドを何度でも使えます。

deploy でよく使うオプション

オプション 役割
--template-file テンプレートのパス(必須)
--stack-name スタック名(必須)
--parameter-overrides Key=Value ... パラメータの値。更新時に書かなかったものは、いまの値を引き継ぐ
--capabilities CAPABILITY_NAMED_IAM IAM リソースを作るテンプレートで必要な確認
--no-execute-changeset 変更セットを作るところで止める
--no-fail-on-empty-changeset 変更が無いときも終了コード 0 で終える
--tags Key=Value ... スタックに付けるタグ。対応しているリソースにも引き継がれる
--s3-bucket テンプレートのアップロード先。51,200 バイトを超えるテンプレートで必要
--role-arn 変更セットの実行時に CloudFormation が使うロール
--disable-rollback 途中で止まったとき、作成済みのリソースを残す

作成された内容を確かめる

aws cloudformation describe-stacks --stack-name task-stack \
  --query "Stacks[0].{Status:StackStatus,Params:Parameters,Tags:Tags}"
{
    "Status": "CREATE_COMPLETE",
    "Params": [
        {
            "ParameterKey": "Env",
            "ParameterValue": "dev"
        },
        {
            "ParameterKey": "Timeout",
            "ParameterValue": "30"
        }
    ],
    "Tags": [
        {
            "Key": "Team",
            "Value": "platform"
        }
    ]
}

スタックに含まれるリソースは list-stack-resources で一覧にできます。

aws cloudformation list-stack-resources --stack-name task-stack --output text \
  --query "StackResourceSummaries[].[LogicalResourceId,ResourceType,PhysicalResourceId,ResourceStatus]"
TaskQueue   AWS::SQS::Queue https://sqs.ap-northeast-1.amazonaws.com/123456789012/task-queue-dev    CREATE_COMPLETE

手順3:変更セットを作って中身を確かめる

変更セットは、「この内容で更新すると、どのリソースがどう変わるか」をまとめた下書きです。作っただけではリソースは変わりません。ここでは Timeout を 30 から 60 に変える下書きを作ります。

aws cloudformation create-change-set \
  --stack-name task-stack \
  --change-set-name timeout-60 \
  --change-set-type UPDATE \
  --template-body file://queue.yaml \
  --parameters ParameterKey=Env,ParameterValue=dev ParameterKey=Timeout,ParameterValue=60
{
    "Id": "arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/timeout-60/c491a6bd-b096-4a6c-8174-ff7c64a07d46",
    "StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/task-stack/6c7c592c-11f3-4bf5-ac27-de54e3f83120"
}

--change-set-type は CREATE(新規作成用)、UPDATE(更新用)、IMPORT(既存リソースの取り込み用)から選びます。

変更セットの作成は少し時間がかかるので、wait で待ってから中身を見ます。

aws cloudformation wait change-set-create-complete \
  --stack-name task-stack --change-set-name timeout-60

aws cloudformation describe-change-set \
  --stack-name task-stack --change-set-name timeout-60 \
  --query "{Status:Status,ExecutionStatus:ExecutionStatus,Parameters:Parameters}"
{
    "Status": "CREATE_COMPLETE",
    "ExecutionStatus": "AVAILABLE",
    "Parameters": [
        {
            "ParameterKey": "Env",
            "ParameterValue": "dev"
        },
        {
            "ParameterKey": "Timeout",
            "ParameterValue": "60"
        }
    ]
}

Status が CREATE_COMPLETE、ExecutionStatus が AVAILABLE になっていれば実行できます。

Changes の読み方

describe-change-set の出力には Changes という配列があり、リソースごとの変更が入ります。AWS CLI のリファレンスに載っている例は次の形です。

{
    "Type": "Resource",
    "ResourceChange": {
        "Action": "Modify",
        "LogicalResourceId": "function",
        "PhysicalResourceId": "my-function-SEZV4XMPL4S5",
        "ResourceType": "AWS::Lambda::Function",
        "Replacement": "False",
        "Scope": [
            "Properties"
        ],
        "Details": [
            {
                "Target": {
                    "Attribute": "Properties",
                    "Name": "Timeout",
                    "RequiresRecreation": "Never"
                },
                "Evaluation": "Static",
                "ChangeSource": "DirectModification"
            }
        ]
    }
}
項目 値 意味
Action Add / Modify / Remove / Import / Dynamic 追加・変更・削除・取り込み・実行時に決まる
Replacement True / False / Conditional True はリソースを作り直す。False はそのまま変更する
Scope Properties / Metadata / Tags など どの部分が変わるか
Details の Target.Name プロパティ名 変わるプロパティ
Details の RequiresRecreation Never など そのプロパティの変更で作り直しが必要か

実行前に必ず見たいのは Action が Remove の行と、Replacement が True の行です。どちらも既存のリソースが無くなる変更なので、データを持つリソースでは特に確認します。この2つだけを抜き出す式は次のとおりです。

aws cloudformation describe-change-set \
  --stack-name task-stack --change-set-name timeout-60 \
  --query "Changes[?ResourceChange.Action=='Remove' || ResourceChange.Replacement=='True'].ResourceChange.[Action,LogicalResourceId,ResourceType,Replacement]" \
  --output text

Status と ExecutionStatus の値

項目 値 意味
Status CREATE_PENDING / CREATE_IN_PROGRESS 作成中
Status CREATE_COMPLETE 作成できた
Status FAILED 作成できなかった(StatusReason に理由)
ExecutionStatus AVAILABLE 実行できる
ExecutionStatus UNAVAILABLE 実行できない
ExecutionStatus EXECUTE_IN_PROGRESS / EXECUTE_COMPLETE / EXECUTE_FAILED 実行中/実行済み/実行が止まった
ExecutionStatus OBSOLETE スタックが別の変更で先に更新された

手順4:execute-change-set で反映する

aws cloudformation execute-change-set \
  --stack-name task-stack --change-set-name timeout-60

aws cloudformation wait stack-update-complete --stack-name task-stack

どちらも、うまくいくと何も表示せずに終わります。状態とパラメータを1行で確かめます。

aws cloudformation describe-stacks --stack-name task-stack --output text \
  --query "Stacks[0].[StackStatus,Parameters[?ParameterKey=='Timeout'].ParameterValue|[0]]"
UPDATE_COMPLETE 60

キューの設定も変わっています。

aws sqs get-queue-attributes \
  --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/task-queue-dev \
  --attribute-names VisibilityTimeout
{
    "Attributes": {
        "VisibilityTimeout": "60"
    }
}

deploy で変更セットだけを作る

deploy に --no-execute-changeset を付けると、変更セットを作ったところで止まり、確認用のコマンドを表示してくれます。次の出力は、新しいスタック名に対して実行したときのものです。

aws cloudformation deploy --template-file queue.yaml --stack-name task-stack --no-execute-changeset
Waiting for changeset to be created..
Changeset created successfully. Run the following command to review changes:
aws cloudformation describe-change-set --change-set-name arn:aws:cloudformation:ap-northeast-1:123456789012:changeSet/awscli-cloudformation-package-deploy-1791180361/c0a7dce9-0ffa-45ec-96f5-bde445fe16e2

表示された describe-change-set で中身を確かめ、同じ ARN を execute-change-set --change-set-name に渡せば反映できます。新しいスタックに対してこの形で止めると、スタックは REVIEW_IN_PROGRESS という状態で残ります。使わないと決めたら delete-stack で片付けます。

update-stack で更新する場合

変更セットを挟まずに、すぐ更新する方法です。テンプレートを変えないときは --use-previous-template、値を変えないパラメータには UsePreviousValue=true が使えます。

aws cloudformation update-stack \
  --stack-name task-stack \
  --use-previous-template \
  --parameters ParameterKey=Env,UsePreviousValue=true ParameterKey=Timeout,ParameterValue=45
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/task-stack/6c7c592c-11f3-4bf5-ac27-de54e3f83120"
}

update-stack は StackId を返してすぐ戻るので、完了は wait で待ちます。

aws cloudformation wait stack-update-complete --stack-name task-stack
aws cloudformation describe-stacks --stack-name task-stack --output text \
  --query "Stacks[0].[StackStatus,Parameters[?ParameterKey=='Timeout'].ParameterValue|[0]]"
UPDATE_COMPLETE 45

create-stack で作成する場合

create-stack は、同じ名前のスタックがすでに有るとエラーになります。「新規作成のつもりが既存のスタックを更新していた」という取り違えを避けたいときに向いています。

aws cloudformation create-stack \
  --stack-name task-stack-stg \
  --template-body file://queue.yaml \
  --parameters ParameterKey=Env,ParameterValue=stg

aws cloudformation wait stack-create-complete --stack-name task-stack-stg
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/task-stack-stg/ce2e4ca9-3c76-4d1a-ad8c-47c09d57dbda"
}

テンプレートの Outputs に書いた値は、describe-stacks で取り出せます。

aws cloudformation describe-stacks --stack-name task-stack-stg --query "Stacks[0].Outputs"
[
    {
        "OutputKey": "QueueUrl",
        "OutputValue": "https://sqs.ap-northeast-1.amazonaws.com/123456789012/task-queue-stg"
    }
]

スタックの一覧は list-stacks です。--stack-status-filter で状態を絞れます。

aws cloudformation list-stacks \
  --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE \
  --query "StackSummaries[].[StackName,StackStatus]" --output text
task-stack  UPDATE_COMPLETE
task-stack-stg  CREATE_COMPLETE

手順5:delete-stack で削除する

aws cloudformation delete-stack --stack-name task-stack
aws cloudformation wait stack-delete-complete --stack-name task-stack

どちらも出力はありません。削除が終わると、スタック名での describe-stacks は次のエラーを返します。これは削除できたことの確認になります。

aws cloudformation describe-stacks --stack-name task-stack
An error occurred (ValidationError) when calling the DescribeStacks operation: Stack with id task-stack does not exist

削除済みのスタックは、list-stacks に状態を指定すると見られます。

aws cloudformation list-stacks --stack-status-filter DELETE_COMPLETE \
  --query "StackSummaries[].[StackName,StackStatus]" --output text
task-stack  DELETE_COMPLETE
task-stack-stg  DELETE_COMPLETE

delete-stack は確認を求めずに受け付けられます。打つ前に、スタック名と、接続先のアカウント・リージョンを見直す習慣を付けておくと安心です。

スタック状態の一覧と「次に打つコマンド」

状態名は、AWS CloudFormation ユーザーガイドの状態コード一覧に沿っています。

作成まわり

状態 意味 次に打つコマンド
CREATE_IN_PROGRESS 作成中 aws cloudformation wait stack-create-complete --stack-name S
CREATE_COMPLETE 作成できた そのまま使える
CREATE_FAILED 作成が止まった(--disable-rollback で作成済みリソースを残したとき) describe-stack-events で理由を確認 → 直して update-stack か deploy、戻すなら rollback-stack、やり直すなら delete-stack
ROLLBACK_IN_PROGRESS 作成を取り消し中 終わるまで待つ
ROLLBACK_COMPLETE 作成が止まり、作りかけのリソースを片付け終えた。この状態で行える操作は削除だけ describe-stack-events で理由を控える → delete-stack → テンプレートを直して作り直す
ROLLBACK_FAILED 取り消しの途中で止まった describe-stack-events で理由を確認 → delete-stack
REVIEW_IN_PROGRESS 作成用の変更セットだけがある(リソースはまだ無い) execute-change-set で作成、使わないなら delete-stack

更新まわり

状態 意味 次に打つコマンド
UPDATE_IN_PROGRESS 更新中 wait stack-update-complete。止めたいときは cancel-update-stack
UPDATE_COMPLETE_CLEANUP_IN_PROGRESS 更新は済み、置き換え前のリソースを片付け中 待つ(スタックはもう使える)
UPDATE_COMPLETE 更新できた そのまま使える
UPDATE_FAILED 更新が止まった(--disable-rollback を付けたとき) 理由を確認 → 直して update-stack、戻すなら rollback-stack
UPDATE_ROLLBACK_IN_PROGRESS 更新前の状態へ戻している 待つ
UPDATE_ROLLBACK_COMPLETE 更新前の状態に戻った(スタックは使える) 理由を確認 → テンプレートを直してもう一度 deploy
UPDATE_ROLLBACK_FAILED 更新前の状態へ戻す途中で止まった。更新はできない 原因を直して continue-update-rollback --stack-name S。戻せないリソースは --resources-to-skip 論理ID で飛ばす

削除・取り込みまわり

状態 意味 次に打つコマンド
DELETE_IN_PROGRESS 削除中 wait stack-delete-complete
DELETE_COMPLETE 削除できた(一覧には 90 日間残る) 何もしなくてよい
DELETE_FAILED 削除できないリソースがあって止まった 理由を確認 → もう一度 delete-stack。残したいリソースは delete-stack --retain-resources 論理ID
IMPORT_IN_PROGRESS / IMPORT_COMPLETE 既存リソースの取り込み中/取り込みできた 待つ/そのまま使える
IMPORT_ROLLBACK_IN_PROGRESS / IMPORT_ROLLBACK_COMPLETE / IMPORT_ROLLBACK_FAILED 取り込みを取り消し中/取り消した/取り消しの途中で止まった describe-stack-events で理由を確認

名前に ROLLBACK が付く状態のうち、スタックをそのまま使えるのは UPDATE_ROLLBACK_COMPLETE だけです。ROLLBACK_COMPLETE(先頭に UPDATE が付かないほう)は、最初の作成が通らなかったことを表すので、削除して作り直します。

describe-stack-events から理由だけを抜く1行

スタックの出来事は describe-stack-events に時刻の新しい順で並びます。うまくいかなかった理由は、ResourceStatus が _FAILED で終わる行の ResourceStatusReason に入っています。そこで、その行だけを --query で抜きます。

aws cloudformation describe-stack-events --stack-name task-stack \
  --query "StackEvents[?ends_with(ResourceStatus,'_FAILED')].[LogicalResourceId,ResourceStatus,ResourceStatusReason]" \
  --output text

式の働きが分かるように、説明用に用意したイベントのデータ(events.json)に同じ式を当ててみます。キューは作れたものの、ロールの作成で止まり、取り消された、という並びです。

{"StackEvents":[
 {"Timestamp":"2026-10-05T06:10:09Z","LogicalResourceId":"task-stack","ResourceStatus":"ROLLBACK_COMPLETE"},
 {"Timestamp":"2026-10-05T06:10:07Z","LogicalResourceId":"TaskQueue","ResourceStatus":"DELETE_COMPLETE"},
 {"Timestamp":"2026-10-05T06:10:05Z","LogicalResourceId":"task-stack","ResourceStatus":"ROLLBACK_IN_PROGRESS","ResourceStatusReason":"The following resource(s) failed to create: [AppRole]."},
 {"Timestamp":"2026-10-05T06:10:04Z","LogicalResourceId":"AppRole","ResourceStatus":"CREATE_FAILED","ResourceStatusReason":"(sample) role name app-role is already in use"},
 {"Timestamp":"2026-10-05T06:10:03Z","LogicalResourceId":"TaskQueue","ResourceStatus":"CREATE_COMPLETE"},
 {"Timestamp":"2026-10-05T06:10:01Z","LogicalResourceId":"task-stack","ResourceStatus":"CREATE_IN_PROGRESS","ResourceStatusReason":"User Initiated"}
]}

AWS CLI の --query と同じ JMESPath ライブラリで評価します。

import json, jmespath

events = json.load(open("events.json"))
expr = "StackEvents[?ends_with(ResourceStatus,'_FAILED')].[LogicalResourceId,ResourceStatus,ResourceStatusReason]"
for row in jmespath.search(expr, events):
    print("\t".join(row))
AppRole CREATE_FAILED   (sample) role name app-role is already in use

6行のうち、原因の1行だけが残りました。複数のリソースが止まったときは、いちばん下(最初に起きたもの)が出発点であることが多いので、最後の1件だけを取る形も便利です。

aws cloudformation describe-stack-events --stack-name task-stack --output text \
  --query "StackEvents[?ends_with(ResourceStatus,'_FAILED')] | [-1].ResourceStatusReason"

エラー文ごとの対処

No updates are to be performed

テンプレートにもパラメータにも、いまのスタックとの違いが無いときに出ます。直すところがあるわけではなく、「反映するものが無い」という知らせです。

状況 対処
本当に変更が無い そのままでよい
CI で deploy が 0 以外の終了コードになり、後続が止まる --no-fail-on-empty-changeset を付ける
変えたつもりの箇所が反映されない 下の「更新として扱われない変更」を確認する

deploy の場合、変更が無いと「No changes to deploy. Stack スタック名 is up to date」と表示されます。このときの終了コードは CLI の版で既定が異なります。

AWS CLI 変更が無いときの既定 切り替え
1.46.1(v1) 0 以外の終了コード --no-fail-on-empty-changeset で 0 にする
v2 のリファレンス 0 --fail-on-empty-changeset で 0 以外にする

v1 の既定は、インストールされている AWS CLI 1.46.1 のヘルプ文(By default, a non-zero exit code is returned)で、v2 の既定は AWS CLI コマンドリファレンスの deploy のページで確かめました。どちらの版でも同じ動きにしたいときは、オプションを明示しておくと揃います。

更新として扱われない変更もあります。CloudFormation のトラブルシューティングのページによると、削除ポリシー、更新ポリシー、条件の宣言、出力の宣言だけを変えた場合は更新と見なされないことがあります。そのような変更だけを反映したいときは、いずれかのリソースのメタデータ属性を追加または変更します。

Requires capabilities

テンプレートに IAM のリソース(ロール、ポリシー、ユーザーなど)が含まれているのに、--capabilities を付けていないときに出ます。権限に関わるリソースを作ることを、利用者が分かったうえで実行していると示すための確認です。

テンプレートの内容 付けるオプション
IAM リソースを含む(名前は自動) --capabilities CAPABILITY_IAM または CAPABILITY_NAMED_IAM
IAM リソースに独自の名前(RoleName など)を付けている --capabilities CAPABILITY_NAMED_IAM

エラー文の角かっこの中に、必要な値がそのまま書かれているので、それを付けて打ち直します。

aws cloudformation deploy \
  --template-file role.yaml \
  --stack-name role-stack \
  --capabilities CAPABILITY_NAMED_IAM

create-stack、update-stack、create-change-set でも同じオプションが使えます。独自の名前を付けた IAM リソースは、アカウントの中で名前が重ならないようにする必要があるため、同じテンプレートから複数のスタックを作るときは、名前にパラメータを含めるか、名前を自動に任せます。

ROLLBACK_COMPLETE state and can not be updated

最初の作成が通らなかったスタックに、もう一度 deploy や update-stack をしたときに出ます。ROLLBACK_COMPLETE のスタックは、作りかけのリソースを片付け終えた「抜け殻」のような状態で、ユーザーガイドにも「この状態で行える操作は削除だけ」と書かれています。

対処は3ステップです。

# 1. 理由を控える(削除の前に)
aws cloudformation describe-stack-events --stack-name task-stack --output text \
  --query "StackEvents[?ends_with(ResourceStatus,'_FAILED')].[LogicalResourceId,ResourceStatusReason]"

# 2. スタックを削除して、終わるまで待つ
aws cloudformation delete-stack --stack-name task-stack
aws cloudformation wait stack-delete-complete --stack-name task-stack

# 3. テンプレートやパラメータを直して、もう一度作成する
aws cloudformation deploy --template-file queue.yaml --stack-name task-stack

2 の削除と待機は、この記事の手順5 で出力を確かめたものと同じコマンドです。

CI で繰り返し反映する場合は、deploy の前に状態を調べ、ROLLBACK_COMPLETE のときだけ削除するようにしておくと、手で片付ける手間が減ります。

status=$(aws cloudformation describe-stacks --stack-name task-stack \
  --query "Stacks[0].StackStatus" --output text 2>/dev/null)
if [ "$status" = "ROLLBACK_COMPLETE" ]; then
  aws cloudformation delete-stack --stack-name task-stack
  aws cloudformation wait stack-delete-complete --stack-name task-stack
fi

なお、更新が通らなかったときの UPDATE_ROLLBACK_COMPLETE は別物で、こちらは更新前の内容に戻っているため、削除せずにそのまま deploy し直せます。

つまずきやすい点のチェックリスト

確認すること 理由
--template-body に file:// を付けたか 付けないとファイル名が中身として送られる
deploy には --template-file、create-stack には --template-body コマンドごとにオプション名が違う
パラメータの書式は合っているか deploy は Key=Value、ほかは ParameterKey=K,ParameterValue=V
update-stack で全パラメータを指定したか 変えないものは UsePreviousValue=true
create-stack / update-stack のあとに wait を入れたか StackId が返った時点では、まだ処理の途中
変更セットの Remove と Replacement: True を見たか 既存のリソースが無くなる変更
IAM を含むテンプレートに --capabilities を付けたか 付けないと Requires capabilities になる
削除の前にスタック名とリージョンを見直したか delete-stack は確認なしで受け付けられる

よくある質問

Q. deploy と create-stack は、どちらを使えばよいですか? A. 日常の反映には deploy が向いています。作成と更新を同じコマンドで行え、完了まで待ってくれるためです。「必ず新規作成であること」を保証したいときは create-stack、差分を見てから反映したいときは変更セットを使います。

Q. 変更セットを作ると、リソースに影響しますか? A. 変更セットを作っただけでは、リソースは変わりません。execute-change-set を打ったときに初めて反映されます。使わない変更セットは aws cloudformation delete-change-set で片付けられます。

Q. deploy のパラメータを毎回すべて書く必要はありますか? A. 更新のときは、書かなかったパラメータはいまの値を引き継ぎます。新しく作るときは、Default の無いパラメータを必ず指定します。

Q. ROLLBACK_COMPLETE と UPDATE_ROLLBACK_COMPLETE の違いは何ですか? A. ROLLBACK_COMPLETE は最初の作成が通らなかった状態で、削除して作り直します。UPDATE_ROLLBACK_COMPLETE は更新が通らず更新前に戻った状態で、スタックはそのまま使え、直してからもう一度更新できます。

まとめ

  • 日常の反映は deploy。作成と更新を1つのコマンドで行い、完了まで待つ
  • 差分を先に見たいときは変更セット。create-change-set → describe-change-set → execute-change-set の順
  • 変更セットでは Action が Remove、Replacement が True の行を必ず確かめる
  • create-stack / update-stack は StackId を返してすぐ戻るので、wait を組み合わせる
  • うまくいかなかった理由は describe-stack-events の _FAILED の行を --query で抜く
  • ROLLBACK_COMPLETE は削除して作り直す。UPDATE_ROLLBACK_COMPLETE はそのまま更新し直せる
  • UPDATE_ROLLBACK_FAILED は continue-update-rollback、DELETE_FAILED は --retain-resources を使う

参考・出典

  • AWS CLI Command Reference「cloudformation deploy」「cloudformation describe-change-set」(docs.aws.amazon.com/cli/latest/reference/cloudformation/)
  • AWS CloudFormation ユーザーガイド「スタックのイベントと状態コード(view-stack-events)」「トラブルシューティング」「更新のロールバックを続行する」「プロビジョニング済みリソースを残すオプション(stack-failure-options)」「IAM によるアクセス制御(control-access-with-iam)」
  • AWS CloudFormation API リファレンス「Stack」

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CloudFormationをAWS CLIで操作|deployと変更セット」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?