{"id":14984787,"url":"https://github.com/kenych/jenkins_config_as_code","last_synced_at":"2025-08-16T11:44:37.466Z","repository":{"id":198655821,"uuid":"125677685","full_name":"kenych/jenkins_config_as_code","owner":"kenych","description":"jenkins config as code, poc","archived":false,"fork":false,"pushed_at":"2018-03-18T14:36:47.000Z","size":8,"stargazers_count":28,"open_issues_count":0,"forks_count":12,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-03T09:14:00.583Z","etag":null,"topics":["consul-template","groovy-scripts","jenkins","jenkins-configuration","jenkins-pipeline","kubernetes","kubernetes-plugin","vault"],"latest_commit_sha":null,"homepage":"http://devopsystuff.com/2018/03/18/advanced-jenkins-setup-creating-jenkins-configuration-as-code-and-applying-changes-without-downtime-with-java-groovy-docker-vault-consul-template-and-jenkins-job/","language":"Groovy","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kenych.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-03-17T23:37:06.000Z","updated_at":"2021-12-21T15:43:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"9bf4e08c-6220-4c3b-ae69-ea8fa3727477","html_url":"https://github.com/kenych/jenkins_config_as_code","commit_stats":null,"previous_names":["kenych/jenkins_config_as_code"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenych%2Fjenkins_config_as_code","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenych%2Fjenkins_config_as_code/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenych%2Fjenkins_config_as_code/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenych%2Fjenkins_config_as_code/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kenych","download_url":"https://codeload.github.com/kenych/jenkins_config_as_code/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239405899,"owners_count":19633010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["consul-template","groovy-scripts","jenkins","jenkins-configuration","jenkins-pipeline","kubernetes","kubernetes-plugin","vault"],"created_at":"2024-09-24T14:09:40.236Z","updated_at":"2025-02-18T03:31:53.969Z","avatar_url":"https://github.com/kenych.png","language":"Groovy","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Advanced Jenkins config as code setup with 4 steps\n\nCreating Jenkins configation as code and applying changes without downtime with Groovy, Java, Docker and Jenkins job.\n\nPOC: \n1) Being able to update any Jenkins master or slave immediately - no new image, no redeploy, no downtime \n2) No manual changes through UI - everything is kept as a code, and as a result:\n3) Jenkins current state and state of image + config is kept in sync\n4) Any change could be tested immediatelly without vicious cycle: create a new image, deploy, test, and if fails - repeat!\n5) Creating a configuration that could be applied for specific environment only(prod vs test/dev Jenkins), with inheritence of common config and custom per jenkins config\n\n#### Step 1: Write groovy to interact with Java API\n```\nimport hudson.model.*\nimport jenkins.model.*\nimport com.cloudbees.plugins.credentials.CredentialsScope\nimport com.cloudbees.plugins.credentials.domains.Domain\nimport com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl\n\ndef domain = Domain.global()\ndef store = Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()\n\ndef instance = System.getenv(\"JENKINS_INSTANCE_NAME\").replaceAll('-','_')\n\nConfigObject conf = new ConfigSlurper().parse(new File(System.getenv(\"JENKINS_HOME\")+'/jenkins_config/credentials.txt').text)\n\nconf.common_credentials.each { key, credentials -\u003e\n    println(\"Adding common credential ${key}\")\n    store.addCredentials(domain, new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, key, credentials.description, credentials.username, credentials.password))\n}\n\n\nconf.\"${instance}_credentials\".each { key, credentials -\u003e\n    println(\"Adding ${instance} credential ${key}\")\n    store.addCredentials(domain, new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, key, credentials.description, credentials.username, credentials.password))\n}\n\nprintln(\"Successfully configured credentials\")\n\n```\n\n#### Step 2: Create config for the script\n\n```\ncommon_credentials {\n\n    exclude{\n        tyrion-jenkins\n    }\n\n    data{\n        jenkins_service_user = [\n             username: 'jenkins_service_user',\n             password: '{{with $secret := secret \"secret/jenkins/jenkins_service_user\" }}{{ $secret.Data.value }}{{end}}',\n             description :'for automated jenkins jobs'\n         ]\n\n         slack = [\n             username: '{{with $secret := secret \"secret/slack/user\" }}{{ $secret.Data.value }}{{end}}',\n             password: '{{with $secret := secret \"secret/slack/pass\" }}{{ $secret.Data.value }}{{end}}',\n             description: 'slack credentials'\n         ]\n    }\n\n}\n\ncustom_credentials  {\n\n    include{\n        john-snow-jenkins\n        arya-jenkins\n        sansa-jenkins\n    }\n\n    data{\n        artifactory = [\n                username: 'arti',\n                password: '{{with $secret := secret \"secret/jenkins/artifactory\" }}{{ $secret.Data.artifactory_password }}{{end}}',\n                description: 'Artifactory credentials'\n        ]\n\n    }\n\n}\n\ntyrion-jenkins_credentials  {\n\n    data{\n       nexus=[\n                'username':'deployment',\n                'password':'{{with $secret := secret \"secret/jenkins/nexus\" }}{{ $secret.Data.nexus_password }}{{end}}',\n                'description':'Nexus credentials'\n        ]\n\n    }\n\n}\n```\n\n#### Step 3: Checkout config and script and inject secrets and other variables with consul-template in container:\n```\n#!/usr/bin/env bash\n\ngit clone ssh://git@your_scm_here/jenkins_config_as_code.git ${JENKINS_HOME}/jenkins_config\nmv ${JENKINS_HOME}/jenkins_config/*.groovy ${JENKINS_HOME}/init.groovy.d/\n\nconsul-template \\\n  -consul-addr \"$CONSUL_ADDR\" \\\n  -vault-addr \"$VAULT_ADDR\" \\\n  -config \"jenkins_config.hcl\" \\\n  -once\n\n\n```\n\n\n#### Step 4: Update continuously with Jenkins job without downtime\n```\nnode {\n    stage('checkout') {\n\n        sh '''\n\n\t\t    git clone ssh://git@your_scm_here/jenkins_config_as_code.git ${JENKINS_HOME}/jenkins_config\n\t\t\tmv ${JENKINS_HOME}/jenkins_config/*.groovy ${JENKINS_HOME}/init.groovy.d/\n\n\t\t'''\n    }\n\n    stage('run consul template'){\n        sh '''\n\t\t\tconsul-template \\\n\t\t\t  -consul-addr \"$CONSUL_ADDR\" \\\n\t\t\t  -vault-addr \"$VAULT_ADDR\" \\\n\t\t\t  -config \"jenkins_config.hcl\" \\\n\t\t\t  -once        \n        '''\n    }\n\n    stage('update credentials') {\n        load(\"/var/jenkins_home/init.groovy.d/credentials.groovy\")\n    }\n\n    stage('update k8s') {\n        load(\"/var/jenkins_home/init.groovy.d/kubernetes.groovy\")\n    }\n\n}\n\n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkenych%2Fjenkins_config_as_code","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkenych%2Fjenkins_config_as_code","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkenych%2Fjenkins_config_as_code/lists"}