🗒️
【初心者向け】AWS 用 Iac 使い分け【CloudFormation / AWS SAM / CDK】
はじめに
現在、Reactアプリを開発中です。
以前、S3 + CloudFront でホスティングしたので今回もそうしようと、
S3 と CloudFront を AWSマネジメントコンソールから作ったのですが
- 前作ったときどんな設定だっけ?
- 設定を間違えてないか心配
- 手動でポチポチ作るのめんどくさい
と思ったので、IaC(Infrastructure as Code)を使ったAWSリソース作成方法を調べてみました。
本記事では、AWSで使える IaC の特徴と使い分けを整理しつつ、
フロントエンド・バックエンドの開発ケース別に選択指針を紹介します。
IaC 化のメリット
IaC 化すると以下のメリットがあります:
-
設定の再現性が高い
→ 開発環境 / 本番環境など、複数環境の構築が簡単 -
ヒューマンエラーを減らせる
→ コンソール操作ミスの心配なし -
GitHub Actions などと組み合わせた自動デプロイが容易
→ リソース定義がコードになっているので自動デプロイに組み込みやすい
AWS で使える IaC
AWSで使える代表的な IaC は以下の3つです。
- CloudFormation
- AWS SAM (Serverless Application Model)
- AWS CDK (Cloud Development Kit)
基本的な特徴や使い分け方針は以下の通りです。
CloudFormation
- AWS 公式の IaC の基盤
- JSON / YAML でリソースを定義
- メリット: AWS の全サービスを網羅的に扱える、公式テンプレートが豊富
- デメリット: 記述が冗長になりがち、大規模環境だとメンテが大変
→ 「シンプルな環境をテンプレート化したい」「公式テンプレートを参考にしたい」場合に有効
AWS SAM
- CloudFormation を拡張したフレームワーク
- Lambda, API Gateway, DynamoDB など サーバーレスアプリ 向けに特化
- CLI が便利(sam build, sam local invoke, sam deploy)
- メリット: サーバーレスに必要な設定を少ない記述で書ける
- デメリット: サーバーレス以外のサービスは扱いづらい
→ 「サーバーレスアプリを迅速に開発・デプロイしたい」場合に最適
AWS CDK
- TypeScript / Python / Java などの プログラミング言語で IaC を記述できる
- 内部的には CloudFormation に変換されて実行される
- メリット: 条件分岐やループが書けるので、大規模構成も整理しやすい
- デメリット: 学習コストがやや高め
→ 「好きな言語を使って管理したい」「複雑なロジックが必要になる」場合に便利
開発ケース別の使い分け
ケース① フロントエンド(S3 + CloudFront)
- おすすめ: CDK または CloudFormation
- React アプリを S3 にデプロイして、CloudFront で配信
- 例: CDK (TypeScript)
// 定義しているリソース
// S3 バケット (s3.Bucket)
// ・フロントエンドの静的ファイル(HTML / JS / CSS)を置く場所
// ・websiteIndexDocument でトップページを指定
// ・publicReadAccess: false でバケットの公開アクセスを制御
// CloudFront 配信 (cloudfront.CloudFrontWebDistribution)
// ・S3 バケットをオリジンとして設定
// ・コンテンツをグローバルに高速配信(CDN)
// ・HTTPS 化、キャッシュ制御なども可能
import * as cdk from "aws-cdk-lib";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
export class FrontendStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const bucket = new s3.Bucket(this, "FrontendBucket", {
websiteIndexDocument: "index.html",
publicReadAccess: false,
});
new cloudfront.CloudFrontWebDistribution(this, "FrontendCDN", {
originConfigs: [
{
s3OriginSource: { s3BucketSource: bucket },
behaviors: [{ isDefaultBehavior: true }],
},
],
});
}
}
ケース② サーバーレスのバックエンド(Lambda + API Gateway)
- おすすめ: AWS SAM
- CloudFormation でも書けるが、SAM の方が楽
- 例: SAM テンプレート
# 定義しているリソース
# Lambda 関数 (AWS::Serverless::Function)
# ・Python で書いた関数 app.lambda_handler を実行するサーバーレス関数
# ・Runtime で実行環境を指定
# API Gateway (Events 配下の ApiEvent)
# ・HTTP リクエストを Lambda にルーティング
# ・Path: /hello、Method: get に設定
# ・SAM が自動的に API Gateway リソースを作成して Lambda と接続
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
HelloFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
Runtime: python3.11
Events:
ApiEvent:
Type: Api
Properties:
Path: /hello
Method: get
ケース③ サーバーレスではないバックエンド(EC2 / ECS / RDS など)
- おすすめ: CDK
- EC2, ECS, RDS, VPC など複雑な構成を整理しやすい
- 例: CDK で ECS Fargate サービス
// 定義しているリソース
// VPC (ec2.Vpc)
// ・AWS 内の仮想ネットワーク
// ・ECS や EC2 のリソースをネットワーク内に配置
// ECS クラスター (ecs.Cluster)
// ・ECS タスク(コンテナ)の管理単位
// ・クラスター内に複数タスクを配置可能
// Fargate サービス (ecs.FargateService)
// ・ECS 上でコンテナを自動でスケーリングして実行
// ・taskDefinition でコンテナの定義(イメージ、CPU / メモリ)を指定
import * as ecs from "aws-cdk-lib/aws-ecs";
import * as ec2 from "aws-cdk-lib/aws-ec2";
const vpc = new ec2.Vpc(this, "MyVpc");
const cluster = new ecs.Cluster(this, "MyCluster", { vpc });
new ecs.FargateService(this, "MyService", {
cluster,
taskDefinition: new ecs.FargateTaskDefinition(this, "TaskDef"),
});
まとめ
-
CloudFormation
→ AWS リソースを YAML/JSON で書きたいときの基本ツール -
AWS SAM
→ サーバーレス特化、Lambda 中心のアプリに最適 -
AWS CDK
→ 使用言語や複雑なロジックに柔軟に対応
普段、AWSコンソールを使っている方も、IaC を導入すると「再現性の高い環境構築」「環境ごとの差分管理」「自動デプロイの実現」といったメリットを実感できます。
まずは小さな構成から IaC 化して、GitHub Actions などの CI/CD と組み合わせて運用してみるのがおすすめです。
Discussion