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.1k forks source link

Terraform doesn't recognize that aws_ec2_traffic_mirror_session should be rebuilt if aws_ec2_traffic_mirror_target is due to change #20567

Closed ekristen closed 22 hours ago

ekristen commented 3 years ago

Community Note

Terraform CLI and Terraform AWS Provider Version

Terraform v1.0.0
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v3.45.0

Your version of Terraform is out of date! The latest version
is 1.0.4. You can update by downloading from https://www.terraform.io/downloads.html

Affected Resource(s)

Terraform Configuration Files

Please include all Terraform configurations required to reproduce the bug. Bug reports without a functional reproduction may be closed without investigation.

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}
resource "aws_instance" "test" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
}
resource "aws_ec2_traffic_mirror_filter" "filter" {
  description      = "traffic mirror filter - terraform example"
}

resource "aws_ec2_traffic_mirror_target" "target" {
  network_load_balancer_arn = aws_lb.lb.arn
}

resource "aws_ec2_traffic_mirror_session" "session" {
  description              = "traffic mirror session - terraform example"
  network_interface_id     = aws_instance.test.primary_network_interface_id
  session_number           = 1
  traffic_mirror_filter_id = aws_ec2_traffic_mirror_filter.filter.id
  traffic_mirror_target_id = aws_ec2_traffic_mirror_target.target.id
}

Expected Behavior

When a target changes the session should be marked for replacement too.

Basically if the aws_instance is replaced or gets a new primary network interface, this will make the target change, the session is dependent on the target and it should be replaced as well.

Actual Behavior

The session does not detect it needs to be replaced and AWS reports a conflict because the target can't be replaced when a session is still using it.

Steps to Reproduce

  1. terraform apply
  2. terraform taint aws_resource.test
  3. terraform plan
  4. terraform apply
ewbankkit commented 3 years ago

@ekristen Thanks for raising this issue. According to the AWS API Reference a session's target can be updated with the caveat that

The target must be in the same VPC as the source, or have a VPC peering connection with the source.

The User Guide isn't so clear on this.

What behavior do you see if the session gets update in place?

ekristen commented 3 years ago

Hi @ewbankkit the issue is that when terraform deems that the resource aws_ec2_traffic_mirror_target needs replacing, it needs to do the same for the aws_ec2_traffic_mirror_session, otherwise it attempts to destroy the target without destroying the sessions and that causes a conflict because the sessions still exist and are referencing the old and is unable to delete the target to replace it.

The conflict is that the session references a target that terraform wants to replacement but hasn't deleted the session reference to be able to delete the target.

aeshaynes commented 2 years ago

Also seeing this error when using v4.23.0 of the provider.

Terraform v1.2.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v4.23.0
Terraform will perform the following actions:

  # module.core.aws_ec2_traffic_mirror_session.capture[0] will be updated in-place
  ~ resource "aws_ec2_traffic_mirror_session" "capture" {
        id                       = "tms-redacted"
        tags                     = {}
      ~ traffic_mirror_target_id = "tmt-redacted" -> (known after apply)
        # (9 unchanged attributes hidden)
    }

  # module.core.aws_ec2_traffic_mirror_session.capture[1] will be updated in-place
  ~ resource "aws_ec2_traffic_mirror_session" "capture" {
        id                       = "tms-redacted"
        tags                     = {}
      ~ traffic_mirror_target_id = "tmt-redacted" -> (known after apply)
        # (9 unchanged attributes hidden)
    }

  # module.core.aws_ec2_traffic_mirror_target.capture[0] must be replaced
-/+ resource "aws_ec2_traffic_mirror_target" "capture" {
      ~ arn                  = "arn:aws:ec2:redacted:traffic-mirror-target/tmt-redacted" -> (known after apply)
      ~ id                   = "tmt-redacted" -> (known after apply)
      ~ network_interface_id = "eni-redacted" -> (known after apply) # forces replacement
      ~ owner_id             = "redacted" -> (known after apply)
      - tags                 = {} -> null
      ~ tags_all             = {} -> (known after apply)
        # (1 unchanged attribute hidden)
    }
aeshaynes commented 2 years ago

I believe this should be quite a simple fix

internal/service/ec2/vpc_traffic_mirror_session.go:

"traffic_mirror_target_id": {
                                Type:     schema.TypeString,
                                Required: true,
                    +>>>        ForceNew: true,
},
github-actions[bot] commented 1 month ago

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!