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.
https://www.terraform.io/
Other
42.74k stars 9.56k forks source link

[FEATURE REQUEST] add prefix or suffix to given parameter while using create_before_destroy #16174

Closed janschumann closed 10 months ago

janschumann commented 7 years ago

Using

  lifecycle {
    create_before_destroy = true
  }

on some resources, e.g. aws_elastic_beanstalk_environment, will result in a resource already exists error. E.g

* aws_elastic_beanstalk_environment.default: InvalidParameterValue: Environment testing already exists.

Usually this is the expected behavior. But in the case of aws_elastic_beanstalk_environment it would be great to have the ability to create a new environment, before destroying the current one. This is currently not possible through terraform.

I propose to respect a configuration like this:

resource "aws_elastic_beanstalk_environment" "foo" {
  name                = "foo"
  application       = "bar"
  cname_prefix   = "foo"

  lifecycle {
    create_before_destroy = true
    on_force_new_resource = {
      attribute = "name"
      prefix      = "${uuid()}_"
    }
  }

Which should create a new elastic beanstalk environment foo_<uuid> every time the environment is forced to be re-created through terraform, leaving the previous environment intact, until the new one has been created successfully.

The recreation can than be forced by

terraform taint aws_elastic_beanstalk_environment.foo
terraform apply

Does this make sense to anyone?

apparentlymart commented 7 years ago

Thanks for sharing this use-case, @janschumann!

In the past we've discussed the idea of exposing some "lifecycle metadata" for each resource that can be interpolated, including a unique id that is remembered in the state but gets re-generated each time the resource is replaced. That might look something like this:

# DRAFT: Not yet implemented and may change before implementation
resource "aws_elastic_beanstalk_environment" "foo" {
  name         = "foo-${meta.self.instance_id}"
  application  = "bar"
  cname_prefix = "foo"

  lifecycle {
    create_before_destroy = true
  }
}

This meta. prefix could potentially expose other interesting information that is maintained by Terraform itself rather than by the provider, such as the timestamp when the resource was created. We'd make sure that meta. behaves as expected when resources are "deposed" as part of the create-before-destroy mechanism, so that the old instance and the new instance both see their own values.

Does this seem like it would address your use-case?

Another related use-case (which I think originally prompted us to sketch out this idea) was referring to metadata about another resource, like this:

# DRAFT: Not yet implemented and may change before implementation
resource "null_resource" "example" {
  triggers = {
    # Re-run the provisioner each time the Elastic Beanstalk environment is replaced
    environment_id = "${meta.aws_elastic_beanstalk_environment.foo.instance_id}"
  }
  provisioner "local-exec" {
    # ...
  }
}

Unfortunately I wasn't able to quickly find the other issue where this was first discussed. :disappointed:


Much later update, Nov 2022: I found the place where I originally proposed this and then a subsequent elaboration of it.

janschumann commented 7 years ago

@apparentlymart yeah that makes sense.

If this use-case will be considered in future, I need to say that I just realized, that also cname_prefix will lead to an error with create_before_destroy. But this parameter should not change, as it is a part of the URL of that environment. So the provided use-case is not really valid.

github-actions[bot] commented 9 months ago

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.