terraform-provider-digitalocean: droplet: Inconsistent plan output from 1.0.0 to 1.0.2

Terraform Version

 Terraform v0.11.8
 + provider.acme v1.0.1
 + provider.cloudflare v1.3.0
- + provider.digitalocean v1.0.0
+ + provider.digitalocean v1.0.2
 + provider.google v1.17.1
 + provider.local v1.1.0
 + provider.mailgun v0.1.0
 + provider.null v1.0.0
 + provider.random v2.0.0
 + provider.template v1.0.0
 + provider.tls v1.2.0

Affected Resource(s)

  • digitalocean_droplet

Terraform Configuration Files

resource "digitalocean_droplet" "server" {
  name       = "${var.server_name}"
  image      = "ubuntu-18-04-x64"
  region     = "${var.server_region}"
  size       = "${var.server_size}"
  backups    = "${var.server_backups_enabled}"
  monitoring = "${var.server_monitoring_enabled}"
  user_data  = "${data.template_file.cloud_config.rendered}"
  tags       = ["terraform-managed"]

  lifecycle {
    ignore_changes = [
      "user_data",
    ]
  }
}

Debug Output

Unfortunately, I can’t provide a trace

Expected Behavior

Same plan output

Actual Behavior

  • v1.0.0

    Refreshing Terraform state in-memory prior to plan...
    The refreshed state will be used to calculate this plan, but will not be
    persisted to local or remote state storage.
    
    <redacted>
    
    digitalocean_droplet.server: Refreshing state... (ID: <redacted>)
    
    <redacted>
    
    ------------------------------------------------------------------------
    
    No changes. Infrastructure is up-to-date.
    
    This means that Terraform did not detect any differences between your
    configuration and real physical resources that exist. As a result, no
    actions need to be performed.
    
  • v1.0.2

    Refreshing Terraform state in-memory prior to plan...
    The refreshed state will be used to calculate this plan, but will not be
    persisted to local or remote state storage.
    
    <redacted>
    
    digitalocean_droplet.server: Refreshing state... (ID: <redacted>)
    
    <redacted>
    
    ------------------------------------------------------------------------
    
    An execution plan has been generated and is shown below.
    Resource actions are indicated with the following symbols:
      ~ update in-place
    -/+ destroy and then create replacement
    
    Terraform will perform the following actions:
    
    <redacted>
    
    -/+ module.one.digitalocean_droplet.server (new resource required)
          id:                   "<redacted>" => <computed> (forces new resource)
          image:                "37208325" => "ubuntu-18-04-x64" (forces new resource)
          <redacted>
    
    <redacted>
    ------------------------------------------------------------------------
    
    Note: You didn't specify an "-out" parameter to save this plan, so Terraform
    can't guarantee that exactly these actions will be performed if
    "terraform apply" is subsequently run.
    

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform plan with v1.0.0
  2. terraform plan with v1.0.2

Important Factoids

  • $ doctl compute droplet get <redacted> -o json | jq '.[].image'

    {
      "id": 37208325,
      "name": "18.04 x64",
      "type": "snapshot",
      "distribution": "Ubuntu",
      "regions": [
        "nyc1",
        "sfo1",
        "nyc2",
        "ams2",
        "sgp1",
        "lon1",
        "nyc3",
        "ams3",
        "fra1",
        "tor1",
        "sfo2",
        "blr1"
      ],
      "min_disk_size": 20,
      "created_at": "2018-08-14T20:03:35Z"
    }
    
  • $ doctl compute image get ubuntu-18-04-x64 -o json

    [
      {
        "id": 38897365,
        "name": "18.04 x64",
        "type": "snapshot",
        "distribution": "Ubuntu",
        "slug": "ubuntu-18-04-x64",
        "public": true,
        "regions": [
          "nyc1",
          "sfo1",
          "nyc2",
          "ams2",
          "sgp1",
          "lon1",
          "nyc3",
          "ams3",
          "fra1",
          "tor1",
          "sfo2",
          "blr1"
        ],
        "min_disk_size": 20,
        "created_at": "2018-10-05T16:44:52Z"
      }
    ]
    
  • default.tfstate

    {
        "version": 3,
        "terraform_version": "0.11.8",
        "serial": 90,
        "lineage": "d9a9709a-052f-1397-8026-d913d84d1e8e",
        "modules": [
            {
                "path": [ "root" ],
                "outputs": {},
                "resources": {"<redacted>"},
                "depends_on": []
            },
            {
                "path": [ "root", "one" ],
                "outputs": {},
                "resources": {
                    "digitalocean_droplet.server": {
                        "type": "digitalocean_droplet",
                        "depends_on": [ "data.template_file.cloud_config" ],
                        "primary": {
                            "id": "<redacted>",
                            "attributes": {
                                "id": "<redacted>",
                                "image": "ubuntu-18-04-x64",
                                <redacted>
                            },
                            "meta": {
                                "schema_version": "1"
                            },
                            "tainted": false
                        },
                        "deposed": [],
                        "provider": "provider.digitalocean"
                    }
                },
                "depends_on": []
            }
        ]
    }
    

Notes

  • Ran terraform on two machines ( ubuntu 16.04 & 18.04 )
  • I checked the changes between v1.0.0 & v1.0.2 and couldn’t find a reason for this behavior
  • At the time of server creation, I suspect that digitalocean was returning a slug in the api response but no longer does as the image id is not associated with the latest distribution image available

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 17 (3 by maintainers)

Commits related to this issue

Most upvoted comments

@eddiezane I can’t provide a reproducible test case as it appears by changes in digitalocean api response over time, but I’ll try to explain how I think it happens.

using this configuration:

resource "digitalocean_droplet" "server" {
  name   = "server"
  image  = "ubuntu-18-04-x64"
  region = "nyc1"
  size   = "s-1vcpu-1gb"
}

terraform apply will submit a godo.DropletCreateRequest with godo.Image.Slug set https://github.com/terraform-providers/terraform-provider-digitalocean/blob/20da9cd4e9536597c8cd0f8ad661e001ae4f6a70/digitalocean/resource_digitalocean_droplet.go#L208-L214

and store the slug returned in tfstate https://github.com/terraform-providers/terraform-provider-digitalocean/blob/20da9cd4e9536597c8cd0f8ad661e001ae4f6a70/digitalocean/resource_digitalocean_droplet.go#L304-L311

this works great as the resource uses a slug and godo.Droplets.Get returns a slug in the response.

sometime passes, Digitalocean updated their official distribution image and moved the “ubuntu-18-04-x64” to point to another image, while the droplet created above stores a reference to an old image ( in digitalocean ) which is no longer identified by the slug.

next terrafrom apply fires godo.Droplets.Get, the response doesn’t contain an image slug and we trip this condition https://github.com/terraform-providers/terraform-provider-digitalocean/blob/20da9cd4e9536597c8cd0f8ad661e001ae4f6a70/digitalocean/resource_digitalocean_droplet.go#L305-L308

terrafrom now thinks we changed the image when we didn’t, DigitalOcean just changed their response.

I hope I made it clearer, If this doesn’t clear it up I’ll look into pointing you at one of our servers which has this problem

A fix for this issue should be available in v1.12.0. In order to upgrade an existing project to the latest version, run:

terraform init -upgrade

You can find the full changelog here: https://github.com/terraform-providers/terraform-provider-digitalocean/blob/master/CHANGELOG.md#120-april-23-2019