Skip to content

Instantly share code, notes, and snippets.

@gwarf
Last active September 6, 2023 16:44
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gwarf/3d63b24ff86a5311da87baa7ccbb7882 to your computer and use it in GitHub Desktop.
Save gwarf/3d63b24ff86a5311da87baa7ccbb7882 to your computer and use it in GitHub Desktop.
Using terraform in Mac OS X to manage KVM-backed VMs.

Using Terraform on MacOS X to manage KVM-backed VMs

Installing

Terraform

brew install terraform

Installing libvirt provider

brew install golang
go version
go get github.com/dmacvicar/terraform-provider-libvirt
go install github.com/dmacvicar/terraform-provider-libvirt
ls ~/go/bin/terraform-provider-libvirt
mkdir -p ~/.terraform.d/plugins
cp ~/go/bin/terraform-provider-libvirt ~/.terraform.d/plugins
brew install cdrtools

Testing libvirt provider

#cloud-config
users:
  - name: baptiste
    group: users
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_key:
      - SSH_KEY
provider "libvirt" {
  uri = "qemu+ssh://username@SERVER_IP/system?socket=/var/run/libvirt/libvirt-sock"
}

# Use an ubuntu release image from upstream
resource "libvirt_volume" "ubuntu-qcow2" {
  name = "ubuntu-qcow2"
  pool = "guest_images_hddvg"
  source = "https://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img"
  format = "qcow2"
}

# Create a network for our VMs
resource "libvirt_network" "vm_network" {
  name = "vm_network"
  addresses = ["10.0.1.0/24"]
}
 
# Use CloudInit to add our ssh-key to the instance
resource "libvirt_cloudinit_disk" "commoninit" {
  name = "commoninit.iso"
  user_data = "${data.template_file.user_data.rendered}"
}

data "template_file" "user_data" {
  template = "${file("${path.module}/cloud_init.cfg")}"
}

# Create the machine
resource "libvirt_domain" "domain-ubuntu" {
  name = "ubuntu-terraform"
  memory = "512"
  vcpu = 1

  cloudinit = "${libvirt_cloudinit_disk.commoninit.id}"

  network_interface {
    hostname = "master"
    network_name = "vm_network"
  }

  # IMPORTANT
  # Ubuntu can hang is a isa-serial is not present at boot time.
  # If you find your CPU 100% and never is available this is why
  console {
    type        = "pty"
    target_port = "0"
    target_type = "serial"
  }

  console {
    type        = "pty"
    target_type = "virtio"
    target_port = "1"
  }

  disk {
    volume_id = "${libvirt_volume.ubuntu-qcow2.id}"
  }
  graphics {
    type = "spice"
    listen_type = "address"
    autoport = "true"
  }
}

# Print the Boxes IP
# Note: you can use `virsh domifaddr <vm_name> <interface>` to get the ip later
output "ip" {
  value = "${libvirt_domain.domain-ubuntu.network_interface.0.addresses.0}"
}
terraform init
terraform apply
terraform plan

Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment