YAML templating

YAML Templating allows you to inject Bitbucket repository and workspace variables directly into your bitbucket-pipelines.yml using ${{VARIABLE_NAME}} syntax. This lets you parameterize pipeline configuration — such as Docker image names, cache paths, and step names — without hardcoding values.


Syntax

${{VARIABLE_NAME}}

The double-brace syntax is evaluated at pipeline parse time (before the pipeline runs). It is distinct from runtime environment variable expansion ($VARIABLE_NAME), which occurs during script execution.


Supported Variables

Only the following variable sources are supported for YAML templating:

Source

Available Variables

Workspace variables

All non-secured workspace variables

Repository variables

All non-secured repository variables

Built-in Bitbucket variables

BITBUCKET_WORKSPACE, BITBUCKET_REPO_SLUG, BITBUCKET_BRANCH, BITBUCKET_COMMIT, BITBUCKET_PR_ID

Limitations

  • Secured variables cannot be used in YAML templates (their values are masked)

  • Deployment variables are not available at parse time

  • Runtime-defined variables (set via $BITBUCKET_PIPELINES_VARIABLES_PATH) are not available


Supported Fields

${{...}} substitution works in most string fields of the pipeline YAML:

Field

Example

image

image: ${{IMAGE_NAME}}

name

name: Deploy to ${{ENVIRONMENT}}

deployment

deployment: ${{DEPLOY_ENV}}

Cache paths

path: ${{CACHE_DIR}}

Script values

- echo ${{APP_NAME}}

Import paths

shared: ${{REPO_SLUG}}:main:build.yml

Script lines still also support standard shell variable syntax ($VAR) for runtime values. Use ${{VAR}} for parse-time substitution and $VAR for runtime substitution.


Examples

Parameterize Docker Image

image: ${{NODE_IMAGE}} pipelines: default: - step: name: Build script: - npm install - npm test

With repository variable NODE_IMAGE=node:20, the pipeline runs using node:20.

Parameterize Step Name and Deployment

pipelines: branches: main: - step: name: Deploy to ${{DEPLOY_ENVIRONMENT}} deployment: ${{DEPLOY_ENVIRONMENT}} script: - ./deploy.sh

Parameterize Cache Path

definitions: caches: custom-deps: path: ${{DEPS_CACHE_PATH}} pipelines: default: - step: caches: - custom-deps script: - install-deps

Mix Parse-Time and Runtime Variables

image: ${{BASE_IMAGE}} pipelines: default: - step: name: Build ${{APP_NAME}} script: - echo "Building commit $BITBUCKET_COMMIT" # Runtime variable - echo "App: ${{APP_NAME}}" # Parse-time substitution - npm run build

Evaluation order

  1. Parse time: ${{VARIABLE}} substitutions are resolved from workspace/repository variables

  2. Runtime: $VARIABLE substitutions are resolved from environment variables within the build container

This means ${{VARIABLE}} values are baked into the pipeline structure before any step runs.


Combining with YAML anchors

Templates can be combined with anchors for powerful parameterization:

image: node:${{NODE_VERSION}} definitions: steps: - step: &install name: Install (${{NODE_VERSION}}) caches: - node script: - npm ci - step: &test name: Test script: - npm test pipelines: default: - step: *install - step: *test

Set NODE_VERSION=20 in repository variables and every step using the template picks it up.


Troubleshooting

Variable not substituted (shows literal ${{VARIABLE_NAME}}):

  • Check that the variable is defined as a workspace or repository variable

  • Confirm the variable is not secured

  • Verify spelling matches exactly (case-sensitive)

Pipeline fails to parse:

  • If a ${{VARIABLE}} reference cannot be resolved, the pipeline fails immediately

  • Set a fallback/default value in your variable configuration


Best Practices

  • Use for structural configuration — Image tags, environment names, template URLs; not for secrets

  • Document required variables — Add a comment block at the top of your pipeline listing all required ${{...}} variables

  • Provide defaults — Set sensible default values for variables in the repository settings so pipelines work without manual configuration

  • Never use secured variables — Secured variables are intentionally excluded from template substitution

  • Version template imports — Use ${{TEMPLATE_VERSION}} in import paths to let repos control which template version they use


 

Still need help?

The Atlassian Community is here for you.