commit 7b5dce282e5df574ef766ae4092fdd8c0914422d
parent fe01c767c2e67b00e6c79a835f0511b16e1e1169
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date: Wed, 30 Aug 2023 08:02:42 +0200
feat: add jenkins
Diffstat:
4 files changed, 268 insertions(+), 0 deletions(-)
diff --git a/hcl/default/jenkins/data-volume.hcl b/hcl/default/jenkins/data-volume.hcl
@@ -0,0 +1,31 @@
+# Register external nfs volume with Nomad CSI
+# https://www.nomadproject.io/docs/commands/volume/register
+type = "csi"
+# Unique ID of the volume, volume.source field in a job
+id = "jenkins"
+# Display name of the volume.
+name = "jenkins"
+# ID of the physical volume from the storage provider
+external_id = "csi-jenkins"
+plugin_id = "nfs"
+
+# You must provide at least one capability block
+# You must provide a block for each capability
+# youintend to use in a job's volume block
+# https://www.nomadproject.io/docs/commands/volume/register
+capability {
+ access_mode = "multi-node-multi-writer"
+ attachment_mode = "file-system"
+}
+
+# https://github.com/kubernetes-csi/csi-driver-nfs/blob/master/docs/driver-parameters.md
+context {
+ server = "turris"
+ share = "csi-jenkins"
+}
+
+mount_options {
+ # mount.nfs: Either use '-o nolock' to keep locks local, or start statd.
+ mount_flags = ["nolock"]
+}
+
diff --git a/hcl/default/jenkins/jenkins.nomad b/hcl/default/jenkins/jenkins.nomad
@@ -0,0 +1,142 @@
+job "jenkins" {
+ datacenters = ["dc1"]
+
+ vault {
+ policies = ["jenkins"]
+ change_mode = "noop"
+ }
+
+ group "server" {
+ count = 1
+
+ volume "tls" {
+ type = "csi"
+ source = "certbot"
+ access_mode = "multi-node-multi-writer"
+ attachment_mode = "file-system"
+ }
+ volume "jenkins" {
+ type = "csi"
+ source = "jenkins"
+ access_mode = "multi-node-multi-writer"
+ attachment_mode = "file-system"
+ }
+
+ network {
+ port "jenkins" {
+ to = 8080
+ }
+ port "jnlp" {
+ to = 5000
+ }
+ port "https" {}
+ }
+
+ service {
+ port = "https"
+ }
+
+ # Install jenkins plugins
+ # https://www.jenkins.io/doc/book/installing/docker
+ task "install-jenkins-plugins" {
+ driver = "podman"
+
+ volume_mount {
+ volume = "jenkins"
+ destination = "/var/jenkins_home"
+ }
+
+ config {
+ image = "docker.io/jenkins/jenkins:lts-jdk11"
+ command = "jenkins-plugin-cli"
+ args = [
+ "--plugins",
+ "blueocean",
+ "configuration-as-code",
+ "git",
+ "hashicorp-vault-plugin",
+ "nomad",
+ "docker",
+ "--plugin-download-directory",
+ "/var/jenkins_home/plugins",
+ ]
+ }
+
+ resources {
+ memory = 512
+ memory_max = 1024
+ cpu = 300
+ }
+
+ lifecycle {
+ hook = "prestart"
+ sidecar = false
+ }
+ }
+
+ task "jenkins" {
+ driver = "podman"
+
+ template {
+ # https://github.com/GastroGee/jenkins-nomad/blob/main/jenkins-controller/nomad.yaml
+ destination = "${NOMAD_TASK_DIR}/jenkins.yaml"
+ data = file("./templates/jenkins.yaml.tmpl")
+ }
+
+ env {
+ JAVA_OPTS = "-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"
+ }
+
+ config {
+ image = "docker.io/jenkins/jenkins:lts-jdk11"
+ force_pull = true
+ ports = ["jenkins"]
+ volumes = [
+ # mount the templated config from the task directory to the container
+ "local/jenkins.yaml:/var/jenkins_home/jenkins.yaml",
+ ]
+ }
+
+ volume_mount {
+ volume = "jenkins"
+ destination = "/var/jenkins_home"
+ }
+
+ resources {
+ # https://www.jenkins.io/doc/book/installing/docker/#prerequisites
+ memory = 512
+ memory_max = 1024
+ cpu = 300
+ }
+ }
+
+ task "nginx" {
+ driver = "podman"
+
+ config {
+ image = "docker.io/library/nginx:stable-alpine"
+ ports = ["https"]
+ volumes = [
+ # mount the templated config from the task directory to the container
+ "local/jenkins.conf:/etc/nginx/conf.d/jenkins.conf",
+ ]
+ }
+
+ volume_mount {
+ volume = "tls"
+ destination = "/etc/letsencrypt"
+ }
+
+ template {
+ destination = "${NOMAD_TASK_DIR}/jenkins.conf"
+ data = file("./templates/nginx.conf.tmpl")
+ }
+
+ resources {
+ memory = 50
+ memory_max = 256
+ cpu = 200
+ }
+ }
+ }
+}
diff --git a/hcl/default/jenkins/templates/jenkins.yaml.tmpl b/hcl/default/jenkins/templates/jenkins.yaml.tmpl
@@ -0,0 +1,81 @@
+unclassified:
+ location:
+ url: "https://jenkins.in0rdr.ch"
+jenkins:
+ # https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/demos/jenkins/jenkins.yaml
+ systemMessage: "Jenkins configured automatically by Jenkins Configuration as Code plugin\n\n"
+ # Building on the built-in node can be a security issue. You should set the
+ # number of executors on the built-in node to 0:
+ # https://www.jenkins.io/doc/book/security/controller-isolation/#not-building-on-the-built-in-node
+ numExecutors: 0
+ agentProtocols:
+ - "JNLP4-connect"
+ - "Ping"
+ authorizationStrategy:
+ loggedInUsersCanDoAnything:
+ allowAnonymousRead: false
+ securityRealm:
+ # https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos/embedded-userdatabase
+ local:
+ allowsSignup: false
+ users:
+ - id: in0rdr
+ password: "{{with secret "kv/jenkins/users"}}{{index .Data.data.in0rdr}}{{end}}"
+ clouds:
+ - nomad:
+ name: "nomad"
+ nomadUrl: "http://{{env "attr.unique.network.ip-address"}}:4646"
+ prune: true
+ templates:
+ - idleTerminationInMinutes: 10
+ jobTemplate: |-
+ {
+ "Job": {
+ "Region": "global",
+ "ID": "%WORKER_NAME%",
+ "Namespace": "default",
+ "Type": "batch",
+ "Datacenters": [
+ "dc1"
+ ],
+ "TaskGroups": [
+ {
+ "Name": "jenkins-worker-taskgroup",
+ "Count": 1,
+ "RestartPolicy": {
+ "Attempts": 0,
+ "Interval": 10000000000,
+ "Mode": "fail",
+ "Delay": 1000000000
+ },
+ "Tasks": [
+ {
+ "Name": "jenkins-worker",
+ "Driver": "podman",
+ "Config": {
+ "image": "docker.io/jenkins/inbound-agent:latest"
+ },
+ "Env": {
+ "JENKINS_URL": "http://{{ env "NOMAD_ADDR_jenkins" }}",
+ "JENKINS_AGENT_NAME": "%WORKER_NAME%",
+ "JENKINS_SECRET": "%WORKER_SECRET%",
+ "JENKINS_TUNNEL": "{{ env "NOMAD_ADDR_jnlp" }}"
+ },
+ "Resources": {
+ "CPU": 500,
+ "MemoryMB": 256
+ }
+ }
+ ],
+ "EphemeralDisk": {
+ "SizeMB": 300
+ }
+ }
+ ]
+ }
+ }
+ numExecutors: 1
+ prefix: "jenkins"
+ reusable: true
+ tlsEnabled: false
+ workerTimeout: 1
diff --git a/hcl/default/jenkins/templates/nginx.conf.tmpl b/hcl/default/jenkins/templates/nginx.conf.tmpl
@@ -0,0 +1,14 @@
+server {
+ listen {{ env "NOMAD_PORT_https" }} ssl;
+
+ ssl_certificate /etc/letsencrypt/live/jenkins.in0rdr.ch/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/jenkins.in0rdr.ch/privkey.pem;
+
+ location / {
+ proxy_pass http://{{ env "NOMAD_ADDR_jenkins" }};
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+}