Build a real S3 CLI tool with Go from scratch. Start with a one-liner that lists buckets, then …
Jenkins Configuration as Code: The Definitive JCasC Guide Jenkins Configuration as Code: The Definitive JCasC Guide

Summary
Why Jenkins Configuration as Code Matters
If you have ever spent hours clicking through the Jenkins UI to configure a new controller, only to realize you cannot reproduce that setup reliably, Jenkins Configuration as Code (JCasC) is the answer. JCasC lets you define your entire Jenkins configuration in human-readable YAML files that live in version control alongside your application code.
The Jenkins Configuration as Code plugin transforms how teams manage their CI/CD infrastructure. Instead of brittle Groovy init scripts or manual UI clicks, you declare your desired state in YAML and JCasC applies it automatically. Every security setting, cloud configuration, credential, and plugin setting becomes auditable, reproducible, and reviewable through pull requests.
Expand your knowledge with Jenkins UserRemoteConfig: The Ultimate Guide for Dynamic Git Integration
Getting Started with JCasC
Installing the Plugin
The Configuration as Code plugin is available from the Jenkins Update Center. Install it like any other plugin:
- Navigate to Manage Jenkins > Manage Plugins > Available
- Search for “Configuration as Code”
- Install and restart Jenkins
Alternatively, if you are deploying Jenkins via Docker or Helm, include configuration-as-code in your plugin list from the start.
Your First JCasC File
Create a file called jenkins.yaml and place it where Jenkins can find it. By default, JCasC looks at the path defined by the CASC_JENKINS_CONFIG environment variable.
jenkins:
systemMessage: "This Jenkins is fully configured via JCasC"
numExecutors: 0
mode: EXCLUSIVE
securityRealm:
local:
allowsSignup: false
users:
- id: "admin"
password: "${JENKINS_ADMIN_PASSWORD}"
authorizationStrategy:
globalMatrix:
permissions:
- "Overall/Administer:admin"
- "Overall/Read:authenticated"
This simple configuration sets a system message, disables builds on the controller node (a security best practice), creates a local admin user with an environment variable for the password, and applies a basic authorization matrix.
Applying the Configuration
Set the environment variable and start Jenkins:
export CASC_JENKINS_CONFIG=/var/jenkins_home/casc_configs/jenkins.yaml
export JENKINS_ADMIN_PASSWORD=your-secure-password
JCasC applies the configuration on startup. You can also reload it without restarting by navigating to Manage Jenkins > Configuration as Code > Reload existing configuration.
Deepen your understanding in How to Use Amazon Cognito and Google Firebase Auth Without Getting Vendor-Locked
Structuring JCasC for Production
Splitting Configuration into Multiple Files
For production environments, a single monolithic YAML file becomes unwieldy fast. JCasC supports pointing CASC_JENKINS_CONFIG to a directory, and it merges all YAML files it finds.
A recommended structure:
casc_configs/
├── jenkins.yaml # Core settings, executors, mode
├── security.yaml # Auth, RBAC, CSRF, agent protocols
├── credentials.yaml # Credentials and secrets
├── clouds.yaml # Kubernetes/Docker cloud agents
├── shared-libraries.yaml # Global pipeline libraries
└── tool-installations.yaml # JDK, Maven, Node, Git
This separation makes changes reviewable. A security change only touches security.yaml. Adding a new cloud agent only touches clouds.yaml. Your pull request diffs stay clean and focused.
graph TD
A[casc_configs/] --> B[jenkins.yaml]
A --> C[security.yaml]
A --> D[credentials.yaml]
A --> E[clouds.yaml]
A --> F[shared-libraries.yaml]
A --> G[tool-installations.yaml]
B --> H[JCasC Plugin]
C --> H
D --> H
E --> H
F --> H
G --> H
H --> I[Jenkins Controller]
Managing Secrets Securely
Never put plain-text secrets in your JCasC files. The plugin supports variable substitution from multiple sources:
Environment Variables (most common):
credentials:
system:
domainCredentials:
- credentials:
- usernamePassword:
id: "github-creds"
username: "${GITHUB_USERNAME}"
password: "${GITHUB_TOKEN}"
AWS Secrets Manager (for cloud deployments):
credentials:
system:
domainCredentials:
- credentials:
- string:
id: "sonar-token"
secret: "${AWS_SECRET:/jenkins/sonar-token}"
Kubernetes Secrets (when deployed on K8s): Mount secrets as environment variables in your Jenkins pod spec, and JCasC resolves them automatically.
Explore this further in OpenAI Node.js Integration: Complete Developer's Guide [2024]
jenkins.yaml is not accidentally committed with plain-text secrets. Add **/casc_configs/credentials.yaml to .gitignore if you populate secrets locally, or use a secrets manager exclusively.JCasC with Kubernetes
Configuring the Kubernetes Cloud Plugin
One of the most powerful JCasC use cases is configuring Jenkins to dynamically provision build agents as Kubernetes pods. This eliminates permanently running agent VMs and lets your CI/CD scale to zero when idle.
jenkins:
clouds:
- kubernetes:
name: "kubernetes"
serverUrl: "https://kubernetes.default.svc.cluster.local"
namespace: "jenkins-agents"
jenkinsUrl: "http://jenkins.jenkins.svc.cluster.local:8080"
jenkinsTunnel: "jenkins-agent.jenkins.svc.cluster.local:50000"
containerCapStr: "50"
maxRequestsPerHostStr: "32"
retentionTimeout: 5
templates:
- name: "default-agent"
label: "jenkins-agent"
nodeUsageMode: NORMAL
containers:
- name: "jnlp"
image: "jenkins/inbound-agent:latest-jdk21"
resourceRequestCpu: "500m"
resourceRequestMemory: "512Mi"
resourceLimitCpu: "1000m"
resourceLimitMemory: "1Gi"
volumes:
- hostPathVolume:
mountPath: "/var/run/docker.sock"
hostPath: "/var/run/docker.sock"
idleMinutes: 10
activeDeadlineSeconds: 3600
This configuration tells Jenkins to spin up agent pods in the jenkins-agents namespace, use the official inbound-agent image with JDK 21, and shut them down after 10 minutes of inactivity.
Deploying with Helm
The official Jenkins Helm chart has first-class JCasC support. Your values.yaml can embed JCasC configuration directly:
controller:
JCasC:
configScripts:
welcome-message: |
jenkins:
systemMessage: "Production Jenkins — managed by Helm + JCasC"
security: |
jenkins:
securityRealm:
ldap:
configurations:
- server: "ldap.example.com"
rootDN: "dc=example,dc=com"
sidecars:
configAutoReload:
enabled: true
When configAutoReload is enabled, the Helm sidecar watches for ConfigMap changes and triggers JCasC reload automatically — no Jenkins restart needed. This is powerful for GitOps workflows where a merge to main triggers a Helm upgrade.
Discover related concepts in Automating Stock Data Deployment with CI/CD: A Beginner's Guide Using Dow Jones Trends
graph LR
A[Git Push] --> B[Helm Upgrade]
B --> C[ConfigMap Updated]
C --> D[Sidecar Detects Change]
D --> E[JCasC Reload]
E --> F[Jenkins Reconfigured]
Configuring Shared Libraries with JCasC
Shared Pipeline Libraries let you centralize common pipeline logic. JCasC makes configuring them reproducible:
unclassified:
globalLibraries:
libraries:
- name: "pipeline-library"
defaultVersion: "main"
implicit: true
retriever:
modernSCM:
scm:
git:
remote: "https://github.com/your-org/pipeline-library.git"
credentialsId: "github-creds"
- name: "devops-utils"
defaultVersion: "v2.0"
implicit: false
retriever:
modernSCM:
scm:
git:
remote: "https://github.com/your-org/devops-utils.git"
credentialsId: "github-creds"
Setting implicit: true makes the library available to all pipelines without an explicit @Library annotation in the Jenkinsfile.
Uncover more details in Harnessing Chaos: An Overview of Tools and Libraries for Chaos Engineering
Security Hardening with JCasC
RBAC with the Role Strategy Plugin
For production Jenkins instances, the matrix-based security or folder-level permissions are common patterns:
jenkins:
authorizationStrategy:
roleBased:
roles:
global:
- name: "admin"
permissions:
- "Overall/Administer"
entries:
- user: "admin"
- name: "developer"
permissions:
- "Overall/Read"
- "Job/Build"
- "Job/Read"
- "Job/Workspace"
entries:
- group: "developers"
- name: "viewer"
permissions:
- "Overall/Read"
- "Job/Read"
entries:
- group: "stakeholders"
Disabling Unsafe Features
Lock down your Jenkins controller with these JCasC security settings:
Journey deeper into this topic with Security Considerations When Using envsubst: Protecting Your CI/CD Pipeline
jenkins:
remotingSecurity:
enabled: true
crumbIssuer:
standard:
excludeClientIPFromCrumb: false
security:
scriptApproval:
approvedSignatures: []
globalJobDslSecurityConfiguration:
useScriptSecurity: true
unclassified:
buildDiscarders:
configuredBuildDiscarders:
- "jobBuildDiscarder"
numExecutors: 0 on the controller node. All builds should run on agents. This prevents malicious or misconfigured pipelines from accessing the controller’s file system directly.Validating and Testing JCasC
Schema Validation
The JCasC plugin generates a JSON schema for your installed plugins. Export it from Manage Jenkins > Configuration as Code > Download Configuration and use it in your IDE for autocompletion and validation.
In VS Code, add this to your workspace settings:
{
"yaml.schemas": {
"./jenkins-casc-schema.json": "casc_configs/*.yaml"
}
}
Dry-Run with the REST API
Before applying configuration to production, validate it:
curl -X POST \
-u admin:$API_TOKEN \
-F "casc=@jenkins.yaml" \
"https://jenkins.example.com/configuration-as-code/check"
A 200 response with no errors means the configuration is valid. Integrate this into your CI pipeline to catch misconfigurations before they reach production.
Testing with Docker
Spin up a temporary Jenkins instance to test your JCasC configuration:
docker run -d \
--name jenkins-test \
-e CASC_JENKINS_CONFIG=/var/jenkins_home/casc_configs \
-v $(pwd)/casc_configs:/var/jenkins_home/casc_configs \
-p 8080:8080 \
jenkins/jenkins:lts-jdk21
Verify the configuration applied correctly, then tear it down. This pattern works well in a CI pipeline that validates JCasC changes before merging.
Enrich your learning with Boto3 and AWS Lambda: A match made in serverless heaven
Common Pitfalls and How to Avoid Them
Plugin Version Mismatches
JCasC configuration is tightly coupled to the plugins installed. A YAML key that works with Pipeline plugin 2.7 might not exist in 2.6. Always pin your plugin versions and test configuration changes against the same plugin set.
Configuration Drift
JCasC applies configuration on startup or reload, but manual changes through the UI still work. If someone changes a setting through the UI, the next JCasC reload overwrites it. To prevent confusion:
- Disable the “Configure” link for non-admins
- Add a system message reminding users that configuration is managed by JCasC
- Run scheduled JCasC reloads to enforce the declared state
Credential ID Conflicts
If a credential ID in your YAML already exists with a different type, JCasC fails silently or throws a cryptic error. Always use unique, descriptive credential IDs like github-org-token instead of generic names like token.
Gain comprehensive insights from Troubleshooting common EC2 issues
JCasC vs. Groovy Init Scripts
Before JCasC, teams used Groovy init scripts in /usr/share/jenkins/ref/init.groovy.d/ to configure Jenkins programmatically. Here is how the two approaches compare:
| Aspect | JCasC (YAML) | Groovy Init Scripts |
|---|---|---|
| Readability | Human-friendly YAML | Requires Groovy knowledge |
| Validation | JSON schema + dry-run API | No built-in validation |
| Idempotency | Declarative, always converges | Imperative, may cause side effects |
| Security | No code execution | Full Jenkins API access (risky) |
| Plugin support | Automatic for compatible plugins | Manual API calls per plugin |
| Reload | Hot reload without restart | Requires restart |
For new deployments, JCasC is the clear choice. For legacy setups with complex Groovy scripts, migrate incrementally — start with security and credentials in JCasC while keeping advanced customizations in Groovy until plugin support catches up.
Master this concept through Jenkins UserRemoteConfig: The Ultimate Guide for Dynamic Git Integration
Putting It All Together
A production-ready Jenkins Configuration as Code setup combines everything covered in this guide. Here is what a complete workflow looks like:
graph TD
A[Developer edits casc_configs/] --> B[Pull Request]
B --> C[CI validates YAML schema]
C --> D[CI dry-runs against test Jenkins]
D --> E{Tests pass?}
E -->|Yes| F[Merge to main]
E -->|No| G[Fix and re-submit]
F --> H[Helm upgrade triggers]
H --> I[ConfigMap updated in K8s]
I --> J[Sidecar detects change]
J --> K[JCasC reload applied]
K --> L[Jenkins reconfigured — zero downtime]
Jenkins Configuration as Code is not just a convenience — it is a fundamental shift toward treating your CI/CD platform with the same rigor you apply to application code. Version control, code review, automated testing, and declarative configuration eliminate an entire class of “it worked on the old server” problems.
Start small. Convert your security and credential configuration to JCasC first. Then expand to cloud agents, shared libraries, and tool installations. Within a few iterations, your entire Jenkins setup becomes a reviewable, reproducible artifact that any team member can understand and contribute to.
How do you currently manage your Jenkins configuration — UI clicks, Groovy scripts, or JCasC?
Delve into specifics at Building a Facebook-like Platform with Simple AWS Architecture
References and Further Reading
- Jenkins Project. (2026). Configuration as Code Plugin Documentation. Jenkins Documentation.
- Jenkins Project. (2026). JCasC Plugin Page. Jenkins Plugin Index.
- Jenkins CI. (2026). Configuration as Code Demos and Examples. GitHub Repository.
- Eficode. (2025). Getting Started with Jenkins Configuration as Code. Eficode Blog.
- CloudBees. (2025). Jenkins Configuration as Code Documentation. CloudBees Blog.
- Kim, G. et al. (2021). The DevOps Handbook. IT Revolution Press.
Similar Articles
Related Content
More from jenkins
A hands-on, step-by-step guide to building your first AWS Lambda function with Go. Start with a …
Get ahead of the curve with our comprehensive guide on the DevOps trends shaping 2026. From Platform …
You Might Also Like
Complete tutorial on deploying Jenkins to Amazon EKS. Learn what pods are, why deployments matter, …
Explore how Jenkins versions have shaped modern CI/CD practices. This comprehensive guide traces the …
Learn essential Jenkins Versions strategies to optimize your CI/CD pipelines. This guide covers …
Knowledge Quiz
Test your general knowledge with this quick quiz!
The quiz consists of 5 multiple-choice questions.
Take as much time as you need.
Your score will be shown at the end.
Question 1 of 5
Quiz Complete!
Your score: 0 out of 5
Loading next question...
Contents
- Why Jenkins Configuration as Code Matters
- Getting Started with JCasC
- Structuring JCasC for Production
- JCasC with Kubernetes
- Configuring Shared Libraries with JCasC
- Security Hardening with JCasC
- Validating and Testing JCasC
- Common Pitfalls and How to Avoid Them
- JCasC vs. Groovy Init Scripts
- Putting It All Together
- References and Further Reading

