diff --git a/README.md b/README.md
index 32bc4e8..5361c3a 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,56 @@
# Terraform Datastore Module
The `terraform-datastorage-module` provides several datastorage options in a common abstraction. This is a shared module in that this module is designed to be sourced by other modules.
+
+
+## TOC
+* [Release Notes](#release-notes)
+* [Tooling requirements](#tooling-requirements)
+* [Supported Implementations](#supported-implementations)
+ * [No Datastore](#no-datastore)
+ * [RDS (Postgres/MSSQL)](#rds)
+ * [S3](#s3-bucket)
+ * [Dynamodb](#dynamodb-table)
+* [Terraform Docs](#terraform-docs)
+ * [Requirements](#Requirements)
+ * [Providers](#Providers)
+ * [Inputs](#inputs)
+ * [Outputs](#outputs)
+
+## Release notes
+
+See the [Releases](https://github.com/hyprnz/terraform-aws-data-storage-module/releases) page for the complete list.
+
+* [__3.1.0__](https://github.com/hyprnz/terraform-aws-data-storage-module/releases/tag/3.0.1) - Adds support for more RDS parameters including IAM authentication, RDS Parameter Groups, and CloudWatch log exports.
+* [__3.0.0__](https://github.com/hyprnz/terraform-aws-data-storage-module/releases/tag/3.0.0) - Updates the module to support Terraform 0.13 (with backwards compatibility to 0.12.31). Adds support for more RDS parameters.
+* [__2.0.2__](https://github.com/hyprnz/terraform-aws-data-storage-module/releases/tag/2.0.2) - DynamoDB Policy Updates.
+* [__2.0.1__](https://github.com/hyprnz/terraform-aws-data-storage-module/releases/tag/2.0.1) - Dynamodb Policy Name Update.
+* [__2.0.0__](https://github.com/hyprnz/terraform-aws-data-storage-module/releases/tag/2.0.0) - Updated AWS Provider to Version 3.
+
+### Notes
+Branch 0.11 is compatible with Terraform 0.11 but is no longer supported or maintained. We will delete the branch shortly.
+
+## Tooling requirements
This module supports Terraform `0.13.0` (with backwards compatibility for Terraform `0.12.31`)
-The module currently supports the following implementations:
+If you experience issues with this module as a result of aws provider v4.0.0 and above we recommend creating an override to cap the provider version. For example:
+
+```
+aws = {
+ source : "hashicorp/aws",
+ version : ">= 3.38.0, < 4.0.0"
+}
+```
-* [No Datastore](#no-datastore)
-* [RDS (Postgres/MSSQL)](#rds)
-* [S3](#s3-bucket)
-* [Dynamodb](#dynamodb-table)
+# Supported Implementations
## No Datastore
Provides the option to disable the module if required.
## RDS
-RDS datastores support both Postgres and MySQL engines and provide many configuration options (see below). The RDS implementation currently only supports username/password access. The module supports creating a new RDS instance `create_rds_instance` or creating an instance from an existing snapshot `use_rds_snapshot`.
+RDS datastores supports Postgres and MySQL engines and provide many configuration options (see below). The module supports creating a new RDS instance `create_rds_instance` or an instance from an existing snapshot `use_rds_snapshot`.
+
+Although the module supports enabling IAM access to the RDS instance, the module intends that workloads will access the RDS instance via a username and password combination. The IAM access approach requires configuration within the RDS instance to map between the AWS and RDS engine abstractions, which the module does not support. The ability to enable IAM access support allows organisations to define user roles to access RDS instances rather than sharing or generating usernames and passwords.
## S3 Bucket
Creates an S3 bucket and an access policy of which the ARN is returned as an output variable. This allows the root/service module to compose other policies and expose these as an execution role.
@@ -22,10 +58,7 @@ Creates an S3 bucket and an access policy of which the ARN is returned as an out
At this stage, the module does not support adding a custom resource policy, nor does it configure any explicit deny rules for the bucket.
## Dynamodb Table
-Creates a dynamodb table and an access policy of which the ARN is returned as an output variable. There are many configuration options (see below).
-
-## Notes
-Branch 0.11 is compatible with Terraform 0.11 but is no longer supported or maintained. The branch will be deleted in the near future.
+Creates a dynamodb table and an access policy of which the ARN is returned as an output variable. There are many configuration options (see below).
---
@@ -80,6 +113,7 @@ Branch 0.11 is compatible with Terraform 0.11 but is no longer supported or main
| rds_apply_immediately | Specifies whether any database modifications are applied immediately, or during the next maintenance window. Defaults to `false`. | `bool` | `false` | no |
| rds_auto_minor_version_upgrade | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. Defaults to `true`. | `bool` | `true` | no |
| rds_backup_window | The daily time range (in UTC) during which automated backups are created if they are enabled. Example: '09:46-10:16'. Must not overlap with maintenance_window | `string` | `"16:19-16:49"` | no |
+| rds_cloudwatch_logs_exports | Which RDS logs should be sent to CloudWatch. The default is empty (no logs sent to CloudWatch) | `set(string)` | `[]` | no |
| rds_database_name | The name of the database. Can only contain alphanumeric characters | `string` | `""` | no |
| rds_enable_deletion_protection | 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`. | `bool` | `false` | no |
| rds_enable_performance_insights | Controls the enabling of RDS Performance insights. Default to `true` | `bool` | `true` | no |
@@ -87,6 +121,7 @@ Branch 0.11 is compatible with Terraform 0.11 but is no longer supported or main
| rds_engine | The Database engine for the rds instance | `string` | `"postgres"` | no |
| rds_engine_version | The version of the database engine. | `string` | `"11"` | no |
| rds_final_snapshot_identifier | The name of your final DB snapshot when this DB instance is deleted. Must be provided if `rds_skip_final_snapshot` is set to false. The value must begin with a letter, only contain alphanumeric characters and hyphens, and not end with a hyphen or contain two consecutive hyphens. | `string` | `null` | no |
+| rds_iam_authentication_enabled | Controls whether you can use IAM users to log in to the RDS database. The default is `false` | `bool` | `false` | no |
| rds_identifier | Identifier of datastore instance | `string` | `""` | no |
| rds_instance_class | The instance type to use | `string` | `"db.t3.small"` | no |
| rds_iops | The amount of provisioned IOPS. Setting this implies a storage_type of 'io1' | `number` | `0` | no |
@@ -95,6 +130,9 @@ Branch 0.11 is compatible with Terraform 0.11 but is no longer supported or main
| rds_monitoring_role_arn | The ARN for the IAM role that permits RDS to send enhanced monitoring metrics to CloudWatch Logs. Must be specified if monitoring_interval is non-zero. | `string` | `""` | no |
| rds_multi_az | Specifies if the RDS instance is multi-AZ. | `bool` | `false` | no |
| rds_option_group_name | Name of the DB option group to associate | `string` | `null` | no |
+| rds_parameter_group_family | Name of the DB family (engine & version) for the parameter group. eg. postgres11 | `string` | `null` | no |
+| rds_parameter_group_name | Name of the DB parameter group to create and associate with the instance | `string` | `null` | no |
+| rds_parameter_group_parameters | Map of parameters that will be added to this database's parameter group.
Parameters set here will override any AWS default parameters with the same name.
Requires `rds_parameter_group_name` and `rds_parameter_group_family` to be set as well.
Parameters should be provided as a key value pair within this map. eg `"param_name" : "param_value"`.
Default is empty and the AWS default parameter group is used. | `map` | `{}` | no |
| rds_password | RDS database password for the user | `string` | `""` | no |
| rds_security_group_ids | A List of security groups to bind to the rds instance | `list(string)` | `[]` | no |
| rds_skip_final_snapshot | Determines whether a final DB snapshot is created before the DB instance is deleted. If true is specified, no DBSnapshot is created. If false is specified, a DB snapshot is created before the DB instance is deleted, using the value from final_snapshot_identifier | `bool` | `true` | no |
diff --git a/examples/rds/main.tf b/examples/rds/main.tf
index efe794c..b812297 100644
--- a/examples/rds/main.tf
+++ b/examples/rds/main.tf
@@ -49,6 +49,14 @@ module "example_datastore_rds" {
rds_security_group_ids = [aws_security_group.db_security_group.id]
rds_password = "reallylongpassword%&^!"
+
+ rds_parameter_group_name = "example-dev-parameter-group"
+ rds_parameter_group_family = "postgres11"
+ rds_parameter_group_parameters = {
+ "log_connections" : "1",
+ "log_disconnections" : "1",
+ "shared_preload_libraries" : "pg_stat_statements,pgaudit"
+ }
}
provider "aws" {
diff --git a/examples/rds/versions.tf b/examples/rds/versions.tf
deleted file mode 100644
index ac97c6a..0000000
--- a/examples/rds/versions.tf
+++ /dev/null
@@ -1,4 +0,0 @@
-
-terraform {
- required_version = ">= 0.12"
-}
diff --git a/locals.tf b/locals.tf
index 827c3fb..05cbede 100644
--- a/locals.tf
+++ b/locals.tf
@@ -10,5 +10,8 @@ locals {
create_rds_instance_with_snapshot = var.enable_datastore && var.use_rds_snapshot && (! local.create_rds_instance)
count_rds_instance_with_snapshot = local.create_rds_instance_with_snapshot ? 1 : 0
+
+ create_rds_instance_with_parameter_group = var.create_rds_instance && var.rds_parameter_group_name != null && var.rds_parameter_group_family != null
+ count_rds_parameter_group = local.create_rds_instance_with_parameter_group ? 1 : 0
}
diff --git a/rds.tf b/rds.tf
index 0e7376e..9b85f1e 100644
--- a/rds.tf
+++ b/rds.tf
@@ -14,25 +14,29 @@ resource "aws_db_instance" "this" {
username = local.username
password = var.rds_password
- option_group_name = var.rds_option_group_name
- apply_immediately = var.rds_apply_immediately
- auto_minor_version_upgrade = var.rds_auto_minor_version_upgrade
- db_subnet_group_name = var.rds_subnet_group
- vpc_security_group_ids = var.rds_security_group_ids
- allocated_storage = var.rds_allocated_storage
- max_allocated_storage = var.rds_max_allocated_storage
- backup_retention_period = var.backup_retention_period
- iops = var.rds_iops
- multi_az = var.rds_multi_az
- monitoring_interval = var.rds_monitoring_interval
- monitoring_role_arn = var.rds_monitoring_role_arn
- performance_insights_enabled = var.rds_enable_performance_insights
- backup_window = var.rds_backup_window
- skip_final_snapshot = var.rds_skip_final_snapshot
- final_snapshot_identifier = var.rds_final_snapshot_identifier
- storage_encrypted = var.rds_enable_storage_encryption
- kms_key_id = var.rds_storage_encryption_kms_key_arn
- deletion_protection = var.rds_enable_deletion_protection
+ parameter_group_name = local.count_rds_parameter_group > 0 ? var.rds_parameter_group_name : null
+
+ iam_database_authentication_enabled = var.rds_iam_authentication_enabled
+ enabled_cloudwatch_logs_exports = var.rds_cloudwatch_logs_exports
+ option_group_name = var.rds_option_group_name
+ apply_immediately = var.rds_apply_immediately
+ auto_minor_version_upgrade = var.rds_auto_minor_version_upgrade
+ db_subnet_group_name = var.rds_subnet_group
+ vpc_security_group_ids = var.rds_security_group_ids
+ allocated_storage = var.rds_allocated_storage
+ max_allocated_storage = var.rds_max_allocated_storage
+ backup_retention_period = var.backup_retention_period
+ iops = var.rds_iops
+ multi_az = var.rds_multi_az
+ monitoring_interval = var.rds_monitoring_interval
+ monitoring_role_arn = var.rds_monitoring_role_arn
+ performance_insights_enabled = var.rds_enable_performance_insights
+ backup_window = var.rds_backup_window
+ skip_final_snapshot = var.rds_skip_final_snapshot
+ final_snapshot_identifier = var.rds_final_snapshot_identifier
+ storage_encrypted = var.rds_enable_storage_encryption
+ kms_key_id = var.rds_storage_encryption_kms_key_arn
+ deletion_protection = var.rds_enable_deletion_protection
tags = merge(
{
"Name" = var.rds_identifier,
@@ -41,6 +45,12 @@ resource "aws_db_instance" "this" {
var.tags,
var.rds_tags,
)
+
+ // We need this dependency because we only pass the var `rds_parameter_group_name` rather than reference the resource.
+ // Terraform can't tell that it needs to wait for it to be created based on the name alone.
+ depends_on = [
+ aws_db_parameter_group.db_parameter_group
+ ]
}
data "aws_db_snapshot" "latest_snapshot" {
@@ -96,3 +106,28 @@ resource "aws_db_instance" "snapshot" {
ignore_changes = [snapshot_identifier]
}
}
+
+resource "aws_db_parameter_group" "db_parameter_group" {
+ count = local.count_rds_parameter_group
+
+ name = var.rds_parameter_group_name
+ family = var.rds_parameter_group_family
+
+ dynamic "parameter" {
+ for_each = var.rds_parameter_group_parameters
+ content {
+ name = parameter.key
+ value = parameter.value
+ apply_method = "pending-reboot"
+ }
+ }
+
+ tags = merge(
+ {
+ "Name" = var.rds_identifier,
+ "rds_engine" = var.rds_engine
+ },
+ var.tags,
+ var.rds_tags,
+ )
+}
diff --git a/vars.tf b/vars.tf
index e39b267..ec7f9b8 100644
--- a/vars.tf
+++ b/vars.tf
@@ -114,6 +114,30 @@ variable "backup_retention_period" {
default = 7
}
+variable "rds_parameter_group_name" {
+ type = string
+ description = "Name of the DB parameter group to create and associate with the instance"
+ default = null
+}
+
+variable "rds_parameter_group_family" {
+ type = string
+ description = "Name of the DB family (engine & version) for the parameter group. eg. postgres11"
+ default = null
+}
+
+variable "rds_parameter_group_parameters" {
+ type = map
+ description = <