Environment Configurations

This is a beta feature.

This feature was introduced in v1.11.
This feature graduated to beta status in v1.18.

For more information read the Crossplane feature lifecycle.

A Crossplane EnvironmentConfig is a cluster-scoped, strongly typed, ConfigMap-like resource used by Compositions. Compositions can use the environment to store information from individual resources or to apply patches.

Crossplane supports multiple EnvironmentConfigs, each acting as a unique data store.

When Crossplane creates a composite resource, Crossplane merges all the EnvironmentConfigs referenced in the associated Composition and creates a unique in-memory environment for that composite resource.

The composite resource can read and write data to their unique in-memory environment.

Important
The in-memory environment is unique to each composite resource. A composite resource can’t read data in another composite resource’s environment.

Create an EnvironmentConfig

An EnvironmentConfig has a single object field, data.

An EnvironmentConfig supports any data inside the data field.

Here an example EnvironmentConfig.

 1apiVersion: apiextensions.crossplane.io/v1beta1
 2kind: EnvironmentConfig
 3metadata:
 4  name: example-environment
 5data:
 6  locations:
 7    us: us-east-2
 8    eu: eu-north-1
 9  key1: value1
10  key2: value2
11  key3:
12    - item1
13    - item2

Access EnvironmentConfigs

EnvironmentConfigs can be accessed by Composition Functions supporting extra-resources, for example function-environment-configs or function-go-templating.

Migration from Alpha Composition Environment

Crossplane (<=v1.17) natively supported selecting EnvironmentConfigs, merging them into an in-memory environment and patching between that, composed and composite resources. From v1.18, this native capability has been removed, in favor of Composition Functions.

Users that enabled Alpha Composition Environments (--enable-environment-configs) and leveraged the native functionality (spec.environment.patches, spec.environment.environmentConfigs and *Environment patches), will have to migrate to Composition Functions to continue doing so.

Automated migration to Pipeline mode is available through crossplane beta convert pipeline-composition, which will move a composition using Resource mode, to function-patch-and-transform and, if needed, function-environment-configs.

See the documentation of function-environment-configs for more details about manual migration.

Select an EnvironmentConfig using function-environment-configs

Select the EnvironmentConfigs to use through function-environment-configs’s Input.

The environmentConfigs field is a list of EnvironmentConfigs we want retrieved, merged and passed to the next step in the pipeline through the Context at a well known key, apiextensions.crossplane.io/environment.

Select an environment by Reference or by Selector:

  • A Reference selects an EnvironmentConfig by name.
  • The Selector selects an EnvironmentConfig by labels.
 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: example-composition
 5spec:
 6  mode: Pipeline
 7  pipeline:
 8  - step: environmentConfigs
 9    functionRef:
10      name: function-environment-configs
11    input:
12      apiVersion: environmentconfigs.fn.crossplane.io/v1beta1
13      kind: Input
14      spec:
15        environmentConfigs:
16        - type: Reference
17          ref:
18            name: example-environment
19        - type: Selector
20          selector:
21            matchLabels:
22            # Removed for brevity
23    # the environment will be passed to the next function in the pipeline
24    # as part of the context
25
26# Next step consuming the merged environment removed for brevity...

If a Composition uses multiple EnvironmentConfigs, function-environment-configs merges them together in the order they’re listed.

Select by name

Select an EnvironmentConfig by name with type: Reference.

Define ref.name to match the exact name of the environment.

For example, select the EnvironmentConfig named example-environment:

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: example-composition
 5spec:
 6  mode: Pipeline
 7  pipeline:
 8  - step: environmentConfigs
 9    functionRef:
10      name: function-environment-configs
11    input:
12      apiVersion: environmentconfigs.fn.crossplane.io/v1beta1
13      kind: Input
14      spec:
15        environmentConfigs:
16        - type: Reference
17          ref:
18            name: example-environment

Select by label

Select an EnvironmentConfig by labels with a type: Selector.

Define selector.matchLabels to a list of selectors either of type Value, or FromCompositeFieldPath.

When matching the label’s value, provide an exact value with a type: Value and provide the value to match in the value field.

