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

terraform.tfstate in inconsistent state when tofu/terraform is interrupted (null project, remote, etc.) #199

Open
gdonval opened this issue Feb 19, 2025 · 4 comments
Labels
Maybe Undecided whether in scope for the project

Comments

@gdonval
Copy link

gdonval commented Feb 19, 2025

Variables are not properly written in terraform.tfstate if tofu/terraform is interrupted.

They do exist and, crucially, name is written down but the rest is incorrect. E.g. "project"=null instead of the actual project name for instance.

This affects refresh, plan, apply and probably other commands that need correct information to act.


$ tofu refresh
incus_instance.instance-user-1000: Refreshing state... [name=test-instance1]
╷
│ Error: Failed to retrieve instance "test-instance1"
│ 
│   with incus_instance.instance-user-1000,
│   on test.tf line 15, in resource "incus_instance" "instance-user-1000":
│   15: resource "incus_instance" "instance-user-1000"{
│ 
│ User does not have permission for project "default"

The user is in incus, I use the local user unix socket. My tf file is minimal:

terraform {
  required_providers {
    incus = {
      source = "lxc/incus"
      version = "0.2.0"
    }
  }
}

provider incus {
}


resource "incus_instance" "instance-user-1000"{
  project = "user-1000"
  name    = "test-instance1"
  image   = "images:alpine/edge"
}


terraform.tfstate contains:

{..., "instances":[{"name": "test-instance1", "project": null, "remote": null, ...}]...}

I expected:

{..., "instances":[{"name": "test-instance1", "project": "user-1000", ...}]...}

since it's known and that would allow me to tear down the instance that was created without modifying terraform.tfstate to make it work.

@gdonval gdonval changed the title Terraform tries (and fails) to access project "default" when issuing a refresh when user is restricted terraform.tfstate in inconsistent state when tofu/terraform is interrupted (null project, remote, etc.) Feb 19, 2025
@gdonval
Copy link
Author

gdonval commented Feb 19, 2025

Reproducer, wait_for_network = true but no NIC. Just Ctrl+C when you are tired of it and look at your inconsistent terraform.tfstate

terraform {
  required_providers {
    incus = {
      source = "lxc/incus"
      version = "0.2.0"
    }
  }
}

provider incus {
  # Configuration options
}


resource "incus_profile" "myprofile" {
  name = "myprofile"
  project = incus_project.myproject.name

  device {
    type = "disk"
    name = "root"
    properties = {
      pool = "default"
      size = "1GiB"
      path = "/"
    }
  }

  # No NIC
}

resource "incus_project" "myproject" {
  name        = "myproject"
  description = "Trying to set everything right for user"
  config = {
    "features.storage.volumes" = false
    "features.images"          = false
    "features.profiles"        = true
    "features.networks"        = false
    "features.storage.buckets" = false
    restricted = true
  }
}

resource "incus_instance" "instance1"{
  project  = incus_project.myproject.name
  name     = "gene-instance1"
  image    = "images:alpine/edge"
  profiles = [incus_profile.myprofile.name]
  wait_for_network = true
}

@maveonair
Copy link
Member

I’m not sure if this is a bug.

Terraform creates a new resource, like a new instance, and waits for it to be created. Then, it gets the new information, like IP addresses, and stores it in the state. Since the resource is created in Incus and you cancel the execution, it means we’d have to clean up everything we did before, which isn’t really something Terraform takes care of.

I think you can reproduce this behavior with other providers like AWS, where you create something that takes time and then suddenly interrupt the execution with CTRL+C. The resource will be created, but due to the interrupt, the state isn’t stored in Terraform, so the state is now out of sync.

@maveonair maveonair added the Maybe Undecided whether in scope for the project label Feb 21, 2025
@gdonval
Copy link
Author

gdonval commented Feb 21, 2025

I’m not sure if this is a bug.

I think it is, but it might be a terraform bug instead of a terraform provider bug.

it gets the new information

Instance is created, on a remote, in a project. That is done and known. Then it waits for network to come up but it never does. It gets gracefully killed (there is a nuance there). At the stage execution is cancelled, I expect terraform to know (and write down), not only the name of the instance as it does now, but also on which remote and in what project.

Since the resource is created in Incus and you cancel the execution, it means we’d have to clean up everything we did before, which isn’t really something Terraform takes care of.

Agreed.

The resource will be created, but due to the interrupt, the state isn’t stored in Terraform, so the state is now out of sync.

It is stored... Just partially... Yet terraform has all the info: the moment the action "create instance X on remote Y in project Z" was executed, all that info should be persisted, not just "instance X on remote 'null' in project 'null'".

@maveonair
Copy link
Member

It is stored... Just partially... Yet terraform has all the info: the moment the action "create instance X on remote Y in project Z" was executed, all that info should be persisted, not just "instance X on remote 'null' in project 'null'".

As you mentioned, this is a Terraform issue because it doesn’t work the way you expect. But here’s the thing: this is a special situation where a user interrupts the execution flow. In this case, we can’t guarantee that everything is synced properly.

Terraform shows you the plan before you confirm it. Once you confirm, Terraform expects to run to the end without any interruptions from you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Maybe Undecided whether in scope for the project
Development

No branches or pull requests

2 participants