対象読者: AWSをこれから触る人。 AWS勉強シリーズの12本目で、今回はCloudFormationです。全体の地図は索引記事にあります。
ここまでの11本でIAMからCloudWatchまで、部品を1個ずつ手で作ってきました。その先で必ずこう思います。
- 「検証用にもう1セット同じ構成が欲しい。また全部手でクリックするの?」
- 「試しに作ったリソース、消し忘れが怖い。何を作ったか全部覚えてない」
どちらも「構成を1枚の文書に書いて、建てるのも壊すのも文書ごとやる」で答えが出ます。

CloudFormationを設計図に例えた図(筆者作成)。同じテンプレートから検証と本番に同じ構成を建てられます。
CloudFormationとは何か
AWS CloudFormationは、AWSの構成(何をどう作るか)を1枚の文書(テンプレート)に書いておくと、その通りに作ってくれるサービスです。手作業のクリックの代わりに、設計図を渡す。いわゆる「インフラのコード化(IaC)」の、AWS純正の道具です。
上の図の通りで、設計図が同じなら同じ家が建つ。「検証環境と本番環境で微妙に設定が違う」という手作業あるあるが、原理的に起きなくなります。
今AWSの地図のどこにいるか
手作業で部品を覚えるフェーズは、ここで一区切りです(シリーズ自体は全20本まで続きます)。ここまで手で作ってきた全部品(S3もSQSもEC2も)は、テンプレートに書けばCloudFormationが作ってくれます。手で1回作ったことがあるものをコード化する、の順番で覚えるのが一番楽で、このシリーズの並びはそのためのものです。
何に使うか
- 同じ構成をもう1セット: 検証環境・本番環境・勉強用の使い捨て環境。テンプレート1枚から何度でも
- 消し忘れの根絶: スタック(後述)を消せば、そこから作られたリソースがまとめて消える。「何を作ったか覚えてない」が起きない。学習用アカウントとの相性が特に良い
- 構成のレビューと履歴: 文書なのでgitに入る。「いつ誰が何を変えたか」が差分で残る
- 横展開: 上手くできた構成を、別リージョン・別アカウントに配る
今はこれだけ分かればOK
| 必須の3語 | 家で言うと | 中身 |
|---|---|---|
| テンプレート | 設計図 | 「何を作るか」を書いたJSON/YAMLの文書。Resourcesの節が本体 |
| スタック | 設計図から建てた家一式 | テンプレートから作られたリソースのまとまり。作成も削除もスタック単位 |
| ロールバック | 建築失敗時の巻き戻し | 途中で失敗したら、そこまで作った分を自動で片付けて元に戻す |
変更セット、ドリフト検出、ネストスタックは後回しで大丈夫です。この記事にも出てきません。
仕組みの要点。まとめて建てて、まとめて壊す

