skip to Main Content

I am setting up an ECS task using Terraform and am encountering an error. The error is “Error: failed creating ECS Task Definition (web-2048-task): ClientException: Container.name contains invalid characters.”

Here is my task code:

resource "aws_ecs_task_definition" "aws-ecs-task" {
  family = "${var.app_name}-task"
  container_definitions = file("templates/task.json")

  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  memory                   = "2048" #2 GB
  cpu                      = "1024" #1 vCPU
  execution_role_arn       = aws_iam_role.ecsTaskExecutionRole.arn
  task_role_arn            = aws_iam_role.ecsTaskExecutionRole.arn

  tags = {
    Name        = "${var.app_name}-ecs-td"
    Environment = var.app_environment
  }
}

Here is the json task definition code:

[{
    "container_name": "${var.app_name}",
    "name": "${var.app_name}",
        "image": "${data.aws_ecr_repository.aws-ecr.repository_url}:latest",
        "essential": true
    },

   {
        "portMappings": [{
            "containerPort": 80,
            "hostPort": 80
        }],
        "cpu": 1024,
        "memory": 2048,
        "networkMode": "awsvpc"
    }
]

I tried replacing the ${var.app_name} in the json to be the name of the app, which is ‘web-2048`, but the error changes to “Container.name should not be null or empty.” When I change the app name back to a variable, then I get the above error again.

I checked the Terraform Registry for aws_ecs_task_definition but didn’t see any info regarding container names. Same for the Aws developer guide section on task definitions but didn’t find anything that helped.

Can I get some guidance on this?

2

Answers


  1. Have you checked if the substitution to the name of your container image contains only valid character and not having ‘.’ in it? The specific error you are getting appears to be because you have included the ‘.’ character in your name attribute. From the above docs:

    Up to 255 letters (uppercase and lowercase), numbers, hyphens, and underscores are allowed

    If that doesn’t resolve ‘Container.name should not be null or empty’ issue, it could be some other reasons, some in the past has mistakenly define the key-value pair labeled in the environment variable key, double check if it’s "name".
    { "name": "xxx", "value": "yyy" }

    Login or Signup to reply.
  2. I managed to reproduce the error. It is because the variables are not replaced with values in the task.json file as you are using the file built-in function:

    file reads the contents of a file at the given path and returns them as a string.

    Because of that, the "name": "${var.app_name}" is read as a string literal. Since that is the case and as per the documentation [1]:

    Up to 255 letters (uppercase and lowercase), numbers, hyphens, and underscores are allowed

    The ., $ and {} are not allowed and that is why you are getting the ClientException: Container.name contains invalid characters. error.

    In order to fix this, I suggest using the templatefile built-in function [2]. It will require some changes to the code:

    resource "aws_ecs_task_definition" "aws-ecs-task" {
      family = "${var.app_name}-task"
      container_definitions = templatefile("templates/task.json", {
        app_name       = var.app_name
        repository_url = data.aws_ecr_repository.aws-ecr.repository_url
      })
    
      requires_compatibilities = ["FARGATE"]
      network_mode             = "awsvpc"
      memory                   = "2048" #2 GB
      cpu                      = "1024" #1 vCPU
      execution_role_arn       = aws_iam_role.ecsTaskExecutionRole.arn
      task_role_arn            = aws_iam_role.ecsTaskExecutionRole.arn
    
      tags = {
        Name        = "${var.app_name}-ecs-td"
        Environment = var.app_environment
      }
    }
    

    This will also require slight modifications in the task.json file:

    [{
          "name": "${app_name}",
          "image": "${repository_url}:latest",
          "essential": true
        },
    
       {
          "portMappings": [{
             "containerPort": 80,
             "hostPort": 80
          }],
            "cpu": 1024,
            "memory": 2048,
            "networkMode": "awsvpc"
        }
    ]
    

    What templatefile will do is replace the placeholder variables you are passing to it (app_name and repository_url) inside of the JSON file with the values you provide. Additionally, you might consider renaming the template file into something like task.json.tftpl. The call to the templatefile function in that case would have to be fixed to:

      container_definitions = templatefile("templates/task.json.tftpl", {
        app_name       = var.app_name
        repository_url = data.aws_ecr_repository.aws-ecr.repository_url
      })
    

    [1] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

    [2] https://developer.hashicorp.com/terraform/language/functions/templatefile

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search