frp_configuration_and_commands

TOML / Bash

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]
}