AWSでインフラを構築するとき、毎回コンソールをポチポチ操作して設定していませんか?最初は問題なくても、同じ環境を複数作る必要が出てきたり、設定の変更履歴を管理したくなったりすると、手動操作では限界が出てきます。こうした課題を解決するのが「AWS CloudFormation」です。今回は、CloudFormationの基本的な仕組みから、スタックのデプロイ方法、よく出るエラーとその解決策まで、初心者にも分かりやすく解説します。
AWS CloudFormationとは
AWS CloudFormationは、AWSのインフラ構成をコードで定義して自動構築するサービスです。「Infrastructure as Code(IaC)」と呼ばれる考え方を実現するAWSの標準サービスです。
身近な例で言うと、料理のレシピに近いイメージです。「EC2インスタンスを1台・VPCを1つ・RDSを1台」という構成を、レシピ(テンプレート)として書いておけば、そのレシピを使って何度でも同じ環境を自動的に作れます。開発環境・ステージング環境・本番環境を同じテンプレートから作ることで、環境間の設定の差異をなくし、「開発では動いたのに本番では動かない」というトラブルを防ぎやすくなります。
CloudFormationの大きなメリットは4つあります。環境の再現性として同じテンプレートから何度でも同じ環境を作れます。変更管理としてテンプレートをGitで管理することで、インフラの変更履歴を追えます。自動化として手動操作なしに複雑なインフラをワンコマンドで構築できます。コスト削減として不要になったリソースをスタック単位でまとめて削除できます。
テンプレートの基本構造
CloudFormationのテンプレートはJSON形式またはYAML形式で記述します。YAMLの方が読み書きしやすいため、多くの場合YAMLが使われます。テンプレートの基本的な構造は以下の通りです。
yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: "テンプレートの説明"
Parameters:
# 実行時に入力する値を定義
Mappings:
# リージョンごとの値などを定義
Resources: # 必須
# 作成するAWSリソースを定義
Outputs:
# 作成後に出力する値を定義
この中で唯一必須なのがResourcesセクションです。ここに作成したいEC2・VPC・S3バケットなどのリソースを定義します。
Parametersセクションは、テンプレートを実行する際に外部から値を渡すための入力欄です。たとえば「インスタンスタイプ」を毎回指定できるようにしたり、「環境名(dev/prod)」を切り替えられるようにしたりするために使います。
Mappingsセクションは、リージョンごとのAMI IDの違いや、環境ごとの設定値の違いを定義するために使います。同じテンプレートを複数のリージョンで使い回したい場合に特に役立ちます。
Outputsセクションは、スタック作成後に出力したい値(作成されたEC2のIPアドレスやS3バケット名など)を定義します。他のスタックからこの値を参照する「クロススタック参照」にも使われます。
スタックとは
CloudFormationでテンプレートをデプロイすると「スタック」が作成されます。スタックとは、テンプレートで定義したリソースをひとまとまりとして管理する単位です。
スタックを作成するとテンプレートに定義されたすべてのリソースが作成され、スタックを削除するとそこに含まれるすべてのリソースがまとめて削除されます。「環境ごとにスタックを分ける」という管理方法が一般的で、開発環境スタック・本番環境スタックをそれぞれ独立して管理できます。
スタックのデプロイ方法
CloudFormationのデプロイには複数の方法があります。
AWSコンソールからデプロイ
最も手軽な方法です。AWSコンソールのCloudFormationページから「スタックの作成」を選択し、テンプレートファイルをアップロードしてパラメータを入力するだけでデプロイできます。初めてCloudFormationを試す場合は、まずコンソールから操作してみることをおすすめします。
AWS CLIからデプロイ
コマンドラインからデプロイする方法です。CI/CDパイプラインへの組み込みや、スクリプトでの自動化に向いています。
bash
# スタックの新規作成
aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--parameters ParameterKey=Env,ParameterValue=dev
# スタックの更新
aws cloudformation update-stack \
--stack-name my-stack \
--template-body file://template.yaml
# スタックの削除
aws cloudformation delete-stack \
--stack-name my-stack
deploy コマンドを使う方法
create-stackとupdate-stackを使い分ける代わりに、cloudformation deployコマンドを使うと「スタックが存在しなければ作成、存在すれば更新」を自動判別してくれます。CI/CDパイプラインではこちらの方が使いやすいです。
bash
aws cloudformation deploy \
--stack-name my-stack \
--template-file template.yaml \
--parameter-overrides Env=prod
Change Setを使ったデプロイ
既存スタックを更新する際に、変更内容を事前に確認してから適用できる仕組みが「Change Set(変更セット)」です。「このテンプレートを適用すると、どのリソースが追加・変更・削除されるか」をデプロイ前に確認できるため、意図しない変更が本番環境に影響を与えるリスクを減らせます。
bash
# Change Setの作成
aws cloudformation create-change-set \
--stack-name my-stack \
--template-body file://template.yaml \
--change-set-name my-changeset
# Change Setの内容を確認
aws cloudformation describe-change-set \
--stack-name my-stack \
--change-set-name my-changeset
# Change Setの適用
aws cloudformation execute-change-set \
--stack-name my-stack \
--change-set-name my-changeset
本番環境への変更は必ずChange Setで確認してから適用する、というのがベストプラクティスです。
StackSetsを使った複数アカウント・複数リージョンへの一括デプロイ
StackSetsは、1つのテンプレートを複数のAWSアカウント・複数のリージョンに一括デプロイできる機能です。AWS Organizationsと組み合わせることで、「全アカウントに同じセキュリティ設定を一括適用する」といった運用が可能になります。
スタックのデプロイで使われる主なリソースタイプ
CloudFormationで定義できるリソースは200種類以上ありますが、よく使われるものを整理します。
yaml
Resources:
# EC2インスタンス
MyEC2:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: ami-xxxxxxxx
# S3バケット
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-bucket-name
# セキュリティグループ
MySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "My SG"
VpcId: !Ref MyVPC
リソース間の参照には!Refや!GetAttという組み込み関数を使います。!RefはリソースのIDや名前を参照し、!GetAttはリソースの特定の属性(EC2のパブリックIPなど)を取得します。
よく出るエラーとその解決策
CloudFormationを使い始めると様々なエラーに遭遇します。代表的なエラーとその解決策を整理します。
ROLLBACK_COMPLETE状態
スタックの作成・更新に失敗すると、CloudFormationは自動的にロールバック(元の状態に戻す)を実行します。ロールバックが完了した状態が「ROLLBACK_COMPLETE」です。
この状態になったスタックは更新ができないため、一度削除してから再作成する必要があります。エラーの原因はAWSコンソールの「イベント」タブで確認でき、赤字で表示されているイベントが失敗した操作です。
スタック失敗時にリソースを保持する方法
デフォルトでは、スタック作成失敗時にすべてのリソースがロールバックされてしまうため、エラーの原因調査が難しくなります。スタック作成時に「スタック失敗オプション」で「作成したリソースを保持する(Preserve successfully provisioned resources)」を選択すると、失敗したリソースの状態を保持したままエラーを確認できます。
よく出るエラーメッセージと原因
**「Resource handler returned message: “Value (xxx) for parameter xxx is invalid」**はパラメータの値が正しくない場合に出るエラーです。AMI IDやインスタンスタイプのスペルミス、またはそのリージョンに存在しないAMI IDを指定した場合によく発生します。
**「Circular dependency between resources」**は、リソースAがリソースBに依存し、リソースBもリソースAに依存するという循環参照が発生した場合のエラーです。!Refや!GetAttの参照関係を見直して、循環が発生しないように修正します。
**「Resource of type ‘AWS::xxx::xxx’ with identifier ‘xxx’ already exists」**は、すでに同じ名前のリソースが存在している場合のエラーです。スタックの外で手動作成したリソースと名前が衝突している場合によく発生します。リソース名を変更するか、既存のリソースをインポートする方法で対処します。
**「No export named xxx found」**はクロススタック参照を使っている場合に、参照先のOutputsで定義したエクスポート名が見つからないときのエラーです。参照先スタックが正常に作成されているか、エクスポート名のスペルミスがないかを確認します。
Drift Detection(ドリフト検出)でのエラー対応
CloudFormationで作成したリソースを、コンソールや CLIで手動変更すると「ドリフト(テンプレートと実際の状態のズレ)」が発生します。Drift Detectionを実行することでズレを検出し、スタックの更新(Update Stack)を実行してテンプレートの状態に戻すことができます。
CloudFormationとCI/CDパイプラインの連携
実際の開発現場では、CloudFormationのテンプレートをGitHubで管理し、CodePipelineと連携させて自動デプロイする構成が一般的です。
GitHubにテンプレートをプッシュ
↓
CodePipeline がトリガー
↓
CodeBuild(テンプレートの検証)
↓
CloudFormation Change Setの作成
↓
手動承認(本番環境の場合)
↓
Change Setの実行(デプロイ)
この流れにすることで、インフラの変更もアプリケーションのデプロイと同じように、レビュー・承認・自動デプロイのサイクルで管理できるようになります。
まとめ
AWS CloudFormationは、インフラをコードで管理することで再現性・変更管理・自動化を実現するサービスです。テンプレートの基本構造を理解し、コンソール・CLI・Change Setといったデプロイ方法を使い分けることで、安全かつ効率的なインフラ管理が可能になります。エラーが発生した場合も、イベントログを確認して原因を特定し、適切な対処をするという流れを身につけることが、CloudFormationを使いこなす上での重要なスキルです。まずは簡単なEC2インスタンスを1台作るテンプレートを書いて実際にデプロイしてみることで、CloudFormationの仕組みを体感的に理解できると思います。

コメント