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.74k stars 9.09k forks source link

[Bug]: aws_elasticsearch_domain dynamic "ebs_options" block not removed when appropriate #38951

Open staschuk-auvik opened 3 weeks ago

staschuk-auvik commented 3 weeks ago

Terraform Core Version

1.9.4

AWS Provider Version

5.63.1

Affected Resource(s)

aws_elasticsearch_domain

Expected Behavior

If a dynamic ebs_options block on an aws_elasticsearch_domain exists, but then is removed due to changes of variable values in a subsequent run, then the plan should propose to remove the block.

Actual Behavior

In the scenario described, the plan does not propose to remove the dynamic block.

Relevant Error/Panic Output Snippet

No response

Terraform Configuration Files

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "5.63.1"
    }
  }
}

variable "ebs" { type = bool }

resource "aws_elasticsearch_domain" "moo" {
  domain_name = "ebs-options-test"
  elasticsearch_version = "7.9"
  cluster_config {
    instance_count = 1
    instance_type = "${var.ebs ? "r6g" : "r6gd"}.large.elasticsearch"
  }
  dynamic "ebs_options" {
    for_each = var.ebs ? [1] : []
    content {
      ebs_enabled = true
      volume_size = 10
    }
  }
}

Steps to Reproduce

With the attached file moo.tf, run

terraform init
terraform apply -var ebs=true

This completes normally, creating an Elasticsearch domain with a single r6g data node.

Then run

terraform plan -out plan -var ebs=false

Note that the resulting plan proposes only to change the instance type, and not also to remove the ebs_options block:

Terraform will perform the following actions:

  # aws_elasticsearch_domain.moo will be updated in-place
  ~ resource "aws_elasticsearch_domain" "moo" {
        id                    = "arn:aws:es:us-east-1:012345678901:domain/ebs-options-test"
        tags                  = {}
        # (8 unchanged attributes hidden)

      ~ cluster_config {
          ~ instance_type            = "r6g.large.elasticsearch" -> "r6gd.large.elasticsearch"
            # (8 unchanged attributes hidden)

            # (1 unchanged block hidden)
        }

        # (8 unchanged blocks hidden)
    }

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

As a result, the update fails, because r6gd instances don't support EBS volumes:

aws_elasticsearch_domain.moo: Modifying... [id=arn:aws:es:us-east-1:012345678901:domain/ebs-options-test]
╷
│ Error: updating Elasticsearch Domain (arn:aws:es:us-east-1:012345678901:domain/ebs-options-test) config: ValidationException: Instance type r6gd.large.elasticsearch does not support EBS storage
│ 
│   with aws_elasticsearch_domain.moo,
│   on moo.tf line 12, in resource "aws_elasticsearch_domain" "moo":
│   12: resource "aws_elasticsearch_domain" "moo" {
│ 
╵

Indeed, the planned values in the plan file show that the ebs_options block is still present:

% terraform show -json plan | jq '.planned_values.root_module.resources[] | select(.address == "aws_elasticsearch_domain.moo") | .values.ebs_options' 
[
  {
    "ebs_enabled": true,
    "iops": 3000,
    "throughput": 125,
    "volume_size": 10,
    "volume_type": "gp3"
  }
]

Workaround

Don't use a dynamic block, but instead write

  ebs_options {
    ebs_enabled = var.ebs
    volume_size = var.ebs ? 10 : null
  }

(and to similarly null out all other arguments to the ebs_options block that one might wish to use).

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

No

github-actions[bot] commented 3 weeks ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue