This topic describes how to use Services Toolkit to allow Tanzu Application Platform workloads to consume Azure Flexible Server PostgreSQL. This particular topic makes use of Azure Service Operator v2 to manage PostgreSQL instances in Azure.
First of all, a ResourceGroup for all PSQL Instances to reside in will be created:
cat <<EOF | kubectl apply -f -
---
apiVersion: resources.azure.com/v1beta20200601
kind: ResourceGroup
metadata:
name: aso-psql
spec:
location: centralus
EOF
Next, you will create a Flexible Server PSQL Instance, a Database and a Firewall Rule in Azure as well as a Secret for credentials. In this guide you will leverage the Password
API from Carvel’s secretgen controller, which will create the Secrets
for you. However, any other mechanism to manage those secrets works too.
Change the .spec.azureName
of the FlexibleServer
resource below from “aso-psql” to something unique, using only lowercase letters, digits and hyphens. This avoids naming conflicts as Azure has a global naming namespace and this resource may already exist.
cat <<'EOF' | kubectl apply -f -
---
apiVersion: secretgen.k14s.io/v1alpha1
kind: Password
metadata:
name: aso-psql
spec:
length: 64
secretTemplate:
type: Opaque
stringData:
password: $(value)
---
apiVersion: dbforpostgresql.azure.com/v1beta20210601
kind: FlexibleServersDatabase
metadata:
name: aso-psql
spec:
azureName: mydb
owner:
name: aso-psql
charset: utf8
---
apiVersion: dbforpostgresql.azure.com/v1beta20210601
kind: FlexibleServersFirewallRule
metadata:
name: aso-psql
spec:
owner:
name: aso-psql
startIpAddress: 0.0.0.0 #! only allow traffic from azure. See https://docs.microsoft.com/en-us/azure/postgresql/single-server/concepts-firewall-rules#connecting-from-azure. Warning not for production use.
endIpAddress: 0.0.0.0
---
apiVersion: dbforpostgresql.azure.com/v1beta20210601
kind: FlexibleServer
metadata:
name: aso-psql
spec:
location: centralus
azureName: aso-psql #! CHANGE THIS NAME
owner:
name: aso-psql #! the ResourceGroup above
version: "13" #! only 11,12,13 supported
sku:
name: Standard_D4s_v3
tier: GeneralPurpose
administratorLogin: myAdmin
administratorLoginPassword:
name: aso-psql
key: password
storage:
storageSizeGB: 128
EOF
As mentioned in Creating service instances that are compatible with Tanzu Application Platform, in order for Tanzu Application Platform workloads to be able to claim and bind to services such as Azure PostgreSQL, a resource compatible with Service Binding Specification must exist in the cluster. This can take the form of either a ProvisionedService
, as defined by the specification, or a Kubernetes Secret
with some known keys, also as defined in the specification.
In this guide, you create a Kubernetes secret in the necessary format using the secretgen-controller tooling. You do so by using the SecretTemplate
API to extract values from the Azure Service Operator resources and populate a new spec-compatible secret with the values.
As part of using the SecretTemplate
API, a Kubernetes ServiceAccount
must be provided. The ServiceAccount
is used for reading the FlexibleServer
resource and the Secret
created from the Password
resource above.
Create the following Kubernetes resources on your AKS cluster:
cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: aso-psql-reader
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: aso-psql-reading
namespace: default
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
resourceNames:
- aso-psql
- apiGroups:
- dbforpostgresql.azure.com
resources:
- flexibleservers
- flexibleserversdatabases
verbs:
- get
- list
- watch
resourceNames:
- aso-psql
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: aso-psql-reader-to-read
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: aso-psql-reading
subjects:
- kind: ServiceAccount
name: aso-psql-reader
namespace: default
EOF
In combination with the ServiceAccount
just created, a SecretTemplate
can be used to declaratively create a secret that is compatible with the service binding specification. For more information on this API see the Secret Template Documentation.
Create the following Kubernetes resources on your AKS cluster:
cat <<'EOF' | kubectl apply -f -
---
apiVersion: secretgen.carvel.dev/v1alpha1
kind: SecretTemplate
metadata:
name: aso-psql-bindable
namespace: default
spec:
serviceAccountName: aso-psql-reader
inputResources:
- name: server
ref:
apiVersion: dbforpostgresql.azure.com/v1alpha1api20210601
kind: FlexibleServer
name: aso-psql
- name: db
ref:
apiVersion: dbforpostgresql.azure.com/v1alpha1api20210601
kind: FlexibleServersDatabase
name: aso-psql
- name: creds
ref:
apiVersion: v1
kind: Secret
name: "$(.server.spec.administratorLoginPassword.name)"
template:
metadata:
labels:
app.kubernetes.io/component: aso-psql
app.kubernetes.io/instance: "$(.server.metadata.name)"
services.apps.tanzu.vmware.com/class: azure-postgres
type: postgresql
stringData:
type: postgresql
port: "5432"
database: "$(.db.status.name)"
host: "$(.server.status.fullyQualifiedDomainName)"
username: "$(.server.status.administratorLogin)"
data:
password: "$(.creds.data.password)"
EOF
Firstly wait until the PostgreSQL instance is ready. This may take 5 to 10 minutes.
kubectl wait flexibleservers.dbforpostgresql.azure.com aso-psql -n default --for=condition=Ready --timeout=5m
Next, ensure a bindable Secret
was produced by the SecretTemplate
. To do so, run:
kubectl wait SecretTemplate -n default aso-psql-bindable --for=condition=ReconcileSucceeded --timeout=5m
kubectl get Secret -n default aso-psql-bindable