terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
null = {
source = "hashicorp/null"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "ap-northeast-1" # 東京リージョン
}
variable "aws_region" {
default = "ap-northeast-1"
}
# ==========================================
# 1. ネットワーク(VPC / Subnet / IGW)
# ==========================================
resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = { Name = "ecs-ec2-vpc" }
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "192.168.0.0/24"
map_public_ip_on_launch = true # インターネット通信(ECRからのPull等)に必要
availability_zone = "ap-northeast-1a"
}
resource "aws_route_table" "rt" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
}
resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.rt.id
}
resource "aws_security_group" "allow_all" {
name = "allow_all_for_testing"
description = "Allow all inbound/outbound traffic"
vpc_id = aws_vpc.main.id
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# ==========================================
# 2. ECR (プライベートリポジトリと擬似Push)
# ==========================================
resource "aws_ecr_repository" "apache" {
name = "my-apache-repo"
image_tag_mutability = "MUTABLE"
force_delete = true # こちらに変更
}
# ①と②の要件:パブリックからpullしてプライベートECRへpushする擬似再現
# ※ terraform applyを実行するローカル環境に docker と aws cli が必要です
resource "null_resource" "ecr_push" {
depends_on = [aws_ecr_repository.apache]
provisioner "local-exec" {
command = < /dev/null
apt-get update -y
apt-get install -y docker-ce docker-ce-cli containerd.io
# 2. ECS エージェントの設定
mkdir -p /etc/ecs /var/log/ecs /var/lib/ecs/data
echo "ECS_CLUSTER=${aws_ecs_cluster.main.name}" >> /etc/ecs/ecs.config
# 3. AWS公式のECSエージェントをDockerコンテナとして起動(EC2をECSに認識させる)
docker run --name ecs-agent \
--detach=true \
--restart=on-failure:10 \
--volume=/var/run:/var/run \
--volume=/var/log/ecs/:/log \
--volume=/var/lib/ecs/data:/data \
--volume=/etc/ecs:/etc/ecs \
--net=host \
--env-file=/etc/ecs/ecs.config \
amazon/amazon-ecs-agent:latest
EOF
tags = { Name = "ecs-ubuntu-host" }
}
# ==========================================
# 6. ECS タスク定義 & サービス (③デプロイ)
# ==========================================
resource "aws_ecs_task_definition" "apache" {
family = "apache-task"
requires_compatibilities = ["EC2"] # FargateではなくEC2を指定
network_mode = "bridge" # EC2のDocker標準のブリッジモード
cpu = "256"
memory = "512"
container_definitions = jsonencode([{
name = "apache-container"
image = "${aws_ecr_repository.apache.repository_url}:latest" # ③プライベートリポジトリからPULL
cpu = 256
memory = 512
essential = true
portMappings = [{
containerPort = 80
hostPort = 80 # ホスト(EC2)のポート80番にマッピング
}]
}])
}
resource "aws_ecs_service" "apache" {
name = "apache-service"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.apache.arn
desired_count = 1
launch_type = "EC2" # FargateではなくEC2でデプロイ
# 今回は1台のEC2に直接乗せるため、スケジューリング戦略はシンプルに
depends_on = [null_resource.ecr_push, aws_instance.ecs_host]
}