Search code examples
jenkinsjenkins-job-dsljenkins-configuration-as-code

Jenkins Job DSL create Seed Job with Configuration as a Cod Plugin


My task is to sping up Jenkins and have Job DSL Seed job automatically created during installation. That means I have to use Configuration as a Code plugin, but this plugin use Job DSL to create jobs, that means I have to create Job DSL job using Job DSL job, did anyone tried this before? Is it nearly possible?

Possible option would be import seed job as XML but this functionality been deprecated in latest Jenkins helm chart.


Solution

  • Yes, it is totally possible.

    but this plugin use Job DSL to create jobs - yes, but it assumes, that Job DSL plugin has already been installed.

    Let me copy a snippet of deployment of Jenkins that I use:

    - name: Get tag of the latest version of Plugin installation manager tool
      ansible.builtin.raw: |
        git ls-remote https://github.com/jenkinsci/plugin-installation-manager-tool.git \
        | grep -E "refs/tags/[0-9]+\.[0-9]+\.[0-9]+$" | tail -n1 | cut -d / -f 3
      register: plugin_manager_version
    
    # https://github.com/jenkinsci/plugin-installation-manager-tool#getting-started
    - name: Download Plugin installation manager tool
      ansible.builtin.get_url:
        url:
          "https://github.com/jenkinsci/plugin-installation-manager-tool/releases/\
          download/{{ plugin_manager_version.stdout | trim }}/jenkins-plugin-manager-{{ plugin_manager_version.stdout | trim }}.jar"
        dest: /tmp/jenkins/jenkins-plugin-manager.jar
    
    - name: Copy a list of plugins to install
      ansible.builtin.copy:
        src: plugins.txt
        dest: /tmp/jenkins/plugins.txt
        mode: 0444
        owner: jenkins
        group: jenkins
    
    - name: Install the latest version of plugins
      ansible.builtin.command: |
        java -jar /tmp/jenkins/jenkins-plugin-manager.jar --war /usr/lib/jenkins/jenkins.war -f /tmp/jenkins/plugins.txt -d /var/lib/jenkins/plugins
    
    - name: Set ownership of plugins
      ansible.builtin.file:
        path: /var/lib/jenkins/plugins
        owner: jenkins
        group: jenkins
        mode: 0644
        recurse: true
    
    - name: Set ownership of plugins folder
      ansible.builtin.file:
        path: /var/lib/jenkins/plugins
        owner: jenkins
        group: jenkins
        mode: 0755
        recurse: false
    
    - name: Copy Jenkins configuration files
      ansible.builtin.template:
        src: "{{ item }}.yaml.j2"
        dest: "/var/lib/jenkins/casc_configs/{{ item }}.yaml"
        mode: 0644
        owner: jenkins
        group: jenkins
      loop: "{{ ['credentials', 'general', 'seed-job', 'users'] | flatten(1) }}"
    
    - name: Restart Jenkins
      ansible.builtin.systemd:
        name: jenkins
        state: restarted
        enabled: true
    

    In plugins.txt there are, among others, plugins configuration-as-code and job-dsl.

    And seed-job.yaml looks like this:

    jobs:
      - script: >
          freeStyleJob('Seed Job') {
              description('Synchronizes Jenkins jobs with ones in my-repo/jobs folder.')
              displayName('Seed Job')
              scm {
                  git {
                      remote {
                          name('Jenkins jobs')
                          url('https://github.com/my-repo.git')
                          credentials('GITHUB_CREDENTIALS')
                      }
                      branch('master')
                  }
              }
              triggers {
                  pollSCM {
                      scmpoll_spec('* * * * *')
                  }
              }
              steps {
                  dsl {
                      external "jobs/**/*.groovy"
                      removeAction("DELETE")
                      removeViewAction("DELETE")
                  }
              }
          }
    

    And now the seed job will automatically import all the jobs from your repository.

    An example Job DSL looks like this:

    freeStyleJob('System Cleanup') {
        displayName('System Cleanup')
        description('Remove unused Docker stuff and golang cache once a month.')
        label('continuous-integration')
        triggers {
            scm('H 0 1 * *')
        }
        steps {
            shell('docker system prune --all --volumes --force')
            shell('go clean -cache -modcache -testcache')
        }
    }
    

    but of course you can write Job DSLs for other types of jobs (e.g. multibranchPipeline). Refer to the API Viewer in your Jenkins instance.