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

Update moved semantics to allow moving a resource managed by an attribute or inline block to a separate resource #35785

Open
lorengordon opened this issue Sep 26, 2024 · 3 comments
Labels
enhancement new new issue not yet triaged

Comments

@lorengordon
Copy link
Contributor

lorengordon commented Sep 26, 2024

Terraform Version

1.9.5

Use Cases

The AWS provider recently approved a proposal for a pattern that will be used going forward to manage "exclusive relationships" between resources. The first implementation of this pattern was for aws_iam_role and their aws_iam_role_policy attachments.

I'm really excited about this new pattern, and would love to adopt it quickly. However, it introduces a dilemma for module authors. How do we refactor the module and minimize the migration pain for users? With the current features available in Terraform, module users would have to write import blocks for every attachment resource, which makes the refactoring backwards-incompatible and a major version bump.

Attempted Solutions

To demonstrate the problem, I attempted to migrate a module we author to use the new exclusive pattern with the aws_iam_role and aws_iam_role_policy resource. You can see that here, plus3it/terraform-aws-tardigrade-iam-principals#205. There's also a discussion of the migration options on the aws provider repo, hashicorp/terraform-provider-aws#39376 (comment).

Proposal

I would like to propose an update for moved block semantics, allowing users to specify a from expression that uniquely identifies a resource managed by an inline block. Using aws_iam_role as an example, it might look like:

moved {
  from = aws_iam_role.example,inline_policy,<inline_policy_name>
  to   = aws_iam_role_policy.example_policy_name
}

Those semantics largely follow the idea of import requirements for the target resource type. For an inline_policy block on an aws_iam_role resource, we only need to know the inline policy name to map the state to the new resource.

It occurs to me that moved does not currently support interpolation, or expressions, or for_each, the way import does. Since these inline blocks do not have state addresses, I think this proposal would also require updates to extend that support to moved blocks. A complete example, to make my pr testing the migration to the exclusive resource simply a feature release, might look like this:

moved {
  for_each = toset(var.inline_policies[*].name)

  from = aws_iam_role.this,inline_policy,${each.value}
  to   = aws_iam_role_policy.this[each.value]
}

And then similarly for attachments of managed policies (once that "exclusive" resource is available), I'd write something like

moved {
  for_each = toset(var.managed_policy_arns)

  from = aws_iam_role.this,managed_policy_arns,${each.value}
  to   = aws_iam_role_policy_attachment.this[each.value]
}

References

@lorengordon lorengordon added enhancement new new issue not yet triaged labels Sep 26, 2024
@lorengordon lorengordon changed the title Update moved semantics to allow moving a resource managed by an inline block to a separate resource Update moved semantics to allow moving a resource managed by an attribute or inline block to a separate resource Sep 27, 2024
@crw
Copy link
Collaborator

crw commented Sep 27, 2024

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!

@crw
Copy link
Collaborator

crw commented Oct 1, 2024

Hi @lorengordon, just wanted to report back that we discussed this in triage today. This is something we have considered, but would require more research as to how to implement as the eventual solution will somewhat complicated. Just as an FYI.

@lorengordon
Copy link
Contributor Author

Thanks for the update @crw. It occurred to me that I could reframe this as an import problem, also. We would need two things from an import block that it cannot do today:

  1. Allow import in modules, instead of only from the root config.
  2. Ability to indicate that import should not fail if the resource does not exist. Import the resource if it does exist, but if it does not then plan to create it as normal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement new new issue not yet triaged
Projects
None yet
Development

No branches or pull requests

2 participants