Advanced topics

5 minute readScalabilityAutomation

Enabling HTTPS

The security token and Configuration as Code (CasC) for Controllers bundle both contain sensitive information, so it is recommended that they are protected by using HTTPS when sent between the operations center and controller. HTTPS must be enabled on the operations center side. Typically enabling HTTPS is done by terminating the secure connection externally in a reverse proxy, but it can also be terminated in the Jenkins server. To enable HTTPS, add startup parameters to specify the HTTPS port, server certificate, and key.

Example startup parameters

java -jar jenkins.war --httpsPort=8443 \
--httpsCertificate=/etc/certs/jenkins-cert.cert \
--httpsPrivateKey=/etc/certs/jenkins-cert.key

Using a self-signed certificate

This configuration is not recommended and should not be used in production.

If you are using this method in a limited scope for test deployments, refer to Set-up SSL on a CJP environment with a self-sign SSL certificate on each Jenkins box, a CloudBees Knowledge Base article, for guidance on setting up CloudBees CI with a self-signed certificates.

Calculating plugin dependencies

The Plugin Installation Manager Tool can be used to assist with determining the full list of a plugin’s transitive dependencies. The tool takes as input a plugins.yaml that lists plugins you would like to install and outputs a list of all the plugins to be installed, along with all their transitive dependencies. This list can then be used to populate the plugin catalog so the plugins specified in plugins.yaml can be successfully installed.

The plugins.yaml file used by the tool is not the same as the one created previously when authoring the Configuration as Code (CasC) for Controllers bundle.

Prerequisites

  • The plugin.yaml file from the Configuration as Code (CasC) for Controllers bundle

  • Java Developer Kit (JDK) installed and configured

  • Apache Maven installed and configured

  • (Optionally) git installed and configured

  • Access to the jenkins.war file that will be used to create the connected controller

To create a list of plugins to be installed including all transitive dependencies:

  1. Clone (or download) the Plugin Installation Manager Tool’s repository from https://github.com/jenkinsci/plugin-installation-manager-tool.

  2. Build the tool using the following commands:

    cd plugin-installation-manager-tool
    mvn clean package
  3. Using the plugins.yaml file from the Configuration as Code (CasC) for Controllers bundle, create a plugins.yaml file for use with the tool. Rename the Configuration as Code (CasC) for Controllers bundle’s plugins.yaml file’s YAML property id to artifactId as illustrated below:

    plugins.yaml from Configuration as Code (CasC) for Controllers bundleplugins.yaml for use with tool
    plugins:
      - id: "git"
      - id: "maven-plugin"
    plugins:
      - artifactId: "git"
      - artifactId: "maven-plugin"
  4. Run the tool, using the following command, updating it with the location of your controller .war file and the location of your plugins.yaml file:

    cd plugin-installation-manager-tool
    java -jar \
    plugin-management-cli/target/jenkins-plugin-manager-*.jar \
    --no-download --plugin-download-directory plugin-download \
    --list \
    --war $JENKINS_HOME/cloudbees-core-cm.war \  // (1)
    --plugin-file plugins.yaml // (2)
    1location of controller .war file
    2location of plugins.yaml file

Sample output file with list of plugins

File containing list of plugins to be downloaded: plugins.yaml
Reading in plugins from plugins.yaml

Plugin download location: plugin-download
No CLI option or environment variable set for update center, using default of https://updates.jenkins.io
No CLI option or environment variable set for experimental update center, using default of https://updates.jenkins.io/experimental
No CLI option or environment variable set for incrementals mirror, using default of https://repo.jenkins-ci.org/incrementals
Will use war file: $JENKINS_HOME/jenkins.war

Installed plugins:

Bundled plugins:

Set of all requested plugins:
chucknorris 1.2
workflow-step-api 1.14

Set of all requested plugins that will be downloaded:
chucknorris 1.2
workflow-step-api 1.14

Set of all existing plugins and plugins that will be downloaded:
chucknorris 1.2
workflow-step-api 1.14
Done

Find the section in your output titled Set of all requested plugins that will be downloaded. This section is the list of plugins that will need to be added to plugin-catalog.yaml to successfully install the plugins.yaml.

You may get significantly more output than the example, especially in the “Bundled Plugins” and “Set of all existing plugins and plugins that will be downloaded” sections.

Configuring bundle inheritance with CasC

You can simplify bundle composition and maintenance by creating a "child" bundle that inherits common configuration elements from a "parent" bundle. In one parent bundle, you can maintain common configuration elements that are automatically inherited by all bundles in the inheritance chain, which eliminates the need to maintain and update individual bundles.

To configure bundle inheritance, add a parent property to the child bundle’s bundle.yaml file.

  • If making a change to a bundle, do not apply the change to all controllers at once. Instead, apply the change to a single controller-specific bundle, verify it works as expected, and then apply the change to all bundles.

  • Child bundles must only contain configuration elements that are unique to that bundle and should not overwrite the parent bundle’s configuration elements.

Example bundle inheritance

In this example, there is a parent bundle: bundle-global. There are also two child bundles: bundle-1 and bundle-2. The child bundles use the same jenkins.yaml file and plugins.yaml file as the parent bundle but include unique items in their items.yaml files.

$JENKINS_HOME/jcasc-bundles-store/
├── bundle-global
│   ├── bundle.yaml
│   ├── jenkins.yaml
│   ├── plugins.yaml
│   └── items.yaml
├── bundle-1
│   ├── bundle.yaml
│   └── items.yaml
└── bundle-2
    ├── bundle.yaml
    └── items.yaml

bundle-global example

Within bundle-global, the bundle.yaml file defines:

  • The bundle’s unique id: "bundle-global".

  • The contents of the bundle: a jenkins.yaml file, plugins.yaml file, and items.yaml file.

id: "bundle-global"
version: "1"
apiVersion: "1"
description: "CasC parent bundle with common configuration elements"
jcasc:
  - "jenkins.yaml"
plugins:
  - "plugins.yaml"
items:
  - "items.yaml"

bundle-global includes a jenkins.yaml file that describes the controller:

jenkins:
  systemMessage: "Jenkins configured using CasC."
  numExecutors: 0
  mode: NORMAL
  securityRealm:
    local:
      allowsSignup: false
      users:
       - id: admin
         password: admin
       - id: developer
         password: developer
       - id: read
         password: read

bundle-global includes a plugins.yaml file that contains a list of all plugins to install on the controller:

plugins:
  # In CloudBees Assurance Program (CAP)
  - { id: "bitbucket-branch-source" }
  - { id: "branch-api" }
  - { id: "cloudbees-casc-api" }
  - { id: "configuration-as-code" }
  - { id: "git" }
  - { id: "github-branch-source" }
  - { id: "infradna-backup" }
  - { id: "maven-plugin" }
  - { id: "nectar-rbac" }
  - { id: "workflow-job"}
  - { id: "workflow-multibranch"}

bundle-global includes an items.yaml file that contains the required removeStrategy properties and the root property that defines the root folder path for item creation.

removeStrategy:
  items: "none"
  rbac: "sync"

root: "/projects"

bundle-1 example

Within bundle-1, the bundle.yaml file defines:

  • The bundle’s unique id: "bundle-1".

  • The parent bundle to inherit from: "bundle-global".

  • The contents of the bundle that are unique to the child bundle. bundle-1 requires additional folders that are not included in the bundle-global parent bundle. Therefore, the items.yaml file must be added, since it is unique to bundle-1.

id: "bundle-1"
version: "1"
apiVersion: "1"
description: "CasC child bundle 1"
parent: "bundle-global"
items:
  - "items.yaml"

bundle-1 includes an items.yaml file that contains an additional folder and subfolders that should be created under the /projects folder path specified in bundle-global.

removeStrategy:
  items: "none"
  rbac: "sync"

items:
  - kind: "folder"
    name: "project-alpha"
    displayName: "Project Alpha"
    description: "Project Alpha is going to change the world!"
    items:
      - kind: "folder"
        name: "project-alpha-tests"
        displayName: "Project Alpha Tests"
        items:
          - kind: "folder"
            name: "test-1"
          - kind: "folder"
            name: "test-2"

bundle-2 example

Within bundle-2, the bundle.yaml file defines:

  • The bundle’s unique id: "bundle-2".

  • The parent bundle to inherit from: "bundle-global".

  • The contents of the bundle that are unique to the child bundle. bundle-2 requires an additional folder that is not included in the bundle-global parent bundle. Therefore, the items.yaml file must be added, since it is unique to bundle-2.

id: "bundle-2"
version: "1"
apiVersion: "1"
description: "CasC child bundle 2"
parent: "bundle-global"
items:
  - "items.yaml"

bundle-2 includes an items.yaml file that contains an additional folder that should be created under the /projects folder path specified in bundle-global.

removeStrategy:
  items: "none"
  rbac: "sync"

items:
  - kind: "folder"
    name: "project-beta"
    displayName: "Project Beta"
    description: "Secret project! Only Admins can see this!"