TerraformでECS Fargate環境を構築する手順と構成ポイント解説

この記事の目次
はじめに
前回の記事では、AWS CDK(Cloud Development Kit) を使って、プログラミング言語でインフラを定義しながら ECS Fargate 環境を構築する方法を紹介しました。
コードによるインフラ定義(IaC)の便利さを実感された方も多いのではないでしょうか。
今回はその続編として、Terraform を使って同様の ECS Fargate 環境を構築してみます。Terraformは HCL(HashiCorp Configuration Language) という専用の記述言語を使ってインフラを定義するツールで、シンプルな構文で視覚的にわかりやすいのが特長です。
CDKとの違いや、Terraformならではの構成の考え方にも触れながら、最短ステップで「ALB付きのFargate環境」を構築する方法を丁寧に解説していきます。
TerraformによるFargate構築の概要
TerraformとCDKの違い
Terraformは、専用言語 HCL(HashiCorp Configuration Language) を使ってインフラ構成を定義するツールです。TypeScriptなどの汎用言語を使うCDKとは異なり、構文がシンプルで視覚的にも分かりやすく、インフラ構築の初学者にも適したツールとして人気があります。
項目 | CDK | Terraform |
記述言語 | TypeScript / Python など | HCL(専用DSL) |
メリット | アプリ開発と統合しやすい | 宣言的で構文が簡潔 |
向いている人 | アプリケーションエンジニア | インフラエンジニア、IaC未経験者 |
Terraformは「コードは書けないがIaCに挑戦したい」インフラエンジニアにとって、良い入り口になります。
使用する公式モジュールと構成の特徴
本記事では、Terraform公式の terraform-aws-modules/terraform-aws-ecs モジュールを使って、Fargate環境を構築します。
このモジュールは、ECS構築に必要な複数のリソースを包括的に管理でき、最小限のコードでFargate環境を用意できる便利なツールです。
- AWS公式提供のCDKとは異なり、Terraformコミュニティが整備した高機能なモジュール。
- 前回のCDKサンプルとは構成要素が異なり、今回は Fargate Spotとのハイブリッド構成 にも対応。
- デフォルトで ALB + サイドカー構成 + ログ出力 + マルチAZ対応 などが含まれている。
今回の構成で構築されるリソース一覧
Terraformで構築される主なリソースは以下の通りです。
- ECS Fargateクラスター:オンデマンドとSpotのハイブリッド構成
- ALB(Application Load Balancer):外部からのトラフィックを管理
- フロントエンドアプリケーション:3000番ポートでリッスン
- FluentBitサイドカー:ログ収集用
- VPCと関連するネットワークリソース:マルチAZ構成

