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
| Property | Type | Description |
|---|---|---|
stage.name | string | Stage name (e.g., "staging", "production"). |
stage.account_id | string | AWS account ID for this stage. |
stage.region | string | AWS region for this stage. |
stage.artifacts["Name"] | object | Artifact metadata. Properties: image_url, image_tag, s3_url. |
stage.secrets["Name"] | string | Stage-scoped secret value. Resolved at runtime. |
pipeline -- Current pipeline
| Property | Type | Description |
|---|---|---|
pipeline.name | string | Display name of the pipeline. |
pipeline.slug | string | URL-safe pipeline identifier (the folder name under .devramps/). |
organization -- Your organization
| Property | Type | Description |
|---|---|---|
organization.name | string | Organization display name. |
organization.slug | string | URL-safe organization identifier. |
organization.cicd_account_id | string | CI/CD AWS account ID. |
organization.cicd_account_region | string | CI/CD AWS account region. |
organization.secrets["Name"] | string | Organization-level secret value. Resolved at runtime. |
trigger -- Git push context
| Property | Type | Description |
|---|---|---|
trigger.sha | string | Full git commit SHA. |
trigger.branch | string | Git branch name. |
trigger.tag | string | Git tag (empty string if not a tag deploy). |
trigger.revision | number | DevRamps 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:
| Phase | What's Resolved | When |
|---|---|---|
| API plane | stage.*, pipeline.*, organization.name/slug, trigger.*, vars.*, artifact metadata | When the deployment is created. Values are visible in the dashboard. |
| Orchestrator | steps.* (step outputs) | During stage execution, after the referenced step completes. |
| Build plane | secret(), 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: