Install Crossplane on AWS with the native provider

crossplane kubernetes aws s3 native provider

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