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