About: I'm DevOps engineer, I like to share what I'm learning along the way!
Joined:
Nov 1, 2023
Hands-on Lab #1: Creating Crossplane v1.20 Configuration Packages for Keycloak on AWS
Publish Date: Jul 9 '25
2 0
What are Crossplane Configuration Packages?
Crossplane Configuration Packages are the high level of infrastructure reusability in the Crossplane ecosystem. Think of Crossplane Configuration Packages like Docker images for infrastructure. The configurations allow generated distributable packages that can be deployed consistently any environments.
So, for create configurations package is necessary create compositions and compositions resource definitions (xrd), if you have any doubts about these concepts, check this blog.
This a repository for crossplane configuration package keycloak in AWS
Project Overview
This is a Crossplane-based infrastructure-as-code project that deploys a comprehensive AWS EKS cluster with associated infrastructure using KCL. The project creates a multi-AZ infrastructure including VPC, subnets, EKS cluster, RDS database, and various controllers.
Architecture
Core Components
Crossplane Configuration: Manages AWS infrastructure through Crossplane providers
KCL Functions: KCL for infrastructure composition
AWS Resources: Creates VPC, EKS cluster, RDS, security groups, IAM roles, and networking components
These files are the result of the composition and crd created using kcl, any changes should be made from the .k files.
kcl run resources/compositions/infra/crd.k > configuration/apis/crd.yaml
kcl run resources/compositions/infra/composition.k > configuration/apis/composition.yaml
Install-configuration.yaml allow install the configuration package in the cluster using the secret for authenticated and pull the OCI package configuration.
➜ kubectl apply -f install-configuration.yaml
configuration.pkg.crossplane.io/segoja7-configuration-keycloack created
Step 11.
Apply Claim is the end step, basically is create all resources abstracted and wait for her (status = True) for make probes.
➜ kubectl apply -f resources/examples/claim.yaml
multiazinfraclaim.segoja7.example/infra-claim created
Step 12.
Verify all resources created.
➜ kubectl get configuration.pkg
NAME INSTALLED HEALTHY PACKAGE AGE
segoja7-configuration-keycloack True True ghcr.io/segoja7/segoja7-configuration-keycloack:v1.0.0 3h15m
➜ kubectl get compositions
NAME XR-KIND XR-APIVERSION AGE
infra-composition XMultiAzInfra segoja7.example/v1alpha1 3h15m
➜ kubectl get managed
Warning: BucketPolicy has been deprecated. Use spec.forProvider.policy in Bucket instead.
NAME READY SYNCED AGE
dbsubnetgroup.database.aws.crossplane.io/backstage-subnet-group-idp True True 173m
NAME READY SYNCED STATE ENGINE VERSION AGE
rdsinstance.database.aws.crossplane.io/storedata-rds-idp True True available postgres 17.4 173m
NAME READY SYNCED ID IP AGE
address.ec2.aws.crossplane.io/eip-idp True True eipalloc-084d47829c9883e7f 54.146.16.193 173m
NAME READY SYNCED ID VPC AGE
internetgateway.ec2.aws.crossplane.io/igw-idp True True igw-0070a8d25d170cd90 vpc-0194aa72b31ff1d10 173m
NAME READY SYNCED ID VPC SUBNET ALLOCATION ID AGE
natgateway.ec2.aws.crossplane.io/ng-idp True True nat-023fe7472e37f1f37 vpc-0194aa72b31ff1d10 subnet-026e050150dc85f90 eipalloc-084d47829c9883e7f 173m
NAME READY SYNCED ID VPC AGE
routetable.ec2.aws.crossplane.io/rt-private-idp True True rtb-0b62322c0b2315bd6 vpc-0194aa72b31ff1d10 173m
routetable.ec2.aws.crossplane.io/rt-public-idp True True rtb-0aedc83d1aed5cdca vpc-0194aa72b31ff1d10 173m
NAME READY SYNCED ID VPC AGE
securitygroup.ec2.aws.crossplane.io/backstage-rds-sg-idp True True sg-071aed1f2a6d58405 vpc-0194aa72b31ff1d10 173m
NAME READY SYNCED ID VPC CIDR AGE
subnet.ec2.aws.crossplane.io/app-private-subnet-az1-idp True True subnet-0a5e735e87bccc368 vpc-0194aa72b31ff1d10 172.16.3.0/24 173m
subnet.ec2.aws.crossplane.io/app-private-subnet-az2-idp True True subnet-09b23d56234e463fe vpc-0194aa72b31ff1d10 172.16.4.0/24 173m
subnet.ec2.aws.crossplane.io/data-private-subnet-az1-idp True True subnet-07be7b51481002165 vpc-0194aa72b31ff1d10 172.16.1.0/24 173m
subnet.ec2.aws.crossplane.io/data-private-subnet-az2-idp True True subnet-0407ee651c0c58509 vpc-0194aa72b31ff1d10 172.16.2.0/24 173m
subnet.ec2.aws.crossplane.io/public-subnet-az1-idp True True subnet-026e050150dc85f90 vpc-0194aa72b31ff1d10 172.16.5.0/24 173m
subnet.ec2.aws.crossplane.io/public-subnet-az2-idp True True subnet-06404627395c08051 vpc-0194aa72b31ff1d10 172.16.6.0/24 173m
NAME READY SYNCED ID CIDR IPV6CIDR AGE
vpc.ec2.aws.crossplane.io/vpc-idp True True vpc-0194aa72b31ff1d10 172.16.0.0/16 173m
NAME READY SYNCED AGE
cluster.eks.aws.crossplane.io/cluster-idp True True 173m
NAME READY SYNCED EXTERNAL-NAME AGE
addon.eks.aws.crossplane.io/addon-coredns-idp True True arn:aws:eks:us-east-1:476114125818:addon/cluster-idp/coredns/4ccbf7c3-52dd-d8ca-bf02-ccdf71f63fae 173m
addon.eks.aws.crossplane.io/addon-eks-pod-identity-agent-idp True True arn:aws:eks:us-east-1:476114125818:addon/cluster-idp/eks-pod-identity-agent/c6cbf7c3-7123-3fae-d85d-bf0def5f9222 173m
addon.eks.aws.crossplane.io/addon-kube-proxy-idp True True arn:aws:eks:us-east-1:476114125818:addon/cluster-idp/kube-proxy/a8cbf7c3-537e-5279-faba-1c655083254d 173m
addon.eks.aws.crossplane.io/addon-vpc-cni-idp True True arn:aws:eks:us-east-1:476114125818:addon/cluster-idp/vpc-cni/40cbf7c3-7117-f2a4-05db-9fd138a12831 173m
NAME READY SYNCED CLUSTER AGE
nodegroup.eks.aws.crossplane.io/nodegroup-idp True True cluster-idp 173m
NAME CHART VERSION SYNCED READY STATE REVISION DESCRIPTION AGE
release.helm.crossplane.io/aws-load-balancer-controller-idp aws-load-balancer-controller 1.13.3 True True deployed 152 Upgrade complete 173m
release.helm.crossplane.io/cert-manageridp cert-manager v1.18.2 True False 173m
release.helm.crossplane.io/external-dnsidp external-dns 1.17.0 True True deployed 155 Upgrade complete 173m
release.helm.crossplane.io/ingress-nginxidp ingress-nginx 4.12.2 True True deployed 1 Install complete 173m
NAME READY SYNCED URL
openidconnectprovider.iam.aws.crossplane.io/eks-openid-idp True True https://oidc.eks.us-east-1.amazonaws.com/id/C9C33D016B220174E50834BA11189416
NAME ARN READY SYNCED AGE
policy.iam.aws.crossplane.io/awsloadbalancer-controller-idp arn:aws:iam::476114125818:policy/awsloadbalancer-controller-idp True True 173m
policy.iam.aws.crossplane.io/external-dns-idp arn:aws:iam::476114125818:policy/external-dns-idp True True 173m
NAME READY SYNCED ROLENAME POLICYARN AGE
rolepolicyattachment.iam.aws.crossplane.io/clusteradminrolepolicy-idp True True clusteradminrole-idp arn:aws:iam::aws:policy/AdministratorAccess 173m
rolepolicyattachment.iam.aws.crossplane.io/clusternoderolepolicy-idp-1 True True clusternoderole-idp arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy 173m
rolepolicyattachment.iam.aws.crossplane.io/clusternoderolepolicy-idp-2 True True clusternoderole-idp arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy 173m
rolepolicyattachment.iam.aws.crossplane.io/clusternoderolepolicy-idp-3 True True clusternoderole-idp arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 173m
rolepolicyattachment.iam.aws.crossplane.io/clusternoderolepolicy-idp-4 True True clusternoderole-idp arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 173m
rolepolicyattachment.iam.aws.crossplane.io/clusternoderolepolicy-idp-5 True True clusternoderole-idp arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly 173m
rolepolicyattachment.iam.aws.crossplane.io/clusterrolepolicy-idp True True clusterrole-idp arn:aws:iam::aws:policy/AmazonEKSClusterPolicy 173m
rolepolicyattachment.iam.aws.crossplane.io/sa-awsloadbalancer-controller-policy-idp True True sa-awsloadbalancer-controller-idp arn:aws:iam::476114125818:policy/awsloadbalancer-controller-idp 173m
rolepolicyattachment.iam.aws.crossplane.io/sa-cert-manager-policy-idp True True sa-cert-manager-idp arn:aws:iam::aws:policy/AmazonRoute53FullAccess 173m
rolepolicyattachment.iam.aws.crossplane.io/sa-external-dns-policy-idp True True sa-external-dns-idp arn:aws:iam::476114125818:policy/external-dns-idp 173m
NAME ARN READY SYNCED AGE
role.iam.aws.crossplane.io/clusteradminrole-idp arn:aws:iam::476114125818:role/clusteradminrole-idp True True 173m
role.iam.aws.crossplane.io/clusternoderole-idp arn:aws:iam::476114125818:role/clusternoderole-idp True True 173m
role.iam.aws.crossplane.io/clusterrole-idp arn:aws:iam::476114125818:role/clusterrole-idp True True 173m
role.iam.aws.crossplane.io/sa-awsloadbalancer-controller-idp arn:aws:iam::476114125818:role/sa-awsloadbalancer-controller-idp True True 173m
role.iam.aws.crossplane.io/sa-cert-manager-idp arn:aws:iam::476114125818:role/sa-cert-manager-idp True True 173m
role.iam.aws.crossplane.io/sa-external-dns-idp arn:aws:iam::476114125818:role/sa-external-dns-idp True True 173m
NAME KIND PROVIDERCONFIG SYNCED READY AGE
object.kubernetes.crossplane.io/cert-manager-certificate-idp Certificate provider-k8s-idp True True 173m
object.kubernetes.crossplane.io/cert-manager-clusterissuer-idp ClusterIssuer provider-k8s-idp True True 173m
object.kubernetes.crossplane.io/k8s-secret-idp Secret provider-k8s-idp True True 173m
object.kubernetes.crossplane.io/keycloak-deployment-idp Deployment provider-k8s-idp True True 173m
object.kubernetes.crossplane.io/keycloak-ingress-idp Ingress provider-k8s-idp True True 173m
object.kubernetes.crossplane.io/keycloak-service-idp Service provider-k8s-idp True True 173m
TESTING URL FOR KEYCLOAK
ROUTE 53 Configuration from external-DNS
CERTIFICATE FROM CERT-MANAGER
Step 13.
key points the claim
The claim receive the following important parameters:
hostedZoneID: Is a hostzoneID created for route53, is used for cert-manager and external-dns.
keycloakHostname: "idp.segoja7.com" You need to change this parameter for a different url.
domainNames: Is a list for create certificates and use in the keycloack deployment or ingress controller.
> Note: The configuration package create rds secret in the eks cluster, additional the password rds is the same for keycloack admin password.
CONCLUSION:
The configuration packages are:
Composable: Combine multiple cloud resources into higher-level abstractions
Reusable: Package once, deploy many times across teams and environments
Versionable: Semantic versioning for infrastructure components
Distributable: Share via OCI registries, just like container images.