canonical / terraform-provider-maas

Terraform MAAS provider
Mozilla Public License 2.0
64 stars 45 forks source link

user_data is not imported when importing machines #93

Closed dekarl closed 12 months ago

dekarl commented 1 year ago

To test https://github.com/maas/terraform-provider-maas/issues/15 I migrated my homelab from roblox/maas to maas/maas.

It appears that user_data is not being imported leading to terraform wanting to replace the machine. The machine contains data so I'd prefer to be able to switch providers without reinstalling them.

My current workaround was to remove the user_data section from my terraform code, but that is an ugly kludge.

https://gitlab.com/dekarl/homelab/-/commit/64a95a8884db53a17ae27ee25c24982cc2c1b989

skatsaounis commented 1 year ago

Hi @dekarl

Can you please provide a terraform plan after the import? I would like to see which value is making Terraform want to replace the machine. I am expecting deploy_params as a whole rather than user_data but I would like to confirm.

dekarl commented 1 year ago
Terraform will perform the following actions:

  # maas_instance.k3s_master[0] must be replaced
-/+ resource "maas_instance" "k3s_master" {
      ~ cpu_count    = 4 -> (known after apply)
      ~ fqdn         = "key-boxer.maas" -> (known after apply)
      ~ hostname     = "key-boxer" -> (known after apply)
      ~ id           = "pgx6as" -> (known after apply)
      ~ ip_addresses = [
          - "192.168.68.254",
        ] -> (known after apply)
      ~ memory       = 65536 -> (known after apply)
      ~ pool         = "default" -> (known after apply)
      ~ tags         = [
          - "64gb",
          - "t630-64gb",
        ] -> (known after apply)
      ~ zone         = "default" -> (known after apply)

      + allocate_params { # forces replacement
          + min_cpu_count = 0
          + min_memory    = 0
          + tags          = [
              + "64gb",
            ]
        }

      # Warning: this block will be marked as sensitive and will
      # not display in UI output after applying this change
      ~ deploy_params { # forces replacement
          # At least one attribute in this block is (or was) sensitive,
          # so its contents will not be displayed.
        }
    }
skatsaounis commented 1 year ago

The issue here is the following. When we import an instance to the state after contacting the MAAS API, we store to the state only its ID: https://github.com/maas/terraform-provider-maas/blob/master/maas/resource_maas_instance.go#L31

Next step is the terraform plan. When plan is running, it detects that the definition contains among others an deploy_params block, which among others includes user_data, that it is not present in the state. Since that particular field has the attribute ForceNew set (https://github.com/maas/terraform-provider-maas/blob/master/maas/resource_maas_instance.go#L86), Terraform will try to recreate the instance before saving the block to the state. In your snippet, we also see allocate_params trying to recreate the instance for the same reason.

Based on the above, your statement about the user_data is correct. We could save the user_data being used to deploy the existing instance but I am afraid that is information cannot be found in what MAAS REST API is returning.

dekarl commented 1 year ago

I've looked around GUI, API and database and could not find the user_data (only an empty table around the metadataserver) so I guess it's only there until the machine is deployed. So it appears it's not something easy to add to the provider.

I'll try deploying some new machines and see what happens wrt user_data when I find some spare time for experiments. Thank you for looking into it.

skatsaounis commented 12 months ago

Hi @dekarl, I am going to close this issue but before that I want to explain the reasoning.

maas_instance is a resource that is used to deploy/redeploy/release a machine. Starting with a set of MAAS machines in Ready state and a fresh Terraform state:

When you import an existing Deployed machine to the Terraform state, as mentioned in my initial comment, only the system ID is imported. By having definitions on each of the aforementioned blocks, it is an indication to Terraform to perform delete and create. The MAAS translation for this is Release and Deploy. So the behavior with the user_data that you faced is a feature.

Based on your issue though and another one (#45) I was able to find a missing bit on this feature. With #117, this functionality will be more complete. Maybe, we will have another one to enhance what information is recorded when importing the resource but it will be only for computed fields.

Thanks for opening the issue and raising awareness.