Job DSL, Seed Jobs, Folder Hierarchies, Programmatic Job Creation, and Jenkins API Automation: Configuration, Design Choices, and Tradeoffs
Choose deliberately between Job DSL, JCasC and direct REST/XML; between platform-wide and team seed jobs; between sandboxed and administrator-approved Groovy; and between IGNORE, DISABLE and DELETE lifecycle actions. The right design makes generator ownership, permissions, rollback and evidence obvious.
Learning objectives
- Select Job DSL, JCasC or direct API/XML according to the state being managed.
- Choose platform versus team seed topology and folder boundaries.
- Balance sandboxed DSL with approved unsandboxed code.
- Choose IGNORE, DISABLE or DELETE using ownership and recovery evidence.
- Design a migration/version contract for generated jobs.
1. Job DSL versus JCasC versus REST/XML
| Mechanism | Best owner | Main risk | Evidence |
|---|---|---|---|
| JCasC | controller/global/plugin configuration | schema/plugin drift; global blast radius | YAML commit + plugin baseline + live validation |
| Job DSL | folders/jobs/views and repeatable item templates | seed privilege and destructive lifecycle actions | DSL commit + seed build + generated item list |
| REST/XML | specific automation/integration gaps | brittle imperative drift; ACL/CSRF mistakes | actor + exact path + request/response + config digest |
| Pipeline DSL | one build’s stages/steps/dataflow | runtime side effects and CPS semantics | Jenkinsfile SHA + build record |
Use each mechanism for the state it models naturally. “Everything as Groovy” is not a governance strategy.
2. Platform seed versus team/folder seeds
A central platform seed gives one governance point and consistent defaults. It also concentrates permissions and blast radius. Team seeds reduce scope and ownership ambiguity, but require versioned conventions so every team does not invent incompatible DSL patterns.
| Model | Advantages | Costs | Good fit |
|---|---|---|---|
| One platform seed | consistent policy, simple rollout | large privilege/blast radius | small centrally operated Jenkins |
| Seed per team folder | least privilege, local ownership | more repos/jobs to govern | multi-team controller |
| Hybrid | platform creates folders/policy, teams create jobs inside | clear contracts required | larger shared platform |
3. Sandboxed versus approved DSL
Sandboxing is the default design target for team-authored DSL. Job DSL integrates with Script Security: safe DSL methods are available while unsafe Groovy operations are rejected or require signature approval. Jenkins access-control checks then matter, so the seed should run as a real constrained identity.
Administrator-approved unsandboxed DSL can be justified for tightly controlled platform code that truly needs unsupported operations, but approval grants in-process Groovy power. Treat that repository like a controller plugin: protected reviewers, versioned releases, tests and rollback.
4. IGNORE, DISABLE and DELETE are governance states
The Job DSL removedJobAction setting turns a missing
previously-generated job into an explicit lifecycle decision.
Generated-item lifecycle should mirror confidence:
- IGNORE while adopting Job DSL or when ownership cannot be proven.
- DISABLE when a generated job is intentionally retired but history/evidence should remain.
- DELETE only after retention, export/backup and ownership checks confirm removal is intended and recoverable.
The safest production pattern often separates “remove from active service” and “purge after retention” into different changes.
5. Folder-scoped generation
Use a predictable folder hierarchy such as
teams/payments/**. Place the team seed inside its
folder, use lookupStrategy: 'SEED_JOB' and authorize
that identity only for the folder subtree. Test the boundary by
attempting an out-of-scope generation in a disposable clone and
recording the denial.
Names are not ACLs. A script that says team-a/foo is
not secure if the seed identity can also create
../admin-equivalent root items through other APIs.
6. Remote API design choices
Use API tokens for scripted clients and guard exact item paths. For POSTs authenticated with username/password, Jenkins CSRF protection generally requires a crumb/session; API-token requests are exempt. Avoid brittle “latest job” or ambiguous delete operations. Read the job full name and build number you intend to act on.
Direct config.xml mutation should be exceptional
because it bypasses the higher-level desired-state contract. If
used, capture the previous XML/config digest and reconcile the
change back into Job DSL or documented UI ownership.
7. Generated-item ownership contract
A robust generated item carries multiple independent clues:
- Job DSL plugin tracking that links it to the seed.
-
Human-readable description such as
[managed-by=job-dsl][seed=teams/payments/seed]. - SCM commit stored as seed artifact/build metadata.
- Folder placement and ACL inheritance.
- Retention/lifecycle policy and recovery owner.
No single clue is sufficient for destructive deletion; together they make ownership auditable.
8. Worked scenario: three teams on one controller
Platform owns global security/JCasC and creates
teams/a, teams/b and teams/c.
Each team owns a Job DSL repository and seed inside its folder.
Shared job templates live in a versioned library/module, not a
mutable controller script.
| Decision | Choice | Prerequisite | Verification |
|---|---|---|---|
| Global controller config | JCasC | platform review | JCasC commit/live state |
| Team jobs | folder seed + Job DSL | scoped build identity | out-of-scope denial |
| Trust | sandbox by default | Script Security | no broad pending approvals |
| Removal | DISABLE then later purge | ownership + retention | disabled state/history then approved delete |
| Triggering | SCM or exact API POST | API token/webhook policy | cause + queue/build correlation |
9. Version and migration policy
Version the DSL schema just like a Shared Library API. When changing job names, parameters, branch sources or credentials IDs, describe the migration and compatibility impact. Avoid silently replacing a job under a new name because that fragments history and downstream references.
Before a wide generator rollout: run in a clone, compare generated XML/config, run representative jobs, inspect removed-item candidates, then promote the same reviewed DSL commit.
10. Decision checklist
- Which state layer am I managing: controller, item, build runtime or external system?
- Which identity executes the generator, and what can it mutate?
- Can the same outcome be expressed inside the supported DSL/API Viewer?
- How is generated-item ownership proven?
- What happens to removed jobs, views and history?
- How do I roll back both DSL source and persisted controller state?
Knowledge check
Answer before revealing the explanation.
1. When should JCasC be used instead of Job DSL?
Use JCasC for supported controller/global/plugin configuration. Use Job DSL for generated Jenkins items/jobs. They can work together, but they own different state and should not silently compete.
2. What is the strongest reason to prefer a sandboxed DSL?
It limits Groovy operations to an approved safe surface and allows Jenkins access-control checks to remain relevant. It reduces the need for blanket administrator approval of arbitrary in-process Groovy.
3. Why can a single platform seed become a scaling risk?
Its permission scope and blast radius grow with every team. A bug or compromised source can affect many folders. Team/folder seeds reduce scope but add governance and version-management overhead.
4. Why is DELETE a policy decision rather than a default?
Deletion is destructive and may erase job history. It requires strong generated-item ownership, retention evidence, review and recovery. IGNORE or DISABLE is safer when ownership is uncertain.
5. What evidence should accompany a direct REST/XML mutation if one is unavoidable?
Record the authenticated actor, exact item path, request/response, before/after config digest, change ticket/source revision and rollback artifact. Otherwise the mutation is harder to reconcile with the generator source of truth.
Official references and version notes
- Job DSL plugin — current release, minimum core requirement, maintenance/security status and links to the API Viewer.
-
Jenkins Pipeline Steps — Job DSL
— current
jobDslparameters including sandbox, lookup strategy and removed-item actions. - Job DSL upstream repository — getting started, Job DSL versus Pipeline DSL, and API Viewer guidance.
- Job DSL — Script Security — sandbox/approval behavior and build-identity implications.
- Script Security plugin — Groovy sandbox and signature-approval boundary.
- Folders plugin — folder hierarchy baseline used by the examples.
- Matrix Authorization Strategy — optional fine-grained folder/item permission model for the lab.
- Authorize Project plugin — optional explicit build identity used when exercising sandboxed Job DSL with access-control checks.
- Jenkins Remote Access API and CSRF protection — current API authentication/POST semantics.
- Jenkins LTS changelog and Java support policy.
2.568.3 LTS with Java 21 (Jenkins
2.568.3 is tested with Java 21 and 25). Job DSL is
3732.v9a_c49a_61a_313, requires Jenkins 2.479.3 and is
currently marked “up for adoption” on the plugin site. Script
Security is 1422.v06869826dd9b_; Folders is
6.1106.v3a_d9a_6d2465e; Matrix Authorization Strategy
is 3.3; Authorize Project is
534.v2f208c45e11c. Re-check current plugin/API
documentation and security advisories before reusing the lab. The
mandatory path uses only a disposable local controller, synthetic
Git repository and fake identities.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.