6 min read | by Jordi Prats
Following up on the previous crossplane example on Composition: creating a SecurityGroup and a SecurityGroupRule using a Composition we are now going to push information from one of the objects into the Composition and then push it back to the other resource:
The composistion is going to create a SecurityGroup and push it's ID up to the Composite's status. Once the ID is on the Composition, this will push this ID into the SecurityGroupRule to set the SecurityGroup's ID to which we want to create the rule
To achieve this, first we will have to tell the CompositeResourceDefinition that we are going to have the status.sgId field that will hold a string:
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: sgsallowoutgoing.pet2cattle.com
spec:
group: pet2cattle.com
names:
kind: SGAllowOutgoing
plural: sgsallowoutgoing
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
parameters:
type: object
properties:
region:
type: string
required:
- region
required:
- parameters
status:
type: object
properties:
sgId:
description: SecurityGroup ID
type: string
Once we have this sort of variable available, we are going to use the patches attribute to copy from the resource one of it's status fields into it. To do so we are going to use a ToCompositeFieldPath patch to copy it from status.atProvider.id (that's the SecurityGroup resource) to the status.sgId (that's the Composite resource we are building):
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: sgsallowoutgoing
labels:
crossplane.io/xrd: sgsallowoutgoing.pet2cattle.com
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: pet2cattle.com/v1alpha1
kind: SGAllowOutgoing
resources:
- name: sg
base:
apiVersion: ec2.aws.jet.crossplane.io/v1alpha2
kind: SecurityGroup
spec:
forProvider:
description: 'xplane SG test'
vpcId: 'vpc-1234abcd'
providerConfigRef:
name: 'aws-jetprovider-config'
patches:
- type: FromCompositeFieldPath
fromFieldPath: metadata.name
toFieldPath: spec.forProvider.name
- type: FromCompositeFieldPath
fromFieldPath: metadata.name
toFieldPath: metadata.annotations.crossplane.io/external-name
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.region
toFieldPath: spec.forProvider.region
- type: ToCompositeFieldPath
fromFieldPath: status.atProvider.id
toFieldPath: status.sgId
(...)
With this we are going to be able to retrieve the SecurityGroup's ID from the SGAllowOutgoing resource (the Composition) but we want is to be able to define to set it into the SecurityGroupRule. To do so we can use the FromCompositeFieldPath patch to push it into it:
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: sgsallowoutgoing
labels:
crossplane.io/xrd: sgsallowoutgoing.pet2cattle.com
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: pet2cattle.com/v1alpha1
kind: SGAllowOutgoing
resources:
(...)
- name: sg-egress
base:
apiVersion: ec2.aws.jet.crossplane.io/v1alpha2
kind: SecurityGroupRule
spec:
forProvider:
fromPort: 0
toPort: 0
protocol: "-1"
type: 'egress'
cidrBlocks:
- '0.0.0.0/0'
providerConfigRef:
name: 'aws-jetprovider-config'
patches:
- type: FromCompositeFieldPath
fromFieldPath: spec.parameters.region
toFieldPath: spec.forProvider.region
- type: FromCompositeFieldPath
fromFieldPath: status.sgId
toFieldPath: spec.forProvider.securityGroupId
To sum it up, the changes we made to the Composition are the following:
We have removed:
We have added:
An actual patch would look like this:
--- composition/composition.yaml 2022-03-14 23:48:19.246227739 +0100
+++ ../crossplane-composition-publish-status/composition.yaml 2022-03-15 18:19:47.375130779 +0100
@@ -28,11 +28,11 @@
fromFieldPath: metadata.name
toFieldPath: metadata.annotations.crossplane.io/external-name
- type: FromCompositeFieldPath
- fromFieldPath: metadata.name
- toFieldPath: metadata.labels.sgname
- - type: FromCompositeFieldPath
fromFieldPath: spec.parameters.region
toFieldPath: spec.forProvider.region
+ - type: ToCompositeFieldPath
+ fromFieldPath: status.atProvider.id
+ toFieldPath: status.sgId
- name: sg-egress
base:
apiVersion: ec2.aws.jet.crossplane.io/v1alpha2
@@ -52,5 +52,5 @@
fromFieldPath: spec.parameters.region
toFieldPath: spec.forProvider.region
- type: FromCompositeFieldPath
- fromFieldPath: metadata.name
- toFieldPath: spec.forProvider.securityGroupIdSelector.matchLabels.sgname
\ No newline at end of file
+ fromFieldPath: status.sgId
+ toFieldPath: spec.forProvider.securityGroupId
\ No newline at end of file
If we create one instance of this composition:
$ kubectl apply -f instances/sgone.yaml
sgallowoutgoing.pet2cattle.com/sgone created
We can check how the SecurityGroup ID is now part of it's status:
$ kubectl describe sgallowoutgoing.pet2cattle.com/sgone
Name: sgone
Namespace:
Labels: crossplane.io/composite=sgone
Annotations: <none>
API Version: pet2cattle.com/v1alpha1
Kind: SGAllowOutgoing
Metadata:
(...)
Spec:
Composition Ref:
Name: sgsallowoutgoing
Composition Update Policy: Automatic
Parameters:
Region: us-west-2
Resource Refs:
API Version: ec2.aws.jet.crossplane.io/v1alpha2
Kind: SecurityGroup
Name: sgone-5bvfc
API Version: ec2.aws.jet.crossplane.io/v1alpha2
Kind: SecurityGroupRule
Name: sgone-grd7m
Write Connection Secret To Ref:
Name: 203e831b-a64d-4d5a-9757-6f17a0c32940
Namespace: crossplane-system
Status:
Conditions:
Last Transition Time: 2022-03-15T23:26:00Z
Reason: Creating
Status: False
Type: Ready
Connection Details:
Last Published Time: 2022-03-15T23:26:00Z
Sg Id: sg-3c426074e66289c02
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal PublishConnectionSecret 40s defined/compositeresourcedefinition.apiextensions.crossplane.io Successfully published connection details
Normal SelectComposition 10s (x7 over 40s) defined/compositeresourcedefinition.apiextensions.crossplane.io Successfully selected composition
Normal ComposeResources 10s (x7 over 40s) defined/compositeresourcedefinition.apiextensions.crossplane.io Successfully composed resources
If we check the SecurityGroupRule resource we will see how it was not possible to create the resource at first, since the SecurityGroup ID wasn't available yet. However, as soon as this ID propagated up to the Composite and then down to the SecurityGroupRule it could reconcile the resource by creating the rule on it:
$ kubectl describe SecurityGroupRule sgone-grd7m
Name: sgone-grd7m
Namespace:
Labels: crossplane.io/claim-name=
crossplane.io/claim-namespace=
crossplane.io/composite=sgone
Annotations: crossplane.io/composition-resource-name: sg-egress
crossplane.io/external-create-pending: 2022-03-15T23:26:36Z
crossplane.io/external-create-succeeded: 2022-03-15T23:26:42Z
crossplane.io/external-name: sgrule-1606513619
terrajet.crossplane.io/provider-meta: {"schema_version":"2"}
API Version: ec2.aws.jet.crossplane.io/v1alpha2
Kind: SecurityGroupRule
Metadata:
(...)
Spec:
Deletion Policy: Delete
For Provider:
Cidr Blocks:
0.0.0.0/0
From Port: 0
Protocol: -1
Region: us-west-2
Security Group Id: sg-3c426074e66289c02
To Port: 0
Type: egress
Provider Config Ref:
Name: aws-jetprovider-config
Status:
At Provider:
Id: sgrule-1606513619
Conditions:
Last Transition Time: 2022-03-15T23:26:42Z
Reason: ReconcileSuccess
Status: True
Type: Synced
Last Transition Time: 2022-03-15T23:26:46Z
Reason: Available
Status: True
Type: Ready
Last Transition Time: 2022-03-15T23:26:46Z
Reason: Finished
Status: True
Type: AsyncOperation
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning CannotObserveExternalResource 27s (x12 over 55s) managed/ec2.aws.jet.crossplane.io/v1alpha2, kind=securitygrouprule cannot run refresh: refresh failed: Missing required argument: The argument "security_group_id" is required, but no definition was found.: File name: main.tf.json
Normal CreatedExternalResource 17s managed/ec2.aws.jet.crossplane.io/v1alpha2, kind=securitygrouprule Successfully requested creation of external resource
All the YAML definitions on this blog post have been uploaded the the repository pet2cattle/crossplane-composition-publish-status on GitHub
Posted on 22/03/2022