terraformdigital-oceanrke

Terraform tigger a module after a resouce is created


Very new to Terraform so give all the simple advice you got.

I want to setup a RKE-Cluster using/getting the Digital Ocean's newly created droplet IP address. I've setup a local_file to create a txt file in the RKE module (a real weird way to do it but not sure what else I can do.) When I try to terraform plan it I get

on modules/rke/rke.tf line 14, in data "template_file" "rkeip":
│   14:   template = file("${path.module}/rkeip.txt")
│     ├────────────────
│     │ path.module is "modules/rke"
│ 
│ Invalid value for "path" parameter: no file exists at modules/rke/rkeip.txt; this function works only with files
│ that are distributed as part of the configuration source code, so if this file will be created by a resource in
│ this configuration you must instead obtain this result from an attribute of that resource.

Here's what my droplet file looks like

 terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

variable "do_token" {}
variable "ssh_key_name" {}

provider "digitalocean" {
  token = var.do_token
}

data "digitalocean_ssh_key" "default" {
  name = "${var.ssh_key_name}"
}
#this installs Docker
data "template_file" "cloud-yaml" {
  template = file("${path.module}/modules/cloud.yaml")
}

resource "digitalocean_droplet" "terra" {
  image  = "ubuntu-20-04-x64"
  name   = "terra"
  region = "sfo3"
  size   = "s-1vcpu-1gb"
  ssh_keys = ["${data.digitalocean_ssh_key.default.fingerprint}"]
  user_data = data.template_file.cloud-yaml.rendered
}

resource "local_file" "rkeip" {
    content  = "${digitalocean_droplet.terra.ipv4_address}"
    filename = "${path.module}/modules/rke/rkeip.txt"
}

module "RKE" {
    source = "./modules/rke/"
}

and my RKE module

terraform {
  required_providers {
    rke = {
      source  = "rancher/rke"
      version = "1.2.4"
    }
  }
}

data "template_file" "rkeip" {
  template = file("${path.module}/rkeip.txt")
}

provider "rke" {
  log_file = "rke_debug.log"
}

resource "rke_cluster" "test" {
   nodes {
     address = data.template_file.rkeip.rendered
     user    = "root"
     role    = ["controlplane", "etcd", "worker"]
     ssh_key = file("~/.ssh/id_rsa")
    }
}

I've tried to use depends_on in rke.tf and droplet.tf but still same error.


Solution

  • Alrighty it seems that Terraform's rke cannot be made via a droplet in a one-shot so I have decided to use Provisioners to deal with all the mini-steps so for folks in similar positions here's my added code in the droplet.tf.

    resource "null_resource" "rke" {
      connection {
                host = "${digitalocean_droplet.terra.ipv4_address}"
                type = "ssh"
                user = "root"
                private_key = file("${path.module}/YOURDOKEY")
                agent = false
            }
    
        provisioner "file" {
        source      = "${path.module}/keys.sh"
        destination = "/root/keys.sh"
      }
      
      provisioner "remote-exec" {
        inline = [
        "chmod +x /root/keys.sh",
        "./keys.sh",
        "rm keys.sh",
        "wget https://github.com/rancher/rke/releases/download/v1.3.2/rke_linux-amd64",
        "mv rke_linux-amd64 rke",
        "chmod +x rke",
        "printf '%s\n' 'nodes:' '  - address:' '    user: root' '    docker_socket: /var/run/docker.sock' '    role:' '      - controlplane' '      - etcd' '      - worker' '    ssh_key_path: ~/.ssh/id_rsa' >cluster.yml",
        "myip=$(curl ifconfig.co)",
        "sed -i \"s/address:/address: $myip/\" cluster.yml",
        ]
      }
    }
    

    Unfortunately it throws an error if you try ./rke up in remote-exec so you have to run it in the droplet.

    Also I made keys.sh to bypass errors in inline since it did not like the commands. If you managed to place these commands without any errors feel free to comment.

    #!/bin/bash
    # keys.sh
    # create ssh keys without direct input
    ssh-keygen -t rsa -b 4096 -N '' <<<$'\n'
    # so the droplet can ssh itself
    cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
    sed -i '/AllowTcpForwarding/d' /etc/ssh/sshd_config
    echo "AllowTcpForwarding yes" >> /etc/ssh/sshd_config
    # not needed but I wanted to see the output
    grep AllowTcpForwarding /etc/ssh/sshd_config
    

    this is to fix docker errors in rke.