This Terraform module will create an Amazon RDS database for use on the Cloud Platform.
module "rds_instance" {
source = "github.com/ministryofjustice/cloud-platform-terraform-rds-instance?ref=version" # use the latest release
# VPC configuration
vpc_name = var.vpc_name
# Database configuration
db_engine = "postgres"
db_engine_version = "15"
rds_family = "postgres15"
db_instance_class = "db.t4g.micro"
db_max_allocated_storage = "500"
# Tags
business_unit = var.business_unit
application = var.application
is_production = var.is_production
team_name = var.team_name
namespace = var.namespace
environment_name = var.environment
infrastructure_support = var.infrastructure_support
}
The hostname and credentials for accessing your database will be in a
kubernetes secret inside your namespace. You can retrieve them as follows (the
decode.rb
script is available here):
$ kubectl -n [your namespace] get secret [secret name] -o yaml | ./decode.rb
---
apiVersion: v1
data:
database_name: ...
database_password: ...
database_username: ...
access_key_id: ...
secret_access_key: ...
rds_instance_address: cloud-platform-xxxxx.yyyyy.eu-west-2.rds.amazonaws.com
rds_instance_endpoint: cloud-platform-xxxxx.yyyyy.eu-west-2.rds.amazonaws.com:5432
rds_instance_port: '5432'
kind: Secret
metadata:
creationTimestamp: '2019-05-08T16:14:23Z'
name: secret-name
namespace: your-namespace
resourceVersion: '11111111'
selfLink: "/api/v1/namespaces/your-namespace/secrets/secret-name"
uid: 11111111-1111-1111-1111-111111111111
type: Opaque
If you are exporting a database URL from your RDS kubernetes secret, it might have a value like this:
postgres://username:password@database_id.random_id.eu-west-2.rds.amazonaws.com:5432/dbdf3589e0e7acba37
The database hostname is part between @
and :
In the example above, the database hostname is:
database_id.random_id.eu-west-2.rds.amazonaws.com
NB: You should always get the database credentials from this kubernetes secret. Do not be tempted to copy the into another location (such as a ConfigMap). This is because the value of the secret can be updated when this module is updated. As long as you always get your database credentials from the kubernetes secret created by terraform, this is fine. But if you copy the value elsewhere, it will not be automatically updated in the new location, and your application will no longer be able to connect to your database.
A Docker image containing the psql
utility is available from Bitnami (you
cannot use the official postgres image, because it runs as root) and can be
launched like this:
$ kubectl -n [your namespace] run --generator=run-pod/v1 shell --rm -i --tty --image bitnami/postgresql -- bash
If you don't see a command prompt, try pressing enter.
postgres@shell:/$
You can then connect to your database like this
postgres@shell:/$ psql -h [rds_instance_address] -U [database_username] [database_name]
Password for username: [...enter database_password here...]
psql (10.7, server 10.6)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
[database_name]=>
Instructions on how to do this are available here
An IAM user account is created which allows management of RDS snapshots - allowing snapshot create, delete, copy, restore.
Example usage via AWS CLI:
List snapshots
aws rds describe-db-snapshots --db-instance-identifier [db-instance-name]
Create snapshot
aws rds create-db-snapshot --db-instance-identifier [db-instance-name] --db-snapshot-identifier [your-snapshot-name]
See the examples/ folder for more information.
Instructions on how to do this are available here
Name | Version |
---|---|
terraform | >= 1.2.5 |
random | >= 2.0.0 |
Name | Version |
---|---|
aws | n/a |
random | >= 2.0.0 |
No modules.
Name | Type |
---|---|
aws_db_instance.rds | resource |
aws_db_parameter_group.custom_parameters | resource |
aws_db_subnet_group.db_subnet | resource |
aws_iam_policy.irsa | resource |
aws_kms_alias.alias | resource |
aws_kms_key.kms | resource |
aws_security_group.rds-sg | resource |
random_id.id | resource |
random_password.password | resource |
random_string.username | resource |
aws_caller_identity.current | data source |
aws_iam_policy_document.irsa | data source |
aws_region.current | data source |
aws_subnet.eks_private | data source |
aws_subnet.private | data source |
aws_subnets.eks_private | data source |
aws_subnets.private | data source |
aws_vpc.this | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
allow_major_version_upgrade | Indicates that major version upgrades are allowed. | string |
"false" |
no |
allow_minor_version_upgrade | Indicates that minor version upgrades are allowed. | string |
"true" |
no |
application | Application name | string |
n/a | yes |
backup_window | The daily time range (in UTC) during which automated backups are created if they are enabled. Example: 09:46-10:16 | string |
"" |
no |
business_unit | Area of the MOJ responsible for the service | string |
n/a | yes |
ca_cert_identifier | Specifies the identifier of the CA certificate for the DB instance | string |
"rds-ca-rsa2048-g1" |
no |
character_set_name | DB char set, used only by MS-SQL | string |
"SQL_Latin1_General_CP1_CI_AS" |
no |
db_allocated_storage | The allocated storage in gibibytes | number |
"20" |
no |
db_backup_retention_period | The days to retain backups. Must be 1 or greater to be a source for a Read Replica | string |
"7" |
no |
db_engine | Database engine used e.g. postgres, mysql, sqlserver-ex | string |
"postgres" |
no |
db_engine_version | The engine version to use e.g. 13.2 for Postgresql, 8.0 for MySQL, 15.00.4073.23.v1 for MS-SQL. Omitting the minor release part allows for automatic updates. | string |
"10" |
no |
db_instance_class | The instance type of the RDS instance | string |
"db.t2.small" |
no |
db_iops | The amount of provisioned IOPS. | number |
null |
no |
db_max_allocated_storage | Maximum storage limit for storage autoscaling | string |
"10000" |
no |
db_name | The name of the database to be created on the instance (if empty, it will be the generated random identifier) | string |
"" |
no |
db_parameter | A list of DB parameters to apply. Note that parameters may differ from a DB family to another | list(object({ |
[ |
no |
db_password_rotated_date | Using this variable will spin new db password by providing date as value | string |
"" |
no |
deletion_protection | (Optional) If the DB instance should have deletion protection enabled. The database can't be deleted when this value is set to true. The default is false. | string |
"false" |
no |
enable_rds_auto_start_stop | Enable auto start and stop of the RDS instances during 10:00 PM - 6:00 AM for cost saving | bool |
false |
no |
environment_name | Environment name | string |
n/a | yes |
infrastructure_support | The team responsible for managing the infrastructure. Should be of the form () | string |
n/a | yes |
is_production | Whether this is used for production or not | string |
n/a | yes |
license_model | License model information for this DB instance, options for MS-SQL are: license-included | bring-your-own-license | general-public-license | string |
null |
no |
maintenance_window | The window to perform maintenance in. Syntax: 'ddd:hh24:mi-ddd:hh24:mi'. Eg: 'Mon:00:00-Mon:03:00' | string |
null |
no |
namespace | Namespace name | string |
n/a | yes |
option_group_name | (Optional) The name of an 'aws_db_option_group' to associate to the DB instance | string |
null |
no |
performance_insights_enabled | Enable performance insights for RDS? Note: the user should ensure insights are disabled once the desired outcome is achieved. | bool |
false |
no |
prepare_for_major_upgrade | Set this to true to change your parameter group to the default version, and to turn on the ability to upgrade major versions | bool |
false |
no |
rds_family | Maps the engine version with the parameter group family, a family often covers several versions | string |
"postgres10" |
no |
rds_name | Optional name of the RDS cluster. Changing the name will re-create the RDS | string |
"" |
no |
replicate_source_db | Specifies that this resource is a Replicate database, and to use this value as the source database. This correlates to the identifier of another Amazon RDS Database to replicate. | string |
null |
no |
skip_final_snapshot | if false(default), a DB snapshot is created before the DB instance is deleted, using the value from final_snapshot_identifier. If true no DBSnapshot is created | string |
"false" |
no |
snapshot_identifier | Specifies whether or not to create this database from a snapshot. This correlates to the snapshot ID you'd find in the RDS console. | string |
"" |
no |
storage_type | One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), 'io1' (provisioned IOPS SSD), or 'io2' (new generation of provisioned IOPS SSD). If you specify 'io2', you must also include a value for the 'iops' parameter and the allocated_storage must be at least 100 GiB (except for SQL Server which the minimum is 20 GiB). |
string |
"gp3" |
no |
team_name | Team name | string |
n/a | yes |
vpc_name | The name of the vpc (eg.: cloud-platform-live-0) | string |
n/a | yes |
vpc_security_group_ids | (Optional) A list of additional VPC security group IDs to associate with the DB instance - in adition to the default VPC security groups granting access from the Cloud Platform | list(string) |
[] |
no |
Name | Description |
---|---|
database_name | Name of the database |
database_password | Database Password |
database_username | Database Username |
db_identifier | The RDS DB Indentifer |
irsa_policy_arn | IAM policy ARN for access to create database snapshots |
rds_instance_address | The hostname of the RDS instance |
rds_instance_endpoint | The connection endpoint in address:port format |
rds_instance_port | The database port |
resource_id | RDS Resource ID - used for performance insights (metrics) |
Some of the inputs for this module are tags. All infrastructure resources must be tagged to meet the MOJ Technical Guidance on Documenting owners of infrastructure.
You should use your namespace variables to populate these. See the Usage section for more information.