How to create an ECS running in Fargate?

Hiya,

I’m trying to set up a small Docker image to run in Fargate via Terrform, but I keep getting this strange error. Well, strange for me.

$ aws-vault exec foo -- terraform apply -auto-approve
data.template_file.container_definitions: Refreshing state...
data.aws_iam_policy_document.this: Refreshing state...
aws_ecs_cluster.this: Refreshing state... [id=arn:aws:ecs:eu-north-1:112233:cluster/test-123-ecs-service]
aws_iam_role.this: Refreshing state... [id=test-123-ecs-execution-role]
aws_iam_role_policy_attachment.this: Refreshing state... [id=test-123-ecs-execution-role-112233]
aws_ecs_task_definition.this: Refreshing state... [id=test-123-ecs-task-definition-family]
aws_ecs_service.this: Creating...

Error: InvalidParameterException:  "test-123-ecs-service"

  on main.tf line 26, in resource "aws_ecs_service" "this":
  26: resource "aws_ecs_service" "this" {

How can the name test-123-ecs-service be invalid?

The Terraform file looks like

terraform {
  required_version = ">=0.12.20"
  required_providers {
    aws = ">=2.45.0"
    template = ">=2.1.2"
  }
  backend "s3" {
    key = "test-123/terraform.tfstate"
    bucket = "112233"
    dynamodb_table = "terraform-state-lock"
    encrypt = true
  }
}

variable "name" {
  type = string
  default = "test-123"
}

resource "aws_ecs_cluster" "this" {
  name = "${var.name}-ecs-service"
}

resource "aws_ecs_service" "this" {
  name = "${var.name}-ecs-service"
  task_definition = aws_ecs_task_definition.this.arn
  cluster = aws_ecs_cluster.this.id
  launch_type = "FARGATE"
}

resource "aws_ecs_task_definition" "this" {
  family = "${var.name}-ecs-task-definition-family"
  container_definitions = data.template_file.container_definitions.rendered

  cpu = "256"
  memory = "512"
  requires_compatibilities = ["FARGATE"]
  network_mode = "awsvpc"

  execution_role_arn = aws_iam_role.this.arn
}

data "template_file" "container_definitions" {
  template = file("${path.module}/container_definitions.json")
}

resource "aws_iam_role" "this" {
  name = "${var.name}-ecs-execution-role"
  assume_role_policy = data.aws_iam_policy_document.this.json
}

data "aws_iam_policy_document" "this" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type = "Service"
      identifiers = [
        "ecs.amazonaws.com",
      ]
    }
  }
}

resource "aws_iam_role_policy_attachment" "this" {
  role = aws_iam_role.this.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

Ah. Perhaps it’s not the actual name that’s wrong. Simply some “unknown” parameter for the entire resource?

Never mind. Figured it out

what worked? what was the error? could you post the working version?

Haha. I was trying sooo hard to be “that guy”. I succeeded!

It was as I believed, not the name itself that was broken, but other parts of the configuration block. The error message just indicates that something is broken somewhere (in the block). Not that great of a debugging experience, but it is what it is.

I think that in the minimalistic example above you need to add a network_configuration block to get it to work.

  network_configuration {
    security_groups = [...]
    subnets = [...]
  }

So in my actual code I have lots of other stuff. Took me better part of a day to bisect and piece together what works with what. :man_shrugging:

It would be great if there where more fleshed out examples for how to deploy stuff. ECS-on-EC2 vs. ECS-on-Fargate and so on.

In the end I have no working version to post for you. Sorry