Placeholder expressions

Placeholder expressions let you add dynamic elements into the configuration of the Platform Orchestrator.

Placeholder expressions are identified through their ${ prefix and } suffix and follow a strict syntax as shown on this page, e.g. ${context.env_id} for “the ID of the current environment”.

Note that not all locations support all kinds of placeholders. Errors will be thrown if the placeholder is not supported or cannot be resolved. Refer to the list below to see which placeholder expression may be used where and find more usage details in the sections further down.

List of placeholders

Placeholder expression Usable in Description
${context.env_id} Manifest:
  • variables
  • resource params
Module:
  • module_inputs
  • params in dependencies
  • params in coprovisioning
The environment ID of the current deployment (details)
${context.env_type_id} Manifest:
  • variables
  • resource params
Module:
  • module_inputs
  • params in dependencies
  • params in coprovisioning
The environment type ID of the current deployment (details)
${context.org_id} Manifest:
  • variables
  • resource params
Module:
  • module_inputs
  • params in dependencies
  • params in coprovisioning
The organization ID of the current deployment (details)
${context.project_id} Manifest:
  • variables
  • resource params
Module:
  • module_inputs
  • params in dependencies
  • params in coprovisioning
The project ID of the current deployment (details)
${context.res_class} Module:
  • module_inputs
  • params in dependencies
  • params in coprovisioning
The resource class of the resource (details)
${context.res_id} Module:
  • module_inputs
  • params in dependencies
  • params in coprovisioning
The resource ID of the resource (details)
${context.res_type} Module:
  • module_inputs
  • params in dependencies
  • params in coprovisioning
The resource type of the resource (details)
${resources.<alias>.outputs.<traversal>} Module:
  • module_inputs
  • params in dependencies
  • params in coprovisioning
Extract output from a resource in the dependencies (details)
${select.<function chain>.outputs.<traversal>} Module:
  • module_inputs
  • params in dependencies
  • params in coprovisioning
Extract outputs from multiple nodes in the resource graph (details)

Context placeholders

These placeholders allow the behavior or results of a deployment or a module to change depending on its context.

The following context placeholders are available in the deployment manifest, module inputs, and resource parameters (params) in dependencies or coprovisioning:

The following context placeholders are more restrictive and only accessible within the definition of a module since they require knowledge of the resource graph node being provisioned. Specifically, they can be used in module inputs and resource parameters (params) in dependencies or coprovisioning:

  • ${context.res_type} - The resource type of the resource provisioned by this module
  • ${context.res_class} - The resource class of the resource. The default value is “default” but may be different if specified on resource creation
  • ${context.res_id} - The resource ID of the resource. This depends on the location of the resource, whether the ID was set specifically or inherited

When used as params in dependencies, they will resolve to the value of the dependent (child) resource.

When used as params in coprovisioning, they will resolve to the value of the coprovisioned resource.

Resource placeholders

Resource placeholders are used in modules to refer to outputs of any resource defined in the module dependencies section. The outputs may then be used as module inputs as well as in params to other resources in the dependencies or coprovisioning section of the module:

dependencies:
  some-resource:
    type: some-resource-type
  another-resource:
    type: another-resource-type
    params:
      # Resource placeholder referring to the output "x" of the resource aliased as "some-resource" 
      some-param: "${resources.some-resource.outputs.x}"

The resource placeholder first refers to the resource alias, some-resource in the example, which is the key of the resource in the dependencies section and only used locally in the module. The resource placeholder then defines the output value to reference, x in the example.

The syntax of a resource placeholder is of the form resources.<alias>.outputs.<traversal>, e.g.

${resources.my-resource.outputs.something.key}

This resource placeholder refers to the key field in the something output of the resource defined by the my-resource alias in the module.

An error will be thrown if no resource is specified by the alias or if the traversal cannot be resolved.

Selector placeholders

Selector placeholders are an advanced concept used in modules that allow extracting outputs from multiple nodes in the resource graph at the same time. The outputs may then be used as module inputs as well as in params to other resources in the dependencies or coprovisioning section of the module.

The selector uses a chain of functions to traverse the graph. It starts at the resource node defined by the current module, this being the input to the first function in the chain. It then passes the resources found by each function to the next function in the chain which evaluates them one by one.