スタックの図(筆者作成)。1枚のテンプレートから複数のリソースが建ち、削除も一括です。
初心者に一番効くのは「壊す方」です。手で作ったリソースは消し忘れて課金され続ける(RDSの「止めたのに請求が来る」で見た通り、一番ありふれた事故です)。スタックなら削除1回で全部消える。作る自動化は後でいい。先に片付けだけスタックに任せる使い方から入るのが安全です。
このコードを動かす前提
この記事のコードはPython(boto3)です。動かす方法は2通りあります。
A. AWSアカウント無しで試す(おすすめ): motoというAWSのそっくりさんを使うと、課金もサインアップもなしでPCの中だけで動きます。CloudFormationを再現させる場合は追加パッケージ込みで入れます。
python3 -m venv venv
./venv/bin/pip install boto3 "moto[cloudformation]"
from moto import mock_aws
@mock_aws # この中のboto3呼び出しは全部ローカルの偽AWSに行く
def main() -> None:
... # 以下の記事のコードをここに入れる
main()
B. 本物のAWSで動かす: 先にIAMユーザーとアクセスキーの設定が要ります。手順はIAM記事の「最初の1回だけやる手順」にあります。
使い方
シリーズの題材「写真アプリ」の一部(写真置き場のS3と、処理待ちのSQS)を、設計図1枚で建てて、壊します。
import json
import boto3
TEMPLATE = {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "photo app minimal",
"Resources": {
"PhotoBucket": {"Type": "AWS::S3::Bucket"}, # 写真置き場
"JobQueue": {"Type": "AWS::SQS::Queue",
"Properties": {"QueueName": "photo-jobs"}}, # 処理待ち
},
"Outputs": {"BucketName": {"Value": {"Ref": "PhotoBucket"}}}, # 建てた後に知りたい値
}
cfn = boto3.client("cloudformation", region_name="ap-northeast-1")
s3 = boto3.client("s3", region_name="ap-northeast-1")
# ① 設計図を渡して建てる
cfn.create_stack(StackName="photo-app", TemplateBody=json.dumps(TEMPLATE))
st = cfn.describe_stacks(StackName="photo-app")["Stacks"][0]
print(st["StackStatus"]) # -> CREATE_COMPLETE
print(st["Outputs"]) # -> BucketName: photo-app-photobucket-tkubtu9hyjqe
# ② 何が建ったかをスタック側から一覧する
for r in cfn.list_stack_resources(StackName="photo-app")["StackResourceSummaries"]:
print(r["LogicalResourceId"], r["ResourceType"], r["ResourceStatus"])
# -> PhotoBucket AWS::S3::Bucket CREATE_COMPLETE
# -> JobQueue AWS::SQS::Queue CREATE_COMPLETE
# S3側から見ても、ちゃんと存在している
print([b["Name"] for b in s3.list_buckets()["Buckets"]])
# -> ['photo-app-photobucket-tkubtu9hyjqe']
# ③ まとめて壊す
cfn.delete_stack(StackName="photo-app")
print([b["Name"] for b in s3.list_buckets()["Buckets"]])
# -> [] バケットも一緒に消えた
実測で押さえてほしいのは2点です。
- バケット名を指定していないのに
photo-app-photobucket-tkubtu9hyjqeという名前が付いた。名前はCloudFormationが被らないように生成する。自分で決めたい時だけPropertiesに書く -
delete_stack1回で、S3側から見てもバケットが消えた。作った物の台帳をスタックが持っているから、消し忘れが起きない
実際に叩くと止まるところ
間違えたときに何が返るか、実際に叩きました。
| やったこと | 返ってきたもの | 意味 |
|---|---|---|
| 同名スタックを再作成 | AlreadyExistsException |
スタック名はリージョン内で一意。更新したい時はupdate_stack |
| 無いスタックをdescribe | ValidationError: Stack with id ghost does not exist |
名前のタイプミスか、別リージョン |
| 無いスタックをdelete | エラーにならず通った | 削除は冪等。消えていれば成功扱い |
| Resources無しのテンプレート | motoは素のKeyErrorで落ちた |
本物のAWSはValidationError(Resourcesは必須)を返す。motoの再現漏れ |
| 存在しないリソース型 | motoは警告だけ出して通った | 本物のAWSはテンプレート検証で弾く。型名の検証はローカルでは当てにしない |
下2つはmotoの限界です。テンプレートの文法チェックだけは本物のvalidate_template(またはコンソールの検証)で行ってください。逆に「建てる→一覧→壊す」の流れの練習はローカルで完結します。
似たサービスとの使い分け
| 迷うところ | 答え |
|---|---|
| コンソールの手作業と、どっちで作る | 初回の理解は手作業、2回目からはテンプレート。「手で1回→コード化」の順 |
| CDKとの違い | CDKはPython等のプログラミング言語でテンプレートを生成する上位ツール。土台は同じCloudFormation。まず素のテンプレートを読めるようになってから |
| Terraformとの違い | 他社製の同ジャンル。AWS以外も扱える。AWSだけならCloudFormationで足りる |
| boto3のスクリプトと何が違う | boto3の逐次実行は「作る手順」、テンプレートは「あるべき姿」。失敗時の巻き戻しと削除の台帳が付くのがスタックの価値 |
料金の考え方
CloudFormation自体は、AWSのリソースを作る範囲では無料です(サードパーティ拡張などを使うと課金あり)。課金されるのは建てたリソース(EC2やRDS)の方。なので「スタックごと消す」はそのまま節約の道具になります。
よくある注意点
- 消えては困るものを同じスタックに入れない。 delete_stackは容赦なく全部消す。データの入ったS3やDBは、練習スタックと分ける。中身が入ったバケットは削除に失敗して残ることもあるが、それを当てにしない
- 手で変更を混ぜない。 スタックで建てたリソースをコンソールから手で書き換えると、設計図と実物がズレる(ドリフト)。直すのもテンプレート経由で
- ROLLBACK_COMPLETEのスタックは更新できない。 初回作成に失敗して巻き戻ったスタックは、一度消してから作り直す
- 削除は冪等、作成は非冪等。 実測の通り、無いスタックの削除は成功扱い、同名スタックの作成はエラー。スクリプトを流し直す時はここが引っかかる
まとめ
冒頭の2つに戻ります。
- 「また全部手でクリックするの?」→ しません。手で1回作って理解した構成を、テンプレートに書き起こす。2回目からは
create_stack1発です - 「消し忘れが怖い」→ スタックが台帳です。実測の通り、
delete_stack1回でS3側からもバケットが消えました。勉強で作る物は最初からスタックで作ると、片付けが1コマンドになります
これで入門シリーズの主要部品は一巡です。シリーズは全20本の予定で、この先はRoute 53(ドメイン)、CloudFront(配信)、API Gateway、コンテナ(ECS)と続けて、最後に完成形の写真アプリを実際に組みます。全体の進み方は索引記事で更新していきます。
