Jack Moore

Email: jack(at)jmoore53.com
Project Updates

Terraform and Infrastructure as Code

15 Oct 2022 » code, infrastructure, automation

I needed a better way to blow away and setup my dev environment which is where Terraform came in to use for me.

Below is what the code looks like:

Proxmox

On the PVE Server:

pveum role add TerraformProv -privs "VM.Allocate VM.Clone VM.Config.CDROM VM.Config.CPU VM.Config.Cloudinit VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Monitor VM.Audit VM.PowerMgmt Datastore.AllocateSpace Datastore.Audit"
pveum user add terraform-prov@pve --password <password>
pveum aclmod / -user terraform-prov@pve -role TerraformProv

Variables from where terraform will be run:

export PM_USER=terraform-user@pve
export PM_PASS=theterraformpassword

Terraform Config

terraform {
  required_providers {
    proxmox = {
      source  = "telmate/proxmox"
      version = "2.9.11"
    }
  }
}

provider "proxmox" {
  pm_api_url = "https://proxmox.ip:8006/api2/json"
}

locals {
    servers = {
        "node1" = {vmid = 600, node = "proxmox-server-1", clone = "proxmox-cloud-init-template-1", cloudinintip = "ip=172.16.0.1/24,gw=172.16.0.254", ip = "172.16.0.1", tag = "17"},
        "node2" = {vmid = 601, node = "proxmox-server-1", clone = "proxmox-cloud-init-template-1", cloudinintip = "ip=172.16.0.2/24,gw=172.16.0.254", ip = "172.16.0.2", tag = "17"},
        "node3" = {vmid = 602, node = "proxmox-server-2", clone = "proxmox-cloud-init-template-2", cloudinintip = "ip=172.16.0.3/24,gw=172.16.0.254", ip = "172.16.0.3", tag = "17"},
    }
}

/* Uses Cloud-Init options from Proxmox 5.2 */
resource "proxmox_vm_qemu" "getkubedon" {
  for_each = local.servers

  name        = each.key
  vmid        = each.value.vmid
  desc        = "Terraform Test VM"
  target_node = each.value.node 

  clone = each.value.clone

  memory  = 4096
  cpu = "kvm64"
  cores = 2
  network {
    model = "virtio"
    bridge = "vmbr1"
    tag = each.value.tag
  }

  ssh_user        = "root"
  ssh_private_key = <<EOF
-----BEGIN OPENSSH PRIVATE KEY-----
private key here
-----END OPENSSH PRIVATE KEY-----
EOF

  os_type   = "cloud-init"
  ipconfig0 = each.value.cloudinintip
  nameserver = "172.16.0.253"
  hotplug  = "network,disk,usb"

  sshkeys = <<EOF
publickeyhere...
EOF

  provisioner "remote-exec" {
    inline = [
      "ip a"
    ]
    connection {
        type     = "ssh"
        user     = "ubuntu"
        host     = each.value.ip       
        private_key = file("/home/jack/.ssh/id_rsa")
    }
  }
}

Running terraform:

terraform plan
terraform apply

To destroy the infrastructure:

terraform plan -destroy
terraform apply -destroy

Note:

  • After these nodes have been deployed I have an ansible script to provision all the nodes.
  • Terraform is only responsible for deploying the servers and blowing them away
© Jack Moore