0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【図解】AWS CloudFormationとは。建てて壊すまでの使い方まとめ

0
Posted at

対象読者: AWSをこれから触る人。 AWS勉強シリーズの12本目で、今回はCloudFormationです。全体の地図は索引記事にあります。

ここまでの11本でIAMからCloudWatchまで、部品を1個ずつ手で作ってきました。その先で必ずこう思います。

  • 「検証用にもう1セット同じ構成が欲しい。また全部手でクリックするの?」
  • 「試しに作ったリソース、消し忘れが怖い。何を作ったか全部覚えてない」

どちらも「構成を1枚の文書に書いて、建てるのも壊すのも文書ごとやる」で答えが出ます。

CloudFormationは、家の設計図。設計図が同じなら、同じ家が建つ
CloudFormationを設計図に例えた図(筆者作成)。同じテンプレートから検証と本番に同じ構成を建てられます。

CloudFormationとは何か

AWS CloudFormationは、AWSの構成(何をどう作るか)を1枚の文書(テンプレート)に書いておくと、その通りに作ってくれるサービスです。手作業のクリックの代わりに、設計図を渡す。いわゆる「インフラのコード化(IaC)」の、AWS純正の道具です。

上の図の通りで、設計図が同じなら同じ家が建つ。「検証環境と本番環境で微妙に設定が違う」という手作業あるあるが、原理的に起きなくなります。

今AWSの地図のどこにいるか

AWS入門の地図。IAM〜CloudWatchまで済み、今ここがCloudFormation

手作業で部品を覚えるフェーズは、ここで一区切りです(シリーズ自体は全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_stack 1回で、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)と続けて、最後に完成形の写真アプリを実際に組みます。全体の進み方は索引記事で更新していきます。

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?