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

Fully declarative version of "terraform state rm" that supports creating new resources #36303

Open
nightpool opened this issue Jan 10, 2025 · 0 comments
Labels
enhancement new new issue not yet triaged

Comments

@nightpool
Copy link

Terraform Version

Terraform v1.10.2
on darwin_arm64

Use Cases

I have a module named "s3_bucket" that encapsulated the bucket itself, CloudWatch alarms, Cloudfront distributions, Route53 records, etc. My configuration looks like this:

module "rehosted_images_bucket" {
  source = "../modules/s3_bucket"

  bucket = "images.example.dev"
  ...
}

import {
  to = module.rehosted_images_bucket.aws_s3_bucket.bucket
  id = "images.example.dev"
}

I set this up for 10 or so buckets. However, I noticed after doing the import + setup that I got one of the bucket's names wrong. We had an empty bucket with a similar name, and I substituted that instead. I would like to keep all of the resources in the module the same, but point them at the correct bucket.

Right now, the naive change (changing the id of the import and the bucket name in the module var), forces recreation of the bucket:

module "rehosted_images_bucket" {
  source = "../modules/s3_bucket"

  bucket = "example-dev-images"
  ...
}

import {
  to = module.rehosted_images_bucket.aws_s3_bucket.bucket
  id = "example-dev-images"
}

image

Instead of forcing recreation, I would like to re-import the correct bucket into management and drop the old incorrect bucket from terraform management.

Attempted Solutions

My first attempted solution was to use the removed block, since I know removed is the declarative version of terraform state rm:

removed {
  from = module.rehosted_images_bucket.aws_s3_bucket.bucket
  lifecycle {
    destroy = false
  }
}

However, this had no effect. Unlike terraform state rm, removed blocks do not seem to do anything when the resource still exists in the configuration:

Initializing plugins and modules...
╷
│ Error: Removed resource still exists
│ 
│   on ../modules/s3_bucket/s3_bucket.tf line 8:
│    8: resource "aws_s3_bucket" "bucket" {
│ 
│ This statement declares that
│ module.rehosted_images_bucket.aws_s3_bucket.bucket was removed, but it is
│ still declared in configuration.
╵
Operation failed: failed running terraform plan (exit 1)

Then, I had the idea of using a moved block. I would move the bucket to an "ignored" address, and then the old address would be free to import the new resource:

moved {
  from = module.rehosted_images_bucket.aws_s3_bucket.bucket
  to   = aws_s3_bucket.ignored_images_bucket
}

This had a similar issue:

╷
│ Error: Moved object still exists
│ 
│   on s3_buckets.tf line 37:
│   37: moved {
│ 
│ This statement declares a move from
│ module.rehosted_images_bucket.aws_s3_bucket.bucket, but that resource is
│ still declared at ../modules/s3_bucket/s3_bucket.tf:8,1.
│ 
│ Change your configuration so that this resource will be declared as
│ aws_s3_bucket.ignored_images_bucket instead.
╵

Proposal

Allow either (or both!) "removed" or "moved" blocks to reference existing configuration, since there are obviously very valid use-cases for it.

This would also have the benefit of simplifying the checks these blocks need to do, and (at least to a first glance) only involve removing code, not adding new code.

References

No response

@nightpool nightpool added enhancement new new issue not yet triaged labels Jan 10, 2025
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

1 participant