Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1-TO-1 dependency on multi-instance resources #34211

Open
marcofortina opened this issue Nov 9, 2023 · 3 comments
Open

1-TO-1 dependency on multi-instance resources #34211

marcofortina opened this issue Nov 9, 2023 · 3 comments

Comments

@marcofortina
Copy link

Terraform Version

Terraform v1.6.3
on linux_amd64

Use Cases

Using this simple test-case:

resource "local_file" "a" {
  count = 3

  filename = "/tmp/a-${count.index}.txt"
  content = "Risorsa A locale creata da Terraform ${count.index}"
}

resource "local_file" "b" {
  count = length(local_file.a)

  depends_on = [local_file.a]

  filename = "/tmp/b-${count.index}.txt"
  content = "Risorsa B locale creata da Terraform ${count.index}"
}

This is the output of terraform apply:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # local_file.a[0] will be created
  + resource "local_file" "a" {
      + content              = "Risorsa A locale creata da Terraform 0"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/a-0.txt"
      + id                   = (known after apply)
    }

  # local_file.a[1] will be created
  + resource "local_file" "a" {
      + content              = "Risorsa A locale creata da Terraform 1"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/a-1.txt"
      + id                   = (known after apply)
    }

  # local_file.a[2] will be created
  + resource "local_file" "a" {
      + content              = "Risorsa A locale creata da Terraform 2"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/a-2.txt"
      + id                   = (known after apply)
    }

  # local_file.b[0] will be created
  + resource "local_file" "b" {
      + content              = "Risorsa B locale creata da Terraform 0"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/b-0.txt"
      + id                   = (known after apply)
    }

  # local_file.b[1] will be created
  + resource "local_file" "b" {
      + content              = "Risorsa B locale creata da Terraform 1"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/b-1.txt"
      + id                   = (known after apply)
    }

  # local_file.b[2] will be created
  + resource "local_file" "b" {
      + content              = "Risorsa B locale creata da Terraform 2"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/b-2.txt"
      + id                   = (known after apply)
    }

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

As you can see, terraform will create first all "local_file" "a" resource and after all "local_file" "b" resource.

It could be nice to have a sort of 1-TO-1 dependency on multi-instance resources, so terraform will create alternately each instance of "local_file" "a" and "local_file" "b":

Terraform will perform the following actions:

  # local_file.a[0] will be created
  + resource "local_file" "a" {
      + content              = "Risorsa A locale creata da Terraform 0"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/a-0.txt"
      + id                   = (known after apply)
    }

  # local_file.b[0] will be created
  + resource "local_file" "b" {
      + content              = "Risorsa B locale creata da Terraform 0"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/b-0.txt"
      + id                   = (known after apply)
    }

  # local_file.a[1] will be created
  + resource "local_file" "a" {
      + content              = "Risorsa A locale creata da Terraform 1"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/a-1.txt"
      + id                   = (known after apply)
    }

  # local_file.b[1] will be created
  + resource "local_file" "b" {
      + content              = "Risorsa B locale creata da Terraform 1"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/b-1.txt"
      + id                   = (known after apply)
    }

  # local_file.a[2] will be created
  + resource "local_file" "a" {
      + content              = "Risorsa A locale creata da Terraform 2"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/a-2.txt"
      + id                   = (known after apply)
    }

  # local_file.b[2] will be created
  + resource "local_file" "b" {
      + content              = "Risorsa B locale creata da Terraform 2"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/tmp/b-2.txt"
      + id                   = (known after apply)
    }

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

It could be nice if this should be done with:

depends_on = [local_file.a[count.index]]

Attempted Solutions

N/A

Proposal

Please, implements dependency based on count.index

depends_on = [local_file.a[count.index]]

and modify apply order in this way:


local_file.a[0]: Creating...
local_file.a[0]: Creation complete after 0s [id=aa3f8214673fe48dbffa00c0bf482aef7258d0cb]
local_file.b[0]: Creating...
local_file.b[0]: Creation complete after 0s [id=c0a5b2ca321691f4205075661e9ac56087f003e4]
local_file.a[1]: Creating...
local_file.a[1]: Creation complete after 0s [id=fa8b2f2df2d31ce98db8e4dbb92d18e35679d73e]
local_file.b[1]: Creating...
local_file.b[1]: Creation complete after 0s [id=1609ce6a76506ccfb235f9f484b409d07d3e4795]
local_file.a[2]: Creating...
local_file.a[2]: Creation complete after 0s [id=865afe722281f06b5d8290312a8def9feb0415f1]
local_file.b[2]: Creating...
local_file.b[2]: Creation complete after 0s [id=58e049f0c9d26ecc474a03c683de8ceb1c971fbe]

References

No response

@marcofortina marcofortina added enhancement new new issue not yet triaged labels Nov 9, 2023
@marcofortina
Copy link
Author

marcofortina commented Nov 9, 2023

The new feature should also manage the destroy operation in this way:

terraform destroy --target=local_file.a[2]

local_file.b[2]: Destroying... [id=58e049f0c9d26ecc474a03c683de8ceb1c971fbe]
local_file.b[2]: Destruction complete after 0s
local_file.a[2]: Destroying... [id=865afe722281f06b5d8290312a8def9feb0415f1]
local_file.a[2]: Destruction complete after 0s

Destroy complete! Resources: 2 destroyed.

This should destroy only local_file.a[2] and (due the depends_on) local_file.b[2], leaving all other instances of local_file.a and local_file.b untouched.

@crw
Copy link
Contributor

crw commented Nov 10, 2023

Thanks for this feature request! If you are viewing this issue and would like to indicate your interest, please use the 👍 reaction on the issue description to upvote this issue. We also welcome additional use case descriptions. Thanks again!

@jbardin
Copy link
Member

jbardin commented Nov 13, 2023

Hi @marcofortina,

Thanks for filing the issue. Though a slightly different request, the underlying restrictions here are the same as in #27188, #28330, and #30841. Terraform was designed to track dependencies between whole resources, and because the graph must be built from configuration before there are any individual instances, only connections between whole resource blocks can be made at that point. Reconstructing how these dependencies are handled would need to be part of a very large redesign of the core of Terraform.

@jbardin jbardin added core and removed new new issue not yet triaged labels Nov 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants