From 9f68d39731b2e03c5835eb6d25790108ec4bb93f Mon Sep 17 00:00:00 2001 From: surtur Date: Wed, 28 Apr 2021 02:41:22 +0200 Subject: [PATCH] initial commit --- .gitignore | 30 ++++++++++++ libvirt.tf | 34 +++++++++++++ vms/cloudinit.cfg | 55 +++++++++++++++++++++ vms/main.tf | 114 +++++++++++++++++++++++++++++++++++++++++++ vms/terraform.tfvars | 38 +++++++++++++++ 5 files changed, 271 insertions(+) create mode 100644 .gitignore create mode 100644 libvirt.tf create mode 100644 vms/cloudinit.cfg create mode 100644 vms/main.tf create mode 100644 vms/terraform.tfvars diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..78c77a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +### Terraform ### +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log + +# Ignore any .tfvars files that are generated automatically for each Terraform run. Most +# .tfvars files are managed as part of configuration and so should be included in +# version control. +# +# example.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + diff --git a/libvirt.tf b/libvirt.tf new file mode 100644 index 0000000..2acd560 --- /dev/null +++ b/libvirt.tf @@ -0,0 +1,34 @@ +terraform { + required_providers { + libvirt = { + source = "dmacvicar/libvirt" + version = "0.6.3" + } + } +} + +provider "libvirt" { + uri = "qemu:///system" +} + +resource "libvirt_domain" "terraform_libvirt" { + name = "terraform_libvirt" + + console { + type = "pty" + target_type = "serial" + target_port = "0" + } + + console { + type = "pty" + target_type = "virtio" + target_port = "1" + } + + graphics { + type = "spice" + listen_type = "address" + autoport = true + } +} diff --git a/vms/cloudinit.cfg b/vms/cloudinit.cfg new file mode 100644 index 0000000..843fb9e --- /dev/null +++ b/vms/cloudinit.cfg @@ -0,0 +1,55 @@ +#cloud-config +# vim: ft=yaml + +runcmd: + - cat /etc/resolv.conf + - uname -r + +ssh_pwauth: true +chpasswd: + list: | + root:1234 + expire: false + +users: + - name: victim + ssh_authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBtG6NCgdLHX4ztpfvYNRaslKWZcl6KdTc1DehVH4kAL + sudo: ['ALL=(ALL) NOPASSWD:ALL'] + shell: /bin/bash + groups: wheel + - name: root + ssh_authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBtG6NCgdLHX4ztpfvYNRaslKWZcl6KdTc1DehVH4kAL + - name: ansible + ssh_authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBtG6NCgdLHX4ztpfvYNRaslKWZcl6KdTc1DehVH4kAL + sudo: ['ALL=(ALL) NOPASSWD:ALL'] + shell: /bin/bash + groups: wheel + +ssh_publish_hostkeys: + enabled: false +ssh: + emit_keys_to_console: false + +# hostname is set based on main.tf variables +preserve_hostname: false +fqdn: ${hostname}.${domainname} +hostname: ${hostname} + + +# reboot after fqdn is set to update the info in libvirt's dnsmasq +power_state: + delay: "+1" + mode: reboot + condition: true + +packages: + - vim + - htop + - sudo + - python39 # for ansible + +package_upgrade: true +package_reboot_if_required: true diff --git a/vms/main.tf b/vms/main.tf new file mode 100644 index 0000000..57cd179 --- /dev/null +++ b/vms/main.tf @@ -0,0 +1,114 @@ +# tf provider declaration +terraform { + # required_version = ">= 0.13" + required_providers { + libvirt = { + source = "dmacvicar/libvirt" + version = "0.6.3" + } + } +} + +# provider URI for libvirt +provider "libvirt" { + uri = "qemu:///system" +} + +# server settings are defined in terraform.tfvars +# the variables here are the defaults in case no relevant terraform.tfvars setting is found +variable "projectname" { + type = string + default = "vms" +} +variable "hosts" { + default = { + "vm1" = { + name = "vm1", + vcpu = 1, + memory = "1024", + diskpool = "default", + disksize = "4000000000", + mac = "12:12:00:12:12:00", + }, + } +} +variable "baseimagediskpool" { + type = string + default = "default" +} +variable "domainname" { + type = string + default = "domain.local" +} +variable "networkname" { + type = string + default = "default" +} +variable "sourceimage" { + type = string + default = "https://download.fedoraproject.org/pub/fedora/linux/releases/33/Cloud/x86_64/images/Fedora-Cloud-Base-33-1.2.x86_64.qcow2" +} + +# base OS image +resource "libvirt_volume" "baseosimage" { + name = "baseosimage_${var.projectname}" + source = var.sourceimage + pool = var.baseimagediskpool +} + +# vdisk creation +# vdisks are cloned from the base image for each of the "hosts" +resource "libvirt_volume" "qcow2_volume" { + for_each = var.hosts + name = "${each.value.name}.qcow2" + base_volume_id = libvirt_volume.baseosimage.id + pool = each.value.diskpool + format = "qcow2" + size = each.value.disksize +} + +# Use cloudinit config file +# pass certain vars to cloudinit +data "template_file" "user_data" { + template = file("${path.module}/cloudinit.cfg") + for_each = var.hosts + vars = { + hostname = each.value.name + domainname = var.domainname + } +} + +# cloudinit magic +resource "libvirt_cloudinit_disk" "commoninit" { + for_each = var.hosts + name = "commoninit_${each.value.name}.iso" + user_data = data.template_file.user_data[each.key].rendered +} + +# default guest +resource "libvirt_domain" "default_guest" { + for_each = var.hosts + name = each.value.name + vcpu = each.value.vcpu + memory = each.value.memory + + network_interface { + network_name = var.networkname + mac = each.value.mac + # do not wait for a lease if networkname == "host-bridge" + wait_for_lease = var.networkname == "host-bridge" ? false : true + } + + disk { + volume_id = element(libvirt_volume.qcow2_volume[each.key].*.id, 1) + } + + cloudinit = libvirt_cloudinit_disk.commoninit[each.key].id + +} + + +output "hostnames" { + value = [libvirt_domain.default_guest.*] +} + diff --git a/vms/terraform.tfvars b/vms/terraform.tfvars new file mode 100644 index 0000000..aa7e16a --- /dev/null +++ b/vms/terraform.tfvars @@ -0,0 +1,38 @@ +# project name +projectname = "vms" + +# OS image +#sourceimage = "https://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.3.2011-20201204.2.x86_64.qcow2" +sourceimage = "https://download.fedoraproject.org/pub/fedora/linux/releases/33/Cloud/x86_64/images/Fedora-Cloud-Base-33-1.2.x86_64.qcow2" + +# the base image is the source image for all VMs created from it +baseimagediskpool = "default" + + +# domain and network settings +domainname = "local" +networkname = "default" # default==NAT + + +# host-specific settings +# RAM in bytes +# disk size in bytes (disk size must be greater than source image virtual size) +hosts = { + "victim" = { + name = "victim", + vcpu = 1, + memory = "512", + diskpool = "default", + disksize = "4300000000", + mac = "00:00:00:13:37:22", + }, + "attacker" = { + name = "attacker", + vcpu = 1, + memory = "1024", + diskpool = "default", + disksize = "4300000000", + mac = "00:00:00:13:37:23", + }, +} +