Using Amazon RDS


Use an Amazon RDS PostgreSQL instance as the Develocity database instead of the embedded one.

Obtain the Required Permissions

You need permission to create and manage Amazon RDS instances and security groups.

The AmazonRDSFullAccess AWS managed policy grants these permissions.

Set Up an RDS Instance

Develocity is compatible with PostgreSQL versions 14 through 18. The minimum storage space required is 250 GB with 3,000 or more IOPS.

Create a Root Username and Password

Create a root username and password for the database instance, referred to below as «db-root-username» and «db-root-password», respectively. These are the credentials you will use for your database setup. Save them somewhere secure.

Create a Security Group

Before creating the database, you have to create a security group in the VPC you want to use.

In this tutorial you will use the eksctl created VPC used by your cluster.

You can use a different VPC, but you will need to make the RDS instance accessible from your cluster (for example, by peering the VPCs).

To create the Security Group, run:

CLUSTER_VPC_ID=$(
  aws eks describe-cluster \
  --name develocity \
  --query 'cluster.resourcesVpcConfig.vpcId' \
  --output text
)
aws ec2 create-security-group --group-name develocity-database \
  --description "Develocity DB security group" \
  --vpc-id ${CLUSTER_VPC_ID}

Enable Ingress

Then enable ingress to the RDS instance from your cluster for port 5432 by running:

CLUSTER_SECURITY_GROUP_ID=$(
  aws eks describe-cluster --name develocity \
  --query cluster.resourcesVpcConfig.clusterSecurityGroupId \
  --output text
)
RDS_SECURITY_GROUP_ID=$(
  aws ec2 describe-security-groups \
  --filters Name=group-name,Values=develocity-database \
  --query 'SecurityGroups[0].GroupId' \
  --output text
)
aws ec2 authorize-security-group-ingress \
  --protocol tcp --port 5432 \
  --source-group ${CLUSTER_SECURITY_GROUP_ID} \
  --group-id ${RDS_SECURITY_GROUP_ID}

Create a Subnet Group

Before creating the database, create a subnet group to define the RDS instance’s networking.

This subnet group must have subnets in two availability zones, and typically should use private subnets.

eksctl has already created private subnets you can use.

Create a subnet group containing them by running:

CLUSTER_VPC_ID=$(
  aws eks describe-cluster \
  --name develocity \
  --query 'cluster.resourcesVpcConfig.vpcId' \
  --output text
)
SUBNET_IDS=$(
  aws ec2 describe-subnets \
  --query 'Subnets[?!MapPublicIpOnLaunch].SubnetId' \
  --filters Name=vpc-id,Values=${CLUSTER_VPC_ID} \
  --output json
)
aws rds create-db-subnet-group --db-subnet-group-name develocity-database \
  --db-subnet-group-description "Develocity DB subnet group" \
  --subnet-ids ${SUBNET_IDS}
Consult RDS’s subnet group documentation for more details on subnet groups and their requirements.

Create the RDS Instance

Create the RDS instance:

RDS_SECURITY_GROUP_ID=$(
  aws ec2 describe-security-groups \
  --filters Name=group-name,Values=develocity-database \
  --query 'SecurityGroups[0].GroupId' \
  --output text
)
RDS_POSTGRES_VERSION=$(
  aws rds describe-db-engine-versions \
    --engine postgres \
    --engine-version 18 \(1)
    --default-only \
    --query 'DBEngineVersions[0].EngineVersion' \
    --output text
  )
1 The latest major version of PostgreSQL that Develocity supports.
aws rds create-db-instance \
  --engine postgres \
  --engine-version ${RDS_POSTGRES_VERSION} \
  --db-instance-identifier develocity-database \
  --db-name gradle_enterprise \
  --allocated-storage 250 \(1)
  --iops 3000 \(2)
  --db-instance-class db.m5.large \
  --db-subnet-group-name develocity-database \
  --backup-retention-period 3 \(3)
  --no-publicly-accessible \
  --vpc-security-group-ids ${RDS_SECURITY_GROUP_ID} \
  --master-username «db-root-username» \
  --master-user-password «db-root-password»
1 Install Develocity with 250GB of database storage to start with.
2 Develocity’s data volumes and database should support at least 3,000 IOPS.
3 The backup retention period, in days.

While you do not configure it here, RDS supports storage autoscaling.

Consult AWS’s database creation guide and the CLI command reference for more details on RDS instance creation.

You can view the status of your instance with:

aws rds describe-db-instances --db-instance-identifier develocity-database

Wait until the DBInstanceStatus is available.

Once available, you can see the hostname of the instance under Endpoint > Address. This is the hostname you will use to connect to the instance, subsequently referred to as «database-hostname».

Configure the RDS Instance for IAM Authentication

Develocity supports connecting to the database using IAM authentication. This step configures your RDS instance to allow IAM database authentication for every database user Develocity connects as, including the superuser. Develocity can also run without superuser access, as the Database setup with IAM database authentication section of the Kubernetes Helm chart Configuration Guide explains.

Enable IAM Database Authentication on the RDS Instance

