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