From 7a3a43e8c338795f8219128b2248f2828c177bb7 Mon Sep 17 00:00:00 2001 From: Davide Oddone Date: Tue, 15 Oct 2024 23:07:16 +0200 Subject: [PATCH] First working prototype of Terraform deployment with libvirt --- terraform/.local/.ssh/id_rsa | 38 ++++++++ terraform/.local/.ssh/id_rsa.pub | 1 + terraform/LICENSE | 22 +++++ terraform/cloud_init.cfg | 21 +++++ terraform/main.tf | 156 +++++++++++++++++++++++++++++++ terraform/outputs.tf | 11 +++ 6 files changed, 249 insertions(+) create mode 100644 terraform/.local/.ssh/id_rsa create mode 100644 terraform/.local/.ssh/id_rsa.pub create mode 100644 terraform/LICENSE create mode 100644 terraform/cloud_init.cfg create mode 100644 terraform/main.tf create mode 100644 terraform/outputs.tf diff --git a/terraform/.local/.ssh/id_rsa b/terraform/.local/.ssh/id_rsa new file mode 100644 index 0000000..1bf62aa --- /dev/null +++ b/terraform/.local/.ssh/id_rsa @@ -0,0 +1,38 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +qof6Kt1gSBsFEAAAAAAQID +-----END OPENSSH PRIVATE KEY----- diff --git a/terraform/.local/.ssh/id_rsa.pub b/terraform/.local/.ssh/id_rsa.pub new file mode 100644 index 0000000..d167c61 --- /dev/null +++ b/terraform/.local/.ssh/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC9UBUz5D7CU6Iw1YCzsBSCWtAUDPWUNsxCaXJuYxpBO7qOpSUUtEpAD/I7+waDyGTULttFdqcg5xuBdvBQqsdbBlNMsBdUIGY10/WiATFWc4rflsP9boG+vR+NrgJruRcnNhnPFYCsAZlyfZJx0k1fUllBUbSFXWTMMpNj8D8ow9A53iFLBqItLVZAXuW55MWe9t6drTbi0WwnmLh0aymKxq7P9D+gmjh9VFmcYQFCIZA1z5/V/wal6BqWtyy2r77/AYNIT9MoySsske1DhUgr8tgPMjwEdCi8S5Qhx2Y8hP+5NsXed6LjmUFOIGlpqJLjIgHHcJWLPfqRZLvvMQRzE5GnDvYHXa+Qes4Kj7tk3sfQIu1f7mGecPEK9Nv/IBiagE2QsU2UpQnsAIRVsuqrv5a44DmzfAkng74c0wiqqegOosfXHBDX5vzD9bE/wEEuFYwywn3zI/kBCctDZgLjtj69OEwfJPlLPKaxK1MR6NhXxfQR83IGPktV+UE2idE= diff --git a/terraform/LICENSE b/terraform/LICENSE new file mode 100644 index 0000000..1227269 --- /dev/null +++ b/terraform/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2024 Davide Oddone +Copyright (c) 2020 Zachary Loeber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/terraform/cloud_init.cfg b/terraform/cloud_init.cfg new file mode 100644 index 0000000..31186b4 --- /dev/null +++ b/terraform/cloud_init.cfg @@ -0,0 +1,21 @@ +#cloud-config +# https://docs.cloud-init.io/en/24.1/reference/examples.html#configure-instance-to-be-managed-by-ansible +# +# A common use-case for cloud-init is to bootstrap user and ssh +# settings to be managed by a remote configuration management tool, +# such as ansible. +# +# This example assumes a default Ubuntu cloud image, which should contain +# the required software to be managed remotely by Ansible. +# +ssh_pwauth: false + +users: + - name: ansible + gecos: Ansible User + groups: users,admin,wheel + shell: /bin/bash + lock_passwd: true + sudo: ALL=(ALL) NOPASSWD:ALL + ssh_authorized_keys: + - ${public_key} diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000..c0207c2 --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,156 @@ +# Using https://github.com/zloeber/k8s-lab-terraform-libvirt/blob/master/main.tf +# as a base +terraform { + required_providers { + libvirt = { + source = "dmacvicar/libvirt" + } + } +} + +# Define local variables to use within the script +locals { + kube_version = "1.31.1" + masternodes = 1 + workernodes = 2 + subnet_node_prefix = "172.16.1" +} + +# instance the provider +provider "libvirt" { + uri = "qemu:///system" +} + +# path.cwd is the filesystem path of the original working directory from where you ran Terraform before applying any -chdir argument. +resource libvirt_pool local { + name = "ubuntu" + type = "dir" + path = "${path.cwd}/volume_pool" +} + +resource libvirt_volume ubuntu2404_cloud { + name = "ubuntu24.04.qcow2" + pool = libvirt_pool.local.name + source = "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img" + format = "qcow2" +} + +resource libvirt_volume ubuntu2404_resized { + name = "ubuntu-volume-${count.index}" + base_volume_id = libvirt_volume.ubuntu2404_cloud.id + pool = libvirt_pool.local.name + size = 21474836480 + count = local.masternodes + local.workernodes +} + + +data template_file public_key { + template = file("${path.module}/.local/.ssh/id_rsa.pub") +} + +data template_file master_user_data { + count = local.masternodes + template = file("${path.module}/cloud_init.cfg") + vars = { + public_key = data.template_file.public_key.rendered + hostname = "k8s-master-${count.index + 1}" + } +} + +data template_file worker_user_data { + count = local.workernodes + template = file("${path.module}/cloud_init.cfg") + vars = { + public_key = data.template_file.public_key.rendered + hostname = "k8s-worker-${count.index + 1}" + } +} + +resource libvirt_cloudinit_disk masternodes { + count = local.masternodes + name = "cloudinit_master_resized_${count.index}.iso" + pool = libvirt_pool.local.name + user_data = data.template_file.master_user_data[count.index].rendered +} + +resource libvirt_cloudinit_disk workernodes { + count = local.workernodes + name = "cloudinit_worker_resized_${count.index}.iso" + pool = libvirt_pool.local.name + user_data = data.template_file.worker_user_data[count.index].rendered +} + +resource libvirt_network kube_node_network { + name = "kube_nodes" + mode = "nat" + domain = "k8s.local" + autostart = true + addresses = ["${local.subnet_node_prefix}.0/24"] + dns { + enabled = true + } +} + +resource libvirt_domain k8s_masters { + count = local.masternodes + name = "k8s-master-${count.index+1}" + memory = "4096" + vcpu = 2 + + cloudinit = libvirt_cloudinit_disk.masternodes[count.index].id + + network_interface { + network_id = libvirt_network.kube_node_network.id + hostname = "k8s-master-${count.index+1}" + addresses = ["${local.subnet_node_prefix}.1${count.index+1}"] + wait_for_lease = true + } + + disk { + volume_id = libvirt_volume.ubuntu2404_resized[count.index].id + } + + console { + type = "pty" + target_type = "serial" + target_port = "0" + } + + graphics { + type = "spice" + listen_type = "address" + autoport = true + } +} + +resource libvirt_domain k8s_workers { + count = local.workernodes + name = "k8s-worker-${count.index + 1}" + memory = "2048" + vcpu = 2 + + cloudinit = libvirt_cloudinit_disk.workernodes[count.index].id + + network_interface { + network_id = libvirt_network.kube_node_network.id + hostname = "k8s-worker-${count.index + 1}" + addresses = ["${local.subnet_node_prefix}.2${count.index + 1}"] + wait_for_lease = true + } + + disk { + volume_id = libvirt_volume.ubuntu2404_resized[local.masternodes+count.index].id + } + + console { + type = "pty" + target_type = "serial" + target_port = "0" + } + + graphics { + type = "spice" + listen_type = "address" + autoport = true + } +} diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 0000000..8b1ebd1 --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,11 @@ +output master_ip { + value = libvirt_domain.k8s_masters[0].network_interface[0].addresses[0] +} + +output worker_1_ip { + value = libvirt_domain.k8s_workers[0].network_interface[0].addresses[0] +} + +output worker_2_ip { + value = libvirt_domain.k8s_workers[1].network_interface[0].addresses[0] +}