構築に必要な準備(前提条件)
Terraformを使ってAWS上に環境を構築するためには、以下のツールのインストールと設定が必要です。
環境構築前に、必ずこのセクションを確認してください。
インストールが必要なツール
Terraformでインフラを構築するには、以下のツールをローカルPCにインストールする必要があります。
- Terraform v1.0以上
https://developer.hashicorp.com/terraform/downloads
※Mac/Linux/Windowsそれぞれの手順に沿ってインストールしてください。
コマンドラインからAWS環境にアクセスするためのCLIツールです。これらがすでにインストール済みの場合は、この手順はスキップして問題ありません。
AWS CLIの設定と認証方法
TerraformはAWSにリソースを作成するため、AWSの認証情報(アクセス許可)を設定しておく必要があります。
認証方法はいくつかありますが、本記事では以下の2つの方法を紹介します。
- 個人検証向けのIAMユーザーとアクセスキーによる設定(初心者向け)
- 組織利用向けのIAM Identity Center(旧AWS SSO)による認証(推奨)
どちらも、AWS CLIに対して「この人がこの操作をしてもいい」と判断させるための設定です。
方法①:IAMユーザーのアクセスキーで設定(初心者向け)※本番環境ではIAMユーザーのアクセスキー利用は推奨されませんが、個人学習・検証用途では問題ありません。
以下のコマンドで認証情報を設定できます。
aws configure
- AWS Access Key ID:IAMユーザーで発行したアクセスキー
- AWS Secret Access Key:同上
- Default region name:例)ap-northeast-1(東京)
- Default output format:json(推奨)
方法②:IAM Identity Center(旧SSO)による設定(推奨)
AWS CLI v2以降では、IAM Identity Centerを使って安全に認証設定できます。設定手順は以下の公式ガイドを参照してください。
AWS Organizations環境下で運用している場合や、企業アカウントでの利用時はこちらの方法が推奨されます。
TerraformによるFargate構築の手順
Step1. リポジトリのクローンとディレクトリ移動
まず、terraform-aws-modulesのリポジトリをクローンし、Fargateの例のディレクトリに移動します。
今回は examples/fargate ディレクトリの構成を使用します。
git clone https://github.com/terraform-aws-modules/terraform-aws-ecs.git
cd terraform-aws-ecs/examples/fargate
Step2. Terraformの初期化
必要なプロバイダーとモジュールをダウンロードします。特定のAWSプロファイルを使用する場合は、以下のように設定します。
# ローカル端末で使用するプロファイルを環境変数で設定
export AWS_PROFILE=<プロファイル名>
terraform init
プロファイルを指定しない場合は、aws configure で設定したデフォルトプロファイル([default])の認証情報が使用されます。AWS_PROFILE 環境変数を使ってプロファイルを明示的に指定する場合は、aws configure で設定したプロファイル名と一致させる必要があります。
Step3. 実行計画の確認
デプロイ前に、どのようなリソースが作成されるかを確認します。
terraform plan
今回は開発/本番の設定分離の設定は用意していませんが、terraform で環境分離を用意したい場合、Input Variablesという機能を使い、-var-file オプションを使って環境ごとに分けたい変数を記述したファイルを指定します。
Step4. ALBのIPアドレス制限(オプション)
セキュリティ上、ALBへのアクセスを特定のIPアドレスに制限することが推奨されます。以下のように設定します。
# main.tfに追記
module "alb" {
# ... 既存の設定 ...
security_group_rules = {
//元々あった all_http を下記に変更
ingress_allowed_ips = {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_ipv4 = "YOUR_IP_ADDRESS/32" # 許可するIPアドレスを指定
description = "Allow access from specific IP"
}
}
}
Step5. デプロイ
準備ができたら、リソースをデプロイします。
terraform apply
デプロイが完了すると、ALBのDNS名をマネコンから確認できるので、それを使ってアプリケーションにアクセスできます。
※ サンプルのままだとeu-west-1にデプロイされるので、マネコンでみるときもeu-west-1を確認しましょう。
Terraform構成のポイント解説
このセクションでは、前回のCDK構成では触れていなかった、ECS Fargateに特有の実践的な構成ポイントについて解説します。Terraformのサンプルコードには、可用性や運用性を高めるための工夫が多数盛り込まれており、それぞれの意味を理解することで、より効果的なIaC構築が可能になります。
Fargate Spotとのハイブリッド構成
今回の構成では、ECS Fargateにおいて「オンデマンドインスタンス(FARGATE)」と「スポットインスタンス(FARGATE_SPOT)」を併用することで、コストと可用性のバランスを最適化しています。
使用している設定は以下のとおりです。
fargate_capacity_providers = {
FARGATE = {
default_capacity_provider_strategy = {
weight = 50
base = 20
}
}
FARGATE_SPOT = {
default_capacity_provider_strategy = {
weight = 50
}
}
}
この設定の動作は次のようになります。必要に応じて、base や weight を調整してください。
ベースラインの確保
- base = 20 によって、最初の20タスクは必ずオンデマンド(FARGATE)で起動します。
- これにより、安定性が求められるタスクは常に確保されます。
スケーリング時の振り分け
- 21個目以降のタスクは、weight = 50 の比率に従って FARGATE / FARGATE_SPOT に 50:50 で振り分けられます。
例:タスク数が合計40の場合
- 20タスク:FARGATE(ベースライン)
- 10タスク:FARGATE(追加分の50%)
- 10タスク:FARGATE_SPOT(追加分の50%)
コスト最適化の効果
ベースラインで安定稼働を維持しつつ、追加分にスポットを活用することで、全体コストを抑えながら可用性を確保できます。
- ベースラインの20タスクで安定性を確保
- 追加タスクの50%をSpotで実行することでコスト削減
- オンデマンドとSpotのハイブリッドで、コストと可用性のバランスを実現
コンテナ定義
今回のタスクでは、2つのコンテナが定義されています。
- フロントエンドアプリケーション(3000番ポートでリッスン)
- FluentBit(ログ収集用のサイドカー)
定義は以下のとおりです。
container_definitions = {
fluent-bit = {
cpu = 512
memory = 1024
essential = true
image = nonsensitive(data.aws_ssm_parameter.fluentbit.value)
firelens_configuration = {
type = "fluentbit"
}
memory_reservation = 50
user = "0"
}
(local.container_name) = {
cpu = 512
memory = 1024
essential = true
image = "public.ecr.aws/aws-containers/ecsdemo-frontend:776fd50"
port_mappings = [
{
name = local.container_name
containerPort = local.container_port
hostPort = local.container_port
protocol = "tcp"
}
]
readonly_root_filesystem = false
dependencies = [{
containerName = "fluent-bit"
}]
}
}
補足ポイント
- FluentBitサイドカーはfirelens_configurationでログ収集を設定
- フロントエンドアプリは3000番ポートでリッスン
- dependenciesでコンテナの起動順序を制御
このような役割分担を明示することで、Dockerfileの目的が明確になり、後々のメンテナンスや障害対応がスムーズになります。例えば、nginxとphp-fpmを分けたLaravelアプリケーション構成などにも応用可能です。
似たような構成で、nginx と php-fpm のコンテナを分けて Laravel アプリケーションを稼働させることも可能です。 コンテナを分けることで、Dockerfile の用途が分かりやすくなり、後から「これ何のためにインストールしていたかな」といったことになる可能性を下げられます。
ECS Execによるデバッグ対応
Terraformでは、enable_execute_command = true を指定することで、ECS Execによるコンテナ内部へのアクセスを有効にしています。
enable_execute_command = true
ECS Execを有効にすることで、以下の操作が可能になります。
- コンテナ内でのシェルアクセス(sh や bash)
- 実行中プロセスの確認やログの直接参照
- 本番環境での一時的なトラブルシューティング対応
CLIから aws ecs execute-command を使うことで、該当タスクの中に入って調査を行えます。
詳しくはECS Exec を使用して Amazon ECS コンテナをモニタリングする をご参照ください。
補足:運用時の便利なコマンド
Terraformによる環境構築後、実際の運用や検証において役立つ操作もいくつか紹介されていました。このセクションでは、タスクの手動実行とリソース削除という2つの便利な操作について補足します。
タスクの手動実行
terraform apply の後に表示されたコマンド例のように、ECSタスクを手動で実行することができます。
# タスクの手動実行(デバッグ用)
aws ecs run-task --cluster ex-fargate \
--task-definition ex-fargate-standalone:1 \
--network-configuration "awsvpcConfiguration={subnets=[subnet-01be9f2134a111111,subnet-0fa112461df911111,subnet-05dd1930b83011111],securityGroups=[sg-00c2af9b4a2e111111]}" \
--region eu-west-1
このコマンドは、定義済みのタスクを1回だけ即時実行したい場合に使います。
主な用途:
- DBマイグレーションの実行
- バッチ処理やワンタイムスクリプトの実行
これらの運用目的のタスクは、通常のサービスとして常時実行する必要がないため、手動実行が適しています。定期実行するように設定したLambdaやEventBridge の入力トランスフォーマーなどと組み合わせることも可能です。
リソースの削除(Terraform destroy)
今回のような検証環境では、構築後に不要なリソースをそのまま残しておくと、課金の原因になる場合があります。Terraformでは、以下のコマンドで作成したすべてのリソースを一括削除できます。
terraform destroy
- 作成されたVPC、ECSクラスター、ALB、サブネットなどをまとめて削除します。
- terraform apply で構築した環境がそのまま元に戻るイメージです。
テスト用途で環境を構築する際には、終了後に必ず destroy を実行する習慣をつけることで、無駄なAWSリソース使用を防げます。
Terraformの強みの一つは、「構築したものを綺麗に壊せる」点にもあります。これもIaCの大きな利点です。
まとめ
本記事では、Terraformを使ってECS Fargate環境を構築する方法を紹介しました。前回のCDKと比較しながら、Terraformならではの記述スタイルや構成の特徴、運用時に役立つTipsまで一通り解説しました。
今回のポイントをおさらい
- Terraformの基本構文(HCL) によるインフラ構築を体験
- FARGATEとFARGATE_SPOTのハイブリッド構成でコストと安定性を両立
- FluentBitによるログ収集と起動順制御を含む、実践的なタスク定義
- ECS Execや手動タスク実行といった運用面での活用も紹介
- terraform destroyによるリソース削除で、検証環境の片付けも簡単
次回は、今回のTerraform構成をさらに一歩進めて、GitHub Actionsなどを使ったCI/CDパイプラインの構築を解説します。