AWS Fargate で ELB を使用しない Nginx を Terraform で作ってみた

ほとんどのユースケースにおいては、ELB 経由で Fargate のコンテナーにアクセスさせる構成になると思います。今回は、あまり用途は無いかもですが、ELB を使用せず Fargate にパブリック IP アドレスを割り当ててアクセスする方法を Nginx と Terraform を使って試してみました。

検証用の Terraform コード

terraform {}

provider "aws" {}

variable "prefix" {
  default = "mnrstecs"
  type    = string
}

data "aws_caller_identity" "current" {}

resource "aws_vpc" "example" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"

  tags = {
    "Name" = "${var.prefix}-vpc"
  }
}

resource "aws_subnet" "example1a" {
  vpc_id            = aws_vpc.example.id
  cidr_block        = "10.0.0.0/24"
  availability_zone = "ap-northeast-1a"
}

resource "aws_subnet" "example1c" {
  vpc_id            = aws_vpc.example.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-1c"
}

resource "aws_internet_gateway" "example" {
  vpc_id = aws_vpc.example.id
}

resource "aws_route_table" "example" {
  vpc_id = aws_vpc.example.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.example.id
  }
}

resource "aws_route_table_association" "example1a" {
  route_table_id = aws_route_table.example.id
  subnet_id      = aws_subnet.example1a.id
}

resource "aws_route_table_association" "example1c" {
  route_table_id = aws_route_table.example.id
  subnet_id      = aws_subnet.example1c.id
}

resource "aws_security_group" "example" {
  name   = "${var.prefix}-sg"
  vpc_id = aws_vpc.example.id

  egress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = "0"
    to_port     = "0"
    protocol    = "-1"
    self        = "false"
  }
  ingress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = "80"
    to_port     = "80"
    protocol    = "TCP"
    self        = "false"
  }
  ingress {
    from_port = "0"
    to_port   = "0"
    protocol  = "-1"
    self      = "true"
  }
}

resource "aws_ecs_cluster" "example" {
  name = "${var.prefix}-cluster"
}

resource "aws_ecs_cluster_capacity_providers" "example" {
  cluster_name       = aws_ecs_cluster.example.name
  capacity_providers = ["FARGATE"]
}

resource "aws_iam_role" "example" {
  name                = "${var.prefix}-role"
  managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"]

  assume_role_policy = jsonencode(
    {
      "Statement" : [
        {
          "Action" : "sts:AssumeRole",
          "Effect" : "Allow",
          "Principal" : {
            "Service" : "ecs-tasks.amazonaws.com"
          }
        }
      ],
      "Version" : "2012-10-17"
    }
  )
}

resource "aws_ecs_task_definition" "example" {
  family                   = "nginx"
  cpu                      = 256
  memory                   = 512
  network_mode             = "awsvpc"
  execution_role_arn       = aws_iam_role.example.arn
  requires_compatibilities = ["FARGATE"]

  container_definitions = jsonencode(
    [
      {
        "name" : "nginx",
        "image" : "nginx:latest",
        "cpu" : 256,
        "essential" : true,
        "memory" : 128,
        "portMappings" : [
          {
            "containerPort" : 80,
            "hostPort" : 80
          }
        ]
      }
    ]
  )
}

resource "aws_ecs_service" "example" {
  name            = "${var.prefix}-nginx"
  cluster         = aws_ecs_cluster.example.id
  task_definition = aws_ecs_task_definition.example.arn
  desired_count   = 1

  network_configuration {
    subnets = [
      aws_subnet.example1a.id,
      aws_subnet.example1c.id
    ]
    security_groups  = [aws_security_group.example.id]
    assign_public_ip = true
  }

  capacity_provider_strategy {
    base              = 1
    capacity_provider = "FARGATE"
    weight            = 1
  }
}

Fargate コンテナーのタスクでパブリック IP を確認

ブラウザで Nginx にアクセス

参考

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition

タグ: , ,