Search code examples
amazon-web-servicesterraformamazon-ecsaws-code-deployaws-codepipeline

Codedeploy: provided target group has target type instance, which is incompatible with the awsvpc network mode specified in the task definition


ECS Service definition

resource "aws_ecs_service" "service" {
  name                               = "my-service"
  cluster                            = aws_ecs_cluster.cluster.name
  task_definition                    = aws_ecs_task_definition.task_definition.arn
  deployment_minimum_healthy_percent = 0
  deployment_maximum_percent         = 100
  scheduling_strategy                = "REPLICA"

  load_balancer {
    target_group_arn = var.target_group_arn
    container_name   = var.namespace
    container_port   = 8080
  }

  launch_type = "EC2"

   deployment_controller{
     type="CODE_DEPLOY"
   }

  depends_on = [aws_ecs_task_definition.task_definition]
}

My task:

resource "aws_ecs_task_definition" "task_definition" {
  family             = "task-definition"
  task_role_arn      = aws_iam_role.role.arn
  execution_role_arn = aws_iam_role.role.arn

  container_definitions = <<EOF
  [
    {
      "name": "my-name",
      "image": "my-repo:latest",
      "cpu": 7,
      "dnsSearchDomains": null,
      "logConfiguration": null,
      "entryPoint": null,
      "portMappings": [
        {
          "hostPort": 8081,
          "protocol": "tcp",
          "containerPort": 8080
        },
        {
          "hostPort": 8793,
          "protocol": "tcp",
          "containerPort": 8793
        }
      ],
      "command": null,
      "linuxParameters": null,
      "environment": [],
      "resourceRequirements": null,
      "ulimits": null,
      "dnsServers": null,
      "mountPoints": [
        {
          "readOnly": null,
          "containerPath": "/folder",
          "sourceVolume": "folder"
        },
      ],
      "workingDirectory": null,
      "secrets": null,
      "dockerSecurityOptions": null,
      "memoryReservation": 128,
      "volumesFrom": [],
      "stopTimeout": null,
      "startTimeout": null,
      "firelensConfiguration": null,
      "dependsOn": null,
      "disableNetworking": null,
      "interactive": null,
      "healthCheck": null,
      "essential": true,
      "links": null,
      "hostname": null,
      "extraHosts": null,
      "pseudoTerminal": null,
      "user": null,
      "readonlyRootFilesystem": null,
      "dockerLabels": null,
      "systemControls": null,
      "privileged": null
    }
  ]
  EOF


  volume {
    name      = "folder"
    host_path = "/folder"
  }
}

Deploy groups

resource "aws_codedeploy_deployment_group" "dg" {
  app_name              = aws_codedeploy_app.app.name
  deployment_group_name = aws_codedeploy_app.app.name
  service_role_arn   = aws_iam_role.codedeploy.arn
  deployment_config_name = "CodeDeployDefault.ECSAllAtOnce"

  auto_rollback_configuration {
          enabled = true
          events  = ["DEPLOYMENT_FAILURE"]
  }

  blue_green_deployment_config {
    deployment_ready_option {
      action_on_timeout = "CONTINUE_DEPLOYMENT"
    }

    terminate_blue_instances_on_deployment_success {
      action                           = "TERMINATE"
      termination_wait_time_in_minutes = 5
    }
  }

  deployment_style {
    deployment_option = "WITH_TRAFFIC_CONTROL"
    deployment_type   = "BLUE_GREEN"
  }

  ecs_service {
    cluster_name = "ecs-cluster"
    service_name = "ecs-service"
  }

  load_balancer_info {
    target_group_pair_info {
      prod_traffic_route {
        listener_arns = ["${var.listener_arns}"]
      }

      target_group {
        name = "green_fleet"
      }

      target_group {
        name = "blue_fleet"
      }
    }
  }

}

I get in the codedeploy stage of my codepipeline:

The ECS service cannot be updated due to an unexpected error: The provided target group arn:aws:elasticloadbalancing:XXXXX has target type instance, which is incompatible with the awsvpc network mode specified in the task definition. (Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException; Request ID: dcc0be76-ed36-4c6c-9e8c-327b46fb6ecb; Proxy: null). Check your ECS service status.

EDIT

aws_autoscaling_group

resource "aws_autoscaling_group" "this" {
  name_prefix = var.namespace

  min_size         = 1
  max_size         = 1
  desired_capacity = 1

  launch_configuration      = aws_launch_configuration.lc.name
  vpc_zone_identifier       = compact(split(",", var.private_subnets))
  target_group_arns         = var.target_group_arns
  health_check_type         = "EC2"
  default_cooldown          = 0
  health_check_grace_period = 300

  enabled_metrics = [
    "GroupMinSize",
    "GroupMaxSize",
    "GroupDesiredCapacity",
    "GroupInServiceInstances",
    "GroupPendingInstances",
    "GroupStandbyInstances",
    "GroupTerminatingInstances",
    "GroupTotalInstances",
  ]

  lifecycle {
    create_before_destroy = true
  }
}

aws_alb_target_group

resource "aws_alb_target_group" "http" {
  count = "${length(local.target_groups)}"
  name = "${var.namespace}-http-${
    element(local.target_groups, count.index)
  }"

  port     = 8081
  protocol = "HTTP"
  vpc_id   = var.vpc_id
  target_type = "ip"

  health_check {
    healthy_threshold   = var.health_check_healthy_threshold
    unhealthy_threshold = var.health_check_unhealthy_threshold
    timeout             = var.health_check_timeout
    interval            = var.health_check_interval
    path                = var.path
  }

  lifecycle {
    create_before_destroy = true
  }
}

When I run terraform apply it says:

Provided Target Groups 'arn:elasticloadbalancing:blue/7456', 'arn:elasticloadbalancing:green/37e9e' have invalid target type. Please ensure all provided Target Groups have target type of instance.

And:

 The provided target group arn:aws:elasticloadbalancing:green/37e9e has target type ip, which is incompatible with the bridge network mode specified in the task definition. "pro-airflow-service"

Solution

  • In you target group specified by:

    target_group_arn = var.target_group_arn
    

    ... make sure the Target type is 'IP' as ECS Services cannot work with Instance as target as they need to register the ENI of the task with the load balancer and that is not an Instance but instead an IP address.