Introduction to state repair in Terraform

Sometimes you want to change Terraform code without destroying and restoring resources. Following use case might come up: You create an S3 bucket which is the input bucket for some other party. The other party is supposed to upload data into that bucket to be processed by your application. Following code might be used to create the bucket:

resource "aws_s3_bucket" "bucket" {
  bucket = "4bc627ca-23f7-41ab-a9b0-d800128beb56"

After an apply the bucket is created. Let’s see the current state:

$ terraform state list

Now that the bucket exist you tell the other party the bucket name so that they know where to upload data to. We ignore policy setup here. After some thinking you conclude it is time to refactor the name bucket into input_bucket as it is more appropriate for it’s purpose. So you change the name and do an apply:

  # aws_s3_bucket.bucket will be destroyed
  - resource "aws_s3_bucket" "bucket" {
    - bucket = "4bc627ca-23f7-41ab-a9b0-d800128beb56" -> null

  # aws_s3_bucket.input_bucket will be created
  + resource "aws_s3_bucket" "input_bucket" {
    + bucket = "4bc627ca-23f7-41ab-a9b0-d800128beb56"

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

This change destroys the old bucket and re-creates it. For a brief moment the bucket name will be available again for others to claim because S3 bucket names are a globally shared namespace. We want to avoid that scenario even though it is unlikely.

To reconnect Terraforms with the new variable name we need to move the item in the state:

$ terraform state mv aws_s3_bucket.bucket aws_s3_bucket.input_bucket
Move "aws_s3_bucket.bucket" to "aws_s3_bucket.input_bucket"
Successfully moved 1 object(s).

A listing of the state now shows:

$ terraform state list

The variable is now moved to the new name. Let’s see what happens when we try an apply:

$ terraform apply
aws_s3_bucket.input_bucket: Refreshing state... [id=4bc627ca-23f7-41ab-a9b0-d800128beb56]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

We could avoid a re-creation of the resource and a potential loss of the bucket name!

Leave a Reply

Your email address will not be published.