hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.

Home Page:https://www.terraform.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Terraform does not respect -replace option

EugenKon opened this issue · comments

Terraform Version

terraform version
Terraform v1.8.4
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v5.51.1
+ provider registry.terraform.io/hashicorp/external v2.3.3
+ provider registry.terraform.io/hashicorp/local v2.5.1
+ provider registry.terraform.io/hashicorp/null v3.2.2
+ provider registry.terraform.io/hashicorp/random v3.6.2
+ provider registry.terraform.io/hashicorp/tls v4.0.5

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

Terraform Configuration Files

Not relevant

Debug Output

  # module.dns.aws_route53_record.base-private-cloud[0] will be updated in-place
  ~ resource "aws_route53_record" "base-private-cloud" {
        id                               = "*_A"
        name                             = "example.com"
      ~ records                          = [
          - "*",
        ] -> (known after apply)
        # (7 unchanged attributes hidden)
    }
...
  # module.private-cloud.aws_instance.server[0] will be replaced, as requested
-/+ resource "aws_instance" "server" {
      ~ ami                                  = "ami-*" -> "ami-*" # forces replacement
      ~ arn                                  = "arn:aws:ec2:us-west-2:*:instance/i-*
...
  # module.private-cloud.aws_instance.www[0] must be replaced
-/+ resource "aws_instance" "www" {
      ~ ami                                  = "ami-*" -> "ami-*" # forces replacement
      ~ arn                                  = "arn:aws:ec2:us-west-2:*:instance/i-*" -> (known after apply)
...

Expected Behavior

I changed the ami for the instance. Because I have two instances based on this AMI terraform plan tries to update both instances and domain name for the server as expected. The instances are independed of each other. To perform my task I want to update only one "server" instance thus I used -replace option:

terraform -chdir=derived-src/aws/ plan -state=../../state.d/terraform.tfstate -replace "module.private-cloud.aws_instance.server[0]" -out repl

I expect that only one "server" instance will be replaced (and possible dependant resources).

Actual Behavior

The other instance was updated.

Steps to Reproduce

  1. Create two instances
  2. Change AMI for both instances (in our case the AMI option refers to the same variable in configuration. Thus changing one variable interfere with both instances)
  3. I want to restrict replacement to the only one "server" host thus I used "-replace" option
  4. terraform -chdir=derived-src/aws/ plan -state=../../state.d/terraform.tfstate -replace "module.private-cloud.aws_instance.server[0]" -out repl
  5. terraform -chdir=derived-src/aws/ apply -state=../../state.d/terraform.tfstate repl (aside not: it would be nice to get -chdir and -state options from the saved plan, thus it would be as simple as terraform apply repl
  6. Both instances are replaces, though they are independent of each other.

Additional Context

No response

References

No response

Hi @EugenKon,

The -replace flag is equivalent to running "terraform taint" on the target resource instance, which means it must be replaced during the next plan. The -replace flags does not limit actions to the target resource, the configuration is still evaluated in its entirety. If you've made a change to the configuration which would normally force replacement (like changing the AMI for an AWS instance), then the -replace flag is not needed, it will be replaced anyway by the provider. It's possible you may be able to get the result you want via the -target flag, but there is not going to be any way to avoid eventually replacing the other instance without continued use of -target or adding the attribute to ignore_changes.

We use GitHub issues for tracking bugs and enhancements, rather than for questions. While we can sometimes help with certain simple problems here, it's better to use the community forum where there are more people ready to help.

Thanks!

@jbardin I used to the behaviour when commands only those things which are told to them. Eg. to replace the target and dependant object I should use -replace XXX -dependant.

Without options it is expected that terraform works with whole configuration, but if "filtering" options are provided, then the scope should be limited to them.

As was described here -target still does not limit the scope to the given target =(.

So it would be nice to have -replace-target will imply -replace, -target and will ignore dependant objects. There should be some useful tool to manage the scope of resources to which a command is applied.

Probably this is the behaviour how it was designed, but this is not the expected behaviour and increases a learning curve. I hope this explanation will help.

Regards.

The -replace feature is not designed to limit the scope at all, so is working as intended here. If you want to limit the plan, then you could provide the same target address to the -target flag. It is true that -target will include all necessary dependencies to apply the resource, which is required for normal Terraform operation.

If you are interested in a feature to more precisely limit the actions that Terraform will take, we have generally wrapped all similar -target related feature requests into #2253. Since many of those ideas are generally not compatible with the current operation of Terraform, it's going to require a larger project to come up with a different UI and planning mechanism which is why there have been no changes yet.

@jbardin Thank you for the provided link. Subscribed.

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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.