function-environment-configs can also match a label’s value based on an input in the composite resource. Use type: FromCompositeFieldPath and provide the field to match in the valueFromFieldPath field.

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: example-composition
 5spec:
 6  mode: Pipeline
 7  pipeline:
 8  - step: environmentConfigs
 9    functionRef:
10      name: function-environment-configs
11    input:
12      apiVersion: environmentconfigs.fn.crossplane.io/v1beta1
13      kind: Input
14      spec:
15        environmentConfigs:
16        - type: Selector
17          selector: 
18            matchLabels:
19              - key: my-label-key
20                type: Value
21                value: my-label-value
22              - key: my-label-key
23                type: FromCompositeFieldPath
24                valueFromFieldPath: spec.parameters.deploy
25  # Removed for brevity

Manage selector results

Selecting environments by labels may return more than one environment.
function-environment-configs, by default, sorts all the results by name and only uses the first environment in the sorted list.

Set the selector.mode to Multiple to return all matched EnvironmentConfigs. Use mode: Single to return a single environment, and error out if more than one match is found.

Sorting and the selection mode only applies to a single Selector.

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: example-composition
 5spec:
 6  mode: Pipeline
 7  pipeline:
 8  - step: environmentConfigs
 9    functionRef:
10      name: function-environment-configs
11    input:
12      apiVersion: environmentconfigs.fn.crossplane.io/v1beta1
13      kind: Input
14      spec:
15        environmentConfigs:
16        - type: Selector
17          selector:
18            mode: Multiple
19            matchLabels:
20              - key: my-label-key
21                type: Value
22                value: my-label-value
23              - key: my-label-key
24                type: FromCompositeFieldPath
25                valueFromFieldPath: spec.parameters.deploy
26        - type: Selector
27          selector:
28            mode: Single
29            matchLabels:
30              - key: my-other-label-key
31                type: Value
32                value: my-other-label-value
33              - key: my-other-label-key
34                type: FromCompositeFieldPath
35                valueFromFieldPath: spec.parameters.deploy

When using mode: Multiple limit the number of returned EnvironmentConfigs with maxMatch and define the maximum number to select.

Use minMatch and define the minimum number of environments returned.

The Function sorts the returned environments alphabetically by name by default. Sort the environments on a different field with sortByFieldPath and define the field to sort by.

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: example-composition
 5spec:
 6  mode: Pipeline
 7  pipeline:
 8  - step: environmentConfigs
 9    functionRef:
10      name: function-environment-configs
11    input:
12      apiVersion: environmentconfigs.fn.crossplane.io/v1beta1
13      kind: Input
14      spec:
15        environmentConfigs:
16        - type: Selector
17          selector:
18            mode: Multiple
19            maxMatch: 4
20            sortByFieldPath: metadata.annotations[sort.by/weight]
21            matchLabels:
22              - key: my-label-key
23                type: Value
24                value: my-label-value
25              - key: my-label-key
26                type: FromCompositeFieldPath
27                valueFromFieldPath: spec.parameters.deploy

The EnvironmentConfigs selected by matchLabels are then merged with all the other ones specified.

Optional selector labels

By default, Crossplane issues an error if the specified valueFromFieldPath field doesn’t exist in the composite resource.

Set fromFieldPathPolicy to Optional to ignore a field if it doesn’t exist.

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: example-composition
 5spec:
 6  mode: Pipeline
 7  pipeline:
 8  - step: environmentConfigs
 9    functionRef:
10      name: function-environment-configs
11    input:
12      apiVersion: environmentconfigs.fn.crossplane.io/v1beta1
13      kind: Input
14      spec:
15        environmentConfigs:
16        - type: Selector
17          selector:
18            mode: Multiple
19            maxMatch: 4
20            sortByFieldPath: metadata.annotations[sort.by/weight]
21            matchLabels:
22              - key: my-label-key
23                type: Value
24                value: my-label-value
25              - key: my-label-key
26                type: FromCompositeFieldPath
27                valueFromFieldPath: spec.parameters.deploy
28                fromFieldPathPolicy: Optional
29  # Removed for brevity

