commit b29c73c404248e85cc7438a3ca15f3e9ae3a1ec3 Author: Linus Waldowsky Date: Mon Feb 23 23:55:29 2026 +0100 lxc with drone-runner on proxmox via opentofu and ansible diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..77f12ae --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +docs/ diff --git a/ansible/drone-runner.yml b/ansible/drone-runner.yml new file mode 100644 index 0000000..e581063 --- /dev/null +++ b/ansible/drone-runner.yml @@ -0,0 +1,55 @@ +- name: Configure Drone Runner LXC + hosts: drone-runner + tasks: + - name: Install dependencies + apt: + name: + - ca-certificates + - curl + - gnupg + state: present + update_cache: true + + - name: Add Docker GPG key + get_url: + url: https://download.docker.com/linux/debian/gpg + dest: /etc/apt/keyrings/docker.asc + mode: "0644" + + - name: Add Docker repository + apt_repository: + repo: "deb [signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable" + filename: docker + state: present + + - name: Install Docker + apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + state: present + update_cache: true + + - name: Enable and start Docker service + systemd: + name: docker + enabled: true + state: started + + - name: Start Drone Runner + community.docker.docker_container: + name: drone-runner + image: drone/drone-runner-docker:1 + state: started + restart_policy: always + volumes: + - /var/run/docker.sock:/var/run/docker.sock + env: + DRONE_RPC_HOST: "drone.gilmour109.de" + DRONE_RPC_PROTO: "https" + DRONE_RPC_SECRET: "dronegitea" + DRONE_RUNNER_CAPACITY: "4" + DRONE_RUNNER_NAME: "proxmox-runner" diff --git a/ansible/inventory.yml b/ansible/inventory.yml new file mode 100644 index 0000000..f796a68 --- /dev/null +++ b/ansible/inventory.yml @@ -0,0 +1,5 @@ +all: + hosts: + drone-runner: + ansible_host: 192.168.178.200 + ansible_user: root diff --git a/tofu/.gitignore b/tofu/.gitignore new file mode 100644 index 0000000..1cd3b67 --- /dev/null +++ b/tofu/.gitignore @@ -0,0 +1,4 @@ +*.tfstate +*.tfstate.backup +.terraform/ +terraform.tfvars diff --git a/tofu/.terraform.lock.hcl b/tofu/.terraform.lock.hcl new file mode 100644 index 0000000..37da490 --- /dev/null +++ b/tofu/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "registry.opentofu.org/bpg/proxmox" { + version = "0.96.0" + constraints = "~> 0.96.0" + hashes = [ + "h1:BXlbaB7LBlyQcrR1Tpzbq39oxDs10kTpcONK+gppXnM=", + "zh:0840a64ddffdbca48e816f4f2cb338208d80f4d982ed53e6f0482c890ea1b1d6", + "zh:1f07c0aa02b24d81fae010e83c2a375d84c6910f4f861a37764c2c717ae5adf7", + "zh:2d8680abbeab700af7a0f87df505919fcdb314fb777637ddad7ecec626965468", + "zh:3e32f68c236c4b2ccf522ed875514eb579419a9798b783880a4293c375795eef", + "zh:454d031293eaf86d9c97eb748dd9c59f2d454dd2c8ee93e83d2d4125bbb7508f", + "zh:515dbfaeeec99edbd1095314fea10ed16d01c37c9047720e39fb7dd9bb0e1fd2", + "zh:55d4449fe8c50ee2ea57b5c02c2baef51b6be3df21ce0469abd0c952cf3e2ddd", + "zh:86c82e416e95a35fb41ad1eef27acdfbb18fd6e2c53a21c97b6b189f4cd78312", + "zh:88cee9f0e45e0ebed32adb8dc8a6778dbd8f058ad33a890a4cb528f8358da2b4", + "zh:9f0511e933100ad2f0a1dae159f7547057816c35ee3a18a1e7d43077866073e6", + "zh:b76ee0064bf97550fa2d9c492e668621bf214f68072d5c9d3a3adaa95fdc4630", + "zh:bba13b469e15e373c2e9181420ea7d4f8f1996b7b249c28151063588c61a14e6", + "zh:dd164d24926f52b00a9b7e53f83837c5c20a960fcb6925653c360cd83d85d7a5", + "zh:e31d207ea2eaa68a55dd9b13773ddec9b79e86c69fd16a429d916130d93f4ffb", + "zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597", + ] +} diff --git a/tofu/main.tf b/tofu/main.tf new file mode 100644 index 0000000..04cab81 --- /dev/null +++ b/tofu/main.tf @@ -0,0 +1,77 @@ +provider "proxmox" { + endpoint = var.proxmox_endpoint + username = "root@pam" + password = var.proxmox_password + insecure = true + + ssh { + agent = true + username = "root" + } +} + +resource "proxmox_virtual_environment_download_file" "debian_13_lxc_template" { + content_type = "vztmpl" + datastore_id = "local" + node_name = var.node_name + url = "http://download.proxmox.com/images/system/debian-13-standard_13.1-2_amd64.tar.zst" +} + +resource "proxmox_virtual_environment_container" "drone_runner" { + node_name = var.node_name + vm_id = var.drone_runner_id + description = "Drone CI Runner with Docker" + + unprivileged = false + started = true + + features { + nesting = true + keyctl = true + } + + operating_system { + template_file_id = proxmox_virtual_environment_download_file.debian_13_lxc_template.id + type = "debian" + } + + initialization { + hostname = "drone-runner" + + ip_config { + ipv4 { + address = var.drone_runner_ip + gateway = var.gateway + } + } + + user_account { + keys = [trimspace(file(var.ssh_public_key_path))] + password = var.drone_runner_password + } + } + + network_interface { + name = "eth0" + bridge = "vmbr0" + } + + disk { + datastore_id = "local-lvm" + size = 16 + } + + cpu { + cores = 2 + } + + memory { + dedicated = 2048 + swap = 512 + } + + startup { + order = "1" + } + +} diff --git a/tofu/outputs.tf b/tofu/outputs.tf new file mode 100644 index 0000000..dd8e0dd --- /dev/null +++ b/tofu/outputs.tf @@ -0,0 +1,9 @@ +output "drone_runner_id" { + description = "VMID of the Drone Runner LXC" + value = proxmox_virtual_environment_container.drone_runner.vm_id +} + +output "drone_runner_ip" { + description = "IP address of the Drone Runner LXC" + value = var.drone_runner_ip +} diff --git a/tofu/terraform.tfvars.example b/tofu/terraform.tfvars.example new file mode 100644 index 0000000..232e0d2 --- /dev/null +++ b/tofu/terraform.tfvars.example @@ -0,0 +1,8 @@ +proxmox_endpoint = "https://192.168.x.x:8006/" +proxmox_password = "proxmox-root-password" +node_name = "pve" +drone_runner_id = 200 +drone_runner_ip = "192.168.x.200/24" +gateway = "192.168.x.1" +ssh_public_key_path = "~/.ssh/id_ed25519.pub" +drone_runner_password = "lxc-root-password" diff --git a/tofu/variables.tf b/tofu/variables.tf new file mode 100644 index 0000000..c3ce5f5 --- /dev/null +++ b/tofu/variables.tf @@ -0,0 +1,44 @@ +variable "proxmox_endpoint" { + description = "Proxmox API URL" + type = string +} + +variable "proxmox_password" { + description = "Password for root@pam on Proxmox" + type = string + sensitive = true +} + +variable "node_name" { + description = "Proxmox node name" + type = string + default = "pve" +} + +variable "drone_runner_id" { + description = "VMID for the Drone Runner LXC" + type = number + default = 200 +} + +variable "drone_runner_ip" { + description = "Static IP in CIDR notation" + type = string +} + +variable "gateway" { + description = "Network gateway IP" + type = string +} + +variable "ssh_public_key_path" { + description = "Path to SSH public key for LXC root access" + type = string + default = "~/.ssh/id_ed25519.pub" +} + +variable "drone_runner_password" { + description = "Root password inside the LXC container" + type = string + sensitive = true +} diff --git a/tofu/versions.tf b/tofu/versions.tf new file mode 100644 index 0000000..a1d16fc --- /dev/null +++ b/tofu/versions.tf @@ -0,0 +1,26 @@ +terraform { + required_version = ">= 1.6.0" + + backend "s3" { + bucket = "tofu-state" + key = "drone-runner/terraform.tfstate" + region = "garage" + + endpoints = { + s3 = "https://garage.gilmour109.de" + } + + skip_credentials_validation = true + skip_metadata_api_check = true + skip_requesting_account_id = true + skip_region_validation = true + use_path_style = true + } + + required_providers { + proxmox = { + source = "bpg/proxmox" + version = "~> 0.96.0" + } + } +}