To modify your created RDS database instance to allow IAM database authentication, run:

aws rds modify-db-instance \
  --db-instance-identifier develocity-database \
  --apply-immediately \
  --enable-iam-database-authentication

Create a Policy Allowing Database Access

The role needs permission to connect to the RDS database as the required database users, using IAM authentication. To create it, create a database-policy.json file with the following content:

CONFIGURED_REGION=$(aws configure list | grep region | awk '{print $2}')
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
DBI_RESOURCE_ID=$(
  aws rds describe-db-instances \
  --db-instance-identifier develocity-database \
  --query 'DBInstances[0].DbiResourceId' \
  --output text
)
database-policy.json
cat <<EOF > database-policy.json
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
             "rds-db:connect"
         ],
         "Resource": [
             "arn:aws:rds-db:${CONFIGURED_REGION}:${ACCOUNT_ID}:dbuser:${DBI_RESOURCE_ID}/ge_app",
             "arn:aws:rds-db:${CONFIGURED_REGION}:${ACCOUNT_ID}:dbuser:${DBI_RESOURCE_ID}/ge_migrator",
             "arn:aws:rds-db:${CONFIGURED_REGION}:${ACCOUNT_ID}:dbuser:${DBI_RESOURCE_ID}/ge_monitor",
             "arn:aws:rds-db:${CONFIGURED_REGION}:${ACCOUNT_ID}:dbuser:${DBI_RESOURCE_ID}/«db-root-username»" (1)
         ]
      }
   ]
}
EOF
1 Replace «db-root-username» with the username you chose when creating your RDS instance’s root credentials.

Then run the following command:

aws iam create-policy \
  --policy-name "develocity-rds-access" \
  --policy-document file://database-policy.json

Create a Role for EKS

To allow Develocity to connect to RDS, create an IAM role with that policy attached. Kubernetes service accounts in EKS need to be able to assume this role.

Associating a Kubernetes service account with an AWS IAM role requires an AWS OIDC provider. You installed one when setting up the Storage Class EBS CSI driver, so you can use it here.

To create an IAM role that Kubernetes service accounts in EKS can assume, run the following commands:

ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
POLICY_ARN="arn:aws:iam::${ACCOUNT_ID}:policy/develocity-rds-access"
eksctl create iamserviceaccount \
  --name develocity-database-account \
  --namespace develocity \
  --cluster develocity \
  --approve \
  --role-only \
  --role-name Develocity_Database_Role \
  --attach-policy-arn ${POLICY_ARN}

Change the trust relationship policy to allow the service accounts to assume the role:

OIDC_PROVIDER=$(aws eks describe-cluster --name develocity \
  --query "cluster.identity.oidc.issuer" \
  --output text | sed -e "s/^https:\/\///")
cat <<EOF > database-trust-relationship.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::$ACCOUNT_ID:oidc-provider/$OIDC_PROVIDER"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "${OIDC_PROVIDER}:sub": "system:serviceaccount:develocity:gradle-database",
          "${OIDC_PROVIDER}:aud": "sts.amazonaws.com"
        },
        "StringEquals": {
          "${OIDC_PROVIDER}:sub": "system:serviceaccount:develocity:gradle-enterprise-app",
          "${OIDC_PROVIDER}:aud": "sts.amazonaws.com"
        },
        "StringEquals": {
          "${OIDC_PROVIDER}:sub": "system:serviceaccount:develocity:gradle-enterprise-app-background-processor",
          "${OIDC_PROVIDER}:aud": "sts.amazonaws.com"
        },
        "StringEquals": {
          "${OIDC_PROVIDER}:sub": "system:serviceaccount:develocity:gradle-keycloak",
          "${OIDC_PROVIDER}:aud": "sts.amazonaws.com"
        },
        "StringEquals": {
          "${OIDC_PROVIDER}:sub": "system:serviceaccount:develocity:gradle-test-distribution-broker",
          "${OIDC_PROVIDER}:aud": "sts.amazonaws.com"
        }
      }
    }
  ]
}
EOF
aws iam update-assume-role-policy \
  --role-name Develocity_Database_Role \
  --policy-document file://database-trust-relationship.json

Configure Develocity With RDS

The superuser credentials are only required to set up the database and create the migrator and application users. IAM authentication does not work with the superuser without the role rds_iam. For simplicity, this tutorial uses password authentication for the superuser. Consider setting up the database yourself, as described in the Database options section of Develocity’s installation manual, to avoid superuser usage. For this option to work, you must follow the instructions above to enable and configure IAM database authentication for the migrator and application users.

Add the following configuration snippet to your Helm values file:

values.yaml
database:
  location: user-managed
  provider: aws-rds
  connection:
    host: «database-hostname»
    databaseName: gradle_enterprise
  credentials:
    type: irsa
    irsa:
      serviceAccountAnnotations:
        "eks.amazonaws.com/role-arn": "arn:aws:iam::«account-id»:role/Develocity_Database_Role"
    superuser:
      username: «db-root-username» (1)
      password: «db-root-password» (1)
1 The RDS root credentials you chose earlier.

Next Steps