4 min read | by Jordi Prats
Crossplane is an open source Kubernetes add-on that lets you create cloud resources using Kubernetes objects (CRDs). It's installation it's straightforward, but once we have it installed the key it to properly configure it's providers. Here we are going to use the crossplane's native AWS provider
First, we need to install crossplane, we can do so using helm
kubectl create namespace crossplane-system
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
helm install crossplane --namespace crossplane-system crossplane-stable/crossplane
Then we'll have to create an IRSA role with a trust relationship for the entire crossplane namespace (so we can have multiple providers). That would look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789876:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/1B45E2E0B2D55D1E1BC9FA13D02A31CD"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"oidc.eks.eu-west-1.amazonaws.com/id/BC91B45B2E0D1F02AD55D1EA13DE231C:sub": "system:serviceaccount:crossplane-system:*"
}
}
}
]
}
Once we have the role ready, we'll need it's ARN to configure the AWS provider using IRSA we'll have to create the following objects (please notice I'm setting an specific version):
apiVersion: pkg.crossplane.io/v1alpha1
kind: ControllerConfig
metadata:
name: aws-config
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789876:role/crossplane
spec:
podSecurityContext:
fsGroup: 2000
---
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-aws
spec:
package: crossplane/provider-aws:v0.24.1
controllerConfigRef:
name: aws-config
Once we can see the provider's Pod running:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
crossplane-fbf66ff7c7-t8t6n 1/1 Running 0 3d3h
crossplane-rbac-manager-4bc757b79-nz7bb 1/1 Running 0 3d3h
provider-aws-f78664a342f1-575cccfd-shnxc 1/1 Running 0 1m47s
We can now also add the following object:
apiVersion: aws.crossplane.io/v1beta1
kind: ProviderConfig
metadata:
name: aws-provider
spec:
credentials:
source: InjectedIdentity
Once applied we can check that it will have create a ServiceAccount named after the provider. We can check that it has the eks.amazonaws.com/role-arn annotations to be able to use IRSA:
$ kubectl get sa
NAME SECRETS AGE
crossplane 1 16d
default 1 16d
provider-aws-f78664a342f1 1 19m
rbac-manager 1 16d
$ kubectl get sa provider-aws-f78664a342f1 -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789876:role/crossplane
(...)
With these objects in place we have now the AWS provider ready to be used. To test it out we can create an S3 bucket using the object Bucket belonging to the s3.aws.crossplane.io/v1beta1 API.
Since we might have several AWS accounts configured on the cluster, providerConfigRef must match with the name of the ProviderConfig object we have just created; if not specified it looks for an ProviderConfig object named default):
apiVersion: s3.aws.crossplane.io/v1beta1
kind: Bucket
metadata:
name: pet2cattle-xplane-test
spec:
providerConfigRef:
name: aws-provider
forProvider:
locationConstraint: 'eu-west-1'
acl: private
Once we apply the object we can check it's events and status (for example with kubectl describe) to check whether it have been created:
$ kubectl apply -f s3bucket.yaml
bucket.s3.aws.crossplane.io/xplane-native-aws created
$ kubectl describe bucket.s3.aws.crossplane.io/xplane-native-aws
Name: xplane-native-aws
Namespace:
Labels: <none>
Annotations: crossplane.io/external-create-pending: 2022-02-25T23:24:54Z
crossplane.io/external-create-succeeded: 2022-02-25T23:24:55Z
crossplane.io/external-name: xplane-native-aws
API Version: s3.aws.crossplane.io/v1beta1
Kind: Bucket
Metadata:
(...)
Spec:
Deletion Policy: Delete
For Provider:
Acl: private
Location Constraint: eu-west-1
Payment Configuration:
Payer: BucketOwner
Provider Config Ref:
Name: aws-provider
Status:
At Provider:
Arn: arn:aws:s3:::xplane-native-aws
Conditions:
Last Transition Time: 2022-02-25T23:24:55Z
Reason: Available
Status: True
Type: Ready
Last Transition Time: 2022-02-25T23:24:55Z
Reason: ReconcileSuccess
Status: True
Type: Synced
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CreatedExternalResource 45s managed/bucket.s3.aws.crossplane.io Successfully requested creation of external resource
Finally, we can check it with the AWS Console or AWS cli to verify that the bucket have been created:
$ aws s3 ls | grep xpl
2022-02-25 23:25:57 xplane-native-aws
Posted on 28/02/2022