Terraform Cloud SSH Key for

I’ve been researching setting up DigitalOcean droplets via Terraform Cloud and while I’m still relatively new to this I’m stumped by SSH connections for remote-exec. For my tinkering needs I’m just trying to get a generic ubuntu droplet running then have remote-exec run apt update/upgrade followed by installing nginx.

Running from my local machine I can setup the connection to grab a private SSH key from a local file but I’m a little confused as to how to accomplish this with Terraform Cloud. I have tried puttingthe key into an input variable and an environment variable by removing the line breaks but haven’t managed to get it working.

I’m certain I’m missing something elementary - does anyone have any suggestions to accomplish this or a keyword I’m missing in my google searches that might help?

Hi @ewokninja!

As described on the provisioners documentation page, provisioners are a feature of last resort because they introduce a lot of additional setup complexity, including SSH keys, the need for direct network connectivity from Terraform to instances, etc.

Although that documentation doesn’t talk about DigitalOcean specifically, DigitalOcean does have a user_data feature similar to that of Amazon EC2. If the Ubuntu image includes cloud-init (Ubuntu images on cloud platforms usually do) then you can use cloud-init to configure your droplet by placing either a cloud-init configuration or a shell script directly into the user_data argument of digitalocean_droplet.

cloud-init has a built-in ability to interact with apt for package upgrade and installation, so you might be able to get the result you want declaratively with a cloud-init configuration like this:

  # JSON is a subset of YAML, so we can use JSON encoding
  # here for simplicity as long as we add the #cloud-init
  # prefix to help cloud-init detect it as a configuration.
  user_data = "#cloud-config\n${jsonencode({
    package_update  = true
    package_upgrade = true
    packages = ["nginx"]
  })}"

The key advantage of using cloud-init via user_data is that this configuration is then sent to the droplet indirectly via the DigitalOcean API, rather than requiring Terraform to connect directly to the droplet and log in over SSH.

This avoids the need to configure SSH credentials and the need to have the SSH server accessible from the host where Terraform is running, and it will also generally allow your instance to initialize faster because the initialization process can begin immediately that cloud-init loads, rather than pausing initialization until Terraform has successfully connected via SSH.

Terraform Cloud does have a mechanism to configure an SSH key for a workspace, which you can use in situations where SSH-based provisioning is unavoidable, but I think it should be unnecessary in your case because cloud-init and user_data can solve the same problem in a simpler way.

1 Like

Hi @apparentlymart !

Thank you for the quick response and the details! It makes a lot of sense to make use of cloud-init / user-data and I’ll go down that path with my experimentation!