Chapter 10Lesson 03~115 minutes

Declarative Pipeline Syntax, agent, stages, steps, options, parameters, environment, tools, and post: Configuration, Design Choices, and Tradeoffs

Make deliberate Declarative design choices about agent scope, environment scope, timeouts/retries, script escape hatches, tool placement, evidence, and rollback.

DesignTradeoffsAgent scopeOptionsEnvironment scopeScript

Learning objectives

  • Compare top-level and stage-level agents using queue time, isolation, workspace continuity, and cost.
  • Choose pipeline- versus stage-scoped environment values based on ownership and least exposure.
  • Distinguish Declarative options from step wrappers such as timeout/retry.
  • Use script only when Declarative/steps cannot express the required bounded logic clearly.
  • Document prerequisites, affected state, rollback, and evidence for each Pipeline design choice.

1. Declarative design is resource and state design

Two Jenkinsfiles can perform the same commands and still have very different operational properties. Where you place agent changes executor occupancy and workspace continuity. Where you place environment changes value exposure. Whether you use a stage option or a step wrapper changes what lifecycle interval is bounded. Whether you use script changes how much logic escapes Declarative's structured model.

Choose syntax by the state and failure boundary you need—not by which form is shortest.

2. Top-level agent versus stage-level agents

Question Top-level agent agent none + stage agents
Executor occupancy Potentially held across all stages and waits inside steps. Allocated only for stages that request one.
Workspace continuity Simple; stages normally see one workspace context. Do not assume files transfer between stages/nodes.
Toolchain variation Best when stages share one compatible agent. Strong when build/test stages need different labels/toolchains.
Failure isolation Agent loss can affect more of the run. Each stage can reacquire an appropriate agent.
Human waits Easy to accidentally hold capacity with an input step. Stage-level input can wait before allocation.

If stage agents differ, treat data movement explicitly with SCM checkout, deterministic recreation, stash/unstash, or archived/external artifacts. Workspace coincidence is not a dataflow contract.

3. Pipeline versus stage environment

Pipeline-level environment is appropriate for non-secret values truly shared by every stage, such as a synthetic application identifier. Stage-level environment narrows exposure and makes ownership clearer for values used only in one stage.

environment {
  APP_NAME = 'catalog-lab'
}
stages {
  stage('Package') {
    environment {
      FORMAT = 'tar'
    }
    steps {
      sh 'printf "%s %s\\n" "$APP_NAME" "$FORMAT"'
    }
  }
}

For credentials, prefer the smallest practical scope. Secret masking is a defense-in-depth feature, not permission isolation. A process running under the same agent/user context may be able to inspect environment/process data depending on the platform and design.

4. options versus step wrappers

A top-level or stage options block expresses policy around the Pipeline/stage. A timeout or retry step inside steps wraps a specific body of execution. These are not always equivalent.

Need Prefer Reason
Bound an entire stage including stage lifecycle Stage options { timeout(...) } Policy is visible at stage boundary; allocation timing follows documented stage-option semantics.
Retry one flaky read-only network operation retry(n) { ... } around that step/body Avoids repeating unrelated work or side effects.
Global maximum run duration Top-level timeout option One clear run-level guardrail.
Time-limit one external command timeout { sh ... } Narrowest affected scope.

Never wrap non-idempotent deployment/publication side effects in blind retries. Verify external state before retrying.

5. Declarative structure versus script escape hatch

The script step allows Scripted Pipeline/Groovy inside Declarative steps. It is useful for bounded logic that cannot be expressed cleanly with ordinary steps/directives. It should not become a hiding place for an entire second Pipeline language.

steps {
  script {
    def allowed = ['sandbox', 'qa']
    if (!allowed.contains(params.TARGET)) {
      error "Unsupported TARGET"
    }
  }
  sh 'printf "validated target=%s\\n" "$TARGET"'
}

Here the script block performs a small controller-side validation. Heavy computation, network loops, file processing, and long-running work belong in agent-side tools/steps rather than Groovy executed by the Pipeline engine.

6. Tool placement follows agent placement

If one top-level agent serves the whole Pipeline, top-level tools can be simple. With agent none, define tools in the stage that acquires an agent. Remember that Declarative's built-in tool directive currently covers configured Maven, JDK, and Gradle tools; other ecosystems may rely on dedicated plugins, wrappers, or pre-baked agent/container images.

7. when is routing policy, not authorization

when decides whether a stage should execute based on branch, expression, environment, changeset, and other supported conditions. It does not authorize a human or service identity. A deployment stage skipped because TARGET != 'qa' is a control-flow decision, not proof that unauthorized users cannot alter or trigger the job.

8. Design post around evidence ownership

Stage-level post is useful when evidence belongs to that stage's execution context. Pipeline-level post is useful for final run-level status. If cleanup requires an external resource identifier, save that identifier before the risky action and make cleanup bounded/idempotent.

Do not make the only copy of failure evidence something your cleanup step deletes.

9. Worked scenario: three-stage synthetic delivery

Requirements: compile with JDK/Maven, run tests on a generic Linux agent, then pause for approval before writing a synthetic “promotion” record. No production system exists.

Choice Decision Prerequisite Observable evidence Rollback
Agent strategy agent none; stage-specific lab-linux Agent label online Queue/node/workspace per stage Revert Jenkinsfile commit
Tools Stage-local jdk21-build, maven-3.9 Configured/verified tool definitions Version output in artifact Restore previous tool name/revision
Approval Stage input before agent Authorized approver in lab Input action + later node allocation Abort without side effect
Target Choice parameter sandbox|qa No free-form production values Recorded non-secret parameter Trigger a new run with corrected immutable input
Evidence Archive per-stage text/checksum Workspace only during stage Archived artifacts/fingerprints Artifacts stay with original run

10. Decision checklist

  • Which executor must be held, and for how long?
  • Which values must be visible to every stage versus one stage only?
  • Does a retry repeat an external side effect?
  • Is a script block doing orchestration or accidentally doing heavy work on the controller?
  • What source SHA and plugin/tool versions make the run reproducible?
  • What evidence survives workspace deletion?
  • What exact Jenkinsfile commit reverses the configuration change?
Next lesson

Diagnostics, Failure Modes, Security, and Performance

Diagnose wrong-scope directives, capacity waste during waits, secret exposure, and workspace assumptions by preserving the first failure and tracing the correct layer.

Knowledge check

When is a top-level agent attractive?

Why prefer stage-scoped environment for a value used by only one stage?

Why can blindly retrying a deploy step be unsafe?

What is a good use of script?

Does when replace authorization?

Official references and version notes

Version and compatibility note

Rechecked on 2026-09-16. Examples assume Jenkins 2.568.3 LTS, tested with Java 21 and 25, Pipeline aggregator 608.v67378e9d3db_1, Pipeline: Declarative 2.2293.v6e7193cec599, Credentials Binding 728.v902a_273b_8947, and optional Stage View 2.41. Declarative 2.2293 requires Jenkins 2.504.3 or newer. Labs reuse the Chapter 08 tool names jdk21-build and maven-3.9; verify what exact binaries those names resolve to on your disposable agent before running. Plugin versions and supported directives change independently, so capture the installed baseline rather than assuming these versions forever.

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.