The syntax of a selector placeholder is select.<function chain>.outputs.<traversal>, e.g.

${select.dependencies('dns.default#@').consumers('route').outputs.name}

This selector placeholder

  1. Selects all dependencies of the current resource which have the resource type dns, class default, and the same (@) resource ID as the current resource
  2. Selects all consumers of the resources from step 1. which have a resource type route, regardless of class and ID
flowchart LR
    currentResource --> dns2(DNS<br/>class: internal<br/>ID: main)
    route1(Route<br/>class: something<br>ID: anything) -->|2#46; consumers| dns1
    currentResource(Current resource<br/>class: default<br/>ID: main) -->|1#46; dependencies| dns1(DNS<br/>class: default<br/>ID: main)
    route2(Route<br/>class: default<br>ID: main) --> dns2

    class route1 highlight
    linkStyle 1,2 stroke:#2156f6,stroke-width:4px

The selector always returns an array with zero ([]) or more items as a result.

The following functions are supported:

Selector function “dependencies”

The dependencies function selects all nodes in the resource graph on which the input nodes depend and that match the filter. Only direct dependencies are considered.

flowchart LR
    inputResource(Input resource) -->|"${select.dependencies(...)...}"| someResource(Some resource)
    inputResource --> anotherResource(Another resource)

    class someResource highlight

The function requires a filter which must be surrounded by single quotes: dependencies('filter'). The filter must start with the resource type to match followed by optional class and ID filters. The class filter is prefixed with a .. The ID filter must be at the end and is prefixed with a #.

Examples:

  • dependencies('type-a') will filter for all direct dependencies with resource type type-a, regardless of class or ID
  • dependencies('type-a.default') will constrain the selection to only those resources with class default, regardless of ID
  • dependencies('type-a#workloads.example.dep') will constrain the selection to only resources with the ID workloads.example.dep, regardless of class

An @ symbol may be used to insert the current resource’s class or ID:

  • dependencies('type-a.@#@') will filter for only the node with resource type type-a and exactly the class and ID of the current resource node for which this expression is evaluated

Selector function “consumers”

The consumers function selects all nodes in the resource graph that depend on the input nodes and that match the filter. Only direct dependencies are considered.

flowchart LR
    someResource(Some resource) -->|"${select.consumers(...)...}"| inputResource(Input resource)
    anotherResource(Another resource) --> inputResource

    class someResource highlight

The function requires a filter which must be surrounded by single quotes: consumers('filter'). The filter operates exactly the same way as the filter parameters in the dependencies function above.

The “@” symbol in a function chain

A @ symbol is resolved locally for each function in a function chain. It refers to the resource node that is currently being handled by the function. Further down in the chain, this will not be the resource in whose module the selector is declared.

E.g. in this selector

${select.dependencies('dns.default#@').consumers('route.@').outputs.name}

the @ symbol is resolved like this:

  • dependencies('dns.default#@') handles the resource of the current module, so the @ resolves to the ID of the resource in whose module this selector is defined
  • consumers('route.@') handles the dns resource(s) found via the dependencies function, so the @ resolves to the class of the dns resource currently being handled

Examples

Given this resource graph:

flowchart LR
    workload(Workload<br/>type: workload<br/>class: default<br/>ID: main) --> type1(Type 1<br/>type: type1<br/>class: default<br>ID: workloads.main.type-1)
    workload --> type2(Type 2<br/>type: type2<br/>class: default<br>ID: workloads.main.type-2)
    type2 --> type3_1(Type 3-1<br/>type: type3<br/>class: default<br>ID: my-type-3)
    type2 --> type3_2("Type 3-2<br/>type: type3<br/>class: default<br>ID: workloads.main-type-2<br/>(inherited ID)")

This placeholder in the the type2 module returns an array with two elements being the some_output values of both type3 resources:

${select.dependencies('type3').outputs.some_output}

This placeholder in the type1 module returns an array with one element being the some_output value of the type3 resource with ID my-type-3:

${select.consumers('workload').dependencies('type2').dependencies('type3#my-type-3').outputs.some_output}

This modification of the same placeholder now returns the value of the type3 resource with ID workloads.main.type-2 instead by using the @ symbol which is evaluated for the type2 resource:

${select.consumers('workload').dependencies('type2').dependencies('type3#@').outputs.input_echo}
Top