Interpolations and References
Interpolations and references are additional syntactical constructs that ESC layers on top of YAML to allow users to reuse properties to construct new values.
References take the form ${property-path}. References may appear alone or embedded within strings. The former case is referred to as a bare reference; the latter is an interpolation.
Property paths
Property paths–used throughout the Pulumi ecosystem–are JavaScript-inspired expressions that refer to properties within JSON-like values.
The syntax supports both dot notation and bracket notation.
For keys that contain special characters (i.e. [, ], ", or .) or begin with a digit,
bracket notation is required.
Binding references
In the context of ESC, references either refer to properties in the evaluated environment in which they are contained or to built-in properties.
Interpolations and references are early-bound: each reference is evaluated within the context of the environment in which it is contained. This allows the author of an environment definition to reliably predict the form of the value referred to by a reference.
Early binding contrasts with late binding, which would evaluate references within the context of the top-level environment and its entire import stack. ESC does not currently support late-bound references.
Bare references
Bare references evaluate to a copy of the referenced value.
Example
values:
user:
name: Real Name
login: user-login
user-copy: ${user}
Evaluated result
{
"user": {
"name": "Real Name",
"login": "user-login"
},
"user-copy": {
"name": "Real Name",
"login": "user-login"
}
}
Interpolations
Interpolations evaluate to the string representation of the referenced value.
Example
values:
user:
name: Real Name
login: user-login
greeting: Hello, ${user.name}!
Evaluated result
{
"user": {
"name": "Real Name",
"login": "user-login"
},
"greeting": "Hello, Real Name!"
}
Built-in properties
In addition to referencing properties defined within an environment, references can access several built-in properties: information about the user evaluating an environment (context), other environments in the organization (environments), and imported environments (imports).
context
The context built-in property provides information about the environment being evaluated, the user requesting it, and the access token they used.
Environment identity
context.currentEnvironment.name: the name of the environment in which the reference is written, including its projectcontext.rootEnvironment.name: the name of the environment that was opened, including its project
These two differ only inside imported environments. A reference written in an imported environment sees its own name in currentEnvironment.name, but the name of the environment that started the evaluation in rootEnvironment.name. For a worked example, see How attributes resolve across imported environments.
For environments in the legacy default project, both properties resolve to the environment name alone, without a project prefix.
Caller identity
context.pulumi.user.login: the login of the requesting usercontext.pulumi.organization.login: the login of their organizationcontext.pulumi.token.type: the type of the access token used to open the environment, such aspersonal,team, ororganizationcontext.pulumi.token.team: the name of the team a team-scoped token belongs tocontext.pulumi.token.name: the token’s name
Each context.pulumi.token property resolves to an empty string when it doesn’t apply to the credential in use. token.team is empty for tokens that aren’t team-scoped, and token.name is empty for personal and web tokens.
values:
greeting: Hello, ${context.pulumi.organization.login}/${context.pulumi.user.login}!
Open duration
context.pulumi.openDuration: how long the opened environment’s values remain valid, as a Go duration string such as2h0m0s
This reflects the lifetime requested for this particular open, so the same environment can evaluate it differently from one open to the next. Opening with esc env open <environment> --lifetime 30m resolves it to 30m0s; opening without a lifetime resolves it to the default of 2h0m0s. Use it to align a credential’s own expiry with the lifetime of the environment that issued it.
Differentiating callers by token
For team and organization tokens, both user.login and organization.login resolve to the organization name, so neither one distinguishes a team token from an individual user. The context.pulumi.token properties are the way to tell those callers apart:
values:
callerType: ${context.pulumi.token.type}
callerTeam: ${context.pulumi.token.team}
token.type and token.team are also available as OIDC subject attributes, which lets a cloud provider’s trust policy scope an assumable role to a specific team. token.name is deliberately excluded from subject claims because token names are chosen by the user and could be crafted to forge a subject. See Custom token claim.
environments
The environments built-in property provides access to other environments within the same organization. This allows the selective use of values from other environments without explicitly importing them. Reference a value as ${environments.<project>.<environment>.<property-path>}.
values:
other: Hello, ${environments.app.dev.name}!
imports
The imports built-in property provides access to imported environments, including those that are imported without participating in the merge stack (merge: false). For details on importing environments, see Imports.
imports:
- app/dev: { merge: false }
values:
other: Hello, ${imports["app/dev"].name}!