DEV Community

Cover image for Getting Started with ACK RDS Controller
Shardul Srivastava for AWS Community Builders

Posted on • Edited on • Originally published at shardul.dev

Getting Started with ACK RDS Controller

ACK controller for RDS is a Kubernetes Controller for provisioning RDS instances in a kubernetes native way.

ACK controller for RDS supports creating these database engines:

  1. Amazon Aurora (MySQL & PostgreSQL)
  2. Amazon RDS for PostgreSQL
  3. Amazon RDS for MySQL
  4. Amazon RDS for MariaDB
  5. Amazon RDS for Oracle
  6. Amazon RDS for SQL Server

Install ACK Controller for RDS

Let's start by setting up an EKS cluster. ACK Controller for RDS requires AmazonRDSFullAccess to create and manage RDS instances.
We will also create a service account ack-rds-controller for ACK Controller for RDS and attach AmazonRDSFullAccess IAM permissions to this service account with the help of IRSA.

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: ack-cluster
  region: eu-west-1
  version: "1.22"
iam:
  withOIDC: true
  serviceAccounts:
    - metadata:
        # Service account used by rds-controller https://github.com/aws-controllers-k8s/rds-controller/blob/main/helm/values.yaml#L81
        name: ack-rds-controller
        namespace: ack-system
      # https://github.com/aws-controllers-k8s/rds-controller/blob/main/config/iam/recommended-policy-arn
      attachPolicyARNs: 
      - "arn:aws:iam::aws:policy/AmazonRDSFullAccess"

managedNodeGroups:
  - name: managed-ng-1
    minSize: 1
    maxSize: 10
    desiredCapacity: 1
    instanceType: t3.large
    amiFamily: AmazonLinux2
Enter fullscreen mode Exit fullscreen mode
eksctl create cluster -f ack-cluster.yaml
Enter fullscreen mode Exit fullscreen mode

Once the cluster is created, install the ACK Controller for RDS using Helm chart. ACK Controller for RDS helm charts are stored in the public ECR repository.

Note: Check the latest version of the helm chart here

Authenticate to the ECR repo using your AWS credentials :

 aws ecr-public get-login-password --region us-east-1 | helm registry login --username AWS --password-stdin public.ecr.aws
 Login Succeeded
Enter fullscreen mode Exit fullscreen mode

Once you're authenticated, install ACK Controller for RDS in the ack-system namespace :

 helm upgrade \
    --install \
    --create-namespace \
    ack-rds \
    -n ack-system \
    oci://public.ecr.aws/aws-controllers-k8s/rds-chart \
    --version=v0.1.1 \
    --set=aws.region=eu-west-1 \
    --set=serviceAccount.create=false \
    --set=log.level=debug
Enter fullscreen mode Exit fullscreen mode

During installation, we are setting these values in the Helm chart:

  1. aws.region - AWS Region for API Calls.
  2. serviceAccount.create - Setting this to false, since serviceAccount is created by eksctl during cluster creation above.
  3. log.level - Setting this to debug to see detailed logs.

ACK controller for RDS installs several CRDs that allow you to provision RDS instances and related components:

  1. GlobalCluster - Custom resource to create Aurora Global cluster.
  2. DBCluster - Custom resource to create Amazon Aurora DB Cluster.
  3. DBInstance - Custom resource to create Amazon RDS DB Instances.
  4. DBClusterParameterGroup - Custom resource to create DB cluster parameter groups.
  5. DBParameterGroup - Custom resource to create DB parameter groups.
  6. DBProxy - Custom resource to create Amazon RDS Proxy
  7. DBSubnetGroup - Custom resource to create DB Subnet Group.

Note:. Refer here for the reference of these CRDs.

Check ACK controller for RDS logs in cluster:

kubectl logs -f -l app.kubernetes.io/instance=ack-rds
Enter fullscreen mode Exit fullscreen mode