Set a default value for an optional label by setting the default value for the key first using a Value selector, then define the Optional FromCompositeFieldPath one.

For example, the Composition below defines value: my-default-value for the key my-second-label-key. If the Composite resource defines spec.parameters.deploy, function-environment-configs will use that instead.

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: example-composition
 5spec:
 6  mode: Pipeline
 7  pipeline:
 8  - step: environmentConfigs
 9    functionRef:
10      name: function-environment-configs
11    input:
12      apiVersion: environmentconfigs.fn.crossplane.io/v1beta1
13      kind: Input
14      spec:
15        environmentConfigs:
16          - type: Selector
17            selector:
18              matchLabels:
19                - key: my-first-label-key
20                  type: Value
21                  value: my-label-value
22                - key: my-second-label-key
23                  type: Value
24                  value: my-default-value
25                - key: my-second-label-key
26                  type: FromCompositeFieldPath
27                  valueFromFieldPath: spec.parameters.deploy
28                  fromFieldPathPolicy: Optional
29  # Removed for brevity
Warning

function-environment-configs applies values in order. The value of the last key defined always takes precedence.

Defining the default value after the label always overwrites the label value.

Patching with EnvironmentConfigs using function-patch-and-transform

EnvironmentConfigs selected as explained above, are then merged in an in-memory environment by function-environment-configs and passed to the next function in the pipeline at a well known key, apiextensions.crossplane.io/environment.

function-patch-and-transform can be used to read or write data between the in-memory environment and composite resource or individual composed resources.

Tip
The Patch and Transform function can use the environment to patch composed resources. Read about EnvironmentConfig patch types in the Patch and Transform function documentation.

Patch between Composite resource and environment

To patch between Composite resource and environment define patches at spec.environment.patches in the Resources input of function-patch-and-transform.

Use the ToCompositeFieldPath patch type to copy data from the in-memory environment to the Composite resource. Use the FromCompositeFieldPath to copy data from the Composite resource to the in-memory environment.

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: example-composition
 5spec:
 6  mode: Pipeline
 7  pipeline:
 8  # Removed for Brevity
 9  - step: patch-and-transform
10    functionRef:
11      name: function-patch-and-transform
12    input:
13      apiVersion: pt.fn.crossplane.io/v1beta1
14      kind: Resources
15      environment:
16        patches:
17        - type: ToCompositeFieldPath
18          fromFieldPath: tags
19          toFieldPath: metadata.labels[envTag]
20        - type: FromCompositeFieldPath
21          fromFieldPath: metadata.name
22          toFieldPath: newEnvironmentKey
23# Removed for Brevity

Individual resources can use any data written to the in-memory environment.

CombineFromComposite and CombineToComposite can be used to combine multiple values and write the result either to the in-memory environment or the Composite resource, respectively.

Patch an individual resource

To patch between individual resources and the in-memory environment, inside the patches of the resource, use ToEnvironmentFieldPath to copy data from the resource to the in-memory environment. Use FromEnvironmentFieldPath to copy data to the resource from the in-memory environment.

 1apiVersion: apiextensions.crossplane.io/v1
 2kind: Composition
 3metadata:
 4  name: example-composition
 5spec:
 6  mode: Pipeline
 7  pipeline:
 8  # Removed for Brevity
 9  - step: patch-and-transform
10    functionRef:
11      name: function-patch-and-transform
12    input:
13      apiVersion: pt.fn.crossplane.io/v1beta1
14      kind: Resources
15      # Removed for Brevity
16      resources:
17        - name: vpc
18          base:
19            apiVersion: ec2.aws.upbound.io/v1beta1
20            kind: VPC
21            spec:
22              forProvider:
23                cidrBlock: 172.16.0.0/16
24          patches:
25            - type: ToEnvironmentFieldPath
26              fromFieldPath: status.atProvider.id
27              toFieldPath: vpcId
28            - type: FromEnvironmentFieldPath
29              fromFieldPath: tags
30              toFieldPath: spec.forProvider.tags
Tip
The Patch and Transform documentation has more information on patching individual resources.