Last active
July 14, 2022 13:46
-
-
Save benagricola/615a5b07e058e0a44edd442a588a99ae to your computer and use it in GitHub Desktop.
Crossplane provider-aws and provider-sql integration example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apiVersion: apiextensions.crossplane.io/v1 | |
kind: Composition | |
metadata: | |
labels: | |
res.company.io/purpose: database-instance | |
res.company.io/provider: aws | |
database.res.company.io/instance-engine: rds-postgres | |
database.res.company.io/cluster-type: standalone | |
name: database-instance-aws-rds-standalone | |
spec: | |
compositeTypeRef: | |
apiVersion: res.company.io/v1alpha1 | |
kind: CompositeDatabaseInstance | |
# Write composition secrets to crossplane-system so they're not accessible | |
# by any randomer. | |
writeConnectionSecretsToNamespace: crossplane-system | |
resources: | |
# Create an RDS Instance | |
- name: DatabaseInstance | |
base: | |
apiVersion: database.aws.crossplane.io/v1beta1 | |
kind: RDSInstance | |
metadata: | |
labels: | |
"res.company.io/identifier": rds-instance | |
spec: | |
deletionPolicy: Delete | |
forProvider: | |
engine: postgres | |
# TODO: Re-enable this when provider-sql can support a default | |
# database name. | |
# masterUsername: crossplane | |
masterUsername: postgres | |
skipFinalSnapshotBeforeDeletion: true | |
allowMajorVersionUpgrade: true | |
applyModificationsImmediately: true | |
multiAZ: true | |
engineVersion: "13.1" | |
# Pick subnet group and security group using selectors | |
dbSubnetGroupNameSelector: | |
matchLabels: | |
"res.company.io/identifier": rds-subnet-group | |
vpcSecurityGroupIDSelector: | |
matchLabels: | |
"res.company.io/identifier": rds-allow-inbound-psql-from-all | |
writeConnectionSecretToRef: | |
namespace: crossplane-system | |
connectionDetails: | |
- fromConnectionSecretKey: username | |
- fromConnectionSecretKey: password | |
- name: hostname | |
fromConnectionSecretKey: endpoint | |
- name: port | |
value: "5432" | |
patches: | |
- fromFieldPath: metadata.labels["crossplane.io/claim-name"] | |
toFieldPath: spec.writeConnectionSecretToRef.name | |
transforms: | |
- type: string | |
string: | |
fmt: "%s-admin" | |
# Create a Postgres ProviderConfig using the secret written by RDSInstance | |
- name: DatabaseProviderConfig | |
base: | |
apiVersion: postgresql.sql.crossplane.io/v1alpha1 | |
kind: ProviderConfig | |
spec: | |
credentials: | |
source: PostgreSQLConnectionSecret | |
# This is deliberate. We do not want to expose the 'root' postgres | |
# user anywhere outside of the crossplane-system namespace (aka. cluster admin) | |
# If you need to access the database, you can use provider-sql (configured with | |
# this config!) to create a new role. | |
connectionSecretRef: | |
namespace: crossplane-system | |
readinessChecks: | |
- type: None | |
patches: | |
# Generate a deterministic name for this ProviderConfig so it can be referenced | |
# by other resources. | |
# TODO: If ProviderConfigSelector is added, use labels instead :> | |
- fromFieldPath: metadata.labels["crossplane.io/claim-name"] | |
toFieldPath: metadata.name | |
transforms: | |
- type: string | |
string: | |
fmt: "%s-db" | |
- fromFieldPath: metadata.labels["crossplane.io/claim-name"] | |
toFieldPath: spec.credentials.connectionSecretRef.name | |
transforms: | |
- type: string | |
string: | |
# Note that this generates the same string as the patch to RDSInstance above. | |
# The other option is to use bidirectional patching so instead of generating | |
# the same string in 2 different places, it is generated on the RDSInstance and | |
# then patched back to the Composition, to then be patched _forward_ here. | |
fmt: "%s-admin" | |
# Create a Role IN the above RDSInstance using the ProviderConfig from above | |
- name: Role | |
base: | |
apiVersion: postgresql.sql.crossplane.io/v1alpha1 | |
kind: Role | |
metadata: | |
name: my-role | |
labels: | |
"res.company.io/identifier": application-db-role | |
spec: | |
deletionPolicy: Delete | |
forProvider: | |
privileges: | |
login: true | |
patches: | |
- fromFieldPath: metadata.labels["crossplane.io/claim-name"] | |
toFieldPath: spec.providerConfigRef.name | |
transforms: | |
- type: string | |
string: | |
# Note that this generates the same string as the patch to ProviderConfig above. | |
fmt: "%s-db" | |
# These following patches cause provider-sql to output a secret containing | |
# the username, password, endpoint and port for a new 'unprivileged' application user. | |
# These details are stored in the namespace that the claim was created in, so can be | |
# accessed directly by the user application (e.g. referenced in a provider-helm release). | |
- fromFieldPath: metadata.labels["crossplane.io/claim-namespace"] | |
toFieldPath: spec.writeConnectionSecretToRef.namespace | |
- fromFieldPath: metadata.labels["crossplane.io/claim-name"] | |
toFieldPath: spec.writeConnectionSecretToRef.name | |
transforms: | |
- type: string | |
string: | |
fmt: "%s-app-role-login" | |
# Create a database IN the above RDSInstance using the ProviderConfig from above | |
- name: Database | |
base: | |
apiVersion: postgresql.sql.crossplane.io/v1alpha1 | |
kind: Database | |
metadata: | |
name: "my-database-name" | |
spec: | |
forProvider: | |
allowConnections: true | |
connectionLimit: 200 | |
owner: my-role | |
patches: | |
- fromFieldPath: metadata.labels["crossplane.io/claim-name"] | |
toFieldPath: spec.providerConfigRef.name | |
transforms: | |
- type: string | |
string: | |
# Note that this generates the same string as the patch to ProviderConfig above. | |
fmt: "%s-db" |
The readinessChecks None on the ProviderConfig just saved my sanity after a long day of not understanding why my XR isn't ready, thank you :)
Welcome, probably should've commented why that was there 🙂
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The readinessChecks None on the ProviderConfig just saved my sanity after a long day of not understanding why my XR isn't ready, thank you :)