hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.73k stars 9.09k forks source link

[Bug]: Cannot deploy aws_ecs_service when aws_ecs_task_definition has execution_role_arn: You cannot specify an IAM role for services that require a service linked role #30048

Open chandler1331 opened 1 year ago

chandler1331 commented 1 year ago

Terraform Core Version

1.3.7

AWS Provider Version

4.58.0

Affected Resource(s)

aws_ecs_service

Expected Behavior

When deploying a aws_ecs_service based on aws_ecs_task_definition, on FARGATE, the aws_ecs_service should deploy successfully if the aws_ecs_task_definition resource is created successfully. The execution_role_arn supplied to aws_ecs_task_definition meets all requirements outlined in docs.

Actual Behavior

Error is received: Error: creating ECS Service (#####): InvalidParameterException: You cannot specify an IAM role for services that require a service linked role.

The aws provider via the aws_ecs_service resource will not deploy the service. However if I create the aws_ecs_service manually using the console then use the aws_ecs_service import, there is no error.

Relevant Error/Panic Output Snippet

Here is the tf apply/import along with the code.

Terraform Configuration Files

data "aws_iam_role" "ecsTaskExecutionRole"{
  name = "ecsTaskExecutionRole"
}
resource "aws_ecs_task_definition" "#####" {
  depends_on = [
    aws_iam_role.#####_model,
    aws_ecr_repository.#####,
    aws_cloudwatch_log_group.ecs
  ]
  container_definitions = templatefile("${path.module}/policies/ecs/#####-task-definition.json", {
    #####_service_name      = local.#####_service_name
    #####_container_port    = local.#####_container_port
    #####_container_uri     = local.#####_container_uri
    #####_port_mapping_name = local.#####_port_mapping_name
    #####_ecr_name          = local.#####_container_name
    aws_region            = local.aws_region
  })
  family                   = local.#####_task_name
  execution_role_arn       = data.aws_iam_role.ecsTaskExecutionRole.arn
  network_mode             = "awsvpc"
  requires_compatibilities = ["EC2", "FARGATE"]
  cpu                      = "256"
  memory                   = "1024"
  runtime_platform { operating_system_family = "LINUX" }
}
resource "aws_ecs_service" "#####" {
  depends_on = [
    data.aws_subnet.public_cidrs,
    aws_security_group.#####_ecs,
    aws_ecs_cluster.#####,
    aws_ecs_task_definition.#####
  ]
  cluster                           = aws_ecs_cluster.#####.arn
  health_check_grace_period_seconds = 0
  iam_role                          = "aws-service-role"
  launch_type                       = "FARGATE"
  name                              = local.#####_service_name
  platform_version                  = "LATEST"
  propagate_tags                    = "SERVICE"
  desired_count                     = 1
  enable_ecs_managed_tags           = true
  task_definition      = aws_ecs_task_definition.#####.arn
  force_new_deployment = true
  deployment_circuit_breaker {
    enable   = false
    rollback = false
  }
  deployment_controller {
    type = "ECS"
  }
  load_balancer {
    container_name   = local.#####_service_name
    container_port   = local.#####_container_port
    target_group_arn = aws_lb_target_group.#####_tg.arn
  }
  network_configuration {
    assign_public_ip = true
    security_groups  = [
      aws_security_group.#####_ecs.id
    ]
    subnets = [for s in data.aws_subnet.public_cidrs : s.id]
  }
}

Task Definition:
[
  {
    "name": "${#####_service_name}",
    "image": "${#####_container_uri}",
    "cpu": 0,
    "portMappings": [
      {
        "name": "${#####_port_mapping_name}",
        "containerPort": ${#####_container_port},
        "hostPort": ${#####_container_port},
        "protocol": "tcp"
      }
    ],
    "essential": true,
    "environment": [],
    "mountPoints": [],
    "volumesFrom": [],
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "/ecs/${#####_ecr_name}",
        "awslogs-region": "${aws_region}",
        "awslogs-stream-prefix": "ecs"
      }
    }
  }
]

Steps to Reproduce

terraform apply
terraform import
terraform apply

Debug Output

 PS #####\terraform\templates\#####\#####> tf init -reconfigure
Initializing modules...

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Reusing previous version of hashicorp/local from the dependency lock file
- Reusing previous version of hashicorp/vault from the dependency lock file
- Reusing previous version of databricks/databricks from the dependency lock file
- Reusing previous version of hashicorp/time from the dependency lock file
- Using previously-installed databricks/databricks v1.13.0
- Using previously-installed hashicorp/time v0.9.1
- Using previously-installed hashicorp/aws v4.58.0
- Using previously-installed hashicorp/local v2.4.0
- Using previously-installed hashicorp/vault v3.13.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
PS #####\terraform\templates\#####\#####> tf apply
Terraform will perform the following actions:

  # module.#####_infrastructure.aws_ecs_service.##### will be created
  + resource "aws_ecs_service" "#####" {
      + cluster                            = "arn:aws:ecs:###########:###########:cluster/#####-cluster"
      + deployment_maximum_percent         = 200
      + deployment_minimum_healthy_percent = 100
      + desired_count                      = 1
      + enable_ecs_managed_tags            = true
      + enable_execute_command             = false
      + force_new_deployment               = true
      + health_check_grace_period_seconds  = 0
      + iam_role                           = "aws-service-role"
      + id                                 = (known after apply)
      + launch_type                        = "FARGATE"
      + name                               = "#####"
      + platform_version                   = "LATEST"
      + propagate_tags                     = "SERVICE"
      + scheduling_strategy                = "REPLICA"
      + task_definition                    = "arn:aws:ecs:###########:###########:task-definition/#####-#####-task:3"
      + triggers                           = (known after apply)
      + wait_for_steady_state              = false

      + deployment_circuit_breaker {
          + enable   = false
          + rollback = false
        }

      + deployment_controller {
          + type = "ECS"
        }

      + load_balancer {
          + container_name   = "#####"
          + container_port   = "#####"
          + target_group_arn = "arn:aws:elasticloadbalancing:###########:###########::targetgroup/#####-#####-tg/###########"
        }

      + network_configuration {
          + assign_public_ip = true
          + security_groups  = [
              + "###########",
            ]
          + subnets          = [
              + "###########",
              + "###########",
              + "###########",
            ]
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.#####_infrastructure.aws_ecs_service.#####: Creating...
2023-03-15T16:54:22.477-0600 [ERROR] provider.terraform-provider-aws_v4.58.0_x5.exe: Response contains error diagnostic: tf_provider_addr=registry.terraform.io/hashicorp/aws tf_resource_type=aws_ecs_service diagnostic_detail= diagnostic_severity=ERROR diagnostic_summary="creating ECS Service (#####): InvalidParameterException: You cannot specify an IAM role for services that require a service linked role." tf_proto_version=5.3 tf_req_id=c5d75dfd-6b3d-32af-9dcd-c964a9308b7e tf_rpc=ApplyResourceChange @caller=github.com/hashicorp/terraform-plugin-go@v0.14.3/tfprotov5/internal/diag/diagnostics.go:55 @module=sdk.proto timestamp=2023-03-15T16:54:22.477-0600
2023-03-15T16:54:22.478-0600 [ERROR] vertex "module.#####_infrastructure.aws_ecs_service.#####" error: creating ECS Service (#####): InvalidParameterException: You cannot specify an IAM role for services that require a service linked role.
╷
│ Error: creating ECS Service (#####): InvalidParameterException: You cannot specify an IAM role for services that require a service linked role.
│
│   with module.#####_infrastructure.aws_ecs_service.#####,
│   on ..\..\..\modules\#####\#####\ecs.tf line 59, in resource "aws_ecs_service" "#####":
│   59: resource "aws_ecs_service" "#####" {
│
╵
Releasing state lock. This may take a few moments...
PS #####\terraform\templates\#####\#####> tf import module.#####_infrastructure.aws_ecs_service.##### #####-cluster/#####
Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

Releasing state lock. This may take a few moments...
PS #####\terraform\templates\#####\#####> tf apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # module.#####_infrastructure.aws_ecs_service.##### will be updated in-place
  ~ resource "aws_ecs_service" "#####" {
      + force_new_deployment               = true
        id                                 = "arn:aws:ecs:###########:###########:service/#####-cluster/#####"
        name                               = "#####"
      ~ propagate_tags                     = "NONE" -> "SERVICE"
      ~ task_definition                    = "#####-#####-task:3" -> "arn:aws:ecs:###########:###########:task-definition/#####-#####-task:3"
      + wait_for_steady_state              = false
        # (15 unchanged attributes hidden)
        # (2 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.#####_infrastructure.aws_ecs_service.#####: Modifying... [id=arn:aws:ecs:###########:###########:service/#####-cluster/#####]
module.#####_infrastructure.aws_ecs_service.#####: Modifications complete after 1s [id=arn:aws:ecs:###########:###########:service/#####-cluster/#####]
Releasing state lock. This may take a few moments...

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Panic Output

No response

Important Factoids

data "aws_iam_role" "ecsTaskExecutionRole"{
  name = "ecsTaskExecutionRole"
}
resource "aws_ecs_task_definition" "#####" {
  depends_on = [
    aws_iam_role.#####_model,
    aws_ecr_repository.#####,
    aws_cloudwatch_log_group.ecs
  ]
  container_definitions = templatefile("${path.module}/policies/ecs/#####-task-definition.json", {
    #####_service_name      = local.#####_service_name
    #####_container_port    = local.#####_container_port
    #####_container_uri     = local.#####_container_uri
    #####_port_mapping_name = local.#####_port_mapping_name
    #####_ecr_name          = local.#####_container_name
    aws_region            = local.aws_region
  })
  family                   = local.#####_task_name
  execution_role_arn       = data.aws_iam_role.ecsTaskExecutionRole.arn
  network_mode             = "awsvpc"
  requires_compatibilities = ["EC2", "FARGATE"]
  cpu                      = "256"
  memory                   = "1024"
  runtime_platform { operating_system_family = "LINUX" }
}
resource "aws_ecs_service" "#####" {
  depends_on = [
    data.aws_subnet.public_cidrs,
    aws_security_group.#####_ecs,
    aws_ecs_cluster.#####,
    aws_ecs_task_definition.#####
  ]
  cluster                           = aws_ecs_cluster.#####.arn
  health_check_grace_period_seconds = 0
  iam_role                          = "aws-service-role"
  launch_type                       = "FARGATE"
  name                              = local.#####_service_name
  platform_version                  = "LATEST"
  propagate_tags                    = "SERVICE"
  desired_count                     = 1
  enable_ecs_managed_tags           = true
  task_definition      = aws_ecs_task_definition.#####.arn
  force_new_deployment = true
  deployment_circuit_breaker {
    enable   = false
    rollback = false
  }
  deployment_controller {
    type = "ECS"
  }
  load_balancer {
    container_name   = local.#####_service_name
    container_port   = local.#####_container_port
    target_group_arn = aws_lb_target_group.#####_tg.arn
  }
  network_configuration {
    assign_public_ip = true
    security_groups  = [
      aws_security_group.#####_ecs.id
    ]
    subnets = [for s in data.aws_subnet.public_cidrs : s.id]
  }
}

Task Definition:
[
  {
    "name": "${#####_service_name}",
    "image": "${#####_container_uri}",
    "cpu": 0,
    "portMappings": [
      {
        "name": "${#####_port_mapping_name}",
        "containerPort": ${#####_container_port},
        "hostPort": ${#####_container_port},
        "protocol": "tcp"
      }
    ],
    "essential": true,
    "environment": [],
    "mountPoints": [],
    "volumesFrom": [],
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "/ecs/${#####_ecr_name}",
        "awslogs-region": "${aws_region}",
        "awslogs-stream-prefix": "ecs"
      }
    }
  }
]

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

akinmetin commented 1 month ago

This same issue is also happening for EC2 based ECS service deployments with hashicorp/aws == 5.58.0 when I specify multiple load balancers.