Create Autora PostgreSQL Cluster with RDS Controller

To create an Aurora PostgreSQL Cluster with ACK controller for RDS, we have to first create a DB Subnet Group using DBSubnetGroup, then create a Aurora Cluster using DBCluster and add two Aurora Database instances in the cluster using DBInstance.

  1. Create a DB Subnet Group test-ack-subnetgroup with all the subnets that are part of the VPC created by eksctl or use your existing subnets:

    apiVersion: rds.services.k8s.aws/v1alpha1
    kind: DBSubnetGroup
    metadata:
      name: "test-ack-subnetgroup"
    spec:
      name: "test-ack-subnetgroup"
      description: "Test ACK Subnet Group"
      subnetIDs:
        - "subnet-011e4c822231b65fa"
        - "subnet-001ce16b9b7c3578f"
        - "subnet-0a90579d9b066ecf7"
        - "subnet-00e6d2e90ea132c8b"
        - "subnet-0fbc22e542749c98c"
        - "subnet-080c0b1ed39b0aa91"
      tags:
        - key: "created-by"
          value: "ack-rds"
    

    Note: To get all the subnets created by eksctl, run command:

    eksctl get cluster ack-cluster -o json| jq -r '.[0].ResourcesVpcConfig.SubnetIds' 
    
  2. Check the status of test-ack-subnetgroup DB Subnet Group :

    kubectl get dbsubnetgroup test-ack-subnetgroup -ojson| jq -r '.status.subnetGroupStatus'
    Complete
    

    if it returns Complete, then DB Subnet group is successfully created.

  3. Create a secret to store the password of the master user :

    kubectl create secret generic "test-ack-master-password" --from-literal=DATABASE_PASSWORD="mypassword"
    secret/test-ack-master-password created
    
  4. Create an Aurora DB Cluster test-ack-aurora-cluster using DBCluster :

    apiVersion: rds.services.k8s.aws/v1alpha1
    kind: DBCluster
    metadata:
      name: "test-ack-aurora-cluster"
    spec:
      engine: aurora-postgresql
      engineVersion: "14.4"
      engineMode: provisioned
      dbClusterIdentifier: "test-ack-aurora-cluster"
      databaseName: test-ack
      dbSubnetGroupName: test-ack-subnetgroup
      deletionProtection: true
      masterUsername: "test"
      masterUserPassword:
        namespace: "default"
        name: "test-ack-master-password"
        key: "DATABASE_PASSWORD"
      storageEncrypted: true
      enableCloudwatchLogsExports:
        - postgresql
      backupRetentionPeriod: 14
      copyTagsToSnapshot: true
      preferredBackupWindow: 00:00-01:59
      preferredMaintenanceWindow: sat:02:00-sat:04:00
    
    
  5. Once created, check the status of DBCluster resource test-ack-aurora-cluster:

    kubectl describe DBCluster test-ack-aurora-cluster
    

    if the status is available then Aurora DB Cluster is successfully created.

  6. After DBCluster is successfully created, add two Aurora DB Instances test-ack-aurora-instance-1 and test-ack-aurora-instance-2 to the DB cluster using DBInstance :

    apiVersion: rds.services.k8s.aws/v1alpha1
    kind: DBInstance
    metadata:
      name: test-ack-aurora-instance-1
    spec:
      dbInstanceClass: db.t4g.medium
      dbInstanceIdentifier: test-ack-aurora-instance-1
      dbClusterIdentifier: "test-ack"
      engine: aurora-postgresql
    ---
    apiVersion: rds.services.k8s.aws/v1alpha1
    kind: DBInstance
    metadata:
      name: test-ack-aurora-instance-2
    spec:
      dbInstanceClass: db.t4g.medium
      dbInstanceIdentifier: test-ack-aurora-instance-2
      dbClusterIdentifier: "test-ack"
      engine: aurora-postgresql
    

    When these instances are available, one of them will be a Writer Instance and other one will be a Reader Instance.

  7. Check the status of DBInstance :

    kubectl describe DBInstance test-ack-aurora-instance-1
    kubectl describe DBInstance test-ack-aurora-instance-2
    

    rds-instance-status

    Status available means that DB Instances are ready to use now.

  8. Get the Writer Endpoint of the Aurora RDS cluster:

    kubectl get dbcluster test-ack-aurora-cluster -ojson| jq -r '.status.endpoint'
    
    test-ack-aurora-cluster.cluster-cncphmukmdde.eu-west-1.rds.amazonaws.com
    
  9. Get the Reader Endpoint of the Aurora RDS cluster:

    kubectl get dbcluster test-ack-aurora-cluster -ojson| jq -r '.status.readerEndpoint'
    
    test-ack-aurora-cluster.cluster-ro-cncphmukmdde.eu-west-1.rds.amazonaws.com
    

When you have the Aurora DB Cluster provisioned, you would want to extract values such as Reader Endpoint and Writer Endpoint and configure them in the application to connect to the cluster.

ACK controller for RDS provides a way to import these values directly from the DBCluster or DBInstance resource to a desired Configmap or Secret.

Export the Database Details in a Configmap

FieldExport CRD allows you to export any spec or status field from a DBCluster or DBInstance resource into a ConfigMap.

  1. Create an empty ConfigMap :

    kubectl create cm ack-cluster-config
    configmap/ack-cluster-config created
    
  2. Create a FieldExport to import the value of .status.endpoint from test-ack-aurora-cluster DBCluster resource to the ConfigMap ack-cluster-config :

    apiVersion: services.k8s.aws/v1alpha1
    kind: FieldExport
    metadata:
      name: ack-cm-field-export
    spec:
      from:
        resource:
          group: rds.services.k8s.aws
          kind: DBCluster
          name: test-ack-aurora-cluster
        path: ".status.endpoint"
      to:
        kind: configmap
        name: ack-cluster-config
        key: DATABASE_HOST
    
  3. Inspect the values of ConfigMap ack-cluster-config

    kubectl get cm ack-cluster-config -ojson|jq -r '.data'
    

    ack-field-export-cm

Export the Database Details in a Secret

FieldExport CRD allows you to export any spec or status field from a DBCluster or DBInstance into a Secret.

  1. Create an empty Secret :

    kubectl create secret generic ack-cluster-secret
    secret/ack-cluster-secret created
    
  2. Create a FieldExport to import the value of .status.endpoint from test-ack-aurora-cluster DBCluster resource to the Secret ack-cluster-secret :

    apiVersion: services.k8s.aws/v1alpha1
    kind: FieldExport
    metadata:
      name: ack-secret-field-export
    spec:
      from:
        resource:
          group: rds.services.k8s.aws
          kind: DBCluster
          name: test-ack-aurora-cluster
        path: ".status.endpoint"
      to:
        kind: secret
        name: ack-cluster-secret
        key: DATABASE_HOST
    
  3. Inspect the values of Secret ack-cluster-secret

    kubectl view-secret ack-cluster-secret --all
    

    ack-field-export-secret

    Note: view-secret is a kubectl plugin, check out my blog on how to use this plugin.

📌 FieldExport and ACK resource should be in the same namespace.

Important - Clean up

To clean up the clusters, first disable the delete protection by setting .spec.deletionProtection to false for the test-ack-aurora-cluster DBCluster resource:

kubectl apply -f test-ack-aurora-cluster.yaml

dbcluster.rds.services.k8s.aws/test-ack-aurora-cluster configured
Enter fullscreen mode Exit fullscreen mode

Now, you can proceed to delete the instances first and then cluster:

kubectl delete -f test-ack-aurora-instance.yaml
kubectl delete -f test-ack-aurora-cluster.yaml
Enter fullscreen mode Exit fullscreen mode

Top comments (0)