If you are a Jenkins administrator, then you will not be unfamiliar with the above page, every time you deploy a new Jenkins instance, before you can use it, you often need to configure some of the appropriate configuration in the above page (home directory, number of executables, Jenkins URL, system administrator e-mail address, Resource Root URL, etc.). ). In addition to some basic configuration information about Jenkins itself, this page also includes configuration information about the plug-ins installed on the current system.That is, as your Jenkins installs more plugins, chances are there will be more configuration items on that page.
Example 2 Configuring the Security--Security (Configuring Global Security) page:
Jenkins administrators can configure authentication, authorization, proxies, cross domains, etc. here.
Jenkins Configuration as Code is a Jenkins plugin that frees us from a lot of manual configuration work.Jenkins Configuration as Code Plugin Allows users to write System Configuration, Security and other Jenkins configuration information to a YAML file. In this way, you can standardize the configuration of Jenkins , easy to reuse within the team , easy to disseminate , easy to quickly build out-of-the-box Jenkins service .With this plugin, we almost no longer need to configure the Jenkins service by manually clicking on the UI interface.Moreover, the vast majority of other plugins require little (if any) tweaking to be compatible with this plugin. This article will address in detail how to use Jenkins Configuration as Code in Jenkins.
Note 1: The main purpose of the Configuration as Code plugin is to minimize the effort of Jenkins administrators to manually configure Jenkins through the UI interface. However, it is not possible to install the Jenkins plugin from a configuration file managed by CasC. Therefore, before using the Configuration as Code plug-in, you need to make sure that your Jenkins instance has all the plug-ins mentioned in the configuration file installed.
2、Jenkins Configuration as Code full solution (a math problem)
Jenkins Configuration as Code, aka JCasC, allows us to write all the configurations about Jenkins in YAML format to a configuration file and automate the configuration of Jenkins in one click by applying these configurations to the Jenkins instances equipped with the plugin.
JCasC provides a set of specific key values for writing YAML files that correspond to different configuration items in Jenkins. To configure Jenkins by assigning values to these Key values, here is an official example configuration file:
jenkins:
systemMessage: "Jenkins configured automatically by Jenkins Configuration as Code plugin\n\n"
securityRealm:
ldap:
configurations:
- groupMembershipStrategy:
fromUserRecord:
attributeName: "memberOf"
inhibitInferRootDN: false
rootDN: "dc=acme,dc=org"
server: "ldaps://:1636"
nodes:
- permanent:
name: "static-agent"
remoteFS: "/home/jenkins"
launcher:
jnlp:
workDirSettings:
disabled: true
failIfWorkDirIsMissing: false
internalDir: "remoting"
workDirPath: "/tmp"
slaveAgentPort: 50000
agentProtocols:
- "jnlp2"
tool:
git:
installations:
- name: git
home: /usr/local/bin/git
credentials:
system:
domainCredentials:
- credentials:
- basicSSHUserPrivateKey:
scope: SYSTEM
id: ssh_with_passphrase_provided
username: ssh_root
passphrase: ${SSH_KEY_PASSWORD}
description: "SSH passphrase with private key file. Private key provided"
privateKeySource:
directEntry:
privateKey: ${SSH_PRIVATE_KEY}
The configuration file uses three root configuration element keys provided by JCasC: jenkins, tools, and credentials, which correspond to the basic Jenkins configuration item, the global tools configuration item, and the Jenkins Credentials-related configuration item, respectively. By setting appropriate values for the sub-configuration keys provided by these root keys, we configure Jenkins as follows:
- jenkins
- The systemMessage Key sets the "System Message" message for Jenkins.
- The securityRealm Key sets the LDAP-related configuration and sets it as the authentication method for Jenkins.
- nodes Key creates a node named static-agent and configures it appropriately.
- The slaveAgentPort Key sets the port number and protocol for communication between the Jenkins host and the node.
- The agentProtocols Key sets the protocol for communication between the Jenkins host and the node.
- tool
- git specifies the default execution path for Git, the global tool for Jenkins.
- credentials
- Create a system-level SSH credential with the ID ssh_with_passphrase_provided.
In addition to the three root configuration elements used in the example above, theunclassified is another very common root configuration element under which most of the plugin-specific configuration is contained.
In addition to the root configuration elements themselves, there are a number of sub-configuration Keys provided under each root configuration element, and depending on which plugins are installed, these sub-keys are supported differently by each Jenkins instance.The Documentation page (Dashboard -> Manage Jenkins -> Configuration as Code -> page bottom reference -> Documentation) provided by JCasC lists all of the Key values supported in the current Jenkins instance. Documentation page provided by JCasC (Dashboard -> Manage Jenkins -> Configuration as Code -> page bottom reference -> Documentation) lists information about all of the Key values that are supported in the current Jenkins instance.
3, Jenkins installation Configuration as Code Plugin
Jenkins Configuration as Code, aka JCasC, allows us to write all the configurations about Jenkins in YAML format to a configuration file and automate the configuration of Jenkins in one click by applying these configurations to the Jenkins instances equipped with the plugin.
JCasC provides a set of specific key values for writing YAML files that correspond to different configuration items in Jenkins. To configure Jenkins by assigning values to these Key values, here is an official example configuration file:
jenkins: systemMessage: "Jenkins configured automatically by Jenkins Configuration as Code plugin\n\n" securityRealm: ldap: configurations: - groupMembershipStrategy: fromUserRecord: attributeName: "memberOf" inhibitInferRootDN: false rootDN: "dc=acme,dc=org" server: "ldaps://:1636" nodes: - permanent: name: "static-agent" remoteFS: "/home/jenkins" launcher: jnlp: workDirSettings: disabled: true failIfWorkDirIsMissing: false internalDir: "remoting" workDirPath: "/tmp" slaveAgentPort: 50000 agentProtocols: - "jnlp2" tool: git: installations: - name: git home: /usr/local/bin/git credentials: system: domainCredentials: - credentials: - basicSSHUserPrivateKey: scope: SYSTEM id: ssh_with_passphrase_provided username: ssh_root passphrase: ${SSH_KEY_PASSWORD} description: "SSH passphrase with private key file. Private key provided" privateKeySource: directEntry: privateKey: ${SSH_PRIVATE_KEY}
The configuration file uses three root configuration element keys provided by JCasC: jenkins, tools, and credentials, which correspond to the basic Jenkins configuration item, the global tools configuration item, and the Jenkins Credentials-related configuration item, respectively. By setting appropriate values for the sub-configuration keys provided by these root keys, we configure Jenkins as follows:
- jenkins
- The systemMessage Key sets the "System Message" message for Jenkins.
- The securityRealm Key sets the LDAP-related configuration and sets it as the authentication method for Jenkins.
- nodes Key creates a node named static-agent and configures it appropriately.
- The slaveAgentPort Key sets the port number and protocol for communication between the Jenkins host and the node.
- The agentProtocols Key sets the protocol for communication between the Jenkins host and the node.
- tool
- git specifies the default execution path for Git, the global tool for Jenkins.
- credentials
- Create a system-level SSH credential with the ID ssh_with_passphrase_provided.
In addition to the three root configuration elements used in the example above, theunclassified is another very common root configuration element under which most of the plugin-specific configuration is contained.
In addition to the root configuration elements themselves, there are a number of sub-configuration Keys provided under each root configuration element, and depending on which plugins are installed, these sub-keys are supported differently by each Jenkins instance.The Documentation page (Dashboard -> Manage Jenkins -> Configuration as Code -> page bottom reference -> Documentation) provided by JCasC lists all of the Key values supported in the current Jenkins instance. Documentation page provided by JCasC (Dashboard -> Manage Jenkins -> Configuration as Code -> page bottom reference -> Documentation) lists information about all of the Key values that are supported in the current Jenkins instance.
Jenkins Plugin Center to install Configuration as Code Plugin plugin, after the installation is complete, you need to restart Jenkins.
After successful installation, you can see the Configuration as Code option under the System Configuration module.
Click on the Configuration as Code function option to enter the Configuration as Code function page. The function is relatively simple, so I won't go into it here. Here are 2 quick tips for writing documents:
- The official documentation for the JCasC plugin provides a large number ofConfiguration exampleThis contains almost all the configuration of Jenkins and most of the plugin configuration, refer to these configuration examples can help us quickly write their own configuration files.
- Another tip for writing YAML configuration files is to manually configure everything in the Jenkin UI, and then use the "View Configuration" on the plugin's page to get the configuration file that JCasC has generated for us as a reference to write our own configuration file. configuration file that JCasC automatically generates for us as a reference to write our own configuration file.
For example, the current Jenkins environment has only a few plug-ins installed and a basic system configuration and security configuration. Viewing and exporting the configuration through the GUI generates a file. The next time you install a new Jenkins installation, you can simply tweak this file without having to manually configure these parameters in the GUI again.
In addition to operating CasC functions from the UI, the CLI also has support for them.
$ jcli casc Configuration as Code Usage: jcli casc [command] Available Commands: apply From the application's existing configuration export Export Configuration and Configuration of Code open Open the configuration and code page in your browser reload Reload configurations and code for configurations schema Getting the configuration and structure of the code
It is also possible to operate CasC related functions through the Restful interface.
Exporting Configurations curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/export ferret out Schema curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/schema Reload Configuration curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/reload Applying configuration from a request curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/apply
4, start Jenkins when the CasC configuration file loading process
Also, CasC is just configured to support loading multiple configuration files at the same time. If we split different parts of Jenkins into multiple files, it will be easy to maintain.
Supported Strategies:
- ErrorOnConflictMergeStrategy (default): the name of this strategy is errorOnConflict; an exception is thrown if there is a conflict in multiple YAML files.
- Override merge policy: the name of this policy is override; overrides configuration files based on the order in which they are loaded.
Policy names are configured in two ways:
- Setting the environment CASC_MERGE_STRATEGY
- Setting System Properties
5、Jenkins Configuration as Code Configuration example
jenkins:
mode: EXCLUSIVE
numExecutors: 0
scmCheckoutRetryCount: 2
disableRememberMe: true
clouds:
- kubernetes:
name: "kubernetes"
serverUrl: ""
skipTlsVerify: true
namespace: "devops-system"
credentialsId: "k8s-service-account"
jenkinsUrl: "-system:80"
jenkinsTunnel: "-system:50000"
containerCapStr: "10"
connectTimeout: "60"
readTimeout: "60"
maxRequestsPerHostStr: "32"
templates:
- name: "base"
namespace: "devops-system"
label: "base"
nodeUsageMode: "NORMAL"
idleMinutes: 0
containers:
- name: "base"
image: "builder-base:v3.2.2"
command: "cat"
args: ""
ttyEnabled: true
privileged: false
resourceRequestCpu: "100m"
resourceLimitCpu: "4000m"
resourceRequestMemory: "100Mi"
resourceLimitMemory: "8192Mi"
- name: "jnlp"
image: "jenkins/inbound-agent:4.10-2"
args: "^${} ^${}"
resourceRequestCpu: "50m"
resourceLimitCpu: "500m"
resourceRequestMemory: "400Mi"
resourceLimitMemory: "1536Mi"
workspaceVolume:
emptyDirWorkspaceVolume:
memory: false
volumes:
- hostPathVolume:
hostPath: "/var/run/"
mountPath: "/var/run/"
- hostPathVolume:
hostPath: "/var/data/jenkins_sonar_cache"
mountPath: "/root/.sonar/cache"
yaml: |
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: /worker
operator: In
values:
- ci
tolerations:
- key: "/ci"
operator: "Exists"
effect: "NoSchedule"
- key: "/ci"
operator: "Exists"
effect: "PreferNoSchedule"
containers:
- name: "base"
resources:
requests:
ephemeral-storage: "1Gi"
limits:
ephemeral-storage: "10Gi"
securityContext:
fsGroup: 1000
- name: "nodejs"
namespace: "devops-system"
label: "nodejs"
nodeUsageMode: "EXCLUSIVE"
idleMinutes: 0
containers:
- name: "nodejs"
image: "builder-nodejs:v3.2.0"
command: "cat"
args: ""
ttyEnabled: true
privileged: false
resourceRequestCpu: "100m"
resourceLimitCpu: "4000m"
resourceRequestMemory: "100Mi"
resourceLimitMemory: "8192Mi"
- name: "jnlp"
image: "jenkins/inbound-agent:4.10-2"
args: "^${} ^${}"
resourceRequestCpu: "50m"
resourceLimitCpu: "500m"
resourceRequestMemory: "400Mi"
resourceLimitMemory: "1536Mi"
workspaceVolume:
emptyDirWorkspaceVolume:
memory: false
volumes:
- hostPathVolume:
hostPath: "/var/run/"
mountPath: "/var/run/"
- hostPathVolume:
hostPath: "/var/data/jenkins_nodejs_yarn_cache"
mountPath: "/root/.yarn"
- hostPathVolume:
hostPath: "/var/data/jenkins_nodejs_npm_cache"
mountPath: "/root/.npm"
- hostPathVolume:
hostPath: "/var/data/jenkins_sonar_cache"
mountPath: "/root/.sonar/cache"
yaml: |
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: /worker
operator: In
values:
- ci
tolerations:
- key: "/ci"
operator: "Exists"
effect: "NoSchedule"
- key: "/ci"
operator: "Exists"
effect: "PreferNoSchedule"
containers:
- name: "nodejs"
resources:
requests:
ephemeral-storage: "1Gi"
limits:
ephemeral-storage: "10Gi"
securityContext:
fsGroup: 1000
securityRealm:
ldap:
configurations:
- displayNameAttributeName: "uid"
mailAddressAttributeName: "mail"
inhibitInferRootDN: false
managerDN: "cn=admin,dc=zmc,dc=io"
managerPasswordSecret: "admin"
rootDN: "dc=zmc,dc=io"
userSearchBase: "ou=Users"
userSearch: "(&(objectClass=inetOrgPerson)(|(uid={0})(mail={0})))"
groupSearchBase: "ou=Groups"
groupSearchFilter: "(&(objectClass=posixGroup)(cn={0}))"
server: "ldap://:389"
disableMailAddressResolver: false
disableRolePrefixing: true
unclassified:
gitLabServers:
servers:
- name: ""
serverUrl: ""
jenkins: mode: EXCLUSIVE numExecutors: 0 scmCheckoutRetryCount: 2 disableRememberMe: true clouds: - kubernetes: name: "kubernetes" serverUrl: "" skipTlsVerify: true namespace: "devops-system" credentialsId: "k8s-service-account" jenkinsUrl: "-system:80" jenkinsTunnel: "-system:50000" containerCapStr: "10" connectTimeout: "60" readTimeout: "60" maxRequestsPerHostStr: "32" templates: - name: "base" namespace: "devops-system" label: "base" nodeUsageMode: "NORMAL" idleMinutes: 0 containers: - name: "base" image: "builder-base:v3.2.2" command: "cat" args: "" ttyEnabled: true privileged: false resourceRequestCpu: "100m" resourceLimitCpu: "4000m" resourceRequestMemory: "100Mi" resourceLimitMemory: "8192Mi" - name: "jnlp" image: "jenkins/inbound-agent:4.10-2" args: "^${} ^${}" resourceRequestCpu: "50m" resourceLimitCpu: "500m" resourceRequestMemory: "400Mi" resourceLimitMemory: "1536Mi" workspaceVolume: emptyDirWorkspaceVolume: memory: false volumes: - hostPathVolume: hostPath: "/var/run/" mountPath: "/var/run/" - hostPathVolume: hostPath: "/var/data/jenkins_sonar_cache" mountPath: "/root/.sonar/cache" yaml: | spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: /worker operator: In values: - ci tolerations: - key: "/ci" operator: "Exists" effect: "NoSchedule" - key: "/ci" operator: "Exists" effect: "PreferNoSchedule" containers: - name: "base" resources: requests: ephemeral-storage: "1Gi" limits: ephemeral-storage: "10Gi" securityContext: fsGroup: 1000 - name: "nodejs" namespace: "devops-system" label: "nodejs" nodeUsageMode: "EXCLUSIVE" idleMinutes: 0 containers: - name: "nodejs" image: "builder-nodejs:v3.2.0" command: "cat" args: "" ttyEnabled: true privileged: false resourceRequestCpu: "100m" resourceLimitCpu: "4000m" resourceRequestMemory: "100Mi" resourceLimitMemory: "8192Mi" - name: "jnlp" image: "jenkins/inbound-agent:4.10-2" args: "^${} ^${}" resourceRequestCpu: "50m" resourceLimitCpu: "500m" resourceRequestMemory: "400Mi" resourceLimitMemory: "1536Mi" workspaceVolume: emptyDirWorkspaceVolume: memory: false volumes: - hostPathVolume: hostPath: "/var/run/" mountPath: "/var/run/" - hostPathVolume: hostPath: "/var/data/jenkins_nodejs_yarn_cache" mountPath: "/root/.yarn" - hostPathVolume: hostPath: "/var/data/jenkins_nodejs_npm_cache" mountPath: "/root/.npm" - hostPathVolume: hostPath: "/var/data/jenkins_sonar_cache" mountPath: "/root/.sonar/cache" yaml: | spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: /worker operator: In values: - ci tolerations: - key: "/ci" operator: "Exists" effect: "NoSchedule" - key: "/ci" operator: "Exists" effect: "PreferNoSchedule" containers: - name: "nodejs" resources: requests: ephemeral-storage: "1Gi" limits: ephemeral-storage: "10Gi" securityContext: fsGroup: 1000 securityRealm: ldap: configurations: - displayNameAttributeName: "uid" mailAddressAttributeName: "mail" inhibitInferRootDN: false managerDN: "cn=admin,dc=zmc,dc=io" managerPasswordSecret: "admin" rootDN: "dc=zmc,dc=io" userSearchBase: "ou=Users" userSearch: "(&(objectClass=inetOrgPerson)(|(uid={0})(mail={0})))" groupSearchBase: "ou=Groups" groupSearchFilter: "(&(objectClass=posixGroup)(cn={0}))" server: "ldap://:389" disableMailAddressResolver: false disableRolePrefixing: true unclassified: gitLabServers: servers: - name: "" serverUrl: ""
The above configuration file is based on the CASC plugin and is used to automatically load the configuration when the Jenkins instance starts. It configures various aspects of Jenkins including execution mode, Kubernetes cluster connections and Pod templates, security settings, etc. Below is an explanation of each section:
5.1 Jenkins Main Configuration
jenkins: mode: EXCLUSIVE numExecutors: 0 scmCheckoutRetryCount: 2 disableRememberMe: true
- mode: EXCLUSIVE: Jenkins operation mode, set to "EXCLUSIVE" means that Jenkins will only run jobs on the set node, not on the master node.
- numExecutors: 0: The number of executors on the master node is set to 0 to indicate that no jobs will be run on the master node.
- scmCheckoutRetryCount: 2: SCM (Source Code Management) checkout retry count, default is 2.
- disableRememberMe: true: Disable the "remember me" feature to improve security.
5.2 Kubernetes Cloud Configuration
clouds: - kubernetes: name: "kubernetes" serverUrl: "" skipTlsVerify: true namespace: "devops-system" credentialsId: "k8s-service-account" jenkinsUrl: "-system:80" jenkinsTunnel: "-system:50000" containerCapStr: "10" connectTimeout: "60" readTimeout: "60" maxRequestsPerHostStr: "32"
- name: The name of the Kubernetes cloud.
- serverUrl: URL of the Kubernetes API server.
- skipTlsVerify: if or not skip TLS verification, set to true to skip.
- namespace: The namespace used to run the Jenkins agent.
- credentialsId: ID of the Kubernetes credential.
- jenkinsUrl: URL of the Jenkins instance.
- jenkinsTunnel: The address of the tunnel between Jenkins and the Kubernetes agent.
- containerCapStr: Maximum number of containers.
- connectTimeout and readTimeout: connect and read timeout.
- maxRequestsPerHostStr: Maximum number of requests per host.
5.3 Pod Templates
Multiple Pod templates are configured for different build environments. Each template contains specific container configurations, resource requests and limits, storage volumes, and affinities. In the example, we have configured base, nodejs, if you need other container templates, you can add them as needed.
templates: - name: "base" namespace: "devops-system" label: "base" nodeUsageMode: "NORMAL" idleMinutes: 0 ...... securityContext: fsGroup: 1000
- name: The name of the Pod template.
- namespace: The namespace where the Pod will be run.
- label: The label of the Pod, used to specify the node in a Jenkins job.
- nodeUsageMode: node usage mode.
- containers: Container configurations contained in the Pod.
- workspaceVolume: Jenkins workspace volume configuration.
- volumes: Volumes mounted in the Pod.
5.4 Security configuration
securityRealm: ldap: configurations: - displayNameAttributeName: "uid" mailAddressAttributeName: "mail" inhibitInferRootDN: false managerDN: "cn=admin,dc=zmc,dc=io" managerPasswordSecret: "admin" rootDN: "dc=zmc,dc=io" userSearchBase: "ou=Users" userSearch: "(&(objectClass=inetOrgPerson)(|(uid={0})(mail={0})))" groupSearchBase: "ou=Groups" groupSearchFilter: "(&(objectClass=posixGroup)(cn={0}))" server: "ldap://:389" disableMailAddressResolver: false disableRolePrefixing: true
- ldap: Configure LDAP as a security domain.
- configurations: LDAP server configurations, including DNs, passwords, search baselines, and so on.
- server: LDAP server address.
5.4 Uncategorized configuration
unclassified: gitLabServers: servers: - name: "" serverUrl: ""
- gitLabServers: GitLab server configuration.
6. Summary
Jenkins Configuration as Code (Configuration as Code) can help us from a lot of manual configuration of Jenkins work to free . Jenkins Configuration as Code Plugin allows users to System Configuration, Security, etc. to write Jenkins configuration information into a YAML file. The Jenkins Configuration as Code Plugin allows you to write System Configuration, Security, and other Jenkins configuration information to a YAML file. This allows you to standardize Jenkins configurations, make it easy to reuse within your team, and make it easy to disseminate and quickly build out-of-the-box Jenkins services.With this plugin, we almost no longer need to manually click on the UI interface to configure the Jenkins service (to achieve Jenkins zero configuration).Also, the vast majority of other plugins require little (if any) tweaking to be compatible with this plugin.
There are thousands of Jenkins plug-ins, and Jenkins configurations are just as varied. For more information on how to write a JCasC configuration file, refer to theofficial example