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.88k stars 9.22k forks source link

Provider produced inconsistent final plan #14370

Closed jcarlson closed 3 years ago

jcarlson commented 4 years ago

Community Note

Terraform CLI and Terraform AWS Provider Version

$ terraform -v
Terraform v0.12.23
+ provider.alks v1.3.0
+ provider.archive v1.3.0
+ provider.aws v2.70.0
+ provider.datadog v2.5.0
+ provider.external v1.2.0
+ provider.null v2.1.2
+ provider.random v2.2.1
+ provider.shell v1.3.1
+ provider.template v2.1.2

Affected Resource(s)

Terraform Configuration Files

provider "aws" {
  version = "~> 2.70.0"
  region  = "us-east-1"
}

variable "lb_arn" {
  type = string
  default = "arn:aws:elasticloadbalancing:us-east-1:999999999999:loadbalancer/app/test/abc123def456"
}

variable "vpc_id" {
  type = string
  default = "vpc-abc123def456"
}

resource "aws_lb_target_group" "red" {
  name     = "red"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id
}

resource "aws_lb_target_group" "blue" {
  name     = "blue"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id
}

resource "aws_lb_listener" "main" {
  load_balancer_arn = var.lb_arn
  port              = 80

  default_action {
    type = "forward"

    forward {
      target_group {
        arn = aws_lb_target_group.red.arn
        weight = 50
      }

      target_group {
        arn = aws_lb_target_group.blue.arn
        weight = 50
      }
    }
  }
}

resource "aws_ecs_service" "main" {
  name            = "test"
  cluster         = "my-ecs-cluster"
  task_definition = "my-task-definition"

  dynamic "load_balancer" {
    for_each = {
      (aws_lb_target_group.red.arn) = 80,
      (aws_lb_target_group.blue.arn) = 80
    }

    content {
      container_name = "app"
      container_port = load_balancer.value
      target_group_arn = load_balancer.key
    }
  }
}

Debug Output

https://gist.github.com/jcarlson/88ff26db037953c54f9aeac36d9b7c25

Expected Behavior

Terraform should create an ECS Service associated with two Target Groups

Actual Behavior

Terraform planned to create an ECS Service associated with one Target Group, then failed when the plan changed.

Steps to Reproduce

  1. terraform apply
jcarlson commented 4 years ago

This issue likely has to do with the way the for_each value is set on the dynamic "load_balancer" block. Changing that block to something like the following does work:

  dynamic "load_balancer" {
    for_each = {
      red = aws_lb_target_group.red.arn
      blue = aws_lb_target_group.blue.arn
    }

    content {
      container_name = "app"
      container_port = 80
      target_group_arn = load_balancer.value
    }
  }

However, if the issue is that the for_each keys are not known at plan-time, then the error message doesn't accurately reflect that issue.

bflad commented 3 years ago

Hi folks 👋 Is this still a problem on recent versions of Terraform CLI? There have been various fixes to how dynamic blocks operate over Terraform CLI releases, especially around known versus unknown map keys. This type of issue is not likely resolvable in the Terraform AWS Provider code itself, due to the nature of the issue, but if it is still reproducible we are happy to help ensure there is a covering Terraform CLI issue created.

bflad commented 3 years ago

Closing due to lack of response. As mentioned above, if you have a reproduction case using recent versions of Terraform CLI, please submit an issue upstream. 👍

ghost commented 3 years ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!