From 0076e91fb3c4a4e6abe3bf6fc3c06277cf0b37f3 Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Sat, 5 Jan 2019 14:20:49 -0800 Subject: [PATCH 1/8] add support for read replica --- README.md | 5 ++-- docs/terraform.md | 3 ++- main.tf | 62 ++++++++++++++++++++++++++++++++--------------- variables.tf | 16 ++++++++++++ 4 files changed, 63 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 525e682..c4b3f80 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,6 @@ Available targets: lint Lint terraform code ``` - ## Inputs | Name | Description | Type | Default | Required | @@ -136,12 +135,14 @@ Available targets: | host_name | The DB host name created in Route53 | string | `db` | no | | instance_class | Class of RDS instance | string | - | yes | | iops | The amount of provisioned IOPS. Setting this implies a storage_type of 'io1'. Default is 0 if rds storage type is not 'io1' | string | `0` | no | +| kms_key_id | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN | string | - | yes | | maintenance_window | The window to perform maintenance in. Syntax: 'ddd:hh24:mi-ddd:hh24:mi' UTC | string | `Mon:03:00-Mon:04:00` | no | | multi_az | Set to true if multi AZ deployment must be supported | string | `false` | no | | name | The Name of the application or solution (e.g. `bastion` or `portal`) | string | - | yes | | namespace | Namespace (e.g. `eg` or `cp`) | string | - | yes | | parameter_group_name | Name of the DB parameter group to associate | string | `` | no | | publicly_accessible | Determines if database can be publicly available (NOT recommended) | string | `false` | 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. Note that if you are creating a cross-region replica of an encrypted database you will also need to specify a kms_key_id. See [DB Instance Replication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Replication.html) and [Working with PostgreSQL and MySQL Read Replicas](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html) for more information on using Replication. | string | `` | no | | security_group_ids | he IDs of the security groups from which to allow `ingress` traffic to the DB instance | list | `` | no | | skip_final_snapshot | If true (default), no snapshot will be made before deleting DB | string | `true` | no | | snapshot_identifier | Snapshot identifier e.g: rds:production-2015-06-26-06-05. If specified, the module create cluster from the snapshot | string | `` | no | @@ -245,7 +246,7 @@ In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. ## Copyright -Copyright © 2017-2018 [Cloud Posse, LLC](https://cpco.io/copyright) +Copyright © 2017-2019 [Cloud Posse, LLC](https://cpco.io/copyright) diff --git a/docs/terraform.md b/docs/terraform.md index ff90338..f633a30 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -1,4 +1,3 @@ - ## Inputs | Name | Description | Type | Default | Required | @@ -26,12 +25,14 @@ | host_name | The DB host name created in Route53 | string | `db` | no | | instance_class | Class of RDS instance | string | - | yes | | iops | The amount of provisioned IOPS. Setting this implies a storage_type of 'io1'. Default is 0 if rds storage type is not 'io1' | string | `0` | no | +| kms_key_id | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN | string | - | yes | | maintenance_window | The window to perform maintenance in. Syntax: 'ddd:hh24:mi-ddd:hh24:mi' UTC | string | `Mon:03:00-Mon:04:00` | no | | multi_az | Set to true if multi AZ deployment must be supported | string | `false` | no | | name | The Name of the application or solution (e.g. `bastion` or `portal`) | string | - | yes | | namespace | Namespace (e.g. `eg` or `cp`) | string | - | yes | | parameter_group_name | Name of the DB parameter group to associate | string | `` | no | | publicly_accessible | Determines if database can be publicly available (NOT recommended) | string | `false` | 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. Note that if you are creating a cross-region replica of an encrypted database you will also need to specify a kms_key_id. See [DB Instance Replication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Replication.html) and [Working with PostgreSQL and MySQL Read Replicas](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html) for more information on using Replication. | string | `` | no | | security_group_ids | he IDs of the security groups from which to allow `ingress` traffic to the DB instance | list | `` | no | | skip_final_snapshot | If true (default), no snapshot will be made before deleting DB | string | `true` | no | | snapshot_identifier | Snapshot identifier e.g: rds:production-2015-06-26-06-05. If specified, the module create cluster from the snapshot | string | `` | no | diff --git a/main.tf b/main.tf index 3028236..a189977 100644 --- a/main.tf +++ b/main.tf @@ -1,5 +1,6 @@ module "label" { source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.3.3" + enabled = "${var.enabled}" namespace = "${var.namespace}" name = "${var.name}" stage = "${var.stage}" @@ -10,6 +11,7 @@ module "label" { module "final_snapshot_label" { source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.3.3" + enabled = "${var.enabled}" namespace = "${var.namespace}" name = "${var.name}" stage = "${var.stage}" @@ -18,8 +20,23 @@ module "final_snapshot_label" { tags = "${var.tags}" } +locals { + enabled = "${var.enabled == "true"}" + parameter_group_name = "${length(var.parameter_group_name) > 0 ? var.parameter_group_name : join("", aws_db_parameter_group.default.*.name)}" + final_snapshot_identifier = "${length(var.final_snapshot_identifier) > 0 ? var.final_snapshot_identifier : module.final_snapshot_label.id}" + kms_key_id = "${length(var.kms_key_id) ? var.kms_key_id : join("", aws_kms_key.default.*.id)}" +} + +resource "aws_kms_key" "default" { + count = "${local.enabled && length(var.kms_key_id) == 0 ? 1 : 0}" + description = "${module.label.id}" + deletion_window_in_days = 10 + enable_key_rotation = true + tags = "${module.label.tags}" +} + resource "aws_db_instance" "default" { - count = "${var.enabled == "true" ? 1 : 0}" + count = "${local.enabled ? 1 : 0}" identifier = "${module.label.id}" name = "${var.database_name}" username = "${var.database_user}" @@ -32,7 +49,7 @@ resource "aws_db_instance" "default" { storage_encrypted = "${var.storage_encrypted}" vpc_security_group_ids = "${aws_security_group.default.*.id}" db_subnet_group_name = "${join("", aws_db_subnet_group.default.*.name)}" - parameter_group_name = "${length(var.parameter_group_name) > 0 ? var.parameter_group_name : join("", aws_db_parameter_group.default.*.name)}" + parameter_group_name = "${local.parameter_group_name}" multi_az = "${var.multi_az}" storage_type = "${var.storage_type}" iops = "${var.iops}" @@ -47,11 +64,14 @@ resource "aws_db_instance" "default" { backup_retention_period = "${var.backup_retention_period}" backup_window = "${var.backup_window}" tags = "${module.label.tags}" - final_snapshot_identifier = "${length(var.final_snapshot_identifier) > 0 ? var.final_snapshot_identifier : module.final_snapshot_label.id}" + final_snapshot_identifier = "${local.final_snapshot_identifier}" + kms_key_id = "${local.kms_key_id}" + monitoring_interval = "${var.monitoring_interval}" + replicate_source_db = "${var.source_db_identifier}" } resource "aws_db_parameter_group" "default" { - count = "${(length(var.parameter_group_name) == 0 && var.enabled == "true") ? 1 : 0}" + count = "${local.enabled && (length(var.parameter_group_name) == 0) ? 1 : 0}" name = "${module.label.id}" family = "${var.db_parameter_group}" tags = "${module.label.tags}" @@ -59,33 +79,35 @@ resource "aws_db_parameter_group" "default" { } resource "aws_db_subnet_group" "default" { - count = "${var.enabled == "true" ? 1 : 0}" + count = "${local.enabled ? 1 : 0}" name = "${module.label.id}" subnet_ids = ["${var.subnet_ids}"] tags = "${module.label.tags}" } resource "aws_security_group" "default" { - count = "${var.enabled == "true" ? 1 : 0}" + count = "${local.enabled ? 1 : 0}" name = "${module.label.id}" description = "Allow inbound traffic from the security groups" vpc_id = "${var.vpc_id}" - ingress { - from_port = "${var.database_port}" - to_port = "${var.database_port}" - protocol = "tcp" - security_groups = ["${var.security_group_ids}"] - } + tags = "${module.label.tags}" +} - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } +resource "aws_security_group_rule" "allow_ingress" { + type = "ingress" + from_port = "${var.database_port}" + to_port = "${var.database_port}" + protocol = "tcp" + security_groups = ["${var.security_group_ids}"] +} - tags = "${module.label.tags}" +resource "aws_security_group_rule" "allow_egress" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] } module "dns_host_name" { @@ -95,5 +117,5 @@ module "dns_host_name" { stage = "${var.stage}" zone_id = "${var.dns_zone_id}" records = "${aws_db_instance.default.*.address}" - enabled = "${(length(var.dns_zone_id) > 0 && var.enabled == "true") ? "true" : "false"}" + enabled = "${local.enabled && length(var.dns_zone_id) > 0 ? "true" : "false"}" } diff --git a/variables.tf b/variables.tf index 52efd2f..83fbfa3 100644 --- a/variables.tf +++ b/variables.tf @@ -225,3 +225,19 @@ variable "parameter_group_name" { description = "Name of the DB parameter group to associate" default = "" } + +variable "kms_key_id" { + type = "string" + description = "The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN" + value = "" +} + +variable "replicate_source_db" { + description = "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. Note that if you are creating a cross-region replica of an encrypted database you will also need to specify a kms_key_id. See [DB Instance Replication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Replication.html) and [Working with PostgreSQL and MySQL Read Replicas](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html) for more information on using Replication." + default = "" +} + +varwiable "monitoring_interval" { + description = "The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. Valid Values are 0, 1, 5, 10, 15, 30, 60." + default = "0" +} From fc0e6a814d914011451fba8e791fb03a858823dc Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Sat, 5 Jan 2019 15:02:56 -0800 Subject: [PATCH 2/8] fix typos --- main.tf | 2 +- variables.tf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/main.tf b/main.tf index a189977..0726911 100644 --- a/main.tf +++ b/main.tf @@ -67,7 +67,7 @@ resource "aws_db_instance" "default" { final_snapshot_identifier = "${local.final_snapshot_identifier}" kms_key_id = "${local.kms_key_id}" monitoring_interval = "${var.monitoring_interval}" - replicate_source_db = "${var.source_db_identifier}" + replicate_source_db = "${var.replicate_source_db}" } resource "aws_db_parameter_group" "default" { diff --git a/variables.tf b/variables.tf index 83fbfa3..e322753 100644 --- a/variables.tf +++ b/variables.tf @@ -229,7 +229,7 @@ variable "parameter_group_name" { variable "kms_key_id" { type = "string" description = "The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN" - value = "" + default = "" } variable "replicate_source_db" { @@ -237,7 +237,7 @@ variable "replicate_source_db" { default = "" } -varwiable "monitoring_interval" { +variable "monitoring_interval" { description = "The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. Valid Values are 0, 1, 5, 10, 15, 30, 60." default = "0" } From 42d0ff053d44596a8b969fcb83401fe0b7c701bc Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Sat, 5 Jan 2019 18:15:28 -0800 Subject: [PATCH 3/8] set defaults --- variables.tf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/variables.tf b/variables.tf index e322753..7c8b476 100644 --- a/variables.tf +++ b/variables.tf @@ -82,6 +82,7 @@ variable "iops" { variable "allocated_storage" { description = "The allocated storage in GBs" + default = "" # Number, e.g. 10 } @@ -89,6 +90,7 @@ variable "allocated_storage" { variable "engine" { type = "string" description = "Database engine type" + default = "" # http://docs.aws.amazon.com/cli/latest/reference/rds/create-db-instance.html # - mysql @@ -100,6 +102,7 @@ variable "engine" { variable "engine_version" { type = "string" description = "Database engine version, depends on engine type" + default = "" # http://docs.aws.amazon.com/cli/latest/reference/rds/create-db-instance.html } From 2a2ac01a1bdd8feffc957a31f30932d4b00096eb Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Sat, 5 Jan 2019 18:17:10 -0800 Subject: [PATCH 4/8] set defaults --- variables.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/variables.tf b/variables.tf index 7c8b476..6f3a090 100644 --- a/variables.tf +++ b/variables.tf @@ -39,6 +39,7 @@ variable "security_group_ids" { variable "database_name" { type = "string" description = "The name of the database to create when the DB instance is created" + default = "" } variable "database_user" { @@ -119,6 +120,7 @@ variable "instance_class" { variable "db_parameter_group" { type = "string" description = "Parameter group, depends on DB engine used" + default = "" # "mysql5.6" # "postgres9.5" From a4a9394170af67329874a56a9e59d6efa95f2e69 Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Sat, 5 Jan 2019 18:23:03 -0800 Subject: [PATCH 5/8] fix typo --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 0726911..58edbb6 100644 --- a/main.tf +++ b/main.tf @@ -24,7 +24,7 @@ locals { enabled = "${var.enabled == "true"}" parameter_group_name = "${length(var.parameter_group_name) > 0 ? var.parameter_group_name : join("", aws_db_parameter_group.default.*.name)}" final_snapshot_identifier = "${length(var.final_snapshot_identifier) > 0 ? var.final_snapshot_identifier : module.final_snapshot_label.id}" - kms_key_id = "${length(var.kms_key_id) ? var.kms_key_id : join("", aws_kms_key.default.*.id)}" + kms_key_id = "${length(var.kms_key_id) > 0 ? var.kms_key_id : join("", aws_kms_key.default.*.id)}" } resource "aws_kms_key" "default" { From 93583b231303605ed8c0bc7a8c629ead7f0be865 Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Sat, 5 Jan 2019 18:26:59 -0800 Subject: [PATCH 6/8] fix security_group_id --- main.tf | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/main.tf b/main.tf index 58edbb6..7f3e9e7 100644 --- a/main.tf +++ b/main.tf @@ -94,20 +94,26 @@ resource "aws_security_group" "default" { tags = "${module.label.tags}" } +locals { + security_group_id = "${join("", aws_security_group.default.*.id)}" +} + resource "aws_security_group_rule" "allow_ingress" { - type = "ingress" - from_port = "${var.database_port}" - to_port = "${var.database_port}" - protocol = "tcp" - security_groups = ["${var.security_group_ids}"] + security_group_id = "${local.security_group_id}" + type = "ingress" + from_port = "${var.database_port}" + to_port = "${var.database_port}" + protocol = "tcp" + security_groups = ["${var.security_group_ids}"] } resource "aws_security_group_rule" "allow_egress" { - type = "egress" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] + security_group_id = "${local.security_group_id}" + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] } module "dns_host_name" { From bc77adfb3c71e955ec3cdb2d65dd480fcc3fa3bc Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Sat, 5 Jan 2019 18:34:47 -0800 Subject: [PATCH 7/8] fix security group ids --- main.tf | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/main.tf b/main.tf index 7f3e9e7..38b27aa 100644 --- a/main.tf +++ b/main.tf @@ -99,15 +99,17 @@ locals { } resource "aws_security_group_rule" "allow_ingress" { - security_group_id = "${local.security_group_id}" - type = "ingress" - from_port = "${var.database_port}" - to_port = "${var.database_port}" - protocol = "tcp" - security_groups = ["${var.security_group_ids}"] + count = "${local.enabled ? length(var.security_group_ids) : 0}" + security_group_id = "${local.security_group_id}" + type = "ingress" + from_port = "${var.database_port}" + to_port = "${var.database_port}" + protocol = "tcp" + source_security_group_id = ["${var.security_group_ids[count.index]}"] } resource "aws_security_group_rule" "allow_egress" { + count = "${local.enabled ? 1 : 0}" security_group_id = "${local.security_group_id}" type = "egress" from_port = 0 From 6ef0a8d44d1dc2c715f15755070be36af832aaec Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Sat, 5 Jan 2019 18:36:12 -0800 Subject: [PATCH 8/8] fix security group ids --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 38b27aa..da81462 100644 --- a/main.tf +++ b/main.tf @@ -105,7 +105,7 @@ resource "aws_security_group_rule" "allow_ingress" { from_port = "${var.database_port}" to_port = "${var.database_port}" protocol = "tcp" - source_security_group_id = ["${var.security_group_ids[count.index]}"] + source_security_group_id = "${var.security_group_ids[count.index]}" } resource "aws_security_group_rule" "allow_egress" {