Externally Deployed Service With Ignored Task Definition Fails With "InvalidParameterException: TaskDefinition Must Be Blank"

by ADMIN 126 views

Externally Deployed Service with Ignored Task Definition Fails with "InvalidParameterException: TaskDefinition must be blank"

Description

When attempting to create an externally deployed service with task definition changes ignored, the Terraform apply command fails with an InvalidParameterException: TaskDefinition must be blank error. This issue occurs when using the latest version of the Terraform AWS ECS module (v5.12.1) and the AWS provider (v5.95.0).

Versions

  • Module version: v5.12.1 (latest as of the creation of this issue)
  • Terraform version: v1.7.5
  • Provider version(s): v5.95.0

Reproduction Code

The reproduction code is provided below:

provider "aws" {
  region = local.region
}

data "aws_availability_zones" "available" {}

locals {
  region = "eu-west-1"
  name   = "ex-${basename(path.cwd)}"

  vpc_cidr = "10.0.0.0/16"
  azs      = slice(data.aws_availability_zones.available.names, 0, 3)

  container_name = "td-repro"
  container_port = 3000
}

################################################################################
# Cluster
################################################################################

module "complete" {
  source  = "terraform-aws-modules/ecs/aws"
  version = "5.12.1"

  cluster_name = local.name

  services = {
    (local.name) = {
      name = local.name

      ignore_task_definition_changes = true

      deployment_controller = {
        type = "EXTERNAL"
      }

      subnet_ids = module.vpc.public_subnets

      container_definitions = {
        (local.name) = {
          image = "jmalloc/echo-server:latest"
        }
      }

      load_balancer = {
        (local.name) = {
          container_name   = local.name
          container_port   = 8080
          target_group_arn = module.alb.target_groups["ex_ecs"].arn
        }
      }
    }
  }
}

################################################################################
# Supporting Resources
################################################################################

module "alb" {
  source  = "terraform-aws-modules/alb/aws"
  version = "~> 9.0"

  name = local.name

  load_balancer_type = "application"

  vpc_id  = module.vpc.vpc_id
  subnets = module.vpc.public_subnets

  # For example only
  enable_deletion_protection = false

  # Security Group
  security_group_ingress_rules = {
    all_http = {
      from_port   = 80
      to_port     = 80
      ip_protocol = "tcp"
      cidr_ipv4   = "0.0.0.0/0"
    }
  }
  security_group_egress_rules = {
    all = {
      ip_protocol = "-1"
      cidr_ipv4   = module.vpc.vpc_cidr_block
    }
  }

  listeners = {
    ex_http = {
      port     = 80
      protocol = "HTTP"

      forward = {
        target_group_key = "ex_ecs"
      }
    }
  }

  target_groups = {
    ex_ecs = {
      backend_protocol                  = "HTTP"
      backend_port                      = local.container_port      target_type                       = "ip"
      deregistration_delay              = 5
      load_balancing_cross_zone_enabled = true

      health_check = {
        enabled             = true
        healthy_threshold   = 5
        interval            = 30
        matcher             = "200"
        path                = "/"
        port                = "traffic-port"
        protocol            = "HTTP"
        timeout             = 5
        unhealthy_threshold = 2
      }

      # Theres nothing to attach here in this definition. Instead,
      # ECS will attach the IPs of the tasks to this target group
      create_attachment = false
    }
  }
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"

  name = local.name
  cidr = local.vpc_cidr

  azs             = local.azs
  private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
  public_subnets  = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]

  enable_nat_gateway = true
  single_nat_gateway = true
}

Steps to Reproduce the Behavior

  1. Run terraform init to initialize the Terraform working directory.
  2. Run terraform apply to apply the configuration.

Expected Behavior

A cluster, service, and task definition should be created.

Actual Behavior

The terraform apply command fails with an InvalidParameterException: TaskDefinition must be blank error.

Additional Context

This issue is related to the use of the ignore_task_definition_changes parameter in the Terraform AWS ECS module. When this parameter is set to true, the task definition is not created, and the TaskDefinition must be blank error occurs. This issue is specific to the latest version of the Terraform AWS ECS module (v5.12.1) and the AWS provider (v5.95.0).

Terminal Output Screenshot(s)

No screenshot is provided as the issue is related to the Terraform configuration and not a visual output.

Workaround

To work around this issue, you can set the ignore_task_definition_changes parameter to false and create the task definition manually. However, this approach may not be desirable as it requires manual intervention and may not be suitable for automated deployment workflows.

Solution

The solution to this issue is to update the Terraform AWS ECS module to a version that does not have this bug. Alternatively, you can create a custom module that sets the ignore_task_definition_changes parameter to false and creates the task definition manually.
Q&A: Externally Deployed Service with Ignored Task Definition Fails with "InvalidParameterException: TaskDefinition must be blank"

Q: What is the issue with the Terraform AWS ECS module?

A: The issue is that when using the ignore_task_definition_changes parameter in the Terraform AWS ECS module, the task definition is not created, and the TaskDefinition must be blank error occurs.

Q: What is the expected behavior of the Terraform AWS ECS module?

A: The expected behavior is that the task definition is created when using the ignore_task_definition_changes parameter, and the service is deployed successfully.

Q: What is the actual behavior of the Terraform AWS ECS module?

A: The actual behavior is that the TaskDefinition must be blank error occurs when using the ignore_task_definition_changes parameter, and the service deployment fails.

Q: What are the versions of the Terraform AWS ECS module and the AWS provider that are affected by this issue?

A: The issue is specific to the latest version of the Terraform AWS ECS module (v5.12.1) and the AWS provider (v5.95.0).

Q: How can I work around this issue?

A: You can set the ignore_task_definition_changes parameter to false and create the task definition manually. However, this approach may not be desirable as it requires manual intervention and may not be suitable for automated deployment workflows.

Q: What is the solution to this issue?

A: The solution is to update the Terraform AWS ECS module to a version that does not have this bug. Alternatively, you can create a custom module that sets the ignore_task_definition_changes parameter to false and creates the task definition manually.

Q: How can I troubleshoot this issue?

A: You can troubleshoot this issue by checking the Terraform configuration and the AWS provider version. You can also try updating the Terraform AWS ECS module to a newer version and see if the issue is resolved.

Q: What are the best practices for deploying services with the Terraform AWS ECS module?

A: The best practices for deploying services with the Terraform AWS ECS module are to:

  • Use the latest version of the Terraform AWS ECS module and the AWS provider.
  • Set the ignore_task_definition_changes parameter to false if you need to create the task definition manually.
  • Use a custom module to create the task definition and deploy the service.
  • Monitor the service deployment and troubleshoot any issues that arise.

Q: How can I prevent this issue from occurring in the future?

A: You can prevent this issue from occurring in the future by:

  • Keeping the Terraform AWS ECS module and the AWS provider up to date.
  • Using a custom module to create the task definition and deploy the service.
  • Monitoring the service deployment and troubleshooting any issues that arise.