Decoupling Artifacts from Environments: Structuring Bamboo Build Plans and Deployment Projects
Learn how to separate artifact creation from environment promotion in Atlassian Bamboo using Build Plans and Deployment Projects to achieve a true 'build once, deploy many' workflow.
05 Jul 2026, 18:23 UTC

The "Build-to-Deploy" Gap
A common friction point in CI/CD is the tendency to treat a build and a deployment as a single linear sequence. When one pipeline handles everything from compilation to production deployment, changing a production environment variable often forces a full rebuild. That breaks the build once, deploy many principle: the binary you tested is no longer the binary you shipped.
Atlassian Bamboo addresses this by enforcing an architectural boundary between Build Plans (where source code becomes a versioned artifact) and Deployment Projects (where that artifact is promoted through environments). The practical takeaway: the Build Plan should care about validity and packaging; the Deployment Project should care about destination and configuration.
Structuring the Build Plan Around Dependencies
Build Plans are organized into Stages — logical groups of tasks. Stages run sequentially by default, and independent stages can run in parallel when enough Bamboo agents are available. Split stages by dependency rather than by chronology:
- Validation. Unit tests and linting. If these fail, there is no reason to spend agent time on packaging.
- Packaging. Compile and produce the artifact — the versioned bundle (JAR, WAR, ZIP, container image reference) that will move forward.
- Integration tests. Run against the artifact produced in the previous stage, not against a fresh build.
Separating these guarantees that the binary exercised by integration tests is the same one that eventually reaches an environment.
Promotion via Deployment Projects
Once a Build Plan produces a successful artifact, a Deployment Project consumes it. Deployment Projects are structured by Environments (for example Development, QA, Staging, Production) that form a linear promotion path.
Instead of triggering a new build per environment, you select a specific successful build result and promote it forward. Only environment-specific configuration changes between environments — the artifact itself does not.
Worked Example: Environment-Specific Values with Plan Variables
To avoid hardcoding hostnames or endpoints in scripts, use Plan Variables: key-value pairs that can be overridden at the deployment-environment level.
Scenario: a deployment script needs to call a health-check endpoint on a per-environment host.
- In the Deployment Project settings, define a variable, for example
target.server.url. - Override it per environment:
qa-app.internal.examplefor QA,prod-app.internal.examplefor Production. - Reference it from a script task using Bamboo's variable syntax.
# Run on a Bamboo remote agent as the deployment user.
# Required permissions: the agent's OS user must be able to reach the target host.
# Risk: if the variable is undefined, the shell expands it to an empty string
# and curl may still exit 0 against a malformed URL. Validate before use.
: "${bamboo_target_server_url:?variable not set}"
curl --fail --silent --show-error \
-X POST -H "Content-Type: application/json" \
-d '{"status":"deploying"}' \
"https://${bamboo_target_server_url}/api/health-check"
The : "${VAR:?message}" guard is the important part. Without it, a missing variable silently produces a request to https:///api/health-check, which may fail in a confusing way or, worse, succeed against an unintended host.
How to check the result: open the deployment task log and confirm the expanded URL matches the environment you targeted. Bamboo prints the resolved command line for script tasks, so the variable substitution is visible before the request runs.
Trade-offs and Limitations
Parallel stages reduce wall-clock time but increase agent pressure. Ten parallel stages with five available agents means five queue, and the apparent speedup can disappear behind queue latency. Parallelism is a capacity decision, not a free optimization.
The build/deployment split also means a green build does not automatically reach production. That is a safety property, but it requires an explicit promotion process — manual approval, a scheduled trigger, or a scripted call to the Bamboo REST API. Teams that expect automatic promotion are often surprised by this, so document the intended path.
Finally, plan hierarchy matters: circular dependencies between plans are not a supported configuration and can produce confusing or repeated triggering. Keep the dependency graph acyclic and shallow.
Practical Verification Checklist
- Artifact hand-off: create a Build Plan with two stages and confirm the artifact produced in the first is available to the second.
- Promotion path: link a Deployment Project to the Build Plan and confirm you can pick a specific build result for the first environment.
- Variable injection: define a Plan Variable, echo it in a script task, and confirm the value differs between environments.
- Failure behavior: temporarily unset the variable and confirm your guard stops the task rather than sending a malformed request.
Version note: plan variable naming, the deployment-project UI, and permission models have changed across Bamboo releases (the 6.x through 9.x line in particular). Confirm the exact variable syntax and UI wording in the version you run before treating the example above as a working configuration — it is a starting point for review, not a verified setup.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.