fix(opentofu): remove retired Gitea/Woodpecker LXC state drift (Fixes #199) #232
@@ -1,43 +0,0 @@
|
||||
when:
|
||||
# Deploy only on master (merge) + manual — never from a feature branch.
|
||||
- event: push
|
||||
branch: master
|
||||
path:
|
||||
- "ansible/roles/woodpecker-agent/**"
|
||||
- "ansible/plays/install-woodpecker-agent.yml"
|
||||
- ".woodpecker/deploy-woodpecker-agent.yml"
|
||||
- event: manual
|
||||
evaluate: 'PIPELINE == "deploy-woodpecker-agent"'
|
||||
|
||||
# NOTE: this deploys the agents *from* an agent, so applying a change that
|
||||
# restarts Docker (e.g. the daemon.json IPv6 config) will kill this job's own
|
||||
# container mid-run — the pipeline reports failure, but the change still
|
||||
# applies on both agents (the restart commands are dispatched in parallel
|
||||
# before the executing agent's daemon goes down). Re-run / re-trigger
|
||||
# deploy-netbird-proxy afterwards.
|
||||
timeout: 30
|
||||
|
||||
steps:
|
||||
- name: deploy-woodpecker-agent
|
||||
image: gitea.renner.uno/gitea_admin/ci-ansible:2026-04-29
|
||||
environment:
|
||||
ANSIBLE_FORCE_COLOR: "true"
|
||||
ANSIBLE_HOST_KEY_CHECKING: "false"
|
||||
ANSIBLE_ROLES_PATH: "../roles:./roles"
|
||||
SSH_PRIVATE_KEY:
|
||||
from_secret: ssh_private_key
|
||||
VAULT_PASS:
|
||||
from_secret: vault_pass
|
||||
PROXMOX_TOKEN_ID:
|
||||
from_secret: proxmox_token_id
|
||||
PROXMOX_TOKEN_SECRET:
|
||||
from_secret: proxmox_token_secret
|
||||
commands:
|
||||
- mkdir -p ~/.ssh
|
||||
- echo "$SSH_PRIVATE_KEY" | base64 -d > ~/.ssh/id_ed25519
|
||||
- chmod 600 ~/.ssh/id_ed25519
|
||||
- printf "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n" > ~/.ssh/config
|
||||
- cd ansible
|
||||
- echo "$VAULT_PASS" > .vault_pass && chmod 600 .vault_pass
|
||||
- export ANSIBLE_VAULT_PASSWORD_FILE=.vault_pass
|
||||
- ansible-playbook -i inventory/ plays/install-woodpecker-agent.yml -v
|
||||
@@ -1,28 +0,0 @@
|
||||
when:
|
||||
- event: manual
|
||||
evaluate: 'PIPELINE == "install-woodpecker-server"'
|
||||
|
||||
steps:
|
||||
- name: run-playbook
|
||||
image: gitea.renner.uno/gitea_admin/ci-ansible:2026-04-29
|
||||
environment:
|
||||
ANSIBLE_FORCE_COLOR: "true"
|
||||
ANSIBLE_HOST_KEY_CHECKING: "false"
|
||||
ANSIBLE_ROLES_PATH: "../roles:./roles"
|
||||
SSH_PRIVATE_KEY:
|
||||
from_secret: ssh_private_key
|
||||
VAULT_PASS:
|
||||
from_secret: vault_pass
|
||||
PROXMOX_TOKEN_ID:
|
||||
from_secret: proxmox_token_id
|
||||
PROXMOX_TOKEN_SECRET:
|
||||
from_secret: proxmox_token_secret
|
||||
commands:
|
||||
- mkdir -p ~/.ssh
|
||||
- echo "$SSH_PRIVATE_KEY" | base64 -d > ~/.ssh/id_ed25519
|
||||
- chmod 600 ~/.ssh/id_ed25519
|
||||
- 'printf "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n" > ~/.ssh/config'
|
||||
- cd ansible
|
||||
- echo "$$VAULT_PASS" > .vault_pass && chmod 600 .vault_pass
|
||||
- export ANSIBLE_VAULT_PASSWORD_FILE=.vault_pass
|
||||
- ansible-playbook -i inventory/ plays/install-woodpecker-server.yml -v
|
||||
@@ -24,14 +24,10 @@ locals {
|
||||
],
|
||||
# LXCs
|
||||
[
|
||||
"114", # gitea
|
||||
"118", # proxmox-dns-1 (jupiter)
|
||||
"218", # proxmox-dns-2 (saturn)
|
||||
"231", # woodpecker
|
||||
"318", # proxmox-dns-3 (neptune)
|
||||
],
|
||||
# Woodpecker CI agents (VMIDs 910..)
|
||||
[for a in local.woodpecker_agents : tostring(a.vmid)],
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,22 +6,4 @@ locals {
|
||||
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBB1OFjh6Q5xeioI6Cwfuv8Xka27veomYy9tKBbpMo8mcrsB4yIN4FX8HovBLtogetBhwBUefBar8nhA9GbRh6HQ= krenner@krenner-XPS-13-9310"
|
||||
])
|
||||
|
||||
woodpecker_agents = [
|
||||
for i in range(var.woodpecker_agent_count) : {
|
||||
vmid = 910 + i
|
||||
name = "wp-agent-${i + 1}.srv.renner.uno"
|
||||
node = "jupiter"
|
||||
memory = 4096
|
||||
cores = 2
|
||||
type = "lxc"
|
||||
state = "started"
|
||||
tags = "woodpecker;ci;docker"
|
||||
bridge = "v40srv"
|
||||
disk_size = "30G"
|
||||
storage = "local-zfs"
|
||||
nesting = true
|
||||
ostemplate = "local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst"
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
moved {
|
||||
from = proxmox_lxc.lxc["114"]
|
||||
to = proxmox_lxc.gitea_srv_renner_uno
|
||||
}
|
||||
|
||||
module "gitea_srv_renner_uno" {
|
||||
source = "./modules/proxmox_lxc"
|
||||
|
||||
target_node = "jupiter"
|
||||
hostname = "gitea.srv.renner.uno"
|
||||
vmid = 114
|
||||
memory = 2048
|
||||
cores = 2
|
||||
|
||||
cpuunits = 1024
|
||||
tags = "community-script;git"
|
||||
|
||||
hagroup = "olymp"
|
||||
hastate = "started"
|
||||
|
||||
unprivileged = false
|
||||
onboot = true
|
||||
start = true
|
||||
|
||||
storage = "local-zfs"
|
||||
# Bumped 4G→16G on 2026-05-01: container registry blob storage filled
|
||||
# the rootfs and gitea returned 500 on every blob upload during
|
||||
# build-ci-images runs (pipeline 841 — three of four image pushes
|
||||
# failed with "no space left on device" on /var/lib/alloy too).
|
||||
disk_size = "16G"
|
||||
|
||||
# ingress_cnames removed: gitea is now fronted by ingress-nginx via
|
||||
# the ExternalName Service in kubernetes/apps/gitea/. Removing the
|
||||
# CNAMEs to ingress.renner.uno (Caddy VIP) lets external-dns-unifi
|
||||
# take ownership of git/gitea.renner.uno and write A records to the
|
||||
# ingress-nginx LB at 10.2.40.80.
|
||||
ingress_cnames = []
|
||||
}
|
||||
|
||||
moved {
|
||||
from = proxmox_lxc.gitea_srv_renner_uno
|
||||
to = module.gitea_srv_renner_uno.proxmox_lxc.this
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
# Woodpecker CI Server
|
||||
# Lightweight CI/CD engine with Gitea integration
|
||||
# Replaces Gitea Actions for better UI and worker management
|
||||
|
||||
module "woodpecker_srv_renner_uno" {
|
||||
source = "./modules/proxmox_lxc"
|
||||
|
||||
hostname = "woodpecker.srv.renner.uno"
|
||||
vmid = 231
|
||||
target_node = "jupiter"
|
||||
# 1 GiB was insufficient under concurrent pipeline load — SQLite mmap
|
||||
# contention caused "database is locked" cascades that killed otherwise-
|
||||
# healthy long-running steps with `queue: task expired` and
|
||||
# `sql: no rows in result set`.
|
||||
memory = 4096
|
||||
cores = 2
|
||||
|
||||
unprivileged = true
|
||||
|
||||
network_bridge = "v40srv"
|
||||
|
||||
storage = "local-zfs"
|
||||
disk_size = "10G"
|
||||
|
||||
ostemplate = "local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst"
|
||||
|
||||
ssh_public_keys = local.common_ssh_keys
|
||||
|
||||
tags = "ci;docker;woodpecker"
|
||||
|
||||
onboot = true
|
||||
start = true
|
||||
|
||||
features = {
|
||||
nesting = true
|
||||
fuse = false
|
||||
keyctl = false
|
||||
mknod = false
|
||||
}
|
||||
|
||||
# ingress_cnames removed: woodpecker UI is now fronted by ingress-nginx
|
||||
# via the ExternalName Service in kubernetes/apps/woodpecker/. Agents
|
||||
# talk to woodpecker.srv.renner.uno:9000 directly, so the gRPC path
|
||||
# was never on Caddy.
|
||||
ingress_cnames = []
|
||||
cnames = []
|
||||
|
||||
description = <<-EOT
|
||||
Woodpecker CI Server
|
||||
https://woodpecker-ci.org/
|
||||
|
||||
Deployed via Ansible role: woodpecker-server
|
||||
Web UI: https://ci.renner.uno (port 8000)
|
||||
gRPC: port 9000 (agent communication)
|
||||
Auth: Gitea OAuth2
|
||||
Database: SQLite
|
||||
EOT
|
||||
}
|
||||
@@ -28,12 +28,6 @@ variable "proxmox_tls_insecure" {
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "woodpecker_agent_count" {
|
||||
description = "Number of Woodpecker CI agents to deploy"
|
||||
type = number
|
||||
default = 2
|
||||
}
|
||||
|
||||
variable "ssh_public_key" {
|
||||
description = "Public SSH key to inject into containers"
|
||||
type = string
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# Woodpecker CI Agents
|
||||
# Docker-based build agents connecting to woodpecker.srv.renner.uno via gRPC
|
||||
|
||||
module "woodpecker_agents" {
|
||||
source = "./modules/proxmox_lxc"
|
||||
|
||||
for_each = {
|
||||
for lxc in local.woodpecker_agents : lxc.vmid => lxc
|
||||
}
|
||||
|
||||
hostname = each.value.name
|
||||
target_node = each.value.node
|
||||
vmid = each.value.vmid
|
||||
memory = each.value.memory
|
||||
cores = each.value.cores
|
||||
unprivileged = true
|
||||
tags = join(",", compact([each.value.tags, "transient"]))
|
||||
ostemplate = each.value.ostemplate
|
||||
storage = each.value.storage != "" ? each.value.storage : "local-zfs"
|
||||
disk_size = each.value.disk_size
|
||||
|
||||
ssh_public_keys = local.common_ssh_keys
|
||||
|
||||
start = each.value.state == "started" ? true : false
|
||||
network_bridge = each.value.bridge
|
||||
# CI steps must reach IPv6-only hosts; give the LXC SLAAC v6 off v40srv so
|
||||
# Docker has a v6 uplink to NAT the pipeline networks onto.
|
||||
ipv6_address = "auto"
|
||||
|
||||
features = {
|
||||
nesting = each.value.nesting
|
||||
fuse = false
|
||||
keyctl = false
|
||||
mknod = false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user