288 lines
9.6 KiB
Markdown
288 lines
9.6 KiB
Markdown
# Crossplane configuration
|
|
|
|
Once Crossplane [is installed](applications.md#crossplane), it must be configured for
|
|
use.
|
|
|
|
The process of configuring Crossplane includes:
|
|
|
|
1. Configuring RBAC permissions.
|
|
1. Configuring Crossplane with a cloud provider.
|
|
1. Configure managed service access.
|
|
1. Setting up Resource classes.
|
|
1. Using Auto DevOps configuration options.
|
|
1. Connect to the PostgreSQL instance.
|
|
|
|
To allow Crossplane to provision cloud services such as PostgreSQL, the cloud provider
|
|
stack must be configured with a user account. For example:
|
|
|
|
- A service account for GCP.
|
|
- An IAM user for AWS.
|
|
|
|
Important notes:
|
|
|
|
- This guide uses GCP as an example. However, the process for AWS and Azure will be
|
|
similar.
|
|
- Crossplane requires the Kubernetes cluster to be VPC native with Alias IPs enabled so
|
|
that the IP address of the pods are routable within the GCP network.
|
|
|
|
First, we need to declare some environment variables with configuration that will be used throughout this guide:
|
|
|
|
```shell
|
|
export PROJECT_ID=crossplane-playground # the GCP project where all resources reside.
|
|
export NETWORK_NAME=default # the GCP network where your GKE is provisioned.
|
|
export REGION=us-central1 # the GCP region where the GKE cluster is provisioned.
|
|
```
|
|
|
|
## Configure RBAC permissions
|
|
|
|
- For GitLab-managed clusters, RBAC is configured automatically.
|
|
|
|
- For non-GitLab managed clusters, ensure that the service account for the token provided can manage resources in the `database.crossplane.io` API group:
|
|
|
|
1. Save the following YAML as `crossplane-database-role.yaml`:
|
|
|
|
```yaml
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRole
|
|
metadata:
|
|
name: crossplane-database-role
|
|
labels:
|
|
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
|
rules:
|
|
- apiGroups:
|
|
- database.crossplane.io
|
|
resources:
|
|
- postgresqlinstances
|
|
verbs:
|
|
- get
|
|
- list
|
|
- create
|
|
- update
|
|
- delete
|
|
- patch
|
|
- watch
|
|
```
|
|
|
|
1. Apply the cluster role to the cluster:
|
|
|
|
```shell
|
|
kubectl apply -f crossplane-database-role.yaml
|
|
```
|
|
|
|
## Configure Crossplane with a cloud provider
|
|
|
|
See [Configure Your Cloud Provider Account](https://crossplane.io/docs/v0.4/cloud-providers.html)
|
|
to configure the installed cloud provider stack with a user account.
|
|
|
|
Note that the Secret and the Provider resource referencing the Secret needs to be
|
|
applied to the `gitlab-managed-apps` namespace in the guide. Make sure you change that
|
|
while following the process.
|
|
|
|
[Configure Providers](https://crossplane.io/docs/v0.4/cloud-providers.html)
|
|
|
|
## Configure Managed Service Access
|
|
|
|
We need to configure connectivity between the PostgreSQL database and the GKE cluster.
|
|
This can done by either:
|
|
|
|
- Using Crossplane as demonstrated below.
|
|
- Directly in the GCP console by
|
|
[configuring private services access](https://cloud.google.com/vpc/docs/configure-private-services-access).
|
|
Create a GlobalAddress and Connection resources:
|
|
|
|
```shell
|
|
cat > network.yaml <<EOF
|
|
---
|
|
# gitlab-ad-globaladdress defines the IP range that will be allocated for cloud services connecting to the instances in the given Network.
|
|
|
|
apiVersion: compute.gcp.crossplane.io/v1alpha3
|
|
kind: GlobalAddress
|
|
metadata:
|
|
name: gitlab-ad-globaladdress
|
|
spec:
|
|
providerRef:
|
|
name: gcp-provider
|
|
reclaimPolicy: Delete
|
|
name: gitlab-ad-globaladdress
|
|
purpose: VPC_PEERING
|
|
addressType: INTERNAL
|
|
prefixLength: 16
|
|
network: projects/$PROJECT_ID/global/networks/$NETWORK_NAME
|
|
---
|
|
# gitlab-ad-connection is what allows cloud services to use the allocated GlobalAddress for communication. Behind
|
|
# the scenes, it creates a VPC peering to the network that those service instances actually live.
|
|
|
|
apiVersion: servicenetworking.gcp.crossplane.io/v1alpha3
|
|
kind: Connection
|
|
metadata:
|
|
name: gitlab-ad-connection
|
|
spec:
|
|
providerRef:
|
|
name: gcp-provider
|
|
reclaimPolicy: Delete
|
|
parent: services/servicenetworking.googleapis.com
|
|
network: projects/$PROJECT_ID/global/networks/$NETWORK_NAME
|
|
reservedPeeringRangeRefs:
|
|
- name: gitlab-ad-globaladdress
|
|
EOF
|
|
```
|
|
|
|
Apply the settings specified in the file with the following command:
|
|
|
|
```shell
|
|
kubectl apply -f network.yaml
|
|
```
|
|
|
|
You can verify creation of the network resources with the following commands.
|
|
Verify that the status of both of these resources is ready and is synced.
|
|
|
|
```shell
|
|
kubectl describe connection.servicenetworking.gcp.crossplane.io gitlab-ad-connection
|
|
kubectl describe globaladdress.compute.gcp.crossplane.io gitlab-ad-globaladdress
|
|
```
|
|
|
|
## Setting up Resource classes
|
|
|
|
Resource classes are a way of defining a configuration for the required managed service. We will define the Postgres Resource class
|
|
|
|
- Define a gcp-postgres-standard.yaml resourceclass which contains
|
|
|
|
1. A default CloudSQLInstanceClass.
|
|
1. A CloudSQLInstanceClass with labels.
|
|
|
|
```shell
|
|
cat > gcp-postgres-standard.yaml <<EOF
|
|
apiVersion: database.gcp.crossplane.io/v1beta1
|
|
kind: CloudSQLInstanceClass
|
|
metadata:
|
|
name: cloudsqlinstancepostgresql-standard
|
|
labels:
|
|
gitlab-ad-demo: "true"
|
|
specTemplate:
|
|
writeConnectionSecretsToNamespace: gitlab-managed-apps
|
|
forProvider:
|
|
databaseVersion: POSTGRES_9_6
|
|
region: $REGION
|
|
settings:
|
|
tier: db-custom-1-3840
|
|
dataDiskType: PD_SSD
|
|
dataDiskSizeGb: 10
|
|
ipConfiguration:
|
|
privateNetwork: projects/$PROJECT_ID/global/networks/$NETWORK_NAME
|
|
# this should match the name of the provider created in the above step
|
|
providerRef:
|
|
name: gcp-provider
|
|
reclaimPolicy: Delete
|
|
---
|
|
apiVersion: database.gcp.crossplane.io/v1beta1
|
|
kind: CloudSQLInstanceClass
|
|
metadata:
|
|
name: cloudsqlinstancepostgresql-standard-default
|
|
annotations:
|
|
resourceclass.crossplane.io/is-default-class: "true"
|
|
specTemplate:
|
|
writeConnectionSecretsToNamespace: gitlab-managed-apps
|
|
forProvider:
|
|
databaseVersion: POSTGRES_9_6
|
|
region: $REGION
|
|
settings:
|
|
tier: db-custom-1-3840
|
|
dataDiskType: PD_SSD
|
|
dataDiskSizeGb: 10
|
|
ipConfiguration:
|
|
privateNetwork: projects/$PROJECT_ID/global/networks/$NETWORK_NAME
|
|
# this should match the name of the provider created in the above step
|
|
providerRef:
|
|
name: gcp-provider
|
|
reclaimPolicy: Delete
|
|
EOF
|
|
```
|
|
|
|
Apply the resource class configuration with the following command:
|
|
|
|
```shell
|
|
kubectl apply -f gcp-postgres-standard.yaml
|
|
```
|
|
|
|
Verify creation of the Resource class with the following command:
|
|
|
|
```shell
|
|
kubectl get cloudsqlinstanceclasses
|
|
```
|
|
|
|
The Resource Classes allow you to define classes of service for a managed service. We could create another `CloudSQLInstanceClass` which requests for a larger or a faster disk. It could also request for a specific version of the database.
|
|
|
|
## Auto DevOps Configuration Options
|
|
|
|
The Auto DevOps pipeline can be run with the following options:
|
|
|
|
The Environment variables, `AUTO_DEVOPS_POSTGRES_MANAGED` and `AUTO_DEVOPS_POSTGRES_MANAGED_CLASS_SELECTOR` need to be set to provision PostgreSQL using Crossplane
|
|
|
|
Alternatively, the following options can be overridden from the values for the Helm chart.
|
|
|
|
- `postgres.managed` set to true which will select a default resource class.
|
|
The resource class needs to be marked with the annotation
|
|
`resourceclass.crossplane.io/is-default-class: "true"`. The CloudSQLInstanceClass
|
|
`cloudsqlinstancepostgresql-standard-default` will be used to satisfy the claim.
|
|
|
|
- `postgres.managed` set to `true` with `postgres.managedClassSelector`
|
|
providing the resource class to choose based on labels. In this case, the
|
|
value of `postgres.managedClassSelector.matchLabels.gitlab-ad-demo="true"`
|
|
will select the CloudSQLInstance class `cloudsqlinstancepostgresql-standard`
|
|
to satisfy the claim request.
|
|
|
|
The Auto DevOps pipeline should provision a PostgresqlInstance when it runs successfully.
|
|
|
|
Verify creation of the PostgreSQL Instance.
|
|
|
|
```shell
|
|
kubectl get postgresqlinstance
|
|
```
|
|
|
|
Sample Output: The `STATUS` field of the PostgresqlInstance transitions to `BOUND` when it is successfully provisioned.
|
|
|
|
```plaintext
|
|
NAME STATUS CLASS-KIND CLASS-NAME RESOURCE-KIND RESOURCE-NAME AGE
|
|
staging-test8 Bound CloudSQLInstanceClass cloudsqlinstancepostgresql-standard CloudSQLInstance xp-ad-demo-24-staging-staging-test8-jj55c 9m
|
|
```
|
|
|
|
The endpoint of the PostgreSQL instance, and the user credentials, are present in a secret called `app-postgres` within the same project namespace.
|
|
|
|
Verify the secret with the database information is created with the following command:
|
|
|
|
```shell
|
|
kubectl describe secret app-postgres
|
|
```
|
|
|
|
Sample Output:
|
|
|
|
```plaintext
|
|
Name: app-postgres
|
|
Namespace: xp-ad-demo-24-staging
|
|
Labels: <none>
|
|
Annotations: crossplane.io/propagate-from-name: 108e460e-06c7-11ea-b907-42010a8000bd
|
|
crossplane.io/propagate-from-namespace: gitlab-managed-apps
|
|
crossplane.io/propagate-from-uid: 10c79605-06c7-11ea-b907-42010a8000bd
|
|
|
|
Type: Opaque
|
|
|
|
Data
|
|
====
|
|
privateIP: 8 bytes
|
|
publicIP: 13 bytes
|
|
serverCACertificateCert: 1272 bytes
|
|
serverCACertificateCertSerialNumber: 1 bytes
|
|
serverCACertificateCreateTime: 24 bytes
|
|
serverCACertificateExpirationTime: 24 bytes
|
|
username: 8 bytes
|
|
endpoint: 8 bytes
|
|
password: 27 bytes
|
|
serverCACertificateCommonName: 98 bytes
|
|
serverCACertificateInstance: 41 bytes
|
|
serverCACertificateSha1Fingerprint: 40 bytes
|
|
```
|
|
|
|
## Connect to the PostgreSQL instance
|
|
|
|
Follow this [GCP guide](https://cloud.google.com/sql/docs/postgres/connect-kubernetes-engine) if you
|
|
would like to connect to the newly provisioned Postgres database instance on CloudSQL.
|