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]: Unexpected force destroy in aws_eks_cluster and aws_eks_nodegroup #28213

Open blaargh opened 1 year ago

blaargh commented 1 year ago

Terraform Core Version

1.3.6

AWS Provider Version

4.42.0

Affected Resource(s)

resource "aws_eks_cluster" resource "aws_eks_node_group" resource "aws_iam_role"

Expected Behavior

When making a change to the trust relationship in the IAM role attached to the cluster/nodegroup manually, Terraform should not force replace both resources.

Terraform should NOT care about the trust relationship in my attached IAM role. It doesn't care about the attached policies either. If you change these things manually, AWS EKS doesn't have problems with it either.

Actual Behavior

When changing the trust relationship in the IAM role attached to the cluster/nodegroup manually, Terraform requires a force replace of both. It doesn't state this explicitly, the force replace is reported on subnet_ids that come from data objects instead.

When reverting the manual change of the trust relationship, everything goes back to normal and Terraform reports that the configuration matches the infrastructure.

Relevant Error/Panic Output Snippet

No response

Terraform Configuration Files

resource "aws_eks_cluster" "cluster" {
  name    = var.cluster_name
  version = "1.23"
  role_arn = var.aws_iam_role_eks_arn
  vpc_config {
    security_group_ids      = [data.aws_security_group.kubernetes.id]
    subnet_ids              = data.aws_subnets.sz.ids
    endpoint_public_access  = false
    endpoint_private_access = true
  }
  lifecycle {
    ignore_changes  = [tags, version]
    prevent_destroy = true
  }
}

resource "aws_eks_node_group" "nodegroup" {
  cluster_name         = aws_eks_cluster.cluster.name
  node_group_name      = "nodegroup"
  node_role_arn        = var.aws_iam_role_eks_arn
  subnet_ids           = data.aws_subnets.sz.ids

  launch_template {
    name    = aws_launch_template.eks.name
    version = aws_launch_template.eks.latest_version
  }
  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_iam_role" "k8s_node" {
  name               = "eks"
  assume_role_policy = data.aws_iam_policy_document.k8s_node.json
}

data "aws_iam_policy_document" "k8s_node" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

Steps to Reproduce

Create an EKS Cluster as well as the attached IAM role via Terraform Modify the IAM Role trust relationship manually in the AWS UI Run Terraform again

Debug Output

No response

Panic Output

No response

Important Factoids

No response

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

justinretzolk commented 1 year ago

Hey @blaargh πŸ‘‹ Thank you for taking the time to raise this! I don't see anything that's connecting the IAM role in the sample config to the nodegroup/cluster, though something you mentioned did catch my eye:

It doesn't state this explicitly, the force replace is reported on subnet_ids that come from data objects instead.

Can you supply the part of the configuration where you're defining the data source for data.aws_subnets.sz.ids, and anything that it's dependent on? I think that's going to be a key detail in determining what's going on here.

blaargh commented 1 year ago

Hi @justinretzolk

the project structure is a bit more complex, but basically this:

β”œβ”€β”€ global.tfvars β”œβ”€β”€ workspace_eks # workspace folder for all eks stuff β”‚ β”œβ”€β”€ variables.tf # passed through variables from .tfvars land here β”‚ β”œβ”€β”€ eks.tf # eks resources that use objects defined from variables.tf

And then the data definition:

data "aws_subnets" "sz" {
  filter {
    name   = "vpc-id"
    values = [var.vpc_id]
  }
  filter {
    name   = "tag:type"
    values = ["sz"]
  }
}

var.vpc_id is coming from variables.tf, the value itself for this is coming from the global.tfvars file

justinretzolk commented 1 year ago

Hey @blaargh πŸ‘‹ Apologies, I should have been more clear (though the configuration bits do help, so happy accident πŸŽ‰). What I was looking for was whether or not the data.aws_subnets.sz data source shows up in the output as a change when you run terraform plan, and what that logging looks like.

bryantbiggs commented 2 days ago

@blaargh is this still an issue or can we close this out now?