Search code examples
nginxterraformdroplet

Using Terraform to install NGINX without "remote_exec"


resource "digitalocean_droplet" "web-server" {
    image = "ubuntu-18-04-x64"
    name = "web-server"
    region = "nyc2"
    size = "s-1vcpu-1gb"
    ssh_keys = [
        var.ssh_fingerprint
    ]
    connection {
        host = digitalocean_droplet.web-server.ipv4_address
        user = "root"
        type = "ssh"
        private_key = file(var.pvt_key)
        timeout = "2m"
    }
    provisioner "remote-exec" {
        inline = [
            "export PATH=$PATH:/usr/bin",
            "sudo apt-get update",
            "sudo apt-get -y install nginx"
        ]
    }
}

Currently, I'm using the above to install NGINX on a Digital Ocean droplet via Terraform, but is there another way that will let Terraform manage the state of this? I want to be able to manage things like upgrades, load balancing etc and this seems like it's an anti-pattern?


Solution

  • You can use the droplet user_data as described in https://www.terraform.io/docs/providers/do/r/droplet.html.

    Create a template and then use the template rendered as your userdata value

    #!/usr/bin/env bash
    set -x
    exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
    export PATH="$PATH:/usr/bin"
    sudo apt-get update
    sudo apt-get -y install nginx
    

    And your resource will now look like this:

    data "template_file" "userdata" {
      template = "${file("${path.module}/userdata.sh")}"
    }
    
    
     resource "digitalocean_droplet" "web-server" {
            image = "ubuntu-18-04-x64"
            name = "web-server"
            region = "nyc2"
            size = "s-1vcpu-1gb"
            user_data   "${data.template_file.userdata.rendered}"
            ssh_keys = [
                var.ssh_fingerprint
            ]
        }