[!WARNING] This function relies on functionalities only available in Crossplane 1.15 and later. It will not work with earlier versions.
[!IMPORTANT]
This function is meant to replace native Composition Environment (--enable-environment-configs
), see below for more details.
This composition function allows you to request
EnvironmentConfigs
, merge them in the requested order and return inject the
computed environment
into the Context
at a well-known key,
apiextensions.crossplane.io/environment
, so that other functions such as
function-patch-and-transform can access it.
See the example directory for examples that you can run locally using the Crossplane CLI:
$ crossplane beta render \
--extra-resources example/environmentConfigs.yaml \
--include-context \
example/xr.yaml example/composition.yaml example/functions.yaml
To validate the rendered output, you can use the crossplane beta validate
command:
$ crossplane beta render \
--extra-resources example/environmentConfigs.yaml \
--include-full-xr \
example/xr.yaml example/composition.yaml example/functions.yaml | crossplane beta validate example -
See the composition functions documentation to learn more
about crossplane beta render
.
Crossplane 1.18 dropped native Composition Environment, meaning
spec.environment
and *Environment
patches were removed, while
EnvironmentConfig
as a resource was promoted to Beta
.
crossplane beta convert pipeline-composition
has been updated to
automatically migrate Compositions using those fields to this function.
A manual migration can be performed moving the following fields from a
Composition
spec to this function's Input
:
spec.environment.environmentConfigs
-> spec.environmentConfigs
spec.environment.defaultData
-> spec.defaultData
spec.environment.policy.resolution
-> spec.policy.resolution
spec.environment.policy.resolve
is not configurable at the moment, defaulting
to policy Always
.
spec.environment.patches
and resources' *Environment
patches will have to
be moved to function-patch-and-transform's input.
The diagram below shows what part of the usual Composition is replaced by this function and how it fits with other functions:
Given an example Resource
-mode Composition:
[!WARNING] The example below is using the old native Composition Environment, which was dropped in Crossplane 1.18.
```yaml apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: name: foo spec: compositeTypeRef: apiVersion: example.crossplane.io/v1 kind: XR mode: Resources environment: environmentConfigs: - type: Reference ref: name: example-config patches: # So you can then use it in all your patches: # - Env -> XR - type: ToCompositeFieldPath fromFieldPath: "someFieldInTheEnvironment" toFieldPath: "status.someFieldFromTheEnvironment" # - XR -> Env - type: FromCompositeFieldPath fromFieldPath: "spec.someFieldInTheXR" toFieldPath: "someFieldFromTheXR" resources: - name: bucket base: apiVersion: s3.aws.upbound.io/v1beta1 kind: Bucket spec: forProvider: region: us-east-2 patches: # - Env -> Resource - type: FromEnvironmentFieldPath fromFieldPath: "someFieldInTheEnvironment" toFieldPath: "spec.forProvider.someFieldFromTheEnvironment" # - Resource -> Env - type: ToEnvironmentFieldPath fromFieldPath: "status.someOtherFieldInTheResource" toFieldPath: "someOtherFieldInTheEnvironment" ```
The above can be converted to use this function and function-patch-and-transform as follows:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: foo
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: XR
mode: Pipeline
pipeline:
- step: environmentConfigs
functionRef:
name: function-environment-configs
input:
apiVersion: environmentconfigs.fn.crossplane.io/v1beta1
kind: Input
spec:
environmentConfigs:
- type: Reference
ref:
name: example-config
# the environment is be passed to the next function in the pipeline
# as part of the context
- step: patch-and-transform
# function-patch-and-transform knows it has to look for the environment in the
# context at "apiextensions.crossplane.io/environment"
functionRef:
name: function-patch-and-transform
input:
apiVersion: pt.fn.crossplane.io/v1beta1
kind: Resources
environment:
patches:
# So you can then use it in all your patches:
# - Env -> XR
- type: ToCompositeFieldPath
fromFieldPath: "someFieldInTheEnvironment"
toFieldPath: "status.someFieldFromTheEnvironment"
# - XR -> Env
- type: FromCompositeFieldPath
fromFieldPath: "spec.someFieldInTheXR"
toFieldPath: "someFieldFromTheXR"
resources:
- name: bucket
base:
apiVersion: s3.aws.upbound.io/v1beta1
kind: Bucket
spec:
forProvider:
region: us-east-2
patches:
# - Env -> Resource
- type: FromEnvironmentFieldPath
fromFieldPath: "someFieldInTheEnvironment"
toFieldPath: "spec.forProvider.someFieldFromTheEnvironment"
# - Resource -> Env
- type: ToEnvironmentFieldPath
fromFieldPath: "status.someOtherFieldInTheResource"
toFieldPath: "someOtherFieldInTheEnvironment"
This function just merges selected EnvironmentConfigs
into the Context
at a well-known key, apiextensions.crossplane.io/environment
, therefore any Context
-aware function can access it.
For example, using function-go-templating:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: foo
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: XR
mode: Pipeline
pipeline:
- step: environmentConfigs
functionRef:
name: function-environment-configs
input:
apiVersion: environmentconfigs.fn.crossplane.io/v1beta1
kind: Input
spec:
environmentConfigs:
- type: Reference
ref:
name: example-config
# the environment is be passed to the next function in the pipeline
# as part of the context
- step: go-templating
functionRef:
name: function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
kind: GoTemplate
source: Inline
inline:
template: |
---
apiVersion: example.crossplane.io/v1
kind: XR
status:
fromEnv: {{ index .context "apiextensions.crossplane.io/environment" "complex" "c" "d" }}
This function uses Go, Docker, and the Crossplane CLI to build functions.
# Run code generation - see input/generate.go
$ go generate ./...
# Run tests - see fn_test.go
$ go test ./...
# Build the function's runtime image - see Dockerfile
$ docker build . --tag=runtime
# Build a function package - see package/crossplane.yaml
$ crossplane xpkg build -f package --embed-runtime-image=runtime