Terraform-provider-digitalocean: user_data not working, passes empty string ""

Created on 6 Dec 2018  路  5Comments  路  Source: digitalocean/terraform-provider-digitalocean

Terraform Version

Terraform v0.11.8

  • provider.digitalocean v1.0.2

Affected Resource(s)

  • digitalocean_droplet

    Terraform Configuration Files

// this is a resource in the "runners" dir
resource "digitalocean_droplet" "browser-check-runner" {
  count = "${var.count}"
  region = "${var.region}"
  image  = "docker-18-04"
  name   = "browser-check-runner-${count.index}"
  size   = "s-1vcpu-2gb"
  monitoring = true
  ssh_keys = ["${digitalocean_ssh_key.checkly.fingerprint}"]
  lifecycle  {
    create_before_destroy = true
  }

  provisioner "remote-exec" {
    inline = [
      "until ps -ef | grep [l]auncher.js > /dev/null; do sleep 5; done"
    ]

    connection {
      type     = "ssh"
      user     = "root"
      private_key = "${file("~/.ssh/checkly.pem")}"
    }
  }
}

output "hostname" {
  value = "${var.hostname}"
}

// references the runners resource
module "runners-eu-central-1-test" {
  digitalocean_token = "${var.digitalocean_token}"
  hostname = "browser-check-runner"
  source = "runners"
  region = "fra1"
  count = 1
  user_data = "${file("user-data-fra1-test.yml")}"
  env = "test"
}

Debug Output

2018-12-06T19:03:52.074+0100 [DEBUG] plugin.terraform-provider-digitalocean_v1.0.2_x4: 2018/12/06 19:03:52 [DEBUG] Droplet create configuration: &godo.DropletCreateRequest{Name:"browser-check-runner-0", Region:"fra1", Size:"s-1vcpu-2gb", Image:godo.DropletCreateImage{ID:0, Slug:"docker-18-04"}, SSHKeys:[]godo.DropletCreateSSHKey{godo.DropletCreateSSHKey{ID:0, Fingerprint:"bla bla bla"}}, Backups:false, IPv6:false, PrivateNetworking:false, Monitoring:true, UserData:"", Volumes:[]godo.DropletCreateVolume(nil), Tags:[]string{}}
private_networking: "" => "false"
region: "" => "fra1"
resize_disk: "" => "true"
size: "" => "s-1vcpu-2gb"
ssh_keys.#: "" => "1"
ssh_keys.3775177484: "" => "bla bla bla"
status: "" => ""
vcpus: "" => ""
volume_ids.#: "" => ""

Expected Behavior

Create the DO droplet with user_data .

Actual Behavior

Creates the DO droplet perfectly, just without the user_data. See the debug output, the UserData value is "".

Steps to Reproduce

Terraform apply. Providing the user_data in the Digital Ocean UI does work.

Important Factoids

I use exactly the same user_data files on AWS and that works fine.

Most helpful comment

There shouldn't be any difference in the way the provider handles modules generally.

Here's a very basic example of this working in a module as well:

module "foo" {
  source  = "./module"

  ssh_keys   = ["${data.digitalocean_ssh_key.foo.fingerprint}"]
  user_data  = "${file("user-data.yml")}"
}

And the module itself:

vars.tf

variable "name" {
  description = "name"
  default = "foobar"
}

variable "image" {
  description = "image"
  default = "ubuntu-18-04-x64"
}

variable "region" {
  description = "region"
  default = "nyc1"
}

variable "size" {
  description = "size"
  default = "s-1vcpu-1gb"
}

variable "user_data" {
  description = "user_data"
  default = ""
}

variable "ssh_keys" {
  description = "ssh_keys"
  type = "list"
}

main.tf

resource "digitalocean_droplet" "droplet_node" {
  name = "${var.name}"
  image = "${var.image}"
  region = "${var.region}"
  size = "${var.size}"
  user_data = "${var.user_data}"
  ssh_keys = ["${var.ssh_keys}"]
}

Any differences jumping out to you from what you are using?

All 5 comments

Thanks for the report. Is the source for the module you are using publically available? Passing user data directly in a Droplet resource is working for me as expected. For example:

resource "digitalocean_droplet" "foobar" {
  name       = "foobar-001"
  size       = "s-1vcpu-1gb"
  image      = "ubuntu-18-04-x64"
  region     = "nyc3"
  ssh_keys   = ["${data.digitalocean_ssh_key.foo.fingerprint}"]
  user_data  = "${file("./user-data.yml")}"
}

@andrewsomething it is not regretfully.

But I can confirm when I don't use the module pattern, it works. I think this is a bug in the digital ocean provider, as I use the exact same pattern in my AWS setup, i.e. a "runner" module that provides all the defaults and then a main.tf file where I create instances for each region with some tweaks in the user_data and sometimes the instance types and counts.

Works 100% great on AWS. Is there some difference in how the digital ocean provider handles modules?

There shouldn't be any difference in the way the provider handles modules generally.

Here's a very basic example of this working in a module as well:

module "foo" {
  source  = "./module"

  ssh_keys   = ["${data.digitalocean_ssh_key.foo.fingerprint}"]
  user_data  = "${file("user-data.yml")}"
}

And the module itself:

vars.tf

variable "name" {
  description = "name"
  default = "foobar"
}

variable "image" {
  description = "image"
  default = "ubuntu-18-04-x64"
}

variable "region" {
  description = "region"
  default = "nyc1"
}

variable "size" {
  description = "size"
  default = "s-1vcpu-1gb"
}

variable "user_data" {
  description = "user_data"
  default = ""
}

variable "ssh_keys" {
  description = "ssh_keys"
  type = "list"
}

main.tf

resource "digitalocean_droplet" "droplet_node" {
  name = "${var.name}"
  image = "${var.image}"
  region = "${var.region}"
  size = "${var.size}"
  user_data = "${var.user_data}"
  ssh_keys = ["${var.ssh_keys}"]
}

Any differences jumping out to you from what you are using?

@andrewsomething this fixes it. For some dark reason I did not copy & paste the user_data = "${var.user_data}" in the resource definition from my AWS example. It was staring me right in the face. Sorry for the hassle, thanks for the great support.

No worries. Glad you found a solution!

Was this page helpful?
0 / 5 - 0 ratings