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.85k stars 9.2k forks source link

[Bug]: aws_s3_object.x.etag using existing value rather than (known after apply) #30029

Open samwarley opened 1 year ago

samwarley commented 1 year ago

Terraform Core Version

1.0.11

AWS Provider Version

4.58.0

Affected Resource(s)

Expected Behavior

I am attempting to trigger an instance refresh when an S3 object is updated. I am trying to do this by updating the tags in the launch template with the etag of the S3 object, which would then trigger a new version of the launch template, and consequently an instance refresh.

I expect the tag to use the etag for the object added as part of the apply and as such the plan for my tags to show:

tag_specifications {
          ~ tags          = {
              ~ "App Env Hash" = "<old_etag>" -> "(known after apply)"
        }

Actual Behavior

However instead of doing this, it uses the existing etag for the object in the state, so if the etag is out of date, the plan shows:

tag_specifications {
          ~ tags          = {
              ~ "App Env Hash" = "<old_etag>" -> "<current_etag_in_state>"
        }

Which then leads to the following error as the etag is updated as the new object is uploaded.

Relevant Error/Panic Output Snippet

│ Error: Provider produced inconsistent final plan
│
│ When expanding the plan for module.asg_main.aws_launch_template.this[0] to include new values learned so far during apply, provider
│ "registry.terraform.io/hashicorp/aws" produced an invalid new value for .tag_specifications[0].tags["App Env Hash"]: was
│ cty.StringVal("<current_etag_in_state>"), but now cty.StringVal("<known_after_apply_etag>").
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.

Terraform Configuration Files

resource "aws_s3_object" "app_env" {
  key                    = "<some_key>.env"
  bucket                 = aws_s3_bucket.config.id
  server_side_encryption = "aws:kms"
  content                 = templatefile("files/<some_source>.env",
    {
      variables = {
        "IAM_ENDPOINT" = "Hi"
    }
}
module "asg_main" {
  source  = "terraform-aws-modules/autoscaling/aws"
  version = "6.7.1"

  # Autoscaling group
  name            = join("-", [var.label, var.environment])
  use_name_prefix = false

  min_size                  = var.min_number_of_instances
  max_size                  = var.max_number_of_instances
  desired_capacity          = var.default_number_of_instances
  wait_for_capacity_timeout = "10m"
  health_check_type         = "ELB"
  health_check_grace_period = 600
  vpc_zone_identifier       = var.private_subnets
  load_balancers            = [module.elb_external.id, module.elb_internal.id]

  instance_refresh = {
    strategy = "Rolling"
    preferences = {
      checkpoint_delay       = 60
      checkpoint_percentages = [100]
      min_healthy_percentage = 50
    }
  }

  # Launch template
  launch_template_name            = join("-", [var.label, var.environment])
  launch_template_description     = join("-", [var.label, var.environment])
  launch_template_use_name_prefix = false
  update_default_version          = true

  key_name          = var.key_name
  image_id          = data.aws_ami.main.id
  instance_type     = var.instance_type
  user_data         = base64encode(templatefile("files/user_data.sh", { bucket_name = aws_s3_bucket.config.id }))
  security_groups   = [module.sg_instance.security_group_id]
  ebs_optimized     = false
  enable_monitoring = true

  # IAM role & instance profile
  create_iam_instance_profile = true
  iam_role_use_name_prefix    = false
  iam_role_name               = join("-", [var.label, var.environment])
  iam_role_description        = join("-", [var.label, var.environment])
  iam_role_path               = "/"
  iam_role_policies = {
    main = aws_iam_policy.instance_profile.arn
  }

  block_device_mappings = [
    {
      # Root volume
      device_name = "/dev/sda1"
      no_device   = 0
      ebs = {
        delete_on_termination = true
        encrypted             = true
        kms_key_id            = "arn:aws:kms:eu-west-1:${var.packer_build_account_id}:alias/ebs"
        volume_size           = var.instance_storage_capacity
        volume_type           = "gp2"
      }
    }
  ]

  tag_specifications = [
    {
      resource_type = "instance"
      tags          = "${merge({"App Env Hash" = aws_s3_object.app_env.etag}, var.tags)}"
    },
    {
      resource_type = "volume"
      tags          = "${merge({"App Env Hash" = aws_s3_object.app_env.etag}, var.tags)}"
    }
  ]

  tags = "${merge({"App Env Hash" = aws_s3_object.app_env.etag}, var.tags)}"

}

Steps to Reproduce

Attempt to reference the aws_s3_object.x.etag output in a configuration when updating the aws_s3_object.x resource as part of apply.

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