nomad

HCL and Docker files for Nomad deployments
git clone https://git.in0rdr.ch/nomad.git
Log | Files | Refs | Pull requests

commit 7b5dce282e5df574ef766ae4092fdd8c0914422d
parent fe01c767c2e67b00e6c79a835f0511b16e1e1169
Author: Andreas Gruhler <andreas.gruhler@adfinis.com>
Date:   Wed, 30 Aug 2023 08:02:42 +0200

feat: add jenkins

Diffstat:
Ahcl/default/jenkins/data-volume.hcl | 31+++++++++++++++++++++++++++++++
Ahcl/default/jenkins/jenkins.nomad | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahcl/default/jenkins/templates/jenkins.yaml.tmpl | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahcl/default/jenkins/templates/nginx.conf.tmpl | 14++++++++++++++
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; + } +}