Variable expressions
The syntax of ${{ }} expressions in variable values, what each form produces, when it is evaluated, where it is allowed, and the messages a bad one produces.
An expression is text between ${{ and }} inside a value. It lets one value point at another service's variable, draw a random secret, or name a service's address. Whitespace inside the braces is ignored: ${{ api.KEY }} and ${{api.KEY}} are the same. A value without ${{ is stored as written. For the task-oriented view, see Variables.
Quick reference
| Form | Produces | Evaluated |
|---|---|---|
${{ slug.KEY }} | The value of KEY as service slug sees it | At every release |
${{ host(slug) }} | svc-slug, the in-cluster host name of a service | Once, when the value is written |
${{ secret(N) }} | N random letters and digits, and marks the variable secret | Once, when the value is written |
${{ inputs.KEY }} | The answer to a template's install form | When the template is installed |
Any other text between the braces is refused. A value can mix literal text and several expressions: postgres://app:${{ db.PASSWORD }}@${{ host(db) }}:5432/app.
Reference: slug.KEY
${{ slug.KEY }}Points at a variable of another service in the same environment. slug is the service's slug, lowercase letters, digits and hyphens. KEY is a variable key in UPPER_SNAKE_CASE: it matches [A-Z_][A-Z0-9_]*. KEY may be any key the service has in that environment, on any tier it sees, including a database service's connection variables.
- Evaluated: every time a release is made, so a change to the target's value reaches the referring service on its next deployment. The stored value keeps the reference.
- Chains: a referenced value can itself hold references, up to 5 deep.
- Checked when written: the slug must be a service of the project, and the service must have
KEYin that environment, or the same change set must add it. A service that exists only in a change set that is not applied yet can only be named from that change set. - Also a dependency: a reference makes the referring service depend on the target. The canvas draws it as an edge.
host(slug): address of a service
${{ host(slug) }}Becomes the in-cluster host name of the service slug: svc- plus the slug, for example svc-api. A name longer than 63 characters is shortened and ends in a hash. The host name has no port; write the port after it.
- Evaluated: once, when the value is written. The stored value is the host name, not the expression.
- Checked when written:
slugmust name a service of the project. In a project config, it may also name a service or database that the file declares. - Not a dependency: an address alone does not make the service wait for the target.
secret(N): a random value
${{ secret(N) }}
${{ secret() }}Draws N random letters and digits (A-Z, a-z, 0-9) and stores the result as a secret variable. N is a whole number from 16 to 128. Without a number, N is 32. Every secret(N) is a separate draw, so two of them in one value are different.
- Evaluated: once, when the value is written. The drawn text is sealed and is not drawn again.
- Secret: a value that draws a secret is a secret variable, shown masked in the console.
inputs.KEY: a template answer
${{ inputs.KEY }}Exists only in templates, where it stands for the answer to the install form's input KEY. It is evaluated when the template is installed. A service variable and a nebula.toml file refuse it.
Where each form is allowed
| Where the value is written | slug.KEY | host(slug) | secret(N) | inputs.KEY |
|---|---|---|---|---|
| A service variable, in the console or through the API | Yes | Yes | Yes | Refused |
[env] and [connection] of a project config | Yes | Yes | Yes | Refused |
[env] of a service's nebula.toml | Kept as written and followed at release | Not evaluated | Not evaluated | Not evaluated |
| A template | Yes, by the template's service name | Yes | Yes | Yes |
A service's nebula.toml stores its [env] values as written. A reference in it works because references are followed at release time. Use a service variable or the project config to draw a secret or name an address.
Messages
A refused value names the problem and the fix. The messages below are the fixed wording; <...> stands for your text.
| Message | Cause |
|---|---|
has an unterminated "${{" with no matching "}}"; close it, or remove the "${{" if it is literal text. | A ${{ with no }}. |
has an empty ${{ }}; write ${{ service.KEY }}, ${{ secret(N) }} or ${{ host(service) }} between the braces. | Nothing between the braces. |
<function>() is not a supported function. Use ${{ secret(N) }} for a random secret (N from 16 to 128), or ${{ host(service) }} for a service's in-cluster host name. | A function other than secret and host. |
${{ secret(<N>) }} must look like ${{ secret() }} or ${{ secret(N) }}, N a whole number from 16 to 128. | A secret call with something other than a whole number. |
${{ host(<text>) }} must name a service: ${{ host(service) }}, with the service's slug. | A host call with no service name. |
${{ secret(<N>) }} draws between 16 and 128 characters, not <N>; write ${{ secret(32) }} or another length in that range. | N outside 16 to 128. |
host(<slug>) names no service in this project. Use the slug of one of: <slugs>. | host names a service the project does not have. |
${{ <text> }} is not a valid reference: a service slug is lowercase letters, digits and hyphens, and a key is UPPER_SNAKE_CASE, as in ${{ db.DATABASE_URL }}. | The slug or the key is not written the way slugs and keys are. |
<KEY> references <slug>.<KEY2>, but this project has no service <slug>. Services here: <slugs>. | A reference to a service the project does not have. |
<KEY> references <slug>.<KEY2>, but <slug> has no variable <KEY2> in <environment>. Pick one of: <keys>, or add it to <slug> first. | The target service lacks that key in the environment. If the service has no variables there, the message ends Add it to <slug> first. instead of listing keys. |
inputs.<KEY> only exists inside templates; in a service variable write the value itself, or reference another service's variable as ${{ service.KEY }}. | inputs.KEY in a service variable. |
${{ <text> }} is not a reference or a function. Write ${{ service.KEY }}, ${{ secret(N) }} or ${{ host(service) }}. | Text between the braces that is none of the three forms. |
<slug> is staged in a change set and doesn't exist yet: reference it from the same change set, or commit that change set first. | A value written at once names a service that only a change set that is not applied creates. |
At release time, a reference that cannot resolve holds the deployment with the configuration blocker. Its message reads <service> can't be deployed: <reason>. ..., and the reason is one of these:
| Reason | Cause |
|---|---|
variable references form a cycle: <chain>; replace one of them with a value | Values refer to each other in a loop. The chain shows each slug.KEY in order. |
variable references nest deeper than 5: <chain>; point the first one closer to the value | More than 5 references in a chain. |
<slug.KEY> references service "<slug>", which is not in this environment's project: <chain>; fix the slug or remove the reference | The target service was deleted or renamed after the value was written. |
<slug.KEY> references ${{ <slug>.<KEY> }}, but service "<slug>" has no variable <KEY> in this environment: <chain>; add it or remove the reference | The target's key was deleted after the value was written. |
See Deployment states and blockers for the blocker, and Limits for the numbers.