From e9dfed440210ea0d472aa4b28562a193a79cdf61 Mon Sep 17 00:00:00 2001 From: Alois Barreras Date: Wed, 21 Mar 2018 17:46:46 -0400 Subject: [PATCH 1/7] adding two missing arguments for aws_db_instance: timezone & character_set_name --- main.tf | 3 +++ modules/db_instance/main.tf | 3 +++ modules/db_instance/variables.tf | 10 ++++++++++ variables.tf | 10 ++++++++++ 4 files changed, 26 insertions(+) diff --git a/main.tf b/main.tf index c5cad3f2..1f0bbcc0 100644 --- a/main.tf +++ b/main.tf @@ -88,4 +88,7 @@ module "db_instance" { create_monitoring_role = "${var.create_monitoring_role}" tags = "${var.tags}" + + timezone = "${var.timezone}" + character_set_name = "${var.character_set_name}" } diff --git a/modules/db_instance/main.tf b/modules/db_instance/main.tf index 4ec97f59..71e364a9 100644 --- a/modules/db_instance/main.tf +++ b/modules/db_instance/main.tf @@ -63,4 +63,7 @@ resource "aws_db_instance" "this" { backup_window = "${var.backup_window}" tags = "${merge(var.tags, map("Name", format("%s", var.identifier)))}" + + timezone = "${var.timezone}" + character_set_name = "${var.character_set_name}" } diff --git a/modules/db_instance/variables.tf b/modules/db_instance/variables.tf index b88063d4..2d70ad18 100644 --- a/modules/db_instance/variables.tf +++ b/modules/db_instance/variables.tf @@ -177,3 +177,13 @@ variable "tags" { description = "A mapping of tags to assign to all resources" default = {} } + +variable "timezone" { + description = "(Optional) Time zone of the DB instance. timezone is currently only supported by Microsoft SQL Server. The timezone can only be set on creation. See MSSQL User Guide for more information." + default = "" +} + +variable "character_set_name" { + description = "(Optional) The character set name to use for DB encoding in Oracle instances. This can't be changed. See Oracle Character Sets Supported in Amazon RDS for more information." + default = "" +} diff --git a/variables.tf b/variables.tf index 3cba108a..767dc19f 100644 --- a/variables.tf +++ b/variables.tf @@ -205,3 +205,13 @@ variable "create_db_instance" { description = "Whether to create a database instance" default = true } + +variable "timezone" { + description = "(Optional) Time zone of the DB instance. timezone is currently only supported by Microsoft SQL Server. The timezone can only be set on creation. See MSSQL User Guide for more information." + default = "" +} + +variable "character_set_name" { + description = "(Optional) The character set name to use for DB encoding in Oracle instances. This can't be changed. See Oracle Character Sets Supported in Amazon RDS for more information." + default = "" +} From 13a478837982144763118d16dc4f26cf3632af04 Mon Sep 17 00:00:00 2001 From: Alois Barreras Date: Wed, 21 Mar 2018 17:53:24 -0400 Subject: [PATCH 2/7] added character_set_name to oracle example --- examples/complete-oracle/main.tf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/complete-oracle/main.tf b/examples/complete-oracle/main.tf index d055810f..81b1430f 100644 --- a/examples/complete-oracle/main.tf +++ b/examples/complete-oracle/main.tf @@ -60,4 +60,7 @@ module "db" { # Snapshot name upon DB deletion final_snapshot_identifier = "demodb" + + # See here for support character sets https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.OracleCharacterSets.html + character_set_name = "AL32UTF8" } From 05812b03fbb56a8f220b34f4ab0da914782d4f77 Mon Sep 17 00:00:00 2001 From: Alois Barreras Date: Wed, 21 Mar 2018 18:09:27 -0400 Subject: [PATCH 3/7] added example for mssql --- examples/complete-mssql/README.md | 19 +++++++ examples/complete-mssql/main.tf | 60 ++++++++++++++++++++++ examples/complete-mssql/outputs.tf | 82 ++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 examples/complete-mssql/README.md create mode 100644 examples/complete-mssql/main.tf create mode 100644 examples/complete-mssql/outputs.tf diff --git a/examples/complete-mssql/README.md b/examples/complete-mssql/README.md new file mode 100644 index 00000000..b4f28466 --- /dev/null +++ b/examples/complete-mssql/README.md @@ -0,0 +1,19 @@ +Complete RDS example for MSSQL Server +=================================== + +Configuration in this directory creates set of RDS resources including DB instance, DB subnet group and DB parameter group. + +Data sources are used to discover existing VPC resources (VPC, subnet and security group). + +Usage +===== + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. diff --git a/examples/complete-mssql/main.tf b/examples/complete-mssql/main.tf new file mode 100644 index 00000000..b1334f17 --- /dev/null +++ b/examples/complete-mssql/main.tf @@ -0,0 +1,60 @@ +provider "aws" { + region = "us-west-1" +} + +############################################################## +# Data sources to get VPC, subnets and security group details +############################################################## +data "aws_vpc" "default" { + default = true +} + +data "aws_subnet_ids" "all" { + vpc_id = "${data.aws_vpc.default.id}" +} + +data "aws_security_group" "default" { + vpc_id = "${data.aws_vpc.default.id}" + name = "default" +} + +##### +# DB +##### +module "db" { + source = "../../" + + identifier = "demodb" + + engine = "sqlserver-se" + engine_version = "14.00.1000.169.v1" + instance_class = "db.t2.large" + allocated_storage = 5 + storage_encrypted = false + + username = "demouser" + + password = "YourPwdShouldBeLongAndSecure!" + port = "1433" + + vpc_security_group_ids = ["${data.aws_security_group.default.id}"] + + maintenance_window = "Mon:00:00-Mon:03:00" + backup_window = "03:00-06:00" + + # disable backups to create DB faster + backup_retention_period = 0 + + tags = { + Owner = "user" + Environment = "dev" + } + + # DB subnet group + subnet_ids = ["${data.aws_subnet_ids.all.ids}"] + + # Snapshot name upon DB deletion + final_snapshot_identifier = "demodb" + + timezone = "Central Standard Time" +} diff --git a/examples/complete-mssql/outputs.tf b/examples/complete-mssql/outputs.tf new file mode 100644 index 00000000..f5c4a719 --- /dev/null +++ b/examples/complete-mssql/outputs.tf @@ -0,0 +1,82 @@ +# DB instance +output "this_db_instance_address" { + description = "The address of the RDS instance" + value = "${module.db.this_db_instance_address}" +} + +output "this_db_instance_arn" { + description = "The ARN of the RDS instance" + value = "${module.db.this_db_instance_arn}" +} + +output "this_db_instance_availability_zone" { + description = "The availability zone of the RDS instance" + value = "${module.db.this_db_instance_availability_zone}" +} + +output "this_db_instance_endpoint" { + description = "The connection endpoint" + value = "${module.db.this_db_instance_endpoint}" +} + +output "this_db_instance_hosted_zone_id" { + description = "The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record)" + value = "${module.db.this_db_instance_hosted_zone_id}" +} + +output "this_db_instance_id" { + description = "The RDS instance ID" + value = "${module.db.this_db_instance_id}" +} + +output "this_db_instance_resource_id" { + description = "The RDS Resource ID of this instance" + value = "${module.db.this_db_instance_resource_id}" +} + +output "this_db_instance_status" { + description = "The RDS instance status" + value = "${module.db.this_db_instance_status}" +} + +output "this_db_instance_name" { + description = "The database name" + value = "${module.db.this_db_instance_name}" +} + +output "this_db_instance_username" { + description = "The master username for the database" + value = "${module.db.this_db_instance_username}" +} + +output "this_db_instance_password" { + description = "The database password (this password may be old, because Terraform doesn't track it after initial creation)" + value = "${module.db.this_db_instance_password}" +} + +output "this_db_instance_port" { + description = "The database port" + value = "${module.db.this_db_instance_port}" +} + +# DB subnet group +output "this_db_subnet_group_id" { + description = "The db subnet group name" + value = "${module.db.this_db_subnet_group_id}" +} + +output "this_db_subnet_group_arn" { + description = "The ARN of the db subnet group" + value = "${module.db.this_db_subnet_group_arn}" +} + +# DB parameter group +output "this_db_parameter_group_id" { + description = "The db parameter group id" + value = "${module.db.this_db_parameter_group_id}" +} + +output "this_db_parameter_group_arn" { + description = "The ARN of the db parameter group" + value = "${module.db.this_db_parameter_group_arn}" +} From bb4ef5e58bcc037041779484189d2f34fc989665 Mon Sep 17 00:00:00 2001 From: Alois Barreras Date: Wed, 21 Mar 2018 18:11:36 -0400 Subject: [PATCH 4/7] added link to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5b54c061..80ceac6e 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Examples * [Complete RDS example for MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-mysql) * [Complete RDS example for PostgreSQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-postgres) * [Complete RDS example for Oracle](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-oracle) +* [Complete RDS example for MSSQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-mssql) * [Enhanced monitoring example](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/enhanced-monitoring) Notes From 8665c3da4ec2ea7c38c9492a9c790b68e738ebfd Mon Sep 17 00:00:00 2001 From: Alois Barreras Date: Thu, 22 Mar 2018 11:14:36 -0400 Subject: [PATCH 5/7] moved tags to last line --- main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 1f0bbcc0..1a09a4ea 100644 --- a/main.tf +++ b/main.tf @@ -87,8 +87,8 @@ module "db_instance" { monitoring_role_name = "${var.monitoring_role_name}" create_monitoring_role = "${var.create_monitoring_role}" - tags = "${var.tags}" - timezone = "${var.timezone}" character_set_name = "${var.character_set_name}" + + tags = "${var.tags}" } From 870b3d39bc47868e2b9f4e856049b867d6920959 Mon Sep 17 00:00:00 2001 From: Alois Barreras Date: Thu, 22 Mar 2018 11:34:43 -0400 Subject: [PATCH 6/7] fixed mssql example --- examples/complete-mssql/main.tf | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/complete-mssql/main.tf b/examples/complete-mssql/main.tf index b1334f17..a9b339d8 100644 --- a/examples/complete-mssql/main.tf +++ b/examples/complete-mssql/main.tf @@ -26,10 +26,10 @@ module "db" { identifier = "demodb" - engine = "sqlserver-se" + engine = "sqlserver-ex" engine_version = "14.00.1000.169.v1" - instance_class = "db.t2.large" - allocated_storage = 5 + instance_class = "db.t2.medium" + allocated_storage = 20 storage_encrypted = false username = "demouser" @@ -56,5 +56,8 @@ module "db" { # Snapshot name upon DB deletion final_snapshot_identifier = "demodb" + create_db_parameter_group = false + license_model = "license-included" + timezone = "Central Standard Time" } From 95ffaf6746275cefdee20dc6f79dc2d85da61248 Mon Sep 17 00:00:00 2001 From: Alois Barreras Date: Thu, 22 Mar 2018 12:33:30 -0400 Subject: [PATCH 7/7] Added conditional mssql db_instance based on var.engine. Added conditional outputs --- modules/db_instance/main.tf | 58 ++++++++++++++++++++++++++++++++-- modules/db_instance/outputs.tf | 39 ++++++++++++++++------- 2 files changed, 83 insertions(+), 14 deletions(-) diff --git a/modules/db_instance/main.tf b/modules/db_instance/main.tf index 71e364a9..a873cded 100644 --- a/modules/db_instance/main.tf +++ b/modules/db_instance/main.tf @@ -2,6 +2,10 @@ # DB instance ############## +locals { + is_mssql = "${element(split("-",var.engine), 0) == "sqlserver"}" +} + resource "aws_iam_role" "enhanced_monitoring" { count = "${var.create_monitoring_role ? 1 : 0}" @@ -17,7 +21,7 @@ resource "aws_iam_role_policy_attachment" "enhanced_monitoring" { } resource "aws_db_instance" "this" { - count = "${var.create ? 1 : 0}" + count = "${var.create && !local.is_mssql ? 1 : 0}" identifier = "${var.identifier}" @@ -64,6 +68,56 @@ resource "aws_db_instance" "this" { tags = "${merge(var.tags, map("Name", format("%s", var.identifier)))}" - timezone = "${var.timezone}" character_set_name = "${var.character_set_name}" } + +resource "aws_db_instance" "this_mssql" { + count = "${var.create && local.is_mssql ? 1 : 0}" + + identifier = "${var.identifier}" + + engine = "${var.engine}" + engine_version = "${var.engine_version}" + instance_class = "${var.instance_class}" + allocated_storage = "${var.allocated_storage}" + storage_type = "${var.storage_type}" + storage_encrypted = "${var.storage_encrypted}" + kms_key_id = "${var.kms_key_id}" + license_model = "${var.license_model}" + + name = "${var.name}" + username = "${var.username}" + password = "${var.password}" + port = "${var.port}" + iam_database_authentication_enabled = "${var.iam_database_authentication_enabled}" + + replicate_source_db = "${var.replicate_source_db}" + + snapshot_identifier = "${var.snapshot_identifier}" + + vpc_security_group_ids = ["${var.vpc_security_group_ids}"] + db_subnet_group_name = "${var.db_subnet_group_name}" + parameter_group_name = "${var.parameter_group_name}" + + availability_zone = "${var.availability_zone}" + multi_az = "${var.multi_az}" + iops = "${var.iops}" + publicly_accessible = "${var.publicly_accessible}" + monitoring_interval = "${var.monitoring_interval}" + monitoring_role_arn = "${coalesce(var.monitoring_role_arn, join("", aws_iam_role.enhanced_monitoring.*.arn))}" + + allow_major_version_upgrade = "${var.allow_major_version_upgrade}" + auto_minor_version_upgrade = "${var.auto_minor_version_upgrade}" + apply_immediately = "${var.apply_immediately}" + maintenance_window = "${var.maintenance_window}" + skip_final_snapshot = "${var.skip_final_snapshot}" + copy_tags_to_snapshot = "${var.copy_tags_to_snapshot}" + final_snapshot_identifier = "${var.final_snapshot_identifier}" + + backup_retention_period = "${var.backup_retention_period}" + backup_window = "${var.backup_window}" + + timezone = "${var.timezone}" + + tags = "${merge(var.tags, map("Name", format("%s", var.identifier)))}" +} diff --git a/modules/db_instance/outputs.tf b/modules/db_instance/outputs.tf index c2e65b38..d1cc25b9 100644 --- a/modules/db_instance/outputs.tf +++ b/modules/db_instance/outputs.tf @@ -1,60 +1,75 @@ +locals { + this_db_instance_address = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.address, list("")), 0) : element(concat(aws_db_instance.this.*.address, list("")), 0)}" + this_db_instance_arn = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.arn, list("")), 0) : element(concat(aws_db_instance.this.*.arn, list("")), 0)}" + this_db_instance_availability_zone = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.availability_zone, list("")), 0) : element(concat(aws_db_instance.this.*.availability_zone, list("")), 0)}" + this_db_instance_endpoint = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.endpoint, list("")), 0) : element(concat(aws_db_instance.this.*.endpoint, list("")), 0)}" + this_db_instance_hosted_zone_id = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.hosted_zone_id, list("")), 0) : element(concat(aws_db_instance.this.*.hosted_zone_id, list("")), 0)}" + this_db_instance_id = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.id, list("")), 0) : element(concat(aws_db_instance.this.*.id, list("")), 0)}" + this_db_instance_resource_id = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.resource_id, list("")), 0) : element(concat(aws_db_instance.this.*.resource_id, list("")), 0)}" + this_db_instance_status = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.status, list("")), 0) : element(concat(aws_db_instance.this.*.status, list("")), 0)}" + this_db_instance_name = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.name, list("")), 0) : element(concat(aws_db_instance.this.*.name, list("")), 0)}" + this_db_instance_username = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.username, list("")), 0) : element(concat(aws_db_instance.this.*.username, list("")), 0)}" + this_db_instance_password = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.password, list("")), 0) : element(concat(aws_db_instance.this.*.password, list("")), 0)}" + this_db_instance_port = "${local.is_mssql ? element(concat(aws_db_instance.this_mssql.*.port, list("")), 0) : element(concat(aws_db_instance.this.*.port, list("")), 0)}" +} + # DB instance output "this_db_instance_address" { description = "The address of the RDS instance" - value = "${element(concat(aws_db_instance.this.*.address, list("")), 0)}" + value = "${local.this_db_instance_address}" } output "this_db_instance_arn" { description = "The ARN of the RDS instance" - value = "${element(concat(aws_db_instance.this.*.arn, list("")), 0)}" + value = "${local.this_db_instance_arn}" } output "this_db_instance_availability_zone" { description = "The availability zone of the RDS instance" - value = "${element(concat(aws_db_instance.this.*.availability_zone, list("")), 0)}" + value = "${local.this_db_instance_availability_zone}" } output "this_db_instance_endpoint" { description = "The connection endpoint" - value = "${element(concat(aws_db_instance.this.*.endpoint, list("")), 0)}" + value = "${local.this_db_instance_endpoint}" } output "this_db_instance_hosted_zone_id" { description = "The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record)" - value = "${element(concat(aws_db_instance.this.*.hosted_zone_id, list("")), 0)}" + value = "${local.this_db_instance_hosted_zone_id}" } output "this_db_instance_id" { description = "The RDS instance ID" - value = "${element(concat(aws_db_instance.this.*.id, list("")), 0)}" + value = "${local.this_db_instance_id}" } output "this_db_instance_resource_id" { description = "The RDS Resource ID of this instance" - value = "${element(concat(aws_db_instance.this.*.resource_id, list("")), 0)}" + value = "${local.this_db_instance_resource_id}" } output "this_db_instance_status" { description = "The RDS instance status" - value = "${element(concat(aws_db_instance.this.*.status, list("")), 0)}" + value = "${local.this_db_instance_status}" } output "this_db_instance_name" { description = "The database name" - value = "${element(concat(aws_db_instance.this.*.name, list("")), 0)}" + value = "${local.this_db_instance_name}" } output "this_db_instance_username" { description = "The master username for the database" - value = "${element(concat(aws_db_instance.this.*.username, list("")), 0)}" + value = "${local.this_db_instance_username}" } output "this_db_instance_password" { description = "The database password (this password may be old, because Terraform doesn't track it after initial creation)" - value = "${var.password}" + value = "${local.this_db_instance_password}" } output "this_db_instance_port" { description = "The database port" - value = "${element(concat(aws_db_instance.this.*.port, list("")), 0)}" + value = "${local.this_db_instance_port}" }