In the Cloud Foundry(CF) architecture, two of the CF components have databases, one is Cloud Controller(CC), the other is OAuth2 Server (UAA). The reliability of these two databases is extremely important to the success of the CF system.

PostgreSQL has become a very popular open source relational database for many enterprises. Amazon RDS provide PostgreSQL deployments in an efficient way. It can also provide you with multiple AZ PostgreSQL deployment and read replicas. In addition, you do not need to worry about backup and recovery. Hence we use RDS PostgreSQL for UAADB and CCDB in CF.

This blog will show you step by step how to use AWS RDS PostgreSQL for UAADB and CCDB in Cloud Foundry.

Create RDS PostgreSQL Instance

You can go to your AWS Console and click Services on the top bar, then select RDS from the dropdown menu. Click Launch a DB Instance, then it will ask you to select an engine, pick PostgreSQL and then choose either Dev/Test or Production. You can just then follow the rest of steps to configure your database. We recommend you enable multiple AZ deployment for your production environment.

Another way to create AWS RDS PostgreSQL instance is using terraform. HashiCorp's website has a very good documentation about How to create RDS DB Instance.

Create UAADB and CCDB

Next step is creating databases you need. First lets connect to postgres database by running the following command:

psql postgres://user_name:your_password@your_rds_instance_endpoint:5432/postgres  

Then you can run create database uaadb and create database ccdb to create two databases.

Configure uaadb and ccdb in the CF manifest

Now that we have RDS instance and ccdb and uaadb databases created inside it, lets refer to them in the manifest. Note that db_scheme setting for ccdb and uaadb is different even both of them are using PostgreSQL database.

  ccdb:
    address: your RDS PostgreSQL Instance endpoint
    databases:
    - citext: true
      name: ccdb
      tag: cc
    db_scheme: postgres
    port: 5432
  uaadb:
    address: your RDS PostgreSQL Instance endpoint
    databases:
    - citext: true
      name: uaadb
      tag: uaa
    db_scheme: postgresql
    port: 5432

Deploy

Assume you already have other parts of the CF manifest configured correctly, now it is time to deploy! Things usually do not work as you expected. That is life! There is the error you may see:

  Failed updating job api_worker_z1 > api_worker_z1/0 (4655908b-35b7-4b58-b87e-99dd25e90b97) (canary): 'api_worker_z1/0 (4655908b-35b7-4b58-b87e-99dd25e90b97)' is not running after update. Review logs for failed jobs: cloud_controller_worker_1 (00:03:15)
  Failed updating job clock_global > clock_global/0 (f9114f3d-f8c8-4e71-8679-340b09fb3260) (canary): 'clock_global/0 (f9114f3d-f8c8-4e71-8679-340b09fb3260)' is not running after update. Review logs for failed jobs: cloud_controller_clock (00:03:24)
  Failed updating job api_worker_z2 > api_worker_z2/0 (3b137215-5cd3-4782-9e2d-97cd95315a44) (canary): 'api_worker_z2/0 (3b137215-5cd3-4782-9e2d-97cd95315a44)' is not running after update. Review logs for failed jobs: cloud_controller_worker_1 (00:03:30)
  Failed updating job api_z1 > api_z1/0 (f9cb05dd-4a68-49f4-aa79-0bbb212c8c27) (canary): 'api_z1/0 (f9cb05dd-4a68-49f4-aa79-0bbb212c8c27)' is not running after update. Review logs for failed jobs: cloud_controller_ng, cloud_controller_worker_local_1, cloud_controller_worker_local_2, nginx_cc, cloud_controller_migration (00:04:21)
  Done updating job uaa_z2 > uaa_z2/0 (d3fa0320-dbe1-4c21-8f98-832c66f9009a) (canary) (00:04:23)
  Failed updating job api_z2 > api_z2/0 (ccd5a63d-f5d0-4303-9c94-3eebbdcc77d1) (canary): 'api_z2/0 (ccd5a63d-f5d0-4303-9c94-3eebbdcc77d1)' is not running after update. Review logs for failed jobs: cloud_controller_ng, cloud_controller_worker_local_1, cloud_controller_worker_local_2, nginx_cc, cloud_controller_migration (00:05:28)

Error 400007: 'api_worker_z1/0 (4655908b-35b7-4b58-b87e-99dd25e90b97)' is not running after update. Review logs for failed jobs: cloud_controller_worker_1

You can run bosh ssh api_z1 to connect to the api VM in z1, check the /var/vcap/sys/log/cloud_controller_migration/cloud_controller_migration_ctl.err.log file. You may see the following error:

[2016-08-30 05:01:31+0000] ------------ STARTING cloud_controller_migration_ctl at Tue Aug 30 05:01:31 UTC 2016 --------------
[2016-08-30 05:01:43+0000] rake aborted!
[2016-08-30 05:01:43+0000] Sequel::DatabaseError: PG::UndefinedObject: ERROR:  type citext does not exist
[2016-08-30 05:01:43+0000] LINE 1: ...IMESTAMP NOT NULL, updated_at Timestamp, name CIText NOT...
[2016-08-30 05:01:43+0000]                                                              ^
[2016-08-30 05:01:43+0000] PG::UndefinedObject: ERROR:  type citext does not exist
[2016-08-30 05:01:43+0000] LINE 1: ...IMESTAMP NOT NULL, updated_at Timestamp, name CIText NOT...
[2016-08-30 05:01:43+0000]                                                              ^
[2016-08-30 05:01:43+0000] Tasks: TOP => db:migrate
[2016-08-30 05:01:43+0000] (See full trace by running task with --trace)

It complains that citext does not exist. In this case, you need to add citext extension. First you can connect to the ccdb by typing \c ccdb if you are still connected with postgres database. If not, you can run the following psql command to connect with ccdb,and then you run create extension citext after you connect the ccdb successfully.

psql postgres://user_name:your_password@your_rds_instance_endpoint:5432/ccdb  

The similar error may occur for uaadb and you can create the same extension to fix the problem.

Now Deploy your CF again and good luck!