Point one value at another
For feature teams. This page explains the ${{ ... }} reference. A reference lets one value in your file point at another value, so that you do not repeat it or guess it.
What a reference is
A reference is a ${{ ... }} value that points to a fact of your file or to an output of a resource. An output is a value that a provisioner reports after it creates a resource.
A reference is useful when a value does not exist yet. For example, a database password does not exist until the database exists. The deployment that needs it holds a reference.
This part of the file has many references. Each line sets one environment variable of a cloud-foundry-app deployment:
env:
# Facts that the file declares once.
SERVICE_NAME: "${{application.name}}"
OWNER_NAME: "${{application.owner.name}}"
CONFIGURATION_ITEM: "${{application.metadata.configuration-item}}"
JAR_PATH: "${{artifacts.shop-jar.spec.path}}"
UPDATE_SCHEDULE: "${{tooling.renovate.spec.schedule}}"
# Values of the resources of this environment.
CF_SPACE: "${{targets.test-foundation.spec.space}}"
DB_VERSION: "${{managed-resources.shop-db.spec.version}}"
EVENTS_TOPIC: "${{consumed-resources.shop-events.spec.topic}}"
# A value that a provisioner reports after it creates a resource.
DB_PASSWORD: "${{managed-resources.shop-db.outputs.password}}"
SPACE_GUID: "${{targets.test-foundation.outputs.space-guid}}"
# Text and a reference in one value.
CONNECTION_NOTE: "database ${{managed-resources.shop-db.spec.version}} in ${{targets.test-foundation.spec.space}}"
The complete file is the example references.
You can write a reference in a text value of a spec. The env setting of a cloud-foundry-app deployment is the usual place. A setting that needs a number cannot hold a reference. The rules of the setting apply to the text that you write, including its length limit.
The syntax
A reference has this form:
${{ path }}
A path is a root followed by one or more segments. Dots separate the parts. A segment has letters, digits, hyphens and underscores. Spaces inside the braces are allowed.
A value can be one reference alone, as DB_PASSWORD is. It can also mix text and references, as CONNECTION_NOTE does.
A reference names one value. It has no operators, no functions and no list positions. These are errors:
${{application.name | upper}}
${{tooling[0].id}}
The seven roots
The first part of a path is the root. It is spelled like the key that it names in your file.
| Root | Names | Written once for the file? |
|---|---|---|
application | A field of the application block, its owner or its metadata. | Yes |
artifacts | An entry of the artifacts list. | Yes |
tooling | An entry of the tooling list. | Yes |
targets | An entry of targets in the same environment. | No |
deployments | An entry of deployments in the same environment. | No |
managed-resources | An entry of managed-resources in the same environment. | No |
consumed-resources | An entry of consumed-resources in the same environment. | No |
An artifacts or tooling entry has an id, a type and a spec. A tool also has enabled. These entries have no outputs. This reference is an error:
error: the control plane found 1 problem in joomiz.yaml (checked by https://joomiz.example.com/validate)
environments:
test:
shop-test-deployment (cloud-foundry-app): shop-jar -> test-foundation
spec: '${{artifacts.shop-jar.outputs.digest}}' — 'artifacts.shop-jar.outputs.digest' does not name a value; declared here: id, type, spec
The path of an entry of an environment has four parts: the root, the id of the entry, a section and a field. The section is spec or outputs.
specis a setting that you wrote under thespecof that entry.outputsis a value that the provisioner of the entry reports.
For example, managed-resources.shop-db.outputs.password has the root managed-resources, the id shop-db, the section outputs and the field password.
A reference stays inside its environment
A reference can name a fact that the file declares once. It can also name an entry of the environment in which you write it. It cannot name anything else.
There is no root for another environment. A path such as environments.prod... is not a reference at all:
error: the control plane found 1 problem in joomiz.yaml (checked by https://joomiz.example.com/validate)
environments:
test:
shop-test-deployment (cloud-foundry-app): shop-jar -> test-foundation
spec: '${{environments.prod.targets.test-foundation.spec.space}}' is not a valid reference — 'environments' is not something a reference can start with — write 'application' for a fact about this application, or one of 'targets', 'deployments', 'managed-resources' or 'consumed-resources' for a resource of this same environment, which is the only environment a reference can see
The same reference text in test names an entry of test. In prod it names an entry of prod. Two environments that both write ${{managed-resources.billing-service-db.outputs.password}} share nothing.
An id that exists only in another environment is not found:
error: the control plane found 1 problem in joomiz.yaml (checked by https://joomiz.example.com/validate)
environments:
test:
shop-test-deployment (cloud-foundry-app): shop-jar -> test-foundation
spec: '${{managed-resources.shop-database.spec.version}}' names no managed-resource with id 'shop-database' in this environment — declared managed-resources there: shop-db
Which outputs exist
The catalog says which outputs each type can report. A type with no outputs accepts no outputs reference.
| Type | Outputs |
|---|---|
postgres | password |
cloud-foundry-space | org-guid, space-guid |
cloud-foundry-app | pipeline-id, pipeline-url |
The other types of this guide report no outputs. Your platform can have other types with other outputs. A reference to an output that the type does not have is an error that lists the outputs it has:
error: the control plane found 1 problem in joomiz.yaml (checked by https://joomiz.example.com/validate)
environments:
test:
shop-test-deployment (cloud-foundry-app): shop-jar -> test-foundation
spec: '${{targets.test-foundation.outputs.space}}' — 'targets.test-foundation.outputs.space' does not name a value; declared here: org-guid, space-guid
A path that names a section other than spec or outputs is an error too:
error: the control plane found 1 problem in joomiz.yaml (checked by https://joomiz.example.com/validate)
environments:
test:
shop-test-deployment (cloud-foundry-app): shop-jar -> test-foundation
spec: '${{managed-resources.shop-db.version}}' reads 'version' of the managed-resource 'shop-db', which is neither 'spec' nor 'outputs'
What a plan prints
validate checks that each reference is well formed and that it points at something that your file declares. It does not give a value.
The control plane replaces each reference with its value before it calls a provisioner. A value that does not exist yet cannot be replaced in a plan. The plan prints (known after apply) for it.
This plan is for the file above, in an environment where nothing exists yet:
plan for joomiz.yaml in environment test (computed by https://joomiz.example.com/plan?environment=test)
target/cloud-foundry-space: succeeded — Planned 1 change for target/cloud-foundry-space.
test-foundation (created): succeeded — Would create 'test-foundation' (target/cloud-foundry-space) in environment 'test'. Nothing was changed.
outputs.org-guid: 3b1f6c0e-52a4-4d8e-9a7b-0c4e8d2f7a11
outputs.space-guid: 9d2e4b7a-61c3-4f05-8b3a-5e7c1a0d9f22
consumed-resource/kafka-topic: succeeded — Planned 1 change for consumed-resource/kafka-topic.
shop-events (created): succeeded — Would create 'shop-events' (consumed-resource/kafka-topic) in environment 'test'. Nothing was changed.
managed-resource/postgres: succeeded — Planned 1 change for managed-resource/postgres.
shop-db (created): succeeded — Would create 'shop-db' (managed-resource/postgres) in environment 'test'. Nothing was changed.
outputs.password: https://vault.example.com/secrets/quick-start-shop-db-password
deployment/cloud-foundry-app: succeeded — Planned 2 changes for deployment/cloud-foundry-app.
shop-test-deployment (created): succeeded — Would create 'shop-test-deployment' (deployment/cloud-foundry-app) in environment 'test'. Nothing was changed. 2 spec values are not known until apply.
env.DB_PASSWORD: (known after apply)
env.SPACE_GUID: (known after apply)
shop-test-worker (created): succeeded — Would create 'shop-test-worker' (deployment/cloud-foundry-app) in environment 'test'. Nothing was changed.
4 resource types, 5 resources
plan succeeded (revision 14526948-0e76-4855-86fa-4ae2eb132a36, plan 1bea443c-f448-4d71-bbfa-286cf76037d4)
The two lines env.DB_PASSWORD and env.SPACE_GUID hold references to outputs of resources that this plan creates. The plan cannot fill them, even when the provisioner shows an outputs line for the entry in the plan. A resource that exists already has known outputs, so a later plan uses them and prints no (known after apply) for them.
apply creates the entries in dependency order, and it uses the outputs that the provisioners really report. If a provisioner does not report an output that a reference needs, the apply of that deployment stops with this reference could not be resolved.
Limits
| Limit | Value |
|---|---|
| Characters of one text value that Joomiz reads for references | 4096 |
| References in one text value | 64 |
| Segments after the root | 16 |
| Characters in one segment | 255 |
A normal file does not reach these limits. A value with more than 64 references, or with references after its 4096th character, stops plan for that resource type with this reference could not be resolved.
Common errors
| Message | Cause | Fix |
|---|---|---|
is not something a reference can start with | The root is not one of the seven. | Start with one of the seven roots. |
names no managed-resource with id | The entry is not in this environment. | Check the id and the environment. |
does not name a value; declared here: | The field does not exist. The message lists the fields that do. | Use one of the listed fields. |
which is neither 'spec' nor 'outputs' | The part after the id is not a section. | Write spec or outputs after the id. |
is never closed with '}}' | A reference has no closing braces. | Add }}. |
reference each other in a cycle | Two entries need each other's values. | Remove one of the references. |
references this deployment itself | An entry reads its own value. | Point at another entry. |
is not an identifier | A segment has a character that is not allowed. | Use letters, digits, hyphens and underscores. |
this reference could not be resolved | A value goes over a limit, or a provisioner did not report the output. | Keep the value within the limits, or tell your platform team. |
This is the message for a cycle between two deployments:
error: the control plane found 1 problem in joomiz.yaml (checked by https://joomiz.example.com/validate)
environments:
test:
these resources reference each other in a cycle and cannot be ordered: deployment/shop-test-deployment, deployment/shop-test-worker
Next
Learn how a database reports its password without showing it in Use outputs and secrets.