lxc with drone-runner on proxmox via opentofu and ansible

This commit is contained in:
2026-02-23 23:55:29 +01:00
commit b29c73c404
10 changed files with 254 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
docs/

55
ansible/drone-runner.yml Normal file
View File

@@ -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"

5
ansible/inventory.yml Normal file
View File

@@ -0,0 +1,5 @@
all:
hosts:
drone-runner:
ansible_host: 192.168.178.200
ansible_user: root

4
tofu/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.tfstate
*.tfstate.backup
.terraform/
terraform.tfvars

25
tofu/.terraform.lock.hcl generated Normal file
View File

@@ -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",
]
}

77
tofu/main.tf Normal file
View File

@@ -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"
}
}

9
tofu/outputs.tf Normal file
View File

@@ -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
}

View File

@@ -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"

44
tofu/variables.tf Normal file
View File

@@ -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
}

26
tofu/versions.tf Normal file
View File

@@ -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"
}
}
}