hetznercloud / terraform-provider-hcloud

Terraform Hetzner Cloud provider
https://registry.terraform.io/providers/hetznercloud/hcloud/latest
Mozilla Public License 2.0
516 stars 74 forks source link

[Bug]: After importing hcloud_server terraform plan is showing fields to be updated #944

Open phoewass opened 5 months ago

phoewass commented 5 months ago

What happened?

I created a terraform hcloud_server to import my server that I created manually.
Then I import it: terraform import hcloud_server.my_server XXXXXXX

It works fine but when I execute terraform plan I see this result:

hcloud_server.my_server: Refreshing state... [id=XXXXXXX]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # hcloud_server.my_server will be updated in-place
  ~ resource "hcloud_server" "my_server" {
      + allow_deprecated_images    = false
      ~ delete_protection          = true -> false
        id                         = "XXXXXXX"
      + ignore_remote_firewall_ids = false
      + keep_disk                  = false
        name                       = "xxxxxxxxxxxx"
      ~ rebuild_protection         = true -> false
      ~ server_type                = "cpx11" -> "cxp11"
      + shutdown_before_deletion   = false
        # (13 unchanged attributes hidden)

      + public_net {
          + ipv4         = (known after apply)
          + ipv4_enabled = true
          + ipv6         = (known after apply)
          + ipv6_enabled = true
        }
    }

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

What did you expect to happen?

terraform plan should show:

No changes. Your infrastructure matches the configuration.

Looking at "terraform.tfstate" file after import, everything looks fine:

{
  "resources": [
    {
      "instances": [
        {
          "attributes": {
            ..
            "delete_protection": true,
            ..
            "rebuild_protection": true,
            ..
            "server_type": "cpx11",

Please provide a minimal working example

terraform: 1.8.4 hetznercloud/hcloud: 1.47

resource "hcloud_server" "my_server" {
  name                = "xxxxxxxxxxxx"
  image               = "ubuntu-20.04"
  server_type         = "cxp11"

  public_net {
    ipv4_enabled = true
    ipv6_enabled = true
  }
}
  1. terraform import hcloud_server.my_server XXXXXXX

  2. terraform plan

uda commented 2 months ago

This happened to me as well, it looks like the public_net and network fields are not imported, maybe an API change.

The weird thing though, I copied the network section for private network, but no matter what the IP you put it doesn't trigger a change.

Anyway, now no changes are shown in plan.

{
            "network": [
              {
                "alias_ips": [],
                "ip": "INTERNAL_IP",
                "mac_address": "MA:CA:DD:RE:SS:00",
                "network_id": NETWORK_ID
              }
            ],
            "public_net": [
              {
                "ipv4": IPV4_ID,
                "ipv4_enabled": true,
                "ipv6": IPV6_ID,
                "ipv6_enabled": true
              }
            ],
}
apricote commented 2 months ago

I can reproduce the issue. I have written an acceptance test that also exhibits the bug:

func TestServerResource_ImportPublicNet(t *testing.T) {
    // Regression test for https://github.com/hetznercloud/terraform-provider-hcloud/issues/944
    var s hcloud.Server

    sk := sshkey.NewRData(t, "server-import-public-net")
    res := &server.RData{
        Name:    "server-import-public-net",
        Type:    teste2e.TestServerType,
        Image:   teste2e.TestImage,
        SSHKeys: []string{sk.TFID() + ".id"},
        PublicNet: map[string]interface{}{
            "ipv4_enabled": true,
            "ipv6_enabled": true,
        },
    }
    res.SetRName("server-import-public-net")

    tmplMan := testtemplate.Manager{}
    resource.ParallelTest(t, resource.TestCase{
        PreCheck:                 teste2e.PreCheck(t),
        ProtoV6ProviderFactories: teste2e.ProtoV6ProviderFactories(),
        CheckDestroy:             testsupport.CheckResourcesDestroyed(server.ResourceType, server.ByID(t, &s)),
        Steps: []resource.TestStep{
            {
                Config: tmplMan.Render(t,
                    "testdata/r/hcloud_ssh_key", sk,
                    "testdata/r/hcloud_server", res,
                ),
                Check: resource.ComposeTestCheckFunc(
                    testsupport.CheckResourceExists(res.TFID(), server.ByID(t, &s)),
                ),
            },
            {
                // Try to import the newly created Server. Verify that import of "public_net" works
                ResourceName:      res.TFID(),
                ImportState:       true,
                ImportStateVerify: true,
                ImportStateVerifyIgnore: []string{
                    "ssh_keys", "user_data", "keep_disk", "ignore_remote_firewall_ids", "allow_deprecated_images", "shutdown_before_deletion",
                },
            },
        },
    })
}

@phoewass You have some additional changes in between the actual configuration of your server and what you have defined in terraform:

apricote commented 2 months ago

Applying the patch from #597 fixes this particular issue. But in the comments of the PR I wrote:

Closing as I have not managed to fix the bugs that came with my changes. This will be easier to implement after https://github.com/hetznercloud/terraform-provider-hcloud/issues/752

I will take another look if I can fix the bugs now.

apricote commented 2 months ago

The bugs from #597 are still there and can not be fixed with the SDKv2. We will need to migrate the hcloud_server resource to the Plugin Framework to have a chance of making progress here.

Sorry for this annoying resolution :(