Gonçalo Rodrigues bd174be094 fix(cicd): switch act runner to Docker mode with node:20 image
Host mode lacks Node.js so actions/checkout@v4 fails. Switch label to
ubuntu-latest:docker:node:20 which has Node.js for JS actions. Install
Docker CLI in the deploy job since node:20 doesn't include it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 23:43:44 +01:00

194 lines
4.9 KiB
HCL

resource "kubernetes_service_account" "act_runner" {
count = var.enable_gitea ? 1 : 0
metadata {
name = "act-runner"
namespace = kubernetes_namespace.domains["gitea"].metadata[0].name
}
}
resource "kubernetes_cluster_role" "act_runner" {
count = var.enable_gitea ? 1 : 0
metadata {
name = "act-runner"
}
rule {
api_groups = ["apps"]
resources = ["deployments"]
verbs = ["get", "list", "patch", "update"]
}
rule {
api_groups = [""]
resources = ["pods", "pods/log"]
verbs = ["get", "list"]
}
rule {
api_groups = ["batch"]
resources = ["jobs"]
verbs = ["create", "get", "list", "watch", "delete"]
}
}
resource "kubernetes_cluster_role_binding" "act_runner" {
count = var.enable_gitea ? 1 : 0
metadata {
name = "act-runner"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = kubernetes_cluster_role.act_runner[0].metadata[0].name
}
subject {
kind = "ServiceAccount"
name = kubernetes_service_account.act_runner[0].metadata[0].name
namespace = kubernetes_namespace.domains["gitea"].metadata[0].name
}
}
resource "kubernetes_config_map" "act_runner" {
count = var.enable_gitea ? 1 : 0
metadata {
name = "act-runner-config"
namespace = kubernetes_namespace.domains["gitea"].metadata[0].name
}
data = {
"config.yaml" = yamlencode({
log = { level = "info" }
runner = {
capacity = 2
fetch_timeout = "5s"
fetch_interval = "2s"
report_interval = "1s"
envs = {}
}
cache = { enabled = false }
container = {
network = "host"
valid_volumes = ["/var/run/secrets/kubernetes.io/serviceaccount"]
docker_host = "tcp://localhost:2375"
}
})
}
}
resource "kubernetes_deployment" "act_runner" {
count = var.enable_gitea ? 1 : 0
depends_on = [helm_release.gitea, kubernetes_secret.gitea_runner_token]
metadata {
name = "act-runner"
namespace = kubernetes_namespace.domains["gitea"].metadata[0].name
labels = { app = "act-runner" }
}
spec {
replicas = 1
selector {
match_labels = { app = "act-runner" }
}
template {
metadata {
labels = { app = "act-runner" }
}
spec {
service_account_name = kubernetes_service_account.act_runner[0].metadata[0].name
container {
name = "runner"
image = "gitea/act_runner:latest"
command = ["/bin/sh", "-c"]
args = [<<-EOT
set -e
if [ ! -f /data/.runner ]; then
act_runner register \
--no-interactive \
--instance http://gitea-http.gitea.svc.cluster.local:3000 \
--token "$(cat /etc/runner-token/token)" \
--name "k3d-runner-$(hostname)" \
--labels ubuntu-latest:docker:node:20
fi
exec act_runner daemon --config /etc/act-runner/config.yaml
EOT
]
env {
name = "DOCKER_HOST"
value = "tcp://localhost:2375"
}
env {
name = "KUBERNETES_SERVICE_HOST"
value_from {
field_ref { field_path = "status.hostIP" }
}
}
volume_mount {
name = "runner-data"
mount_path = "/data"
}
volume_mount {
name = "runner-config"
mount_path = "/etc/act-runner"
}
volume_mount {
name = "runner-token"
mount_path = "/etc/runner-token"
read_only = true
}
resources {
requests = { cpu = "100m", memory = "128Mi" }
limits = { cpu = "500m", memory = "512Mi" }
}
}
container {
name = "dind"
image = "docker:27-dind"
security_context {
privileged = true
}
args = ["--insecure-registry=gitea-http.gitea.svc.cluster.local:3000"]
env {
name = "DOCKER_TLS_CERTDIR"
value = ""
}
volume_mount {
name = "docker-storage"
mount_path = "/var/lib/docker"
}
resources {
requests = { cpu = "200m", memory = "256Mi" }
limits = { cpu = "1", memory = "1Gi" }
}
}
volume {
name = "runner-data"
empty_dir {}
}
volume {
name = "docker-storage"
empty_dir {}
}
volume {
name = "runner-config"
config_map {
name = kubernetes_config_map.act_runner[0].metadata[0].name
}
}
volume {
name = "runner-token"
secret {
secret_name = kubernetes_secret.gitea_runner_token[0].metadata[0].name
}
}
}
}
}
}