Skip to main content

Expressions

Expressions let you inject dynamic values into your pipeline configuration using the ${{ }} syntax. Instead of hardcoding values, you reference stage-specific properties, secrets, step outputs, and variables.

Syntax

Expressions are enclosed in ${{ }} delimiters and can appear anywhere in step or artifact parameter values:

# Simple property access
region: ${{ stage.region }}

# Bracket notation for names with spaces
image: ${{ stage.artifacts["API Image"].image_url }}

# Function call
api_key: ${{ secret("API_KEY") }}

# String interpolation (mix expressions with static text)
role_name: MyRole-${{ stage.name }}
prefix: ${{ organization.slug }}-${{ pipeline.slug }}-${{ stage.name }}

Available Objects

stage -- Current deployment stage

PropertyTypeDescription
stage.namestringStage name (e.g., "staging", "production").
stage.account_idstringAWS account ID for this stage.
stage.regionstringAWS region for this stage.
stage.artifacts["Name"]objectArtifact metadata. Properties: image_url, image_tag, s3_url.
stage.secrets["Name"]stringStage-scoped secret value. Resolved at runtime.

pipeline -- Current pipeline

PropertyTypeDescription
pipeline.namestringDisplay name of the pipeline.
pipeline.slugstringURL-safe pipeline identifier (the folder name under .devramps/).

organization -- Your organization

PropertyTypeDescription
organization.namestringOrganization display name.
organization.slugstringURL-safe organization identifier.
organization.cicd_account_idstringCI/CD AWS account ID.
organization.cicd_account_regionstringCI/CD AWS account region.
organization.secrets["Name"]stringOrganization-level secret value. Resolved at runtime.

trigger -- Git push context

PropertyTypeDescription
trigger.shastringFull git commit SHA.
trigger.branchstringGit branch name.
trigger.tagstringGit tag (empty string if not a tag deploy).
trigger.revisionnumberDevRamps revision number for this deployment.

vars -- Stage variables

Access any variable defined in the stage's vars field. Supports nested access with dot notation:

# Stage config
stages:
- name: staging
vars:
env: staging
azs: ["us-east-1a", "us-east-1b"]
config:
database:
host: db.example.com

# Accessing vars in steps
${{ vars.env }} # "staging"
${{ vars.azs }} # ["us-east-1a", "us-east-1b"]
${{ vars.config.database.host }} # "db.example.com"

steps -- Step outputs

Reference outputs from other steps in the same stage. Access by step name (bracket notation) or step ID (dot notation):

steps:
- name: Synthesize Infrastructure
id: infra
type: DEVRAMPS:TERRAFORM:SYNTHESIZE
params: { ... }

- name: Deploy
type: DEVRAMPS:ECS:DEPLOY
params:
# By ID (dot notation)
cluster_name: ${{ steps.infra.ecs_cluster_name }}
# By name (bracket notation)
service_name: ${{ steps["Synthesize Infrastructure"].ecs_service_name }}

Step outputs are only available to steps that run after the referenced step. DevRamps resolves these at orchestration time, once the referenced step completes.

Functions

secret(name) -- Organization secret

References an organization-level secret. Equivalent to ${{ organization.secrets["name"] }}.

api_key: ${{ secret("STRIPE_API_KEY") }}
db_password: ${{ secret("DATABASE_PASSWORD") }}

stage_secret(name) -- Stage secret

References a stage-scoped secret. Equivalent to ${{ stage.secrets["name"] }}.

db_password: ${{ stage_secret("DB_PASSWORD") }}

Resolution Phases

Expressions are resolved at different points during deployment:

PhaseWhat's ResolvedWhen
API planestage.*, pipeline.*, organization.name/slug, trigger.*, vars.*, artifact metadataWhen the deployment is created. Values are visible in the dashboard.
Orchestratorsteps.* (step outputs)During stage execution, after the referenced step completes.
Build planesecret(), stage_secret(), *.secrets[""]At runtime, just before the step executes. Secrets are never stored in the deployment plan.

This phased resolution means secrets are never visible in the UI or API -- they're only injected at the moment a step needs them.

Common Patterns

Terraform variables from stage context

- name: Synthesize Infrastructure
type: DEVRAMPS:TERRAFORM:SYNTHESIZE
params:
source: /infrastructure
variables:
environment: ${{ vars.env }}
region: ${{ stage.region }}
account_id: ${{ stage.account_id }}
image_url: ${{ stage.artifacts["App Image"].image_url }}
api_key: ${{ secret("API_KEY") }}

Chaining step outputs

- name: Terraform
id: infra
type: DEVRAMPS:TERRAFORM:SYNTHESIZE
params: { ... }

- name: Deploy API
type: DEVRAMPS:ECS:DEPLOY
goes_after: ["Terraform"]
params:
cluster_name: ${{ steps.infra.ecs_cluster_name }}
service_name: ${{ steps.infra.ecs_service_name }}
reference_task_definition: ${{ steps.infra.task_definition }}
image_url: ${{ stage.artifacts["API Image"].image_url }}

Import artifact with git context

artifacts:
External Image:
type: DEVRAMPS:DOCKER:IMPORT
params:
source_image_url: 123456789.dkr.ecr.us-west-2.amazonaws.com/my-app:${{ trigger.sha }}

Limitations

Undefined references

If an expression references a variable or property that doesn't exist (e.g., ${{ vars.nonexistent }}), the deployment will fail during synthesis with a validation error. Step output references (${{ steps.id.field }}) that point to a non-existent output will fail when the orchestrator attempts to resolve them.

No conditional expressions

The expression language does not support conditional logic (e.g., ternary operators like ${{ vars.env == "prod" ? "3" : "1" }}). To handle per-stage differences, use stage variables with different values per stage.

No string manipulation

There are no built-in string functions (uppercase, lowercase, concat, trim, etc.). Expressions perform simple property access and function calls only.

For the complete auto-generated reference, see: