diff --git a/.sops.yaml b/.sops.yaml index 9b0fdfb..821c263 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -35,3 +35,6 @@ creation_rules: - path_regex: gitea.*\.enc\.yaml$ encrypted_regex: ^(data|stringData)$ age: age1ktlxm0hukw6jxm62txqy5x2nl8hpdnal8nv00kfhrf3pw33574aqa6j5cj + - path_regex: woodpecker.*\.enc\.yaml$ + encrypted_regex: ^(data|stringData)$ + age: age13qwkssk8esashln2j3gfv6e9csashr4vddkdav5v38hm5wejl36qd2ew9s diff --git a/clusters/base/apps/woodpecker/helmrelease.yaml b/clusters/base/apps/woodpecker/helmrelease.yaml new file mode 100644 index 0000000..b60e814 --- /dev/null +++ b/clusters/base/apps/woodpecker/helmrelease.yaml @@ -0,0 +1,100 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: woodpecker + namespace: ci +spec: + interval: 10m + chartRef: + kind: OCIRepository + name: woodpecker + driftDetection: + mode: enabled + values: + controllers: + server: + replicas: 1 + strategy: Recreate # sqlite on RWO volume + containers: + app: + image: + repository: woodpeckerci/woodpecker-server + tag: v3.8.0 + env: + WOODPECKER_HOST: https://ci.aggtaa.com + WOODPECKER_OPEN: "false" + WOODPECKER_ADMIN: anton + WOODPECKER_GITEA: "true" + WOODPECKER_GITEA_URL: https://git.aggtaa.com + WOODPECKER_DATABASE_DRIVER: sqlite3 + WOODPECKER_DATABASE_DATASOURCE: /var/lib/woodpecker/woodpecker.sqlite + envFrom: + - secretRef: + name: woodpecker-secrets + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi + agent: + replicas: 1 + serviceAccount: + name: woodpecker-agent # created in rbac.yaml + containers: + app: + image: + repository: woodpeckerci/woodpecker-agent + tag: v3.8.0 + env: + WOODPECKER_SERVER: woodpecker-server:9000 + WOODPECKER_BACKEND: kubernetes + WOODPECKER_BACKEND_K8S_NAMESPACE: ci + WOODPECKER_BACKEND_K8S_STORAGE_CLASS: longhorn-no-retain + WOODPECKER_BACKEND_K8S_VOLUME_SIZE: 5G + WOODPECKER_MAX_WORKFLOWS: "2" + envFrom: + - secretRef: + name: woodpecker-secrets + resources: + requests: + cpu: 20m + memory: 64Mi + limits: + memory: 256Mi + + service: + server: + controller: server + ports: + http: + port: 8000 + grpc: + port: 9000 + + ingress: + server: + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + hosts: + - host: ci.aggtaa.com + paths: + - path: / + pathType: Prefix + service: + identifier: server + port: http + tls: + - secretName: woodpecker-tls + hosts: + - ci.aggtaa.com + + persistence: + data: + type: persistentVolumeClaim + existingClaim: woodpecker-data + advancedMounts: + server: + app: + - path: /var/lib/woodpecker diff --git a/clusters/base/apps/woodpecker/helmrepository.yaml b/clusters/base/apps/woodpecker/helmrepository.yaml new file mode 100644 index 0000000..7d61503 --- /dev/null +++ b/clusters/base/apps/woodpecker/helmrepository.yaml @@ -0,0 +1,10 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: woodpecker + namespace: ci +spec: + interval: 10m + url: oci://ghcr.io/bjw-s-labs/helm/app-template + ref: + tag: "5.0.1" diff --git a/clusters/base/apps/woodpecker/kustomization.yaml b/clusters/base/apps/woodpecker/kustomization.yaml new file mode 100644 index 0000000..554f073 --- /dev/null +++ b/clusters/base/apps/woodpecker/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - helmrepository.yaml + - secret.enc.yaml + - pvc.yaml + - rbac.yaml + - helmrelease.yaml diff --git a/clusters/base/apps/woodpecker/pvc.yaml b/clusters/base/apps/woodpecker/pvc.yaml new file mode 100644 index 0000000..548bc74 --- /dev/null +++ b/clusters/base/apps/woodpecker/pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: woodpecker-data + namespace: ci +spec: + accessModes: + - ReadWriteOnce + storageClassName: longhorn + resources: + requests: + storage: 2Gi diff --git a/clusters/base/apps/woodpecker/rbac.yaml b/clusters/base/apps/woodpecker/rbac.yaml new file mode 100644 index 0000000..44c7456 --- /dev/null +++ b/clusters/base/apps/woodpecker/rbac.yaml @@ -0,0 +1,33 @@ +# Agent runs pipeline steps as pods in this namespace (kubernetes backend) +apiVersion: v1 +kind: ServiceAccount +metadata: + name: woodpecker-agent + namespace: ci +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: woodpecker-agent + namespace: ci +rules: + - apiGroups: [""] + resources: [pods, pods/log] + verbs: [create, get, list, watch, delete] + - apiGroups: [""] + resources: [persistentvolumeclaims, services, secrets, configmaps] + verbs: [create, get, list, watch, update, delete] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: woodpecker-agent + namespace: ci +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: woodpecker-agent +subjects: + - kind: ServiceAccount + name: woodpecker-agent + namespace: ci diff --git a/clusters/base/apps/woodpecker/secret.enc.yaml b/clusters/base/apps/woodpecker/secret.enc.yaml new file mode 100644 index 0000000..ec8b109 --- /dev/null +++ b/clusters/base/apps/woodpecker/secret.enc.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Secret +metadata: + name: woodpecker-secrets + namespace: ci +stringData: + WOODPECKER_AGENT_SECRET: ENC[AES256_GCM,data:UyYPJpkHb2G1Vpe2tEtkNDMktp6zFbeNtDF34Kp8vf6nAY5/2EYXBJvT4+Ns2oOGNZOupdCUmTowrJ+ITNFwhQ==,iv:EtXILwt+FFYvqvLw9kLODh0wyhrHG+GJNGZRu6wzXd4=,tag:Ly5dsTWio741VxgtPy51XQ==,type:str] + WOODPECKER_GITEA_CLIENT: ENC[AES256_GCM,data:hXBo5EwhHuCTQ4vQBAmjnLTlQ6cY2dKeJ5vZJ27wMFUsKZpS,iv:Pzt78GVSWngjVvpVSEgvsImK+siHEHOqQy+jOAxrGkc=,tag:JYu+Jf+n9J4L4LPwRPPbSw==,type:str] + WOODPECKER_GITEA_SECRET: ENC[AES256_GCM,data:nu4FTBjdJe7oHx2Vt1ElxJXVnYzONC3kKYlXwvtmVI3/DokjSGA0YwLy0jI58l7K9nBbzGKuuZM=,iv:U6mfIG+LYhSfooIK3yhJay+fQh5oCNyGUggN+MrY4os=,tag:Oho0FnhePMLhFzsyhFISZQ==,type:str] +sops: + age: + - recipient: age13qwkssk8esashln2j3gfv6e9csashr4vddkdav5v38hm5wejl36qd2ew9s + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1anNnNDlnSjhMU2h4clVV + eFJnNEx6VmU1RjR0a1RQQTRML3lBaUphSkU4CnNuM0I2NkFPMlU1clFNY3V5Sk9Y + b0NJNzlUMjJsRVZMdndzUWYyNWhjeHMKLS0tIEp0Y2E3dTRwRTUyUmprRktFNUJp + TXlXWjViSGNFb1FhQ0xDT0gvajdwSlEKXB7N64RmaWgCCSvG/nNWOziO7QnN729i + jJLB6SPiHjgNMn1GP+rsAstVFStB0fn2mh6QpWrdhAM3/NFBqQfy7A== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-10-07T08:19:00Z" + mac: ENC[AES256_GCM,data:MInWU0fjxmodXDN7x9U6rd2V2xCjty94Bb7Y0HlwJscaSmLR0jgkjTV0dYimPlyBfVhNlJzgmKcMj9ZvZOqxMKVive6L5Hghq5RXG2LKimWu5VyjffMabP9w3Edob+4prfT2EJ8rAY1OjuP00CiKc/958+ZoVYafN/hj4wqEmas=,iv:cpc2LcbdxJv0LenEA0W7TWLQSAMyCCEd/pHgxs9EUus=,tag:5dC2RKTm079OxgyG8aF3Ow==,type:str] + encrypted_regex: ^(data|stringData)$ + version: 3.11.0 diff --git a/clusters/base/namespaces/ci.yaml b/clusters/base/namespaces/ci.yaml new file mode 100644 index 0000000..feecd98 --- /dev/null +++ b/clusters/base/namespaces/ci.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ci diff --git a/clusters/home/apps/kustomization.yaml b/clusters/home/apps/kustomization.yaml index 0aa87ae..f28d897 100644 --- a/clusters/home/apps/kustomization.yaml +++ b/clusters/home/apps/kustomization.yaml @@ -16,4 +16,5 @@ resources: - immich.yaml - joplin.yaml - gitea.yaml - - dev.yaml \ No newline at end of file + - dev.yaml + - woodpecker.yaml \ No newline at end of file diff --git a/clusters/home/apps/woodpecker.yaml b/clusters/home/apps/woodpecker.yaml new file mode 100644 index 0000000..60c5d44 --- /dev/null +++ b/clusters/home/apps/woodpecker.yaml @@ -0,0 +1,22 @@ +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: woodpecker + namespace: flux-system +spec: + interval: 10m + sourceRef: + kind: GitRepository + name: flux-system + path: ./clusters/base/apps/woodpecker + prune: true + wait: true + dependsOn: + - name: namespaces + - name: infra + - name: gitea + retryInterval: 5s + decryption: + provider: sops + secretRef: + name: sops-age-woodpecker diff --git a/clusters/home/namespaces/kustomization.yaml b/clusters/home/namespaces/kustomization.yaml index 92693a7..d096fde 100644 --- a/clusters/home/namespaces/kustomization.yaml +++ b/clusters/home/namespaces/kustomization.yaml @@ -18,3 +18,4 @@ resources: - ../../base/namespaces/photo.yaml - ../../base/namespaces/git.yaml - ../../base/namespaces/dev.yaml + - ../../base/namespaces/ci.yaml