Charts: [stable/jenkins] Better support for Configuration as Code Plugin (JCasC)

Created on 6 Sep 2019  路  15Comments  路  Source: helm/charts

Is your feature request related to a problem? Please describe.
Currently most settings in Jenkins are configured by templating XML file. This works well if you configure every setting correctly before the first install. However if people change a setting within the values.yaml which would affect the XML configuration these settings are not applied later on.
The reason for this is simple as one would have to overwrite the whole XML configuration file and all other settings a user might have done within the UI which are also stored within those files are lost. If that's ok the chart has a setting which allows overwriting the XML configs.

However for most people that's not what they desire. Also many people are not aware of this and raise issue that something is not working when they try to update values.yaml, which has no effect in Jenkins.

Describe the solution you'd like
What I'd like to have is a default configuration of Jenkins done via the Jenkins Configuration as Code (a.k.a. JCasC) Plugin.
This way one could update config settings later on as the plugin would only change settings which it is managing.

The plugin offers an easy way for users to configure Jenkins and contains lot's of examples. Just check out the demos and test directories.Many people will find it easier to use those compared to figuring out in which xml file a setting is stored.

There already was an attempt to https://github.com/helm/charts/issues/11276. The PR which belongs has been closed by stale bot after comments from @maorfr

I have given this PR a lot of thought.
I am very glad about improving this chart!

There is one thing that is bugging me though, and I would appreciate your thoughts.

I always felt like values.yaml should be as simple and as lean as possible, and not just another container for configuration. As a user, I want a simple experience. For example, if I want the exact stable chart, but with a different slave image, this PR will make it harder then simply using .Agent.Image.

I would suggest to keep values.yaml more similar to its current state (I'm always +1 for simplifying it), and add the configuration complexity into the templates.
https://github.com/helm/charts/pull/11706#issuecomment-469038573

and @viglesiasce

I agree with @maorfr that we should leave in the old values for now and maybe start thinking about making a JCasC only version of this chart (v2?) that attempts to simplify things back down. https://github.com/helm/charts/pull/11706#issuecomment-470651484

As it seems to be an often requested feature (#15340) I'd like to restart the discussion and address the point made there.

I suggest to have an option to enable a default JCasC configuration which in the end should be very similar to what is currently possible via XML configs. So the configuration should ideally use the same values from the values.yaml, but instead of templating XML configs it should template yaml files.

The PR https://github.com/helm/charts/pull/16929 is a beginning of this journey. It adds a very simple default config, which for now just configures the Jenkins URL. Everyone is invited to extend this to over time have the same functionality via JCasC config as what is currently possible via XML templating. The possibility to disable the XML config via master.enableXmlConfig: false helps here to test if a configuration was really done via the plugin or via XML.

Her is an example:

master:
  enableXmlConfig: false
  javaOpts: "-Djenkins.install.runSetupWizard=false"
  JCasC:
    enabled: true
    defaultConfig: true
  sidecars:
    configAutoReload:
      enabled: true

Once all settings are migrated to JCasC config and there is no negative feedback from the community we can think of deprecate settings within values.yaml which only make sense with XML configuration and at the same time release a 2.0.0 version of the chart which has JCasC enabled by default.

Additional context
There are limitation with the JCasC plugin as well. For example if you start using it to configure credentials, then you can't at the same time manage credentials manually as the JCasC plugin would remove all credentials it's not aware of.

One can work with it by either not enabling the JCasC configuration or supplement it with your own config via master.JCasC.configScripts

lifecyclstale

Most helpful comment

I get one error with casc in the helm chart. But finally solved it!

I use a simple jenkins.yaml to test the JCasC, normally I use my bigger configuration file. But his example is want I want to run via values.yaml in helm chart:

credentials:
  system:
    domainCredentials:
    - credentials:
      - usernamePassword:
          id: "someid"
          password: "somepass"
          scope: GLOBAL
          username: "someusername"

jenkins:
  systemMessage: "Welcome to Jenkins from Helm Chart"
  mode: NORMAL
  numExecutors: 4

jobs:
  - script: >
      pipelineJob('createJobs') {
          quietPeriod(10)
          concurrentBuild(false)
          blockOn('createJobs')
          logRotator(7,7,7,7)
          definition {
              cpsScm {
                  scm {
                    git {
                      remote { 
                        url 'https://myspecialurl.git' 
                        credentials("someid")
                        }
                        branch '*/master'
                        scriptPath('code/createJobs.groovy')
                        extensions {}
                    }
                  }
              }
          }
      }

First it didn't work and I get always parsing errors with key,values.
Looked into the template ... found key, value is reading from the values.yaml and parsed for each into the casc-config.yaml

Error was:

Error: template: jenkins/templates/jenkins-master-deployment.yaml:46:28: executing "jenkins/templates/jenkins-master-deployment.yaml" at yaml:302:7: executing "jenkins/templates/config.yaml" at <$val>: wrong type for value; expected string; got map[string]interface {}

Okay cool! finally I could add JCasC config piece in it
For debugging just use:

kubectl get logs --container jenkins -n

in the values.yaml some Code could be added:

JCasC:
    enabled: true
    defaultConfig: false
    pluginVersion: "1.32"
    # it's only used when plugin version is <=1.18 for later version the
    # configuration as code support plugin is no longer needed
    supportPluginVersion: "1.18"
    configScripts: 
        jenkins: | 
          jenkins:
            systemMessage: "Hello World!"
            mode: NORMAL
            numExecutors: 4

        jobs: |
          jobs:
          - script: >
              pipelineJob('createJobs') {
                  quietPeriod(10)
                  concurrentBuild(false)
                  blockOn('createJobs')
                  logRotator(7,7,7,7)
                  definition {
                      cpsScm {
                          scm {
                            git {
                              remote { 
                                url 'https://myspecialurl.git' 
                                credentials("someid")
                                }
                                branch '*/master'
                                scriptPath('code/createJobs.groovy')
                                extensions {}
                            }
                          }
                      }
                  }
              }

If using the job step, the plugin "job-dsl" is required, see in plugins: chapter in values.yaml and add it there.

Thanks for creating this Helm Chart! :) 馃憤

All 15 comments

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Any further update will cause the issue/pull request to no longer be considered stale. Thank you for your contributions.

This issue is being automatically closed due to inactivity.

/reopen

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Any further update will cause the issue/pull request to no longer be considered stale. Thank you for your contributions.

There has been good progress on this even though the ticket has not been updated. This is a brief summary of things which have been implemented:

So we are now able to disable xml configuration and can enable default JCasC configuration. This is an example of the most important settings:

jenkins:
  master:
    enableXmlConfig: false
    JCasC:
      defaultConfig: true
      enabled: true
    sidecars:
      configAutoReload:
        enabled: true
  • enableXmlConfig: false => Disables XML configuration
  • JCasC.eabled: true => Enables configuration as code
  • JCasC.defaultConfig: true => This replaces most of the old XML configurations and implements them as Configuration as Code
  • sidecars.configAutoReload.enabled: true => Enables auto reload for JCasC configuration changes

I get one error with casc in the helm chart. But finally solved it!

I use a simple jenkins.yaml to test the JCasC, normally I use my bigger configuration file. But his example is want I want to run via values.yaml in helm chart:

credentials:
  system:
    domainCredentials:
    - credentials:
      - usernamePassword:
          id: "someid"
          password: "somepass"
          scope: GLOBAL
          username: "someusername"

jenkins:
  systemMessage: "Welcome to Jenkins from Helm Chart"
  mode: NORMAL
  numExecutors: 4

jobs:
  - script: >
      pipelineJob('createJobs') {
          quietPeriod(10)
          concurrentBuild(false)
          blockOn('createJobs')
          logRotator(7,7,7,7)
          definition {
              cpsScm {
                  scm {
                    git {
                      remote { 
                        url 'https://myspecialurl.git' 
                        credentials("someid")
                        }
                        branch '*/master'
                        scriptPath('code/createJobs.groovy')
                        extensions {}
                    }
                  }
              }
          }
      }

First it didn't work and I get always parsing errors with key,values.
Looked into the template ... found key, value is reading from the values.yaml and parsed for each into the casc-config.yaml

Error was:

Error: template: jenkins/templates/jenkins-master-deployment.yaml:46:28: executing "jenkins/templates/jenkins-master-deployment.yaml" at yaml:302:7: executing "jenkins/templates/config.yaml" at <$val>: wrong type for value; expected string; got map[string]interface {}

Okay cool! finally I could add JCasC config piece in it
For debugging just use:

kubectl get logs --container jenkins -n

in the values.yaml some Code could be added:

JCasC:
    enabled: true
    defaultConfig: false
    pluginVersion: "1.32"
    # it's only used when plugin version is <=1.18 for later version the
    # configuration as code support plugin is no longer needed
    supportPluginVersion: "1.18"
    configScripts: 
        jenkins: | 
          jenkins:
            systemMessage: "Hello World!"
            mode: NORMAL
            numExecutors: 4

        jobs: |
          jobs:
          - script: >
              pipelineJob('createJobs') {
                  quietPeriod(10)
                  concurrentBuild(false)
                  blockOn('createJobs')
                  logRotator(7,7,7,7)
                  definition {
                      cpsScm {
                          scm {
                            git {
                              remote { 
                                url 'https://myspecialurl.git' 
                                credentials("someid")
                                }
                                branch '*/master'
                                scriptPath('code/createJobs.groovy')
                                extensions {}
                            }
                          }
                      }
                  }
              }

If using the job step, the plugin "job-dsl" is required, see in plugins: chapter in values.yaml and add it there.

Thanks for creating this Helm Chart! :) 馃憤

Thank you for the feedback!

I would like to configure the pod templates in jcasc. Is this currently possible?
What I've done: disabled xml config, enabled default jcasc config, added jcasc script 'kubernetes' with the pod templates.
But now I get two incomplete copies of the kubernetes cloud config, the first half generated by the default config and the second half by my config script

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Any further update will cause the issue/pull request to no longer be considered stale. Thank you for your contributions.

This issue is being automatically closed due to inactivity.

I would like to configure the pod templates in jcasc. Is this currently possible?
What I've done: disabled xml config, enabled default jcasc config, added jcasc script 'kubernetes' with the pod templates.
But now I get two incomplete copies of the kubernetes cloud config, the first half generated by the default config and the second half by my config script

I wanted to achieve the same goal and and got the same results. I'm wondering if there's a way but I'd be willing to open a PR.

I would like to configure the pod templates in jcasc. Is this currently possible?
What I've done: disabled xml config, enabled default jcasc config, added jcasc script 'kubernetes' with the pod templates.
But now I get two incomplete copies of the kubernetes cloud config, the first half generated by the default config and the second half by my config script

I wanted to achieve the same goal and and got the same results. I'm wondering if there's a way but I'd be willing to open a PR.

Can you open an issue for this problem? Would help to get a minimalistic values.yaml which demonstrates the problem. What does incomplete config mean? What is missing?

@fdlk @lgg42: JCasC default configuration is available here: https://github.com/helm/charts/blob/master/stable/jenkins/templates/_helpers.tpl#L73-L160

If you look at the template then you'll notice that there are quite some properties which can be used for customization.

This one is very powerful as it allows to override any value of the build pod:

        yaml: |-
          {{ tpl .Values.agent.yamlTemplate . | nindent 10 | trim }}
        yamlMergeStrategy: "override"

https://github.com/helm/charts/blob/master/stable/jenkins/templates/_helpers.tpl#L142-L144

@fdlk @lgg42: JCasC default configuration is available here: https://github.com/helm/charts/blob/master/stable/jenkins/templates/_helpers.tpl#L73-L160

If you look at the template then you'll notice that there are quite some properties which can be used for customization.

This one is very powerful as it allows to override any value of the build pod:

        yaml: |-
          {{ tpl .Values.agent.yamlTemplate . | nindent 10 | trim }}
        yamlMergeStrategy: "override"

https://github.com/helm/charts/blob/master/stable/jenkins/templates/_helpers.tpl#L142-L144

Thanks for the info! I just read your message now, I finally pushed a PR, and a couple of hours later another one for the same goal. We'll sort it out for the best approach. :muscle:

I get one error with casc in the helm chart. But finally solved it!

I use a simple jenkins.yaml to test the JCasC, normally I use my bigger configuration file. But his example is want I want to run via values.yaml in helm chart:

credentials:
  system:
    domainCredentials:
    - credentials:
      - usernamePassword:
          id: "someid"
          password: "somepass"
          scope: GLOBAL
          username: "someusername"

jenkins:
  systemMessage: "Welcome to Jenkins from Helm Chart"
  mode: NORMAL
  numExecutors: 4

jobs:
  - script: >
      pipelineJob('createJobs') {
          quietPeriod(10)
          concurrentBuild(false)
          blockOn('createJobs')
          logRotator(7,7,7,7)
          definition {
              cpsScm {
                  scm {
                    git {
                      remote { 
                        url 'https://myspecialurl.git' 
                        credentials("someid")
                        }
                        branch '*/master'
                        scriptPath('code/createJobs.groovy')
                        extensions {}
                    }
                  }
              }
          }
      }

First it didn't work and I get always parsing errors with key,values.
Looked into the template ... found key, value is reading from the values.yaml and parsed for each into the casc-config.yaml

Error was:

Error: template: jenkins/templates/jenkins-master-deployment.yaml:46:28: executing "jenkins/templates/jenkins-master-deployment.yaml" at yaml:302:7: executing "jenkins/templates/config.yaml" at <$val>: wrong type for value; expected string; got map[string]interface {}

Okay cool! finally I could add JCasC config piece in it
For debugging just use:

kubectl get logs --container jenkins -n

in the values.yaml some Code could be added:

JCasC:
    enabled: true
    defaultConfig: false
    pluginVersion: "1.32"
    # it's only used when plugin version is <=1.18 for later version the
    # configuration as code support plugin is no longer needed
    supportPluginVersion: "1.18"
    configScripts: 
        jenkins: | 
          jenkins:
            systemMessage: "Hello World!"
            mode: NORMAL
            numExecutors: 4

        jobs: |
          jobs:
          - script: >
              pipelineJob('createJobs') {
                  quietPeriod(10)
                  concurrentBuild(false)
                  blockOn('createJobs')
                  logRotator(7,7,7,7)
                  definition {
                      cpsScm {
                          scm {
                            git {
                              remote { 
                                url 'https://myspecialurl.git' 
                                credentials("someid")
                                }
                                branch '*/master'
                                scriptPath('code/createJobs.groovy')
                                extensions {}
                            }
                          }
                      }
                  }
              }

If using the job step, the plugin "job-dsl" is required, see in plugins: chapter in values.yaml and add it there.

Thanks for creating this Helm Chart! :) 馃憤

I am getting the same exact error as you. I'm still trouble shooting, but I've I changed the key value pair for the config.yaml file and still getting errors. What did you end up changing in your config.yaml for the key value pair. @schnitzlein

Was this page helpful?
0 / 5 - 0 ratings