Crossplane: (not) handling secrets when defining resources

crossplane kubernetes postgres RDS secret

3 min read | by Jordi Prats

The best way of handling secrets is not having to: When we rely on Crossplane to create cloud resources (such as a RDS instance) we can configure it to create a secret with it's credentials so that we don't have define any secret beforehand

As soon as the instance is created it will create a secret that we'll be able to mount on any Pod to be able to reach the database. We are going to use the following manifest to create a RDS instance:

apiVersion: database.aws.crossplane.io/v1beta1
kind: RDSInstance
metadata:
  name: xplane-demo-rds
  namespace: crossplane-system
  labels:
    vpc: vpc-12345678abc
spec:
  providerConfigRef:
    name: aws-provider
  forProvider:
    allocatedStorage: 20
    dbInstanceClass: db.t4g.micro
    dbName: xplanetest
    vpcSecurityGroupIds:
    - sg-98765431abc
    dbSubnetGroupName: awswebk3s
    deletionProtection: false
    engine: postgres
    multiAZ: false
    region: us-west-2
    masterUsername: jordi
    skipFinalSnapshotBeforeDeletion: true
  writeConnectionSecretToRef:
    name: xplane-con-secret
    namespace: crossplane-system

As soon as the instance gets created:

$ kubectl apply -f instance.yaml
rdsinstance.database.aws.crossplane.io/xplane-demo-rds created
$ kubectl get rdsinstance
NAME              READY   SYNCED   STATE      ENGINE     VERSION   AGE
xplane-demo-rds   False   True     creating   postgres   13.7      3m51s

We'll be able to find the secret that we've configured:

$ kubectl get secret xplane-con-secret
NAME                TYPE                                DATA   AGE
xplane-con-secret   connection.crossplane.io/v1alpha1   2      103s

This secret is going to contain the username and the autogenerated password to be able to connect to the database:

$ kubectl get secret xplane-con-secret -o jsonpath='{.data.username}' | base64 -d
jordi
$ kubectl get secret xplane-con-secret -o jsonpath='{.data.password}' | base64 -d
Ep77wXFEa6HSjAuWISusFlCCkZY

Once the database becomes ready we'll be able to use them to connect to it:

$ kubectl get rdsinstance
NAME              READY   SYNCED   STATE       ENGINE     VERSION   AGE
xplane-demo-rds   True    True     available   postgres   13.7      17m

On the status key we'll be able to find the address and port to connect to it:

$ kubectl get rdsinstance xplane-demo-rds -o jsonpath='{.status.atProvider.endpoint.address}'
xplane-demo-rds.8acxgtpqgvjg.us-west-2.rds.amazonaws.com
$ kubectl get rdsinstance xplane-demo-rds -o jsonpath='{.status.atProvider.endpoint.port}'
5432

Putting all the data together we can use psql to connect to the database as follows (the postgres database we want to connect to is the one we have defined on the manifest as .spec.forProvider.dbName):

# psql -h xplane-demo-rds.8acxgtpqgvjg.us-west-2.rds.amazonaws.com -p 5432 -U jordi -d xplanetest
Password for user jordi:
psql (9.2.24, server 13.7)
WARNING: psql version 9.2, server version 13.0.
         Some psql features might not work.
SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.

postgres=> \l
                                  List of databases
    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
------------+----------+----------+-------------+-------------+-----------------------
 postgres   | jordi    | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 rdsadmin   | rdsadmin | UTF8     | en_US.UTF-8 | en_US.UTF-8 | rdsadmin=CTc/rdsadmin+
            |          |          |             |             | rdstopmgr=Tc/rdsadmin
 template0  | rdsadmin | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/rdsadmin          +
            |          |          |             |             | rdsadmin=CTc/rdsadmin
 template1  | jordi    | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/jordi             +
            |          |          |             |             | jordi=CTc/jordi
 xplanetest | jordi    | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
(5 rows)

postgres->

Posted on 06/10/2022