Configuration as Code (JCasC)
Define your entire Jenkins configuration in a versioned YAML file so a controller can be rebuilt from scratch reproducibly instead of by clicking around.
A controller configured by hand through the web UI is a snowflake: nobody remembers every checkbox, and rebuilding it after a disk failure is a nightmare. Configuration as Code (JCasC) lets you describe the whole controller — security realm, clouds, credentials, tools, global settings — in a single YAML file that lives in Git.
How it works
Install the Configuration as Code plugin and point the CASC_JENKINS_CONFIG environment variable at your YAML file (or a directory of them). On startup Jenkins reads it and applies the configuration. Combined with a plugin manifest and a Docker image, you get a controller that is fully reproducible from source.
What belongs in it
- Security realm and authorization strategy.
- Cloud/agent templates (e.g. the Kubernetes cloud).
- Global tool locations and shared library definitions.
- Credential references — the values themselves come from environment variables or a secrets manager, never committed.
Why seniors love it
Code review for infrastructure, instant disaster recovery, and identical staging/production controllers. You stop debugging "what did someone change in the UI last week?"
Example
# jenkins.yaml — applied at startup via CASC_JENKINS_CONFIG
jenkins:
systemMessage: "Managed by JCasC — do not edit via the UI."
numExecutors: 0 # controller runs no builds
authorizationStrategy:
roleBased:
roles:
global:
- name: "admin"
permissions: ["Overall/Administer"]
assignments: ["platform-team"]
clouds:
- kubernetes:
name: "k8s"
namespace: "jenkins-agents"
jenkinsUrl: "http://jenkins.jenkins.svc:8080"
containerCapStr: "20"
credentials:
system:
domainCredentials:
- credentials:
- usernamePassword:
scope: GLOBAL
id: "registry-deploy"
username: "ci-bot"
# value injected from env, never committed:
password: "${REGISTRY_TOKEN}"
unclassified:
globalLibraries:
libraries:
- name: "acme-pipelines"
defaultVersion: "v2.3.1"
retriever:
modernSCM:
scm:
git:
remote: "https://github.com/acme/acme-pipelines.git"When to use it
- A team stores jenkins.yaml in Git so a destroyed Jenkins controller can be rebuilt identically in under 5 minutes.
- JCasC provisions all credentials, cloud agents, and security settings during container startup so no manual clicking is needed.
- A CI/CD environment is spin up in a PR preview namespace with a full jenkins.yaml so integration tests run against a real Jenkins.
More examples
Minimal jenkins.yaml skeleton
A minimal JCasC YAML that sets the system message, disables the built-in executor, and configures local auth.
jenkins:
systemMessage: 'Managed by JCasC'
numExecutors: 0
securityRealm:
local:
allowsSignup: false
users:
- id: admin
password: '${JENKINS_ADMIN_PASSWORD}'
authorizationStrategy:
loggedInUsersCanDoAnything:
allowAnonymousRead: falseJCasC credential and tool config
Defines a GitHub token credential and auto-installing Maven tool in JCasC YAML.
credentials:
system:
domainCredentials:
- credentials:
- string:
id: github-token
secret: '${GITHUB_TOKEN}'
description: GitHub API token
tool:
maven:
installations:
- name: Maven-3.9
properties:
- installSource:
installers:
- maven:
id: '3.9.6'Mount JCasC in Docker Compose
Mounts a local jenkins.yaml as read-only and sets CASC_JENKINS_CONFIG so Jenkins applies it on startup.
version: '3.8'
services:
jenkins:
image: jenkins/jenkins:lts
environment:
- CASC_JENKINS_CONFIG=/var/jenkins_home/casc/jenkins.yaml
- JENKINS_ADMIN_PASSWORD=changeme
volumes:
- jenkins_home:/var/jenkins_home
- ./jenkins.yaml:/var/jenkins_home/casc/jenkins.yaml:ro
volumes:
jenkins_home:
Discussion