From fb994654277f00bac408773b187be0095bddb886 Mon Sep 17 00:00:00 2001 From: samidbb Date: Fri, 20 Oct 2023 09:30:27 +0200 Subject: [PATCH 01/12] wip --- main.tf | 310 ++++++++++++++++++++ variables.tf | 808 +++++++++++++++++++++++++++++++++++++++++++++++++++ versions.tf | 2 +- 3 files changed, 1119 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index e69de29b..9b715e22 100644 --- a/main.tf +++ b/main.tf @@ -0,0 +1,310 @@ +# generate terraform resources for rds +locals { + + # deploy_options_group = var.engine != "postgres" + + # is_multi_az_cluster = var.is_multi_az_cluster ? create_multi_az_db_cluster : create_db_instance + instance_class = var.instance_class + final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.final_snapshot_identifier_prefix}-${var.identifier}-${try(random_id.snapshot_identifier[0].hex, "")}" + + + storage_size = var.allocated_storage == null && var.storage_type == "gp2" ? 5 : var.allocated_storage # Console suggests 20 GB as minumum storage + + monitoring_role_name = var.create_monitoring_role && var.monitoring_role_name == null ? "${var.identifier}-rds-enhanced-monitoring" : var.monitoring_role_name + monitoring_role_description = var.create_monitoring_role && var.monitoring_role_description == null ? "Role for enhanced monitoring of RDS instance ${var.identifier}" : var.monitoring_role_description + + create_cloudwatch_log_group = length(var.enabled_cloudwatch_logs_exports) > 0 + + cloudwatch_log_group_skip_destroy_on_deletion = true + + parameter_group_name = var.create_db_parameter_group && var.parameter_group_name == null ? "${var.identifier}-rds-parameters" : var.parameter_group_name + + family = var.create_db_parameter_group && var.family == null ? "postgres${var.engine}" : var.family +} +resource "random_id" "snapshot_identifier" { + count = !var.skip_final_snapshot ? 1 : 0 + + keepers = { + id = var.identifier + } + + byte_length = 4 +} + +# Focus on exposing required variables +# and use default values for optional ones +# Provide options for providing abstraction on top of the resourc + +# resource "aws_rds_cluster" "default" { +# cluster_identifier = "aurora-cluster-demo" +# engine = "aurora-mysql" +# engine_version = "5.7.mysql_aurora.2.03.2" +# availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] +# database_name = "mydb" +# master_username = "foo" +# master_password = "bar" +# backup_retention_period = 5 +# preferred_backup_window = "07:00-09:00" +# # tags = var.tags_group1 +# } + +module "db" { + count = var.is_db_cluster ? 0 : 1 + + source = "../opensource_tf_modules//terraform-aws-rds" + + identifier = var.identifier + + create_db_parameter_group = var.create_db_parameter_group # Disabled for now + + instance_class = local.instance_class + + skip_final_snapshot = var.skip_final_snapshot + create_db_instance = var.create_db_instance + + instance_use_identifier_prefix = var.instance_use_identifier_prefix + custom_iam_instance_profile = var.custom_iam_instance_profile + allocated_storage = local.storage_size # var.allocated_storage + storage_type = var.storage_type + storage_throughput = var.storage_throughput + storage_encrypted = var.storage_encrypted + kms_key_id = var.kms_key_id + replicate_source_db = var.replicate_source_db + license_model = var.license_model + replica_mode = var.replica_mode + iam_database_authentication_enabled = var.iam_database_authentication_enabled + domain = var.domain + domain_iam_role_name = var.domain_iam_role_name + engine = var.engine # + engine_version = var.engine_version + snapshot_identifier = var.snapshot_identifier + copy_tags_to_snapshot = var.copy_tags_to_snapshot + final_snapshot_identifier_prefix = var.final_snapshot_identifier_prefix + db_name = var.db_name + username = var.username + password = var.password + manage_master_user_password = var.manage_master_user_password + master_user_secret_kms_key_id = var.master_user_secret_kms_key_id + port = var.port + vpc_security_group_ids = var.vpc_security_group_ids + 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 = var.monitoring_role_arn + monitoring_role_name = local.monitoring_role_name + monitoring_role_use_name_prefix = var.monitoring_role_use_name_prefix + monitoring_role_description = local.monitoring_role_description + create_monitoring_role = var.create_monitoring_role + monitoring_role_permissions_boundary = var.monitoring_role_permissions_boundary + 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 + blue_green_update = var.blue_green_update + backup_retention_period = var.backup_retention_period + backup_window = var.backup_window + restore_to_point_in_time = var.restore_to_point_in_time + s3_import = var.s3_import + tags = var.tags + db_instance_tags = var.db_instance_tags + db_option_group_tags = var.db_option_group_tags + db_parameter_group_tags = var.db_parameter_group_tags + db_subnet_group_tags = var.db_subnet_group_tags + create_db_subnet_group = var.create_db_subnet_group # we don't want to create db_subnet_group + db_subnet_group_name = var.db_subnet_group_name + db_subnet_group_use_name_prefix = var.db_subnet_group_use_name_prefix # we don't want to create db_subnet_group + db_subnet_group_description = var.db_subnet_group_description # we don't want to create db_subnet_group + subnet_ids = var.subnet_ids # we don't want to create db_subnet_group + parameter_group_name = local.parameter_group_name + parameter_group_use_name_prefix = var.parameter_group_use_name_prefix + parameter_group_description = var.parameter_group_description + family = local.family + parameters = var.parameters + option_group_name = var.option_group_name + option_group_use_name_prefix = var.option_group_use_name_prefix + option_group_description = var.option_group_description + major_engine_version = var.option_group_description + options = var.options + timezone = var.timezone + character_set_name = var.character_set_name + nchar_character_set_name = var.nchar_character_set_name + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + timeouts = var.timeouts + option_group_timeouts = var.option_group_timeouts + deletion_protection = var.deletion_protection + performance_insights_enabled = var.performance_insights_enabled + performance_insights_retention_period = var.performance_insights_retention_period + performance_insights_kms_key_id = var.performance_insights_kms_key_id + max_allocated_storage = var.max_allocated_storage + ca_cert_identifier = var.ca_cert_identifier + delete_automated_backups = var.delete_automated_backups + network_type = var.network_type + create_cloudwatch_log_group = local.create_cloudwatch_log_group + cloudwatch_log_group_retention_in_days = var.cloudwatch_log_group_retention_in_days + cloudwatch_log_group_kms_key_id = var.cloudwatch_log_group_kms_key_id + + cloudwatch_log_group_skip_destroy_on_deletion = local.cloudwatch_log_group_skip_destroy_on_deletion # not woeking?? + monitoring_iam_role_path = var.monitoring_iam_role_path + +} + +module "cluster" { + count = var.is_db_cluster ? 1 : 0 + source = "../opensource_tf_modules//terraform-aws-rds-aurora" + + + name = var.identifier + + # engine = var.engine + # engine_version = var.engine_version + + + # master_username = var.username + # master_password = var.password + # manage_master_user_password = var.manage_master_user_password + + tags = var.tags + create_db_subnet_group = var.create_db_subnet_group + db_subnet_group_name = var.db_subnet_group_name + + # subnets = var.subnets # we don't want to create db_subnet_group + is_primary_cluster = var.cluster_is_primary_cluster + cluster_use_name_prefix = var.cluster_use_name_prefix + allocated_storage = var.allocated_storage + allow_major_version_upgrade = var.allow_major_version_upgrade + apply_immediately = var.apply_immediately + availability_zones = var.cluster_availability_zones + backup_retention_period = var.backup_retention_period + backtrack_window = var.cluster_backtrack_window + cluster_members = var.cluster_members + copy_tags_to_snapshot = var.copy_tags_to_snapshot + database_name = var.db_name + db_cluster_instance_class = local.instance_class + db_cluster_db_instance_parameter_group_name = var.parameter_group_name # ? + deletion_protection = var.deletion_protection + enable_global_write_forwarding = var.cluster_enable_global_write_forwarding + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + enable_http_endpoint = var.cluster_enable_http_endpoint + engine = var.engine + engine_mode = var.cluster_engine_mode + engine_version = var.engine_version + final_snapshot_identifier = local.final_snapshot_identifier # update var! + global_cluster_identifier = var.cluster_global_cluster_identifier + iam_database_authentication_enabled = var.iam_database_authentication_enabled + iops = var.iops + kms_key_id = var.kms_key_id + manage_master_user_password = var.manage_master_user_password + master_user_secret_kms_key_id = var.master_user_secret_kms_key_id + master_password = var.password + master_username = var.username + network_type = var.network_type + port = var.port + preferred_backup_window = var.backup_window + preferred_maintenance_window = var.maintenance_window + replication_source_identifier = var.cluster_replication_source_identifier + restore_to_point_in_time = var.restore_to_point_in_time == null ? {} : var.restore_to_point_in_time + s3_import = var.s3_import == null ? {} : var.s3_import + scaling_configuration = var.cluster_scaling_configuration # serverlessv2_scaling_configuration + serverlessv2_scaling_configuration = var.cluster_serverlessv2_scaling_configuration + skip_final_snapshot = var.skip_final_snapshot + snapshot_identifier = var.snapshot_identifier + source_region = var.cluster_source_region + storage_encrypted = var.storage_encrypted + storage_type = var.storage_type + cluster_tags = var.cluster_tags # maybe not needed + vpc_security_group_ids = var.vpc_security_group_ids + cluster_timeouts = var.cluster_timeouts + instances = var.cluster_instances + auto_minor_version_upgrade = var.auto_minor_version_upgrade + ca_cert_identifier = var.ca_cert_identifier + db_parameter_group_name = var.parameter_group_name # ? + instances_use_identifier_prefix = var.cluster_instances_use_identifier_prefix + instance_class = local.instance_class + monitoring_interval = var.monitoring_interval + performance_insights_enabled = var.performance_insights_enabled + performance_insights_kms_key_id = var.performance_insights_kms_key_id + performance_insights_retention_period = var.performance_insights_retention_period + publicly_accessible = var.publicly_accessible + instance_timeouts = var.timeouts + endpoints = var.cluster_endpoints + iam_roles = var.cluster_iam_roles + create_monitoring_role = var.create_monitoring_role + monitoring_role_arn = var.monitoring_role_arn + iam_role_name = var.monitoring_role_arn + iam_role_use_name_prefix = var.monitoring_role_use_name_prefix + iam_role_description = var.monitoring_role_description + iam_role_path = var.monitoring_iam_role_path + iam_role_managed_policy_arns = null #var.iam_role_managed_policy_arns + iam_role_permissions_boundary = var.monitoring_role_permissions_boundary + iam_role_force_detach_policies = null #var.iam_role_force_detach_policies + iam_role_max_session_duration = null # var.iam_role_max_session_duration + autoscaling_enabled = var.cluster_autoscaling_enabled + autoscaling_max_capacity = var.cluster_autoscaling_max_capacity + autoscaling_min_capacity = var.cluster_autoscaling_min_capacity + autoscaling_policy_name = var.cluster_autoscaling_policy_name + predefined_metric_type = var.cluster_predefined_metric_type + autoscaling_scale_in_cooldown = var.cluster_autoscaling_scale_in_cooldown + autoscaling_scale_out_cooldown = var.cluster_autoscaling_scale_out_cooldown + autoscaling_target_cpu = var.cluster_autoscaling_target_cpu + autoscaling_target_connections = var.cluster_autoscaling_target_connections + # create_security_group = var.create_security_group # Create a generic security group for RDS and Aurora + # security_group_name = var.security_group_name + # security_group_use_name_prefix = var.security_group_use_name_prefix + # security_group_description = var.security_group_description + # vpc_id = var.vpc_id + # security_group_rules = var.security_group_rules + # security_group_tags = var.security_group_tags + + # create_db_cluster_parameter_group = var.create_db_cluster_parameter_group # ? + # db_cluster_parameter_group_name = var.db_cluster_parameter_group_name # ? + # db_cluster_parameter_group_use_name_prefix = var.db_cluster_parameter_group_use_name_prefix + # db_cluster_parameter_group_description = var.db_cluster_parameter_group_description + # db_cluster_parameter_group_family = var.db_cluster_parameter_group_family + # db_cluster_parameter_group_parameters = var.db_cluster_parameter_group_parameters + # create_db_parameter_group = var.create_db_parameter_group + # db_parameter_group_use_name_prefix = var.db_parameter_group_use_name_prefix + # db_parameter_group_description = var.db_parameter_group_description + # db_parameter_group_family = var.db_parameter_group_family + # db_parameter_group_parameters = var.db_parameter_group_parameters + create_cloudwatch_log_group = local.create_cloudwatch_log_group + cloudwatch_log_group_retention_in_days = var.cloudwatch_log_group_retention_in_days + cloudwatch_log_group_kms_key_id = var.cloudwatch_log_group_kms_key_id + create_db_cluster_activity_stream = var.create_db_cluster_activity_stream + db_cluster_activity_stream_mode = var.cluster_activity_stream_mode + db_cluster_activity_stream_kms_key_id = var.cluster_activity_stream_kms_key_id + engine_native_audit_fields_included = var.cluster_engine_native_audit_fields_included + + +# vpc_id = module.vpc.vpc_id +# db_subnet_group_name = module.vpc.database_subnet_group_name + +# enabled_cloudwatch_logs_exports = ["postgresql"] + +# # Multi-AZ +# availability_zones = module.vpc.azs +# allocated_storage = 256 +# db_cluster_instance_class = "db.r6gd.large" +# iops = 2500 +# storage_type = "io1" + +# skip_final_snapshot = true + +# tags = local.tags +} + +# +# lightweight_db +# major_engine_version +# resource "aws_rds_cluster" "example" { +# cluster_identifier = "example" +# availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] +# engine = "mysql" +# db_cluster_instance_class = "db.r6gd.xlarge" +# storage_type = "io1" +# allocated_storage = 100 +# iops = 1000 +# master_username = "test" +# master_password = "mustbeeightcharaters" +# } \ No newline at end of file diff --git a/variables.tf b/variables.tf index e69de29b..dd36077e 100644 --- a/variables.tf +++ b/variables.tf @@ -0,0 +1,808 @@ +# Expose vars for DB instance. Override defaults with sensible values for DFDS context + + +################################################################################ +# Instance specific variables - applicable to cluster instances as well +################################################################################ + +variable "identifier" { + description = "The name of the RDS instance" + type = string +} + +variable "instance_use_identifier_prefix" { + description = "Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix" + type = bool + default = false +} + +variable "custom_iam_instance_profile" { + description = "RDS custom iam instance profile" + type = string + default = null +} + +variable "allocated_storage" { + description = "The allocated storage in gigabytes" + type = number + default = null +} + +variable "storage_type" { + description = "One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter" + type = string + # default = null + default = "gp2" +} + +variable "storage_throughput" { + description = "Storage throughput value for the DB instance. See `notes` for limitations regarding this variable for `gp3`" + type = number + default = null +} + +variable "storage_encrypted" { + description = "Specifies whether the DB instance is encrypted" + type = bool + default = true +} + +variable "kms_key_id" { + description = "The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage_encrypted is set to true and kms_key_id is not specified the default KMS key created in your account will be used. Be sure to use the full ARN, not a key alias." + type = string + default = null +} + +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" + type = string + default = null +} + +variable "license_model" { + description = "License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1" + type = string + default = null +} + +variable "replica_mode" { + description = "Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified" + type = string + default = null +} + +variable "iam_database_authentication_enabled" { + description = "Specifies whether or not the mappings of AWS Identity and Access Management (IAM) accounts to database accounts are enabled" + type = bool + default = false +} + +variable "domain" { + description = "The ID of the Directory Service Active Directory domain to create the instance in" + type = string + default = null +} + +variable "domain_iam_role_name" { + description = "(Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service" + type = string + default = null +} + +variable "engine" { + description = "The database engine to use" + type = string +# default = null + default = "postgres" +} + +variable "engine_version" { + description = "The engine version to use" + type = string +# default = null + default = "14" +} + +variable "skip_final_snapshot" { + description = "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" + type = bool +# default = false + default = true # Snapshots are already created by the AWS backup job. +} + +variable "snapshot_identifier" { + description = "Specifies whether or not to create this database from a snapshot. This correlates to the snapshot ID you'd find in the RDS console, e.g: rds:production-2015-06-26-06-05" + type = string + default = null +} + +variable "copy_tags_to_snapshot" { + description = "On delete, copy all Instance tags to the final snapshot" + type = bool + default = false +} + +variable "final_snapshot_identifier_prefix" { + description = "The name which is prefixed to the final snapshot on cluster destroy" + type = string + default = "final" +} + +variable "instance_class" { + description = "The instance type of the RDS instance" + type = string + default = null +} + +variable "db_name" { + description = "The DB name to create. If omitted, no database is created initially" + type = string + default = null +} + +variable "username" { + description = "Username for the master DB user" + type = string + default = null +} + +variable "password" { + description = < Date: Thu, 26 Oct 2023 09:39:41 +0200 Subject: [PATCH 02/12] basic tf modules setup --- _sub/terraform-aws-rds-aurora/README.md | 422 +++++++++++ _sub/terraform-aws-rds-aurora/main.tf | 469 ++++++++++++ _sub/terraform-aws-rds-aurora/outputs.tf | 186 +++++ _sub/terraform-aws-rds-aurora/variables.tf | 710 ++++++++++++++++++ _sub/terraform-aws-rds-aurora/versions.tf | 10 + _sub/terraform-aws-rds-proxy/README.md | 165 ++++ _sub/terraform-aws-rds-proxy/main.tf | 188 +++++ _sub/terraform-aws-rds-proxy/outputs.tf | 95 +++ _sub/terraform-aws-rds-proxy/variables.tf | 255 +++++++ _sub/terraform-aws-rds-proxy/versions.tf | 10 + _sub/terraform-aws-rds/README.md | 370 +++++++++ _sub/terraform-aws-rds/main.tf | 150 ++++ .../modules/db_instance/README.md | 134 ++++ .../modules/db_instance/main.tf | 200 +++++ .../modules/db_instance/outputs.tf | 109 +++ .../modules/db_instance/variables.tf | 431 +++++++++++ .../modules/db_instance/versions.tf | 15 + .../main.tf | 9 + .../outputs.tf | 4 + .../variables.tf | 29 + .../versions.tf | 10 + .../modules/db_option_group/README.md | 47 ++ .../modules/db_option_group/main.tf | 50 ++ .../modules/db_option_group/outputs.tf | 9 + .../modules/db_option_group/variables.tf | 53 ++ .../modules/db_option_group/versions.tf | 10 + .../modules/db_parameter_group/README.md | 45 ++ .../modules/db_parameter_group/main.tf | 35 + .../modules/db_parameter_group/outputs.tf | 9 + .../modules/db_parameter_group/variables.tf | 41 + .../modules/db_parameter_group/versions.tf | 10 + .../modules/db_subnet_group/README.md | 44 ++ .../modules/db_subnet_group/main.tf | 22 + .../modules/db_subnet_group/outputs.tf | 9 + .../modules/db_subnet_group/variables.tf | 35 + .../modules/db_subnet_group/versions.tf | 10 + _sub/terraform-aws-rds/outputs.tf | 140 ++++ _sub/terraform-aws-rds/variables.tf | 552 ++++++++++++++ _sub/terraform-aws-rds/versions.tf | 10 + main.tf | 114 ++- outputs.tf | 9 + variables.tf | 28 +- 42 files changed, 5241 insertions(+), 12 deletions(-) create mode 100644 _sub/terraform-aws-rds-aurora/README.md create mode 100644 _sub/terraform-aws-rds-aurora/main.tf create mode 100644 _sub/terraform-aws-rds-aurora/outputs.tf create mode 100644 _sub/terraform-aws-rds-aurora/variables.tf create mode 100644 _sub/terraform-aws-rds-aurora/versions.tf create mode 100644 _sub/terraform-aws-rds-proxy/README.md create mode 100644 _sub/terraform-aws-rds-proxy/main.tf create mode 100644 _sub/terraform-aws-rds-proxy/outputs.tf create mode 100644 _sub/terraform-aws-rds-proxy/variables.tf create mode 100644 _sub/terraform-aws-rds-proxy/versions.tf create mode 100644 _sub/terraform-aws-rds/README.md create mode 100644 _sub/terraform-aws-rds/main.tf create mode 100644 _sub/terraform-aws-rds/modules/db_instance/README.md create mode 100644 _sub/terraform-aws-rds/modules/db_instance/main.tf create mode 100644 _sub/terraform-aws-rds/modules/db_instance/outputs.tf create mode 100644 _sub/terraform-aws-rds/modules/db_instance/variables.tf create mode 100644 _sub/terraform-aws-rds/modules/db_instance/versions.tf create mode 100644 _sub/terraform-aws-rds/modules/db_instance_automated_backups_replication/main.tf create mode 100644 _sub/terraform-aws-rds/modules/db_instance_automated_backups_replication/outputs.tf create mode 100644 _sub/terraform-aws-rds/modules/db_instance_automated_backups_replication/variables.tf create mode 100644 _sub/terraform-aws-rds/modules/db_instance_automated_backups_replication/versions.tf create mode 100644 _sub/terraform-aws-rds/modules/db_option_group/README.md create mode 100644 _sub/terraform-aws-rds/modules/db_option_group/main.tf create mode 100644 _sub/terraform-aws-rds/modules/db_option_group/outputs.tf create mode 100644 _sub/terraform-aws-rds/modules/db_option_group/variables.tf create mode 100644 _sub/terraform-aws-rds/modules/db_option_group/versions.tf create mode 100644 _sub/terraform-aws-rds/modules/db_parameter_group/README.md create mode 100644 _sub/terraform-aws-rds/modules/db_parameter_group/main.tf create mode 100644 _sub/terraform-aws-rds/modules/db_parameter_group/outputs.tf create mode 100644 _sub/terraform-aws-rds/modules/db_parameter_group/variables.tf create mode 100644 _sub/terraform-aws-rds/modules/db_parameter_group/versions.tf create mode 100644 _sub/terraform-aws-rds/modules/db_subnet_group/README.md create mode 100644 _sub/terraform-aws-rds/modules/db_subnet_group/main.tf create mode 100644 _sub/terraform-aws-rds/modules/db_subnet_group/outputs.tf create mode 100644 _sub/terraform-aws-rds/modules/db_subnet_group/variables.tf create mode 100644 _sub/terraform-aws-rds/modules/db_subnet_group/versions.tf create mode 100644 _sub/terraform-aws-rds/outputs.tf create mode 100644 _sub/terraform-aws-rds/variables.tf create mode 100644 _sub/terraform-aws-rds/versions.tf diff --git a/_sub/terraform-aws-rds-aurora/README.md b/_sub/terraform-aws-rds-aurora/README.md new file mode 100644 index 00000000..26451203 --- /dev/null +++ b/_sub/terraform-aws-rds-aurora/README.md @@ -0,0 +1,422 @@ +# AWS RDS Aurora Terraform module + +Terraform module which creates AWS RDS Aurora resources. + +[![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) + +## Available Features + +- Autoscaling of read-replicas +- Global cluster +- Enhanced monitoring +- Serverless cluster (v1 and v2) +- Import from S3 +- Fine grained control of individual cluster instances +- Custom endpoints +- RDS multi-AZ support (not Aurora) + +## Usage + +```hcl +module "cluster" { + source = "terraform-aws-modules/rds-aurora/aws" + + name = "test-aurora-db-postgres96" + engine = "aurora-postgresql" + engine_version = "14.5" + instance_class = "db.r6g.large" + instances = { + one = {} + 2 = { + instance_class = "db.r6g.2xlarge" + } + } + + vpc_id = "vpc-12345678" + db_subnet_group_name = "db-subnet-group" + security_group_rules = { + ex1_ingress = { + cidr_blocks = ["10.20.0.0/20"] + } + ex1_ingress = { + source_security_group_id = "sg-12345678" + } + } + + storage_encrypted = true + apply_immediately = true + monitoring_interval = 10 + + enabled_cloudwatch_logs_exports = ["postgresql"] + + tags = { + Environment = "dev" + Terraform = "true" + } +} +``` + +### Cluster Instance Configuration + +There are a couple different configuration methods that can be used to create instances within the cluster: + +ℹ️ Only the pertinent attributes are shown for brevity + +1. Create homogenous cluster of any number of instances + + - Resources created: + - Writer: 1 + - Reader(s): 2 + +```hcl + instance_class = "db.r6g.large" + instances = { + one = {} + two = {} + three = {} + } +``` + +2. Create homogenous cluster of instances w/ autoscaling enabled. This is redundant and we'll show why in the next example. + + - Resources created: + - Writer: 1 + - Reader(s): + - At least 4 readers (2 created directly, 2 created by appautoscaling) + - At most 7 reader instances (2 created directly, 5 created by appautoscaling) + +ℹ️ Autoscaling uses the instance class specified by `instance_class`. + +```hcl + instance_class = "db.r6g.large" + instances = { + one = {} + two = {} + three = {} + } + + autoscaling_enabled = true + autoscaling_min_capacity = 2 + autoscaling_max_capacity = 5 +``` + +3. Create homogeneous cluster scaled via autoscaling. At least one instance (writer) is required + + - Resources created: + - Writer: 1 + - Reader(s): + - At least 1 reader + - At most 5 readers + +```hcl + instance_class = "db.r6g.large" + instances = { + one = {} + } + + autoscaling_enabled = true + autoscaling_min_capacity = 1 + autoscaling_max_capacity = 5 +``` + +4. Create heterogenous cluster to support mixed-use workloads + + It is common in this configuration to independently control the instance `promotion_tier` paired with `endpoints` to create custom endpoints directed at select instances or instance groups. + + - Resources created: + - Writer: 1 + - Readers: 2 + +```hcl + instance_class = "db.r5.large" + instances = { + one = { + instance_class = "db.r5.2xlarge" + publicly_accessible = true + } + two = { + identifier = "static-member-1" + instance_class = "db.r5.2xlarge" + } + three = { + identifier = "excluded-member-1" + instance_class = "db.r5.large" + promotion_tier = 15 + } + } +``` + +5. Create heterogenous cluster to support mixed-use workloads w/ autoscaling enabled + + - Resources created: + - Writer: 1 + - Reader(s): + - At least 3 readers (2 created directly, 1 created through appautoscaling) + - At most 7 readers (2 created directly, 5 created through appautoscaling) + +ℹ️ Autoscaling uses the instance class specified by `instance_class`. + +```hcl + instance_class = "db.r5.large" + instances = { + one = { + instance_class = "db.r5.2xlarge" + publicly_accessible = true + } + two = { + identifier = "static-member-1" + instance_class = "db.r5.2xlarge" + } + three = { + identifier = "excluded-member-1" + instance_class = "db.r5.large" + promotion_tier = 15 + } + } + + autoscaling_enabled = true + autoscaling_min_capacity = 1 + autoscaling_max_capacity = 5 +``` + +## Conditional Creation + +The following values are provided to toggle on/off creation of the associated resources as desired: + +```hcl +# This RDS cluster will not be created +module "cluster" { + source = "terraform-aws-modules/rds-aurora/aws" + + # Disable creation of cluster and all resources + create = false + + # Disable creation of subnet group - provide a subnet group + create_db_subnet_group = false + + # Disable creation of security group - provide a security group + create_security_group = false + + # Disable creation of monitoring IAM role - provide a role ARN + create_monitoring_role = false + + # ... omitted +} +``` + +## Examples + +- [Autoscaling](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/autoscaling): A PostgreSQL cluster with enhanced monitoring and autoscaling enabled +- [Global Cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/global-cluster): A PostgreSQL global cluster with clusters provisioned in two different region +- [Multi-AZ](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/multi-az): A multi-AZ RDS cluster (not using Aurora engine) +- [MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/mysql): A simple MySQL cluster +- [PostgreSQL](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/postgresql): A simple PostgreSQL cluster +- [S3 Import](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/s3-import): A MySQL cluster created from a Percona Xtrabackup stored in S3 +- [Serverless](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/serverless): Serverless V1 and V2 (PostgreSQL and MySQL) + +## Documentation + +Terraform documentation is generated automatically using [pre-commit hooks](http://www.pre-commit.com/). Follow installation instructions [here](https://pre-commit.com/#install). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.67 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.67 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_appautoscaling_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_policy) | resource | +| [aws_appautoscaling_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_target) | resource | +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_db_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource | +| [aws_db_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_subnet_group) | resource | +| [aws_iam_role.rds_enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.rds_enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_rds_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster) | resource | +| [aws_rds_cluster_activity_stream.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_activity_stream) | resource | +| [aws_rds_cluster_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_endpoint) | resource | +| [aws_rds_cluster_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_instance) | resource | +| [aws_rds_cluster_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_parameter_group) | resource | +| [aws_rds_cluster_role_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_role_association) | resource | +| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_iam_policy_document.monitoring_rds_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allocated\_storage](#input\_allocated\_storage) | The amount of storage in gibibytes (GiB) to allocate to each DB instance in the Multi-AZ DB cluster. (This setting is required to create a Multi-AZ DB cluster) | `number` | `null` | no | +| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Enable to allow major engine version upgrades when changing engine versions. Defaults to `false` | `bool` | `false` | no | +| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any cluster modifications are applied immediately, or during the next maintenance window. Default is `false` | `bool` | `null` | no | +| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. Default `true` | `bool` | `null` | no | +| [autoscaling\_enabled](#input\_autoscaling\_enabled) | Determines whether autoscaling of the cluster read replicas is enabled | `bool` | `false` | no | +| [autoscaling\_max\_capacity](#input\_autoscaling\_max\_capacity) | Maximum number of read replicas permitted when autoscaling is enabled | `number` | `2` | no | +| [autoscaling\_min\_capacity](#input\_autoscaling\_min\_capacity) | Minimum number of read replicas permitted when autoscaling is enabled | `number` | `0` | no | +| [autoscaling\_policy\_name](#input\_autoscaling\_policy\_name) | Autoscaling policy name | `string` | `"target-metric"` | no | +| [autoscaling\_scale\_in\_cooldown](#input\_autoscaling\_scale\_in\_cooldown) | Cooldown in seconds before allowing further scaling operations after a scale in | `number` | `300` | no | +| [autoscaling\_scale\_out\_cooldown](#input\_autoscaling\_scale\_out\_cooldown) | Cooldown in seconds before allowing further scaling operations after a scale out | `number` | `300` | no | +| [autoscaling\_target\_connections](#input\_autoscaling\_target\_connections) | Average number of connections threshold which will initiate autoscaling. Default value is 70% of db.r4/r5/r6g.large's default max\_connections | `number` | `700` | no | +| [autoscaling\_target\_cpu](#input\_autoscaling\_target\_cpu) | CPU threshold which will initiate autoscaling | `number` | `70` | no | +| [availability\_zones](#input\_availability\_zones) | List of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created. RDS automatically assigns 3 AZs if less than 3 AZs are configured, which will show as a difference requiring resource recreation next Terraform apply | `list(string)` | `null` | no | +| [backtrack\_window](#input\_backtrack\_window) | The target backtrack window, in seconds. Only available for `aurora` engine currently. To disable backtracking, set this value to 0. Must be between 0 and 259200 (72 hours) | `number` | `null` | no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for. Default `7` | `number` | `7` | no | +| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | The identifier of the CA certificate for the DB instance | `string` | `null` | no | +| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | +| [cloudwatch\_log\_group\_retention\_in\_days](#input\_cloudwatch\_log\_group\_retention\_in\_days) | The number of days to retain CloudWatch logs for the DB instance | `number` | `7` | no | +| [cluster\_members](#input\_cluster\_members) | List of RDS Instances that are a part of this cluster | `list(string)` | `null` | no | +| [cluster\_tags](#input\_cluster\_tags) | A map of tags to add to only the cluster. Used for AWS Instance Scheduler tagging | `map(string)` | `{}` | no | +| [cluster\_timeouts](#input\_cluster\_timeouts) | Create, update, and delete timeout configurations for the cluster | `map(string)` | `{}` | no | +| [cluster\_use\_name\_prefix](#input\_cluster\_use\_name\_prefix) | Whether to use `name` as a prefix for the cluster | `bool` | `false` | no | +| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | Copy all Cluster `tags` to snapshots | `bool` | `null` | no | +| [create](#input\_create) | Whether cluster should be created (affects nearly all resources) | `bool` | `true` | no | +| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports` | `bool` | `false` | no | +| [create\_db\_cluster\_activity\_stream](#input\_create\_db\_cluster\_activity\_stream) | Determines whether a cluster activity stream is created. | `bool` | `false` | no | +| [create\_db\_cluster\_parameter\_group](#input\_create\_db\_cluster\_parameter\_group) | Determines whether a cluster parameter should be created or use existing | `bool` | `false` | no | +| [create\_db\_parameter\_group](#input\_create\_db\_parameter\_group) | Determines whether a DB parameter should be created or use existing | `bool` | `false` | no | +| [create\_db\_subnet\_group](#input\_create\_db\_subnet\_group) | Determines whether to create the database subnet group or use existing | `bool` | `false` | no | +| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Determines whether to create the IAM role for RDS enhanced monitoring | `bool` | `true` | no | +| [create\_security\_group](#input\_create\_security\_group) | Determines whether to create security group for RDS cluster | `bool` | `true` | no | +| [database\_name](#input\_database\_name) | Name for an automatically created database on cluster creation | `string` | `null` | no | +| [db\_cluster\_activity\_stream\_kms\_key\_id](#input\_db\_cluster\_activity\_stream\_kms\_key\_id) | The AWS KMS key identifier for encrypting messages in the database activity stream | `string` | `null` | no | +| [db\_cluster\_activity\_stream\_mode](#input\_db\_cluster\_activity\_stream\_mode) | Specifies the mode of the database activity stream. Database events such as a change or access generate an activity stream event. One of: sync, async | `string` | `null` | no | +| [db\_cluster\_db\_instance\_parameter\_group\_name](#input\_db\_cluster\_db\_instance\_parameter\_group\_name) | Instance parameter group to associate with all instances of the DB cluster. The `db_cluster_db_instance_parameter_group_name` is only valid in combination with `allow_major_version_upgrade` | `string` | `null` | no | +| [db\_cluster\_instance\_class](#input\_db\_cluster\_instance\_class) | The compute and memory capacity of each DB instance in the Multi-AZ DB cluster, for example db.m6g.xlarge. Not all DB instance classes are available in all AWS Regions, or for all database engines | `string` | `null` | no | +| [db\_cluster\_parameter\_group\_description](#input\_db\_cluster\_parameter\_group\_description) | The description of the DB cluster parameter group. Defaults to "Managed by Terraform" | `string` | `null` | no | +| [db\_cluster\_parameter\_group\_family](#input\_db\_cluster\_parameter\_group\_family) | The family of the DB cluster parameter group | `string` | `""` | no | +| [db\_cluster\_parameter\_group\_name](#input\_db\_cluster\_parameter\_group\_name) | The name of the DB cluster parameter group | `string` | `null` | no | +| [db\_cluster\_parameter\_group\_parameters](#input\_db\_cluster\_parameter\_group\_parameters) | A list of DB cluster parameters to apply. Note that parameters may differ from a family to an other | `list(map(string))` | `[]` | no | +| [db\_cluster\_parameter\_group\_use\_name\_prefix](#input\_db\_cluster\_parameter\_group\_use\_name\_prefix) | Determines whether the DB cluster parameter group name is used as a prefix | `bool` | `true` | no | +| [db\_parameter\_group\_description](#input\_db\_parameter\_group\_description) | The description of the DB parameter group. Defaults to "Managed by Terraform" | `string` | `null` | no | +| [db\_parameter\_group\_family](#input\_db\_parameter\_group\_family) | The family of the DB parameter group | `string` | `""` | no | +| [db\_parameter\_group\_name](#input\_db\_parameter\_group\_name) | The name of the DB parameter group | `string` | `null` | no | +| [db\_parameter\_group\_parameters](#input\_db\_parameter\_group\_parameters) | A list of DB parameters to apply. Note that parameters may differ from a family to an other | `list(map(string))` | `[]` | no | +| [db\_parameter\_group\_use\_name\_prefix](#input\_db\_parameter\_group\_use\_name\_prefix) | Determines whether the DB parameter group name is used as a prefix | `bool` | `true` | no | +| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | The name of the subnet group name (existing or created) | `string` | `""` | no | +| [deletion\_protection](#input\_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` | `null` | no | +| [enable\_global\_write\_forwarding](#input\_enable\_global\_write\_forwarding) | Whether cluster should forward writes to an associated global cluster. Applied to secondary clusters to enable them to forward writes to an `aws_rds_global_cluster`'s primary cluster | `bool` | `null` | no | +| [enable\_http\_endpoint](#input\_enable\_http\_endpoint) | Enable HTTP endpoint (data API). Only valid when engine\_mode is set to `serverless` | `bool` | `null` | no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | Set of log types to export to cloudwatch. If omitted, no logs will be exported. The following log types are supported: `audit`, `error`, `general`, `slowquery`, `postgresql` | `list(string)` | `[]` | no | +| [endpoints](#input\_endpoints) | Map of additional cluster endpoints and their attributes to be created | `any` | `{}` | no | +| [engine](#input\_engine) | The name of the database engine to be used for this DB cluster. Defaults to `aurora`. Valid Values: `aurora`, `aurora-mysql`, `aurora-postgresql` | `string` | `null` | no | +| [engine\_mode](#input\_engine\_mode) | The database engine mode. Valid values: `global`, `multimaster`, `parallelquery`, `provisioned`, `serverless`. Defaults to: `provisioned` | `string` | `"provisioned"` | no | +| [engine\_native\_audit\_fields\_included](#input\_engine\_native\_audit\_fields\_included) | Specifies whether the database activity stream includes engine-native audit fields. This option only applies to an Oracle DB instance. By default, no engine-native audit fields are included | `bool` | `false` | no | +| [engine\_version](#input\_engine\_version) | The database engine version. Updating this argument results in an outage | `string` | `null` | no | +| [final\_snapshot\_identifier](#input\_final\_snapshot\_identifier) | The name of your final DB snapshot when this DB cluster is deleted. If omitted, no final snapshot will be made | `string` | `null` | no | +| [global\_cluster\_identifier](#input\_global\_cluster\_identifier) | The global cluster identifier specified on `aws_rds_global_cluster` | `string` | `null` | no | +| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled | `bool` | `null` | no | +| [iam\_role\_description](#input\_iam\_role\_description) | Description of the monitoring role | `string` | `null` | no | +| [iam\_role\_force\_detach\_policies](#input\_iam\_role\_force\_detach\_policies) | Whether to force detaching any policies the monitoring role has before destroying it | `bool` | `null` | no | +| [iam\_role\_managed\_policy\_arns](#input\_iam\_role\_managed\_policy\_arns) | Set of exclusive IAM managed policy ARNs to attach to the monitoring role | `list(string)` | `null` | no | +| [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | Maximum session duration (in seconds) that you want to set for the monitoring role | `number` | `null` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | Friendly name of the monitoring role | `string` | `null` | no | +| [iam\_role\_path](#input\_iam\_role\_path) | Path for the monitoring role | `string` | `null` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the policy that is used to set the permissions boundary for the monitoring role | `string` | `null` | no | +| [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether to use `iam_role_name` as is or create a unique name beginning with the `iam_role_name` as the prefix | `bool` | `false` | no | +| [iam\_roles](#input\_iam\_roles) | Map of IAM roles and supported feature names to associate with the cluster | `map(map(string))` | `{}` | no | +| [instance\_class](#input\_instance\_class) | Instance type to use at master instance. Note: if `autoscaling_enabled` is `true`, this will be the same instance class used on instances created by autoscaling | `string` | `""` | no | +| [instance\_timeouts](#input\_instance\_timeouts) | Create, update, and delete timeout configurations for the cluster instance(s) | `map(string)` | `{}` | no | +| [instances](#input\_instances) | Map of cluster instances and any specific/overriding attributes to be created | `any` | `{}` | no | +| [instances\_use\_identifier\_prefix](#input\_instances\_use\_identifier\_prefix) | Determines whether cluster instance identifiers are used as prefixes | `bool` | `false` | no | +| [iops](#input\_iops) | The amount of Provisioned IOPS (input/output operations per second) to be initially allocated for each DB instance in the Multi-AZ DB cluster | `number` | `null` | no | +| [is\_primary\_cluster](#input\_is\_primary\_cluster) | Determines whether cluster is primary cluster with writer instance (set to `false` for global cluster and replica clusters) | `bool` | `true` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to `true` | `string` | `null` | no | +| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if `master_password` is provided | `bool` | `true` | no | +| [master\_password](#input\_master\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file. Required unless `manage_master_user_password` is set to `true` or unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database | `string` | `null` | no | +| [master\_user\_secret\_kms\_key\_id](#input\_master\_user\_secret\_kms\_key\_id) | The Amazon Web Services KMS key identifier is the key ARN, key ID, alias ARN, or alias name for the KMS key | `string` | `null` | no | +| [master\_username](#input\_master\_username) | Username for the master DB user. Required unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database | `string` | `null` | no | +| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for instances. Set to `0` to disable. Default is `0` | `number` | `0` | no | +| [monitoring\_role\_arn](#input\_monitoring\_role\_arn) | IAM role used by RDS to send enhanced monitoring metrics to CloudWatch | `string` | `""` | no | +| [name](#input\_name) | Name used across resources created | `string` | `""` | no | +| [network\_type](#input\_network\_type) | The type of network stack to use (IPV4 or DUAL) | `string` | `null` | no | +| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Specifies whether Performance Insights is enabled or not | `bool` | `null` | no | +| [performance\_insights\_kms\_key\_id](#input\_performance\_insights\_kms\_key\_id) | The ARN for the KMS key to encrypt Performance Insights data | `string` | `null` | no | +| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | Amount of time in days to retain Performance Insights data. Either 7 (7 days) or 731 (2 years) | `number` | `null` | no | +| [port](#input\_port) | The port on which the DB accepts connections | `string` | `null` | no | +| [predefined\_metric\_type](#input\_predefined\_metric\_type) | The metric type to scale on. Valid values are `RDSReaderAverageCPUUtilization` and `RDSReaderAverageDatabaseConnections` | `string` | `"RDSReaderAverageCPUUtilization"` | no | +| [preferred\_backup\_window](#input\_preferred\_backup\_window) | The daily time range during which automated backups are created if automated backups are enabled using the `backup_retention_period` parameter. Time in UTC | `string` | `"02:00-03:00"` | no | +| [preferred\_maintenance\_window](#input\_preferred\_maintenance\_window) | The weekly time range during which system maintenance can occur, in (UTC) | `string` | `"sun:05:00-sun:06:00"` | no | +| [publicly\_accessible](#input\_publicly\_accessible) | Determines whether instances are publicly accessible. Default `false` | `bool` | `null` | no | +| [putin\_khuylo](#input\_putin\_khuylo) | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | `bool` | `true` | no | +| [replication\_source\_identifier](#input\_replication\_source\_identifier) | ARN of a source DB cluster or DB instance if this DB cluster is to be created as a Read Replica | `string` | `null` | no | +| [restore\_to\_point\_in\_time](#input\_restore\_to\_point\_in\_time) | Map of nested attributes for cloning Aurora cluster | `map(string)` | `{}` | no | +| [s3\_import](#input\_s3\_import) | Configuration map used to restore from a Percona Xtrabackup in S3 (only MySQL is supported) | `map(string)` | `{}` | no | +| [scaling\_configuration](#input\_scaling\_configuration) | Map of nested attributes with scaling properties. Only valid when `engine_mode` is set to `serverless` | `map(string)` | `{}` | no | +| [security\_group\_description](#input\_security\_group\_description) | The description of the security group. If value is set to empty string it will contain cluster name in the description | `string` | `null` | no | +| [security\_group\_name](#input\_security\_group\_name) | The security group name. Default value is (`var.name`) | `string` | `""` | no | +| [security\_group\_rules](#input\_security\_group\_rules) | Map of security group rules to add to the cluster security group created | `any` | `{}` | no | +| [security\_group\_tags](#input\_security\_group\_tags) | Additional tags for the security group | `map(string)` | `{}` | no | +| [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`var.name`) is used as a prefix | `bool` | `true` | no | +| [serverlessv2\_scaling\_configuration](#input\_serverlessv2\_scaling\_configuration) | Map of nested attributes with serverless v2 scaling properties. Only valid when `engine_mode` is set to `provisioned` | `map(string)` | `{}` | no | +| [skip\_final\_snapshot](#input\_skip\_final\_snapshot) | Determines whether a final snapshot is created before the cluster is deleted. If true is specified, no snapshot is created | `bool` | `false` | no | +| [snapshot\_identifier](#input\_snapshot\_identifier) | Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot | `string` | `null` | no | +| [source\_region](#input\_source\_region) | The source region for an encrypted replica DB cluster | `string` | `null` | no | +| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB cluster is encrypted. The default is `true` | `bool` | `true` | no | +| [storage\_type](#input\_storage\_type) | Determines the storage type for the DB cluster. Optional for Single-AZ, required for Multi-AZ DB clusters. Valid values for Single-AZ: `aurora`, `""` (default, both refer to Aurora Standard), `aurora-iopt1` (Aurora I/O Optimized). Valid values for Multi-AZ: `io1` (default). | `string` | `null` | no | +| [subnets](#input\_subnets) | List of subnet IDs used by database subnet group created | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | `""` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of VPC security groups to associate to the cluster in addition to the security group created | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [additional\_cluster\_endpoints](#output\_additional\_cluster\_endpoints) | A map of additional cluster endpoints and their attributes | +| [cluster\_arn](#output\_cluster\_arn) | Amazon Resource Name (ARN) of cluster | +| [cluster\_database\_name](#output\_cluster\_database\_name) | Name for an automatically created database on cluster creation | +| [cluster\_endpoint](#output\_cluster\_endpoint) | Writer endpoint for the cluster | +| [cluster\_engine\_version\_actual](#output\_cluster\_engine\_version\_actual) | The running version of the cluster database | +| [cluster\_hosted\_zone\_id](#output\_cluster\_hosted\_zone\_id) | The Route53 Hosted Zone ID of the endpoint | +| [cluster\_id](#output\_cluster\_id) | The RDS Cluster Identifier | +| [cluster\_instances](#output\_cluster\_instances) | A map of cluster instances and their attributes | +| [cluster\_master\_password](#output\_cluster\_master\_password) | The database master password | +| [cluster\_master\_user\_secret](#output\_cluster\_master\_user\_secret) | The generated database master user secret when `manage_master_user_password` is set to `true` | +| [cluster\_master\_username](#output\_cluster\_master\_username) | The database master username | +| [cluster\_members](#output\_cluster\_members) | List of RDS Instances that are a part of this cluster | +| [cluster\_port](#output\_cluster\_port) | The database port | +| [cluster\_reader\_endpoint](#output\_cluster\_reader\_endpoint) | A read-only endpoint for the cluster, automatically load-balanced across replicas | +| [cluster\_resource\_id](#output\_cluster\_resource\_id) | The RDS Cluster Resource ID | +| [cluster\_role\_associations](#output\_cluster\_role\_associations) | A map of IAM roles associated with the cluster and their attributes | +| [db\_cluster\_activity\_stream\_kinesis\_stream\_name](#output\_db\_cluster\_activity\_stream\_kinesis\_stream\_name) | The name of the Amazon Kinesis data stream to be used for the database activity stream | +| [db\_cluster\_cloudwatch\_log\_groups](#output\_db\_cluster\_cloudwatch\_log\_groups) | Map of CloudWatch log groups created and their attributes | +| [db\_cluster\_parameter\_group\_arn](#output\_db\_cluster\_parameter\_group\_arn) | The ARN of the DB cluster parameter group created | +| [db\_cluster\_parameter\_group\_id](#output\_db\_cluster\_parameter\_group\_id) | The ID of the DB cluster parameter group created | +| [db\_parameter\_group\_arn](#output\_db\_parameter\_group\_arn) | The ARN of the DB parameter group created | +| [db\_parameter\_group\_id](#output\_db\_parameter\_group\_id) | The ID of the DB parameter group created | +| [db\_subnet\_group\_name](#output\_db\_subnet\_group\_name) | The db subnet group name | +| [enhanced\_monitoring\_iam\_role\_arn](#output\_enhanced\_monitoring\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the enhanced monitoring role | +| [enhanced\_monitoring\_iam\_role\_name](#output\_enhanced\_monitoring\_iam\_role\_name) | The name of the enhanced monitoring role | +| [enhanced\_monitoring\_iam\_role\_unique\_id](#output\_enhanced\_monitoring\_iam\_role\_unique\_id) | Stable and unique string identifying the enhanced monitoring role | +| [security\_group\_id](#output\_security\_group\_id) | The security group ID of the cluster | + + +## Authors + +Module is maintained by [Anton Babenko](https://github.com/antonbabenko) with help from [these awesome contributors](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/graphs/contributors). + +## License + +Apache 2 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/LICENSE) for full details. + +## Additional information for users from Russia and Belarus + +* Russia has [illegally annexed Crimea in 2014](https://en.wikipedia.org/wiki/Annexation_of_Crimea_by_the_Russian_Federation) and [brought the war in Donbas](https://en.wikipedia.org/wiki/War_in_Donbas) followed by [full-scale invasion of Ukraine in 2022](https://en.wikipedia.org/wiki/2022_Russian_invasion_of_Ukraine). +* Russia has brought sorrow and devastations to millions of Ukrainians, killed hundreds of innocent people, damaged thousands of buildings, and forced several million people to flee. +* [Putin khuylo!](https://en.wikipedia.org/wiki/Putin_khuylo!) diff --git a/_sub/terraform-aws-rds-aurora/main.tf b/_sub/terraform-aws-rds-aurora/main.tf new file mode 100644 index 00000000..46e7ddcb --- /dev/null +++ b/_sub/terraform-aws-rds-aurora/main.tf @@ -0,0 +1,469 @@ +data "aws_partition" "current" {} + +locals { + create = var.create + + port = coalesce(var.port, (var.engine == "aurora-postgresql" || var.engine == "postgres" ? 5432 : 3306)) + + internal_db_subnet_group_name = try(coalesce(var.db_subnet_group_name, var.name), "") + + ### + db_subnet_group_name = var.create_db_subnet_group ? try(aws_db_subnet_group.this[0].name, null) : local.internal_db_subnet_group_name + # db_subnet_group_name = var.db_subnet_group_name + ### + + security_group_name = try(coalesce(var.security_group_name, var.name), "") + + cluster_parameter_group_name = try(coalesce(var.db_cluster_parameter_group_name, var.name), null) + db_parameter_group_name = try(coalesce(var.db_parameter_group_name, var.name), null) + + backtrack_window = (var.engine == "aurora-mysql" || var.engine == "aurora") && var.engine_mode != "serverless" ? var.backtrack_window : 0 + + is_serverless = var.engine_mode == "serverless" +} + +################################################################################ +# DB Subnet Group +################################################################################ + +resource "aws_db_subnet_group" "this" { + count = local.create && var.create_db_subnet_group ? 1 : 0 + + name = local.internal_db_subnet_group_name + description = "For cluster ${var.name}" + subnet_ids = var.subnets + + tags = var.tags +} + +################################################################################ +# Cluster +################################################################################ + +resource "aws_rds_cluster" "this" { + count = local.create ? 1 : 0 + + allocated_storage = var.allocated_storage + allow_major_version_upgrade = var.allow_major_version_upgrade + apply_immediately = var.apply_immediately + availability_zones = var.availability_zones + backup_retention_period = var.backup_retention_period + backtrack_window = local.backtrack_window + cluster_identifier = var.cluster_use_name_prefix ? null : var.name + cluster_identifier_prefix = var.cluster_use_name_prefix ? "${var.name}-" : null + cluster_members = var.cluster_members + copy_tags_to_snapshot = var.copy_tags_to_snapshot + database_name = var.is_primary_cluster ? var.database_name : null + db_cluster_instance_class = var.db_cluster_instance_class + db_cluster_parameter_group_name = var.create_db_cluster_parameter_group ? aws_rds_cluster_parameter_group.this[0].id : var.db_cluster_parameter_group_name + db_instance_parameter_group_name = var.allow_major_version_upgrade ? var.db_cluster_db_instance_parameter_group_name : null + db_subnet_group_name = local.db_subnet_group_name + deletion_protection = var.deletion_protection + enable_global_write_forwarding = var.enable_global_write_forwarding + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + enable_http_endpoint = var.enable_http_endpoint + engine = var.engine + engine_mode = var.engine_mode + engine_version = var.engine_version + final_snapshot_identifier = var.final_snapshot_identifier + global_cluster_identifier = var.global_cluster_identifier + iam_database_authentication_enabled = var.iam_database_authentication_enabled + # iam_roles has been removed from this resource and instead will be used with aws_rds_cluster_role_association below to avoid conflicts per docs + iops = var.iops + kms_key_id = var.kms_key_id + manage_master_user_password = var.global_cluster_identifier == null && var.manage_master_user_password ? var.manage_master_user_password : null + master_user_secret_kms_key_id = var.global_cluster_identifier == null && var.manage_master_user_password ? var.master_user_secret_kms_key_id : null + master_password = var.is_primary_cluster && !var.manage_master_user_password ? var.master_password : null + master_username = var.is_primary_cluster ? var.master_username : null + network_type = var.network_type + port = local.port + preferred_backup_window = local.is_serverless ? null : var.preferred_backup_window + preferred_maintenance_window = local.is_serverless ? null : var.preferred_maintenance_window + replication_source_identifier = var.replication_source_identifier + + dynamic "restore_to_point_in_time" { + for_each = length(var.restore_to_point_in_time) > 0 ? [var.restore_to_point_in_time] : [] + + content { + restore_to_time = try(restore_to_point_in_time.value.restore_to_time, null) + restore_type = try(restore_to_point_in_time.value.restore_type, null) + source_cluster_identifier = restore_to_point_in_time.value.source_cluster_identifier + use_latest_restorable_time = try(restore_to_point_in_time.value.use_latest_restorable_time, null) + } + } + + dynamic "s3_import" { + for_each = length(var.s3_import) > 0 && !local.is_serverless ? [var.s3_import] : [] + + content { + bucket_name = s3_import.value.bucket_name + bucket_prefix = try(s3_import.value.bucket_prefix, null) + ingestion_role = s3_import.value.ingestion_role + source_engine = "mysql" + source_engine_version = s3_import.value.source_engine_version + } + } + + dynamic "scaling_configuration" { + for_each = length(var.scaling_configuration) > 0 && local.is_serverless ? [var.scaling_configuration] : [] + + content { + auto_pause = try(scaling_configuration.value.auto_pause, null) + max_capacity = try(scaling_configuration.value.max_capacity, null) + min_capacity = try(scaling_configuration.value.min_capacity, null) + seconds_until_auto_pause = try(scaling_configuration.value.seconds_until_auto_pause, null) + timeout_action = try(scaling_configuration.value.timeout_action, null) + } + } + + dynamic "serverlessv2_scaling_configuration" { + for_each = length(var.serverlessv2_scaling_configuration) > 0 && var.engine_mode == "provisioned" ? [var.serverlessv2_scaling_configuration] : [] + + content { + max_capacity = serverlessv2_scaling_configuration.value.max_capacity + min_capacity = serverlessv2_scaling_configuration.value.min_capacity + } + } + + skip_final_snapshot = var.skip_final_snapshot + snapshot_identifier = var.snapshot_identifier + source_region = var.source_region + storage_encrypted = var.storage_encrypted + storage_type = var.storage_type + tags = merge(var.tags, var.cluster_tags) + vpc_security_group_ids =var.vpc_security_group_ids # compact(concat([try(aws_security_group.this[0].id, "")], var.vpc_security_group_ids)) + + timeouts { + create = try(var.cluster_timeouts.create, null) + update = try(var.cluster_timeouts.update, null) + delete = try(var.cluster_timeouts.delete, null) + } + + lifecycle { + ignore_changes = [ + # See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster#replication_source_identifier + # Since this is used either in read-replica clusters or global clusters, this should be acceptable to specify + replication_source_identifier, + # See docs here https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_global_cluster#new-global-cluster-from-existing-db-cluster + global_cluster_identifier, + snapshot_identifier, + ] + } + + depends_on = [aws_cloudwatch_log_group.this] +} + +################################################################################ +# Cluster Instance(s) +################################################################################ + + +# TODO: remove the map and use count instead as in https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_instance#example-usage +# and here: https://dev.azure.com/dfds/Phoenix/_git/aws-modules-rds?path=/modules/db_cluster/main.tf&_a=contents&version=GBmaster +# resource "aws_rds_cluster_instance" "this" { +# count = local.create && !local.is_serverless ? var.cluster_db_instance_count : 0 + +# apply_immediately = var.apply_immediately +# auto_minor_version_upgrade = var.auto_minor_version_upgrade +# availability_zone = null # var.availability_zone +# ca_cert_identifier = var.ca_cert_identifier +# cluster_identifier = aws_rds_cluster.this[0].id +# copy_tags_to_snapshot = var.copy_tags_to_snapshot +# db_parameter_group_name = var.create_db_parameter_group ? aws_db_parameter_group.this[0].id : var.db_parameter_group_name +# db_subnet_group_name = local.db_subnet_group_name +# engine = var.engine +# engine_version = var.engine_version +# identifier = null #var.name +# identifier_prefix = "${var.name}-${count.index}-" +# instance_class = var.instance_class +# monitoring_interval = var.monitoring_interval +# monitoring_role_arn = var.create_monitoring_role ? aws_iam_role.rds_enhanced_monitoring[0].arn : var.monitoring_role_arn +# performance_insights_enabled = var.performance_insights_enabled +# performance_insights_kms_key_id = var.performance_insights_kms_key_id +# performance_insights_retention_period = var.performance_insights_retention_period +# # preferred_backup_window - is set at the cluster level and will error if provided here +# preferred_maintenance_window = var.preferred_maintenance_window +# promotion_tier = null +# publicly_accessible = var.publicly_accessible +# tags = var.tags + +# timeouts { +# create = null +# update = null +# delete = null +# } +# } +resource "aws_rds_cluster_instance" "this" { + for_each = { for k, v in var.instances : k => v if local.create && !local.is_serverless } + + apply_immediately = try(each.value.apply_immediately, var.apply_immediately) + auto_minor_version_upgrade = try(each.value.auto_minor_version_upgrade, var.auto_minor_version_upgrade) + availability_zone = try(each.value.availability_zone, null) + ca_cert_identifier = var.ca_cert_identifier + cluster_identifier = aws_rds_cluster.this[0].id + copy_tags_to_snapshot = try(each.value.copy_tags_to_snapshot, var.copy_tags_to_snapshot) + db_parameter_group_name = var.create_db_parameter_group ? aws_db_parameter_group.this[0].id : try(each.value.db_parameter_group_name, var.db_parameter_group_name) + db_subnet_group_name = local.db_subnet_group_name + engine = var.engine + engine_version = var.engine_version + identifier = var.instances_use_identifier_prefix ? null : try(each.value.identifier, "${var.name}-${each.key}") + identifier_prefix = var.instances_use_identifier_prefix ? try(each.value.identifier_prefix, "${var.name}-${each.key}-") : null + instance_class = try(each.value.instance_class, var.instance_class) + monitoring_interval = try(each.value.monitoring_interval, var.monitoring_interval) + monitoring_role_arn = var.create_monitoring_role ? try(aws_iam_role.rds_enhanced_monitoring[0].arn, null) : var.monitoring_role_arn + performance_insights_enabled = try(each.value.performance_insights_enabled, var.performance_insights_enabled) + performance_insights_kms_key_id = try(each.value.performance_insights_kms_key_id, var.performance_insights_kms_key_id) + performance_insights_retention_period = try(each.value.performance_insights_retention_period, var.performance_insights_retention_period) + # preferred_backup_window - is set at the cluster level and will error if provided here + preferred_maintenance_window = try(each.value.preferred_maintenance_window, var.preferred_maintenance_window) + promotion_tier = try(each.value.promotion_tier, null) + publicly_accessible = try(each.value.publicly_accessible, var.publicly_accessible) + tags = merge(var.tags, try(each.value.tags, {})) + + timeouts { + create = try(var.instance_timeouts.create, null) + update = try(var.instance_timeouts.update, null) + delete = try(var.instance_timeouts.delete, null) + } +} + +################################################################################ +# Cluster Endpoint(s) +################################################################################ + +resource "aws_rds_cluster_endpoint" "this" { + for_each = { for k, v in var.endpoints : k => v if local.create && !local.is_serverless } + + cluster_endpoint_identifier = each.value.identifier + cluster_identifier = aws_rds_cluster.this[0].id + custom_endpoint_type = each.value.type + excluded_members = try(each.value.excluded_members, null) + static_members = try(each.value.static_members, null) + tags = merge(var.tags, try(each.value.tags, {})) + + depends_on = [ + aws_rds_cluster_instance.this + ] +} + +################################################################################ +# Cluster IAM Roles +################################################################################ + +resource "aws_rds_cluster_role_association" "this" { + for_each = { for k, v in var.iam_roles : k => v if local.create } + + db_cluster_identifier = aws_rds_cluster.this[0].id + feature_name = each.value.feature_name + role_arn = each.value.role_arn +} + +################################################################################ +# Enhanced Monitoring +################################################################################ + +locals { + create_monitoring_role = local.create && var.create_monitoring_role && var.monitoring_interval > 0 +} + +data "aws_iam_policy_document" "monitoring_rds_assume_role" { + count = local.create_monitoring_role ? 1 : 0 + + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["monitoring.rds.${data.aws_partition.current.dns_suffix}"] + } + } +} + +resource "aws_iam_role" "rds_enhanced_monitoring" { + count = local.create_monitoring_role ? 1 : 0 + + name = var.iam_role_use_name_prefix ? null : var.iam_role_name + name_prefix = var.iam_role_use_name_prefix ? "${var.iam_role_name}-" : null + description = var.iam_role_description + path = var.iam_role_path + + assume_role_policy = data.aws_iam_policy_document.monitoring_rds_assume_role[0].json + managed_policy_arns = var.iam_role_managed_policy_arns + permissions_boundary = var.iam_role_permissions_boundary + force_detach_policies = var.iam_role_force_detach_policies + max_session_duration = var.iam_role_max_session_duration + + tags = var.tags +} + +resource "aws_iam_role_policy_attachment" "rds_enhanced_monitoring" { + count = local.create_monitoring_role ? 1 : 0 + + role = aws_iam_role.rds_enhanced_monitoring[0].name + policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" +} + +################################################################################ +# Autoscaling +################################################################################ + +resource "aws_appautoscaling_target" "this" { + count = local.create && var.autoscaling_enabled && !local.is_serverless ? 1 : 0 + + max_capacity = var.autoscaling_max_capacity + min_capacity = var.autoscaling_min_capacity + resource_id = "cluster:${aws_rds_cluster.this[0].cluster_identifier}" + scalable_dimension = "rds:cluster:ReadReplicaCount" + service_namespace = "rds" + + tags = var.tags +} + +resource "aws_appautoscaling_policy" "this" { + count = local.create && var.autoscaling_enabled && !local.is_serverless ? 1 : 0 + + name = var.autoscaling_policy_name + policy_type = "TargetTrackingScaling" + resource_id = "cluster:${aws_rds_cluster.this[0].cluster_identifier}" + scalable_dimension = "rds:cluster:ReadReplicaCount" + service_namespace = "rds" + + target_tracking_scaling_policy_configuration { + predefined_metric_specification { + predefined_metric_type = var.predefined_metric_type + } + + scale_in_cooldown = var.autoscaling_scale_in_cooldown + scale_out_cooldown = var.autoscaling_scale_out_cooldown + target_value = var.predefined_metric_type == "RDSReaderAverageCPUUtilization" ? var.autoscaling_target_cpu : var.autoscaling_target_connections + } + + depends_on = [ + aws_appautoscaling_target.this + ] +} + +# ################################################################################ +# # Security Group +# ################################################################################ + +# resource "aws_security_group" "this" { +# count = local.create && var.create_security_group ? 1 : 0 + +# name = var.security_group_use_name_prefix ? null : local.security_group_name +# name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null +# vpc_id = var.vpc_id +# description = coalesce(var.security_group_description, "Control traffic to/from RDS Aurora ${var.name}") + +# tags = merge(var.tags, var.security_group_tags, { Name = local.security_group_name }) + +# lifecycle { +# create_before_destroy = true +# } +# } + +# resource "aws_security_group_rule" "this" { +# for_each = { for k, v in var.security_group_rules : k => v if local.create && var.create_security_group } + +# # required +# type = try(each.value.type, "ingress") +# from_port = try(each.value.from_port, local.port) +# to_port = try(each.value.to_port, local.port) +# protocol = try(each.value.protocol, "tcp") +# security_group_id = aws_security_group.this[0].id + +# # optional +# cidr_blocks = try(each.value.cidr_blocks, null) +# description = try(each.value.description, null) +# ipv6_cidr_blocks = try(each.value.ipv6_cidr_blocks, null) +# prefix_list_ids = try(each.value.prefix_list_ids, null) +# source_security_group_id = try(each.value.source_security_group_id, null) +# } + +################################################################################ +# Cluster Parameter Group +################################################################################ + +resource "aws_rds_cluster_parameter_group" "this" { + count = local.create && var.create_db_cluster_parameter_group ? 1 : 0 + + name = var.db_cluster_parameter_group_use_name_prefix ? null : local.cluster_parameter_group_name + name_prefix = var.db_cluster_parameter_group_use_name_prefix ? "${local.cluster_parameter_group_name}-" : null + description = var.db_cluster_parameter_group_description + family = var.db_cluster_parameter_group_family + + dynamic "parameter" { + for_each = var.db_cluster_parameter_group_parameters + + content { + name = parameter.value.name + value = parameter.value.value + apply_method = try(parameter.value.apply_method, "immediate") + } + } + + lifecycle { + create_before_destroy = true + } + + tags = var.tags +} + +################################################################################ +# DB Parameter Group +################################################################################ + +resource "aws_db_parameter_group" "this" { + count = local.create && var.create_db_parameter_group ? 1 : 0 + + name = var.db_parameter_group_use_name_prefix ? null : local.db_parameter_group_name + name_prefix = var.db_parameter_group_use_name_prefix ? "${local.db_parameter_group_name}-" : null + description = var.db_parameter_group_description + family = var.db_parameter_group_family + + dynamic "parameter" { + for_each = var.db_parameter_group_parameters + + content { + name = parameter.value.name + value = parameter.value.value + apply_method = try(parameter.value.apply_method, "immediate") + } + } + + lifecycle { + create_before_destroy = true + } + + tags = var.tags +} + +################################################################################ +# CloudWatch Log Group +################################################################################ + +# Log groups will not be created if using a cluster identifier prefix +resource "aws_cloudwatch_log_group" "this" { + for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log if local.create && var.create_cloudwatch_log_group && !var.cluster_use_name_prefix]) + + name = "/aws/rds/cluster/${var.name}/${each.value}" + retention_in_days = var.cloudwatch_log_group_retention_in_days + kms_key_id = var.cloudwatch_log_group_kms_key_id + + tags = var.tags +} + +################################################################################ +# Cluster Activity Stream +################################################################################ + +resource "aws_rds_cluster_activity_stream" "this" { + count = local.create && var.create_db_cluster_activity_stream ? 1 : 0 + + resource_arn = aws_rds_cluster.this[0].arn + mode = var.db_cluster_activity_stream_mode + kms_key_id = var.db_cluster_activity_stream_kms_key_id + engine_native_audit_fields_included = var.engine_native_audit_fields_included + + depends_on = [aws_rds_cluster_instance.this] +} diff --git a/_sub/terraform-aws-rds-aurora/outputs.tf b/_sub/terraform-aws-rds-aurora/outputs.tf new file mode 100644 index 00000000..49bfe4ad --- /dev/null +++ b/_sub/terraform-aws-rds-aurora/outputs.tf @@ -0,0 +1,186 @@ +################################################################################ +# DB Subnet Group +################################################################################ + +output "db_subnet_group_name" { + description = "The db subnet group name" + value = local.db_subnet_group_name +} + +################################################################################ +# Cluster +################################################################################ + +output "cluster_arn" { + description = "Amazon Resource Name (ARN) of cluster" + value = try(aws_rds_cluster.this[0].arn, null) +} + +output "cluster_id" { + description = "The RDS Cluster Identifier" + value = try(aws_rds_cluster.this[0].id, null) +} + +output "cluster_resource_id" { + description = "The RDS Cluster Resource ID" + value = try(aws_rds_cluster.this[0].cluster_resource_id, null) +} + +output "cluster_members" { + description = "List of RDS Instances that are a part of this cluster" + value = try(aws_rds_cluster.this[0].cluster_members, null) +} + +output "cluster_endpoint" { + description = "Writer endpoint for the cluster" + value = try(aws_rds_cluster.this[0].endpoint, null) +} + +output "cluster_reader_endpoint" { + description = "A read-only endpoint for the cluster, automatically load-balanced across replicas" + value = try(aws_rds_cluster.this[0].reader_endpoint, null) +} + +output "cluster_engine_version_actual" { + description = "The running version of the cluster database" + value = try(aws_rds_cluster.this[0].engine_version_actual, null) +} + +# database_name is not set on `aws_rds_cluster` resource if it was not specified, so can't be used in output +output "cluster_database_name" { + description = "Name for an automatically created database on cluster creation" + value = var.database_name +} + +output "cluster_port" { + description = "The database port" + value = try(aws_rds_cluster.this[0].port, null) +} + +output "cluster_master_password" { + description = "The database master password" + value = try(aws_rds_cluster.this[0].master_password, null) + sensitive = true +} + +output "cluster_master_username" { + description = "The database master username" + value = try(aws_rds_cluster.this[0].master_username, null) + sensitive = true +} + +output "cluster_master_user_secret" { + description = "The generated database master user secret when `manage_master_user_password` is set to `true`" + value = try(aws_rds_cluster.this[0].master_user_secret, null) +} + +output "cluster_master_user_secret_arn" { + description = "The ARN of the master user secret (Only available when manage_master_user_password is set to true)" + value = try(aws_rds_cluster.this[0].master_user_secret[0].secret_arn, null) +} + +output "cluster_hosted_zone_id" { + description = "The Route53 Hosted Zone ID of the endpoint" + value = try(aws_rds_cluster.this[0].hosted_zone_id, null) +} + +################################################################################ +# Cluster Instance(s) +################################################################################ + +output "cluster_instances" { + description = "A map of cluster instances and their attributes" + value = aws_rds_cluster_instance.this +} + +################################################################################ +# Cluster Endpoint(s) +################################################################################ + +output "additional_cluster_endpoints" { + description = "A map of additional cluster endpoints and their attributes" + value = aws_rds_cluster_endpoint.this +} + +################################################################################ +# Cluster IAM Roles +################################################################################ + +output "cluster_role_associations" { + description = "A map of IAM roles associated with the cluster and their attributes" + value = aws_rds_cluster_role_association.this +} + +################################################################################ +# Enhanced Monitoring +################################################################################ + +output "enhanced_monitoring_iam_role_name" { + description = "The name of the enhanced monitoring role" + value = try(aws_iam_role.rds_enhanced_monitoring[0].name, null) +} + +output "enhanced_monitoring_iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the enhanced monitoring role" + value = try(aws_iam_role.rds_enhanced_monitoring[0].arn, null) +} + +output "enhanced_monitoring_iam_role_unique_id" { + description = "Stable and unique string identifying the enhanced monitoring role" + value = try(aws_iam_role.rds_enhanced_monitoring[0].unique_id, null) +} + +################################################################################ +# Security Group +################################################################################ + +# output "security_group_id" { +# description = "The security group ID of the cluster" +# value = try(aws_security_group.this[0].id, null) +# } + +################################################################################ +# Cluster Parameter Group +################################################################################ + +output "db_cluster_parameter_group_arn" { + description = "The ARN of the DB cluster parameter group created" + value = try(aws_rds_cluster_parameter_group.this[0].arn, null) +} + +output "db_cluster_parameter_group_id" { + description = "The ID of the DB cluster parameter group created" + value = try(aws_rds_cluster_parameter_group.this[0].id, null) +} + +################################################################################ +# DB Parameter Group +################################################################################ + +output "db_parameter_group_arn" { + description = "The ARN of the DB parameter group created" + value = try(aws_db_parameter_group.this[0].arn, null) +} + +output "db_parameter_group_id" { + description = "The ID of the DB parameter group created" + value = try(aws_db_parameter_group.this[0].id, null) +} + +################################################################################ +# CloudWatch Log Group +################################################################################ + +output "db_cluster_cloudwatch_log_groups" { + description = "Map of CloudWatch log groups created and their attributes" + value = aws_cloudwatch_log_group.this +} + +################################################################################ +# Cluster Activity Stream +################################################################################ + +output "db_cluster_activity_stream_kinesis_stream_name" { + description = "The name of the Amazon Kinesis data stream to be used for the database activity stream" + value = try(aws_rds_cluster_activity_stream.this[0].kinesis_stream_name, null) +} \ No newline at end of file diff --git a/_sub/terraform-aws-rds-aurora/variables.tf b/_sub/terraform-aws-rds-aurora/variables.tf new file mode 100644 index 00000000..4fe65bc3 --- /dev/null +++ b/_sub/terraform-aws-rds-aurora/variables.tf @@ -0,0 +1,710 @@ +variable "create" { + description = "Whether cluster should be created (affects nearly all resources)" + type = bool + default = true +} + +variable "name" { + description = "Name used across resources created" + type = string + default = "" +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +################################################################################ +# DB Subnet Group +################################################################################ + +variable "create_db_subnet_group" { + description = "Determines whether to create the database subnet group or use existing" + type = bool + default = false +} + +variable "db_subnet_group_name" { + description = "The name of the subnet group name (existing or created)" + type = string + default = "" +} + +variable "subnets" { + description = "List of subnet IDs used by database subnet group created" + type = list(string) + default = [] +} + +################################################################################ +# Cluster +################################################################################ + +variable "is_primary_cluster" { + description = "Determines whether cluster is primary cluster with writer instance (set to `false` for global cluster and replica clusters)" + type = bool + default = true +} + +variable "cluster_use_name_prefix" { + description = "Whether to use `name` as a prefix for the cluster" + type = bool + default = false +} + +variable "allocated_storage" { + description = "The amount of storage in gibibytes (GiB) to allocate to each DB instance in the Multi-AZ DB cluster. (This setting is required to create a Multi-AZ DB cluster)" + type = number + default = null +} + +variable "allow_major_version_upgrade" { + description = "Enable to allow major engine version upgrades when changing engine versions. Defaults to `false`" + type = bool + default = false +} + +variable "apply_immediately" { + description = "Specifies whether any cluster modifications are applied immediately, or during the next maintenance window. Default is `false`" + type = bool + default = null +} + +variable "availability_zones" { + description = "List of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created. RDS automatically assigns 3 AZs if less than 3 AZs are configured, which will show as a difference requiring resource recreation next Terraform apply" + type = list(string) + default = null +} + +variable "backup_retention_period" { + description = "The days to retain backups for. Default `7`" + type = number + default = 7 +} + +variable "backtrack_window" { + description = "The target backtrack window, in seconds. Only available for `aurora` engine currently. To disable backtracking, set this value to 0. Must be between 0 and 259200 (72 hours)" + type = number + default = null +} + +variable "cluster_members" { + description = "List of RDS Instances that are a part of this cluster" + type = list(string) + default = null +} + +variable "copy_tags_to_snapshot" { + description = "Copy all Cluster `tags` to snapshots" + type = bool + default = null +} + +variable "database_name" { + description = "Name for an automatically created database on cluster creation" + type = string + default = null +} + +variable "db_cluster_instance_class" { + description = "The compute and memory capacity of each DB instance in the Multi-AZ DB cluster, for example db.m6g.xlarge. Not all DB instance classes are available in all AWS Regions, or for all database engines" + type = string + default = null +} + +variable "db_cluster_db_instance_parameter_group_name" { + description = "Instance parameter group to associate with all instances of the DB cluster. The `db_cluster_db_instance_parameter_group_name` is only valid in combination with `allow_major_version_upgrade`" + type = string + default = null +} + +variable "deletion_protection" { + description = "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`" + type = bool + default = null +} + +variable "enable_global_write_forwarding" { + description = "Whether cluster should forward writes to an associated global cluster. Applied to secondary clusters to enable them to forward writes to an `aws_rds_global_cluster`'s primary cluster" + type = bool + default = null +} + +variable "enabled_cloudwatch_logs_exports" { + description = "Set of log types to export to cloudwatch. If omitted, no logs will be exported. The following log types are supported: `audit`, `error`, `general`, `slowquery`, `postgresql`" + type = list(string) + default = [] +} + +variable "enable_http_endpoint" { + description = "Enable HTTP endpoint (data API). Only valid when engine_mode is set to `serverless`" + type = bool + default = null +} + +variable "engine" { + description = "The name of the database engine to be used for this DB cluster. Defaults to `aurora`. Valid Values: `aurora`, `aurora-mysql`, `aurora-postgresql`" + type = string + default = null +} + +variable "engine_mode" { + description = "The database engine mode. Valid values: `global`, `multimaster`, `parallelquery`, `provisioned`, `serverless`. Defaults to: `provisioned`" + type = string + default = "provisioned" +} + +variable "engine_version" { + description = "The database engine version. Updating this argument results in an outage" + type = string + default = null +} + +variable "final_snapshot_identifier" { + description = "The name of your final DB snapshot when this DB cluster is deleted. If omitted, no final snapshot will be made" + type = string + default = null +} + +variable "global_cluster_identifier" { + description = "The global cluster identifier specified on `aws_rds_global_cluster`" + type = string + default = null +} + +variable "iam_database_authentication_enabled" { + description = "Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled" + type = bool + default = null +} + +variable "iops" { + description = "The amount of Provisioned IOPS (input/output operations per second) to be initially allocated for each DB instance in the Multi-AZ DB cluster" + type = number + default = null +} + +variable "kms_key_id" { + description = "The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to `true`" + type = string + default = null +} + +variable "manage_master_user_password" { + description = "Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if `master_password` is provided" + type = bool + default = true +} + +variable "master_user_secret_kms_key_id" { + description = "The Amazon Web Services KMS key identifier is the key ARN, key ID, alias ARN, or alias name for the KMS key" + type = string + default = null +} + +variable "master_password" { + description = "Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file. Required unless `manage_master_user_password` is set to `true` or unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database" + type = string + default = null +} + +variable "master_username" { + description = "Username for the master DB user. Required unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database" + type = string + default = null +} + +variable "network_type" { + description = "The type of network stack to use (IPV4 or DUAL)" + type = string + default = null +} + +variable "port" { + description = "The port on which the DB accepts connections" + type = string + default = null +} + +variable "preferred_backup_window" { + description = "The daily time range during which automated backups are created if automated backups are enabled using the `backup_retention_period` parameter. Time in UTC" + type = string + default = "02:00-03:00" +} + +variable "preferred_maintenance_window" { + description = "The weekly time range during which system maintenance can occur, in (UTC)" + type = string + default = "sun:05:00-sun:06:00" +} + +variable "replication_source_identifier" { + description = "ARN of a source DB cluster or DB instance if this DB cluster is to be created as a Read Replica" + type = string + default = null +} + +variable "restore_to_point_in_time" { + description = "Map of nested attributes for cloning Aurora cluster" + type = map(string) + default = {} +} + +variable "s3_import" { + description = "Configuration map used to restore from a Percona Xtrabackup in S3 (only MySQL is supported)" + type = map(string) + default = {} +} + +variable "scaling_configuration" { + description = "Map of nested attributes with scaling properties. Only valid when `engine_mode` is set to `serverless`" + type = map(string) + default = {} +} + +variable "serverlessv2_scaling_configuration" { + description = "Map of nested attributes with serverless v2 scaling properties. Only valid when `engine_mode` is set to `provisioned`" + type = map(string) + default = {} +} + +variable "skip_final_snapshot" { + description = "Determines whether a final snapshot is created before the cluster is deleted. If true is specified, no snapshot is created" + type = bool + default = false +} + +variable "snapshot_identifier" { + description = "Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot" + type = string + default = null +} + +variable "source_region" { + description = "The source region for an encrypted replica DB cluster" + type = string + default = null +} + +variable "storage_encrypted" { + description = "Specifies whether the DB cluster is encrypted. The default is `true`" + type = bool + default = true +} + +variable "storage_type" { + description = "Determines the storage type for the DB cluster. Optional for Single-AZ, required for Multi-AZ DB clusters. Valid values for Single-AZ: `aurora`, `\"\"` (default, both refer to Aurora Standard), `aurora-iopt1` (Aurora I/O Optimized). Valid values for Multi-AZ: `io1` (default)." + type = string + default = null +} + +variable "cluster_tags" { + description = "A map of tags to add to only the cluster. Used for AWS Instance Scheduler tagging" + type = map(string) + default = {} +} + +variable "vpc_security_group_ids" { + description = "List of VPC security groups to associate to the cluster in addition to the security group created" + type = list(string) + default = [] +} + +variable "cluster_timeouts" { + description = "Create, update, and delete timeout configurations for the cluster" + type = map(string) + default = {} +} + +################################################################################ +# Cluster Instance(s) +################################################################################ + +variable "instances" { + description = "Map of cluster instances and any specific/overriding attributes to be created" + type = any + default = {} +} +variable "cluster_db_instance_count" { +type = number +} + +variable "auto_minor_version_upgrade" { + description = "Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. Default `true`" + type = bool + default = null +} + +variable "ca_cert_identifier" { + description = "The identifier of the CA certificate for the DB instance" + type = string + default = null +} + +variable "db_parameter_group_name" { + description = "The name of the DB parameter group" + type = string + default = null +} + +variable "instances_use_identifier_prefix" { + description = "Determines whether cluster instance identifiers are used as prefixes" + type = bool + default = false +} + +variable "instance_class" { + description = "Instance type to use at master instance. Note: if `autoscaling_enabled` is `true`, this will be the same instance class used on instances created by autoscaling" + type = string + default = "" +} + +variable "monitoring_interval" { + description = "The interval, in seconds, between points when Enhanced Monitoring metrics are collected for instances. Set to `0` to disable. Default is `0`" + type = number + default = 0 +} + +variable "performance_insights_enabled" { + description = "Specifies whether Performance Insights is enabled or not" + type = bool + default = null +} + +variable "performance_insights_kms_key_id" { + description = "The ARN for the KMS key to encrypt Performance Insights data" + type = string + default = null +} + +variable "performance_insights_retention_period" { + description = "Amount of time in days to retain Performance Insights data. Either 7 (7 days) or 731 (2 years)" + type = number + default = null +} + +variable "publicly_accessible" { + description = "Determines whether instances are publicly accessible. Default `false`" + type = bool + default = null +} + +variable "instance_timeouts" { + description = "Create, update, and delete timeout configurations for the cluster instance(s)" + type = map(string) + default = {} +} + +################################################################################ +# Cluster Endpoint(s) +################################################################################ + +variable "endpoints" { + description = "Map of additional cluster endpoints and their attributes to be created" + type = any + default = {} +} + +################################################################################ +# Cluster IAM Roles +################################################################################ + +variable "iam_roles" { + description = "Map of IAM roles and supported feature names to associate with the cluster" + type = map(map(string)) + default = {} +} + +################################################################################ +# Enhanced Monitoring +################################################################################ + +variable "create_monitoring_role" { + description = "Determines whether to create the IAM role for RDS enhanced monitoring" + type = bool + default = true +} + +variable "monitoring_role_arn" { + description = "IAM role used by RDS to send enhanced monitoring metrics to CloudWatch" + type = string + default = "" +} + +variable "iam_role_name" { + description = "Friendly name of the monitoring role" + type = string + default = null +} + +variable "iam_role_use_name_prefix" { + description = "Determines whether to use `iam_role_name` as is or create a unique name beginning with the `iam_role_name` as the prefix" + type = bool + default = false +} + +variable "iam_role_description" { + description = "Description of the monitoring role" + type = string + default = null +} + +variable "iam_role_path" { + description = "Path for the monitoring role" + type = string + default = null +} + +variable "iam_role_managed_policy_arns" { + description = "Set of exclusive IAM managed policy ARNs to attach to the monitoring role" + type = list(string) + default = null +} + +variable "iam_role_permissions_boundary" { + description = "The ARN of the policy that is used to set the permissions boundary for the monitoring role" + type = string + default = null +} + +variable "iam_role_force_detach_policies" { + description = "Whether to force detaching any policies the monitoring role has before destroying it" + type = bool + default = null +} + +variable "iam_role_max_session_duration" { + description = "Maximum session duration (in seconds) that you want to set for the monitoring role" + type = number + default = null +} + +################################################################################ +# Autoscaling +################################################################################ + +variable "autoscaling_enabled" { + description = "Determines whether autoscaling of the cluster read replicas is enabled" + type = bool + default = false +} + +variable "autoscaling_max_capacity" { + description = "Maximum number of read replicas permitted when autoscaling is enabled" + type = number + default = 2 +} + +variable "autoscaling_min_capacity" { + description = "Minimum number of read replicas permitted when autoscaling is enabled" + type = number + default = 0 +} + +variable "autoscaling_policy_name" { + description = "Autoscaling policy name" + type = string + default = "target-metric" +} + +variable "predefined_metric_type" { + description = "The metric type to scale on. Valid values are `RDSReaderAverageCPUUtilization` and `RDSReaderAverageDatabaseConnections`" + type = string + default = "RDSReaderAverageCPUUtilization" +} + +variable "autoscaling_scale_in_cooldown" { + description = "Cooldown in seconds before allowing further scaling operations after a scale in" + type = number + default = 300 +} + +variable "autoscaling_scale_out_cooldown" { + description = "Cooldown in seconds before allowing further scaling operations after a scale out" + type = number + default = 300 +} + +variable "autoscaling_target_cpu" { + description = "CPU threshold which will initiate autoscaling" + type = number + default = 70 +} + +variable "autoscaling_target_connections" { + description = "Average number of connections threshold which will initiate autoscaling. Default value is 70% of db.r4/r5/r6g.large's default max_connections" + type = number + default = 700 +} + +################################################################################ +# Security Group +################################################################################ + +variable "create_security_group" { + description = "Determines whether to create security group for RDS cluster" + type = bool + default = true +} + +variable "security_group_name" { + description = "The security group name. Default value is (`var.name`)" + type = string + default = "" +} + +variable "security_group_use_name_prefix" { + description = "Determines whether the security group name (`var.name`) is used as a prefix" + type = bool + default = true +} + +variable "security_group_description" { + description = "The description of the security group. If value is set to empty string it will contain cluster name in the description" + type = string + default = null +} + +variable "vpc_id" { + description = "ID of the VPC where to create security group" + type = string + default = "" +} + +variable "security_group_rules" { + description = "Map of security group rules to add to the cluster security group created" + type = any + default = {} +} + +variable "security_group_tags" { + description = "Additional tags for the security group" + type = map(string) + default = {} +} + +################################################################################ +# Cluster Parameter Group +################################################################################ + +variable "create_db_cluster_parameter_group" { + description = "Determines whether a cluster parameter should be created or use existing" + type = bool + default = false +} + +variable "db_cluster_parameter_group_name" { + description = "The name of the DB cluster parameter group" + type = string + default = null +} + +variable "db_cluster_parameter_group_use_name_prefix" { + description = "Determines whether the DB cluster parameter group name is used as a prefix" + type = bool + default = true +} + +variable "db_cluster_parameter_group_description" { + description = "The description of the DB cluster parameter group. Defaults to \"Managed by Terraform\"" + type = string + default = null +} + +variable "db_cluster_parameter_group_family" { + description = "The family of the DB cluster parameter group" + type = string + default = "" +} + +variable "db_cluster_parameter_group_parameters" { + description = "A list of DB cluster parameters to apply. Note that parameters may differ from a family to an other" + type = list(map(string)) + default = [] +} + +################################################################################ +# DB Parameter Group +################################################################################ + +variable "create_db_parameter_group" { + description = "Determines whether a DB parameter should be created or use existing" + type = bool + default = false +} + +variable "db_parameter_group_use_name_prefix" { + description = "Determines whether the DB parameter group name is used as a prefix" + type = bool + default = true +} + +variable "db_parameter_group_description" { + description = "The description of the DB parameter group. Defaults to \"Managed by Terraform\"" + type = string + default = null +} + +variable "db_parameter_group_family" { + description = "The family of the DB parameter group" + type = string + default = "" +} + +variable "db_parameter_group_parameters" { + description = "A list of DB parameters to apply. Note that parameters may differ from a family to an other" + type = list(map(string)) + default = [] +} + +################################################################################ +# CloudWatch Log Group +################################################################################ + +variable "create_cloudwatch_log_group" { + description = "Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports`" + type = bool + default = false +} + +variable "cloudwatch_log_group_retention_in_days" { + description = "The number of days to retain CloudWatch logs for the DB instance" + type = number + default = 7 +} + +variable "cloudwatch_log_group_kms_key_id" { + description = "The ARN of the KMS Key to use when encrypting log data" + type = string + default = null +} + +################################################################################ +# Cluster Activity Stream +################################################################################ + +variable "create_db_cluster_activity_stream" { + description = "Determines whether a cluster activity stream is created." + type = bool + default = false +} + +variable "db_cluster_activity_stream_mode" { + description = "Specifies the mode of the database activity stream. Database events such as a change or access generate an activity stream event. One of: sync, async" + type = string + default = null +} + +variable "db_cluster_activity_stream_kms_key_id" { + description = "The AWS KMS key identifier for encrypting messages in the database activity stream" + type = string + default = null +} + +variable "engine_native_audit_fields_included" { + description = "Specifies whether the database activity stream includes engine-native audit fields. This option only applies to an Oracle DB instance. By default, no engine-native audit fields are included" + type = bool + default = false +} diff --git a/_sub/terraform-aws-rds-aurora/versions.tf b/_sub/terraform-aws-rds-aurora/versions.tf new file mode 100644 index 00000000..47125bf8 --- /dev/null +++ b/_sub/terraform-aws-rds-aurora/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.67" + } + } +} diff --git a/_sub/terraform-aws-rds-proxy/README.md b/_sub/terraform-aws-rds-proxy/README.md new file mode 100644 index 00000000..4fcd4d5e --- /dev/null +++ b/_sub/terraform-aws-rds-proxy/README.md @@ -0,0 +1,165 @@ +# AWS RDS Proxy Terraform module + +Terraform module which creates an AWS RDS Proxy and its supporting resources. + +## Usage + +See [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) directory for working examples to reference: + +```hcl +module "rds_proxy" { + source = "terraform-aws-modules/rds-proxy/aws" + + name = "rds-proxy" + iam_role_name = "rds-proxy-role" + vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] + vpc_security_group_ids = ["sg-f1d03a88"] + + endpoints = { + read_write = { + name = "read-write-endpoint" + vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] + vpc_security_group_ids = ["sg-f1d03a88"] + }, + read_only = { + name = "read-only-endpoint" + vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] + vpc_security_group_ids = ["sg-f1d03a88"] + target_role = "READ_ONLY" + } + } + + auth = { + "superuser" = { + description = "Aurora PostgreSQL superuser password" + secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD" + } + } + + # Target Aurora cluster + engine_family = "POSTGRESQL" + target_db_cluster = true + db_cluster_identifier = "my-endpoint" + + tags = { + Terraform = "true" + Environment = "dev" + } +} +``` + +## Examples + +Examples codified under the [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module(s). If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you! + +- [IAM auth. w/ MySQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-cluster) +- [IAM auth. w/ MySQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-instance) +- [IAM auth. w/ PostgreSQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-cluster) +- [IAM auth. w/ PostgreSQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-instance) + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_db_proxy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy) | resource | +| [aws_db_proxy_default_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_default_target_group) | resource | +| [aws_db_proxy_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_endpoint) | resource | +| [aws_db_proxy_target.db_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | +| [aws_db_proxy_target.db_instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | +| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auth](#input\_auth) | Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters | `any` | `{}` | no | +| [connection\_borrow\_timeout](#input\_connection\_borrow\_timeout) | The number of seconds for a proxy to wait for a connection to become available in the connection pool | `number` | `null` | no | +| [create](#input\_create) | Whether cluster should be created (affects nearly all resources) | `bool` | `true` | no | +| [create\_iam\_policy](#input\_create\_iam\_policy) | Determines whether an IAM policy is created | `bool` | `true` | no | +| [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created | `bool` | `true` | no | +| [db\_cluster\_identifier](#input\_db\_cluster\_identifier) | DB cluster identifier | `string` | `""` | no | +| [db\_instance\_identifier](#input\_db\_instance\_identifier) | DB instance identifier | `string` | `""` | no | +| [debug\_logging](#input\_debug\_logging) | Whether the proxy includes detailed information about SQL statements in its logs | `bool` | `false` | no | +| [endpoints](#input\_endpoints) | Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`) | `any` | `{}` | no | +| [engine\_family](#input\_engine\_family) | The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL` | `string` | `""` | no | +| [iam\_policy\_name](#input\_iam\_policy\_name) | The name of the role policy. If omitted, Terraform will assign a random, unique name | `string` | `""` | no | +| [iam\_role\_description](#input\_iam\_role\_description) | The description of the role | `string` | `""` | no | +| [iam\_role\_force\_detach\_policies](#input\_iam\_role\_force\_detach\_policies) | Specifies to force detaching any policies the role has before destroying it | `bool` | `true` | no | +| [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | The maximum session duration (in seconds) that you want to set for the specified role | `number` | `43200` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | The name of the role. If omitted, Terraform will assign a random, unique name | `string` | `""` | no | +| [iam\_role\_path](#input\_iam\_role\_path) | The path to the role | `string` | `null` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the policy that is used to set the permissions boundary for the role | `string` | `null` | no | +| [iam\_role\_tags](#input\_iam\_role\_tags) | A map of tags to apply to the IAM role | `map(string)` | `{}` | no | +| [idle\_client\_timeout](#input\_idle\_client\_timeout) | The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it | `number` | `1800` | no | +| [init\_query](#input\_init\_query) | One or more SQL statements for the proxy to run when opening each new database connection | `string` | `""` | no | +| [kms\_key\_arns](#input\_kms\_key\_arns) | List of KMS Key ARNs to allow access to decrypt SecretsManager secrets | `list(string)` | `[]` | no | +| [log\_group\_kms\_key\_id](#input\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | +| [log\_group\_retention\_in\_days](#input\_log\_group\_retention\_in\_days) | Specifies the number of days you want to retain log events in the log group | `number` | `30` | no | +| [log\_group\_tags](#input\_log\_group\_tags) | A map of tags to apply to the CloudWatch log group | `map(string)` | `{}` | no | +| [manage\_log\_group](#input\_manage\_log\_group) | Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist | `bool` | `true` | no | +| [max\_connections\_percent](#input\_max\_connections\_percent) | The maximum size of the connection pool for each target in a target group | `number` | `90` | no | +| [max\_idle\_connections\_percent](#input\_max\_idle\_connections\_percent) | Controls how actively the proxy closes idle database connections in the connection pool | `number` | `50` | no | +| [name](#input\_name) | The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens | `string` | `""` | no | +| [proxy\_tags](#input\_proxy\_tags) | A map of tags to apply to the RDS Proxy | `map(string)` | `{}` | no | +| [require\_tls](#input\_require\_tls) | A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy | `bool` | `true` | no | +| [role\_arn](#input\_role\_arn) | The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager | `string` | `""` | no | +| [session\_pinning\_filters](#input\_session\_pinning\_filters) | Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [target\_db\_cluster](#input\_target\_db\_cluster) | Determines whether DB cluster is targeted by proxy | `bool` | `false` | no | +| [target\_db\_instance](#input\_target\_db\_instance) | Determines whether DB instance is targeted by proxy | `bool` | `false` | no | +| [use\_policy\_name\_prefix](#input\_use\_policy\_name\_prefix) | Whether to use unique name beginning with the specified `iam_policy_name` | `bool` | `false` | no | +| [use\_role\_name\_prefix](#input\_use\_role\_name\_prefix) | Whether to use unique name beginning with the specified `iam_role_name` | `bool` | `false` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | One or more VPC security group IDs to associate with the new proxy | `list(string)` | `[]` | no | +| [vpc\_subnet\_ids](#input\_vpc\_subnet\_ids) | One or more VPC subnet IDs to associate with the new proxy | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created | +| [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager. | +| [iam\_role\_name](#output\_iam\_role\_name) | IAM role name | +| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group | +| [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy | +| [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group | +| [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group | +| [proxy\_default\_target\_group\_name](#output\_proxy\_default\_target\_group\_name) | The name of the default target group | +| [proxy\_endpoint](#output\_proxy\_endpoint) | The endpoint that you can use to connect to the proxy | +| [proxy\_id](#output\_proxy\_id) | The ID for the proxy | +| [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | +| [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) | +| [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB Instance or Aurora DB Cluster | +| [proxy\_target\_rds\_resource\_id](#output\_proxy\_target\_rds\_resource\_id) | Identifier representing the DB Instance or DB Cluster target | +| [proxy\_target\_target\_arn](#output\_proxy\_target\_target\_arn) | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API | +| [proxy\_target\_tracked\_cluster\_id](#output\_proxy\_target\_tracked\_cluster\_id) | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster | +| [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` | + + +## License + +Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE). diff --git a/_sub/terraform-aws-rds-proxy/main.tf b/_sub/terraform-aws-rds-proxy/main.tf new file mode 100644 index 00000000..e8a8efc6 --- /dev/null +++ b/_sub/terraform-aws-rds-proxy/main.tf @@ -0,0 +1,188 @@ +locals { + role_arn = var.create && var.create_iam_role ? aws_iam_role.this[0].arn : var.role_arn + role_name = coalesce(var.iam_role_name, var.name) + policy_name = coalesce(var.iam_policy_name, var.name) +} + +data "aws_region" "current" {} +data "aws_partition" "current" {} + +################################################################################ +# RDS Proxy +################################################################################ + +resource "aws_db_proxy" "this" { + count = var.create ? 1 : 0 + + dynamic "auth" { + for_each = var.auth + + content { + auth_scheme = try(auth.value.auth_scheme, "SECRETS") + client_password_auth_type = try(auth.value.client_password_auth_type, null) + description = try(auth.value.description, null) + iam_auth = try(auth.value.iam_auth, null) + secret_arn = try(auth.value.secret_arn, null) + username = try(auth.value.username, null) + } + } + + debug_logging = var.debug_logging + engine_family = var.engine_family + idle_client_timeout = var.idle_client_timeout + name = var.name + require_tls = var.require_tls + role_arn = local.role_arn + vpc_security_group_ids = var.vpc_security_group_ids + vpc_subnet_ids = var.vpc_subnet_ids + + tags = merge(var.tags, var.proxy_tags) + + depends_on = [aws_cloudwatch_log_group.this] +} + +resource "aws_db_proxy_default_target_group" "this" { + count = var.create ? 1 : 0 + + db_proxy_name = aws_db_proxy.this[0].name + + connection_pool_config { + connection_borrow_timeout = var.connection_borrow_timeout + init_query = var.init_query + max_connections_percent = var.max_connections_percent + max_idle_connections_percent = var.max_idle_connections_percent + session_pinning_filters = var.session_pinning_filters + } +} + +resource "aws_db_proxy_target" "db_instance" { + count = var.create && var.target_db_instance ? 1 : 0 + + db_proxy_name = aws_db_proxy.this[0].name + target_group_name = aws_db_proxy_default_target_group.this[0].name + db_instance_identifier = var.db_instance_identifier +} + +resource "aws_db_proxy_target" "db_cluster" { + count = var.create && var.target_db_cluster ? 1 : 0 + + db_proxy_name = aws_db_proxy.this[0].name + target_group_name = aws_db_proxy_default_target_group.this[0].name + db_cluster_identifier = var.db_cluster_identifier +} + +resource "aws_db_proxy_endpoint" "this" { + for_each = { for k, v in var.endpoints : k => v if var.create } + + db_proxy_name = aws_db_proxy.this[0].name + db_proxy_endpoint_name = each.value.name + vpc_subnet_ids = each.value.vpc_subnet_ids + vpc_security_group_ids = lookup(each.value, "vpc_security_group_ids", null) + target_role = lookup(each.value, "target_role", null) + + tags = lookup(each.value, "tags", var.tags) +} + +################################################################################ +# CloudWatch Logs +################################################################################ + +resource "aws_cloudwatch_log_group" "this" { + count = var.create && var.manage_log_group ? 1 : 0 + + name = "/aws/rds/proxy/${var.name}" + retention_in_days = var.log_group_retention_in_days + kms_key_id = var.log_group_kms_key_id + + tags = merge(var.tags, var.log_group_tags) + skip_destroy = var.cloudwatch_log_group_skip_destroy_on_deletion +} + +################################################################################ +# IAM Role +################################################################################ + +data "aws_iam_policy_document" "assume_role" { + count = var.create && var.create_iam_role ? 1 : 0 + + statement { + sid = "RDSAssume" + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["rds.${data.aws_partition.current.dns_suffix}"] + } + } +} + +resource "aws_iam_role" "this" { + count = var.create && var.create_iam_role ? 1 : 0 + + name = var.use_role_name_prefix ? null : local.role_name + name_prefix = var.use_role_name_prefix ? "${local.role_name}-" : null + description = var.iam_role_description + path = var.iam_role_path + + assume_role_policy = data.aws_iam_policy_document.assume_role[0].json + force_detach_policies = var.iam_role_force_detach_policies + max_session_duration = var.iam_role_max_session_duration + permissions_boundary = var.iam_role_permissions_boundary + + tags = merge(var.tags, var.iam_role_tags) +} + +data "aws_iam_policy_document" "this" { + count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 + + statement { + sid = "DecryptSecrets" + effect = "Allow" + actions = ["kms:Decrypt"] + resources = coalescelist( + var.kms_key_arns, + ["arn:${data.aws_partition.current.partition}:kms:*:*:key/*"] + ) + + condition { + test = "StringEquals" + variable = "kms:ViaService" + values = [ + "secretsmanager.${data.aws_region.current.name}.${data.aws_partition.current.dns_suffix}" + ] + } + } + + statement { + sid = "ListSecrets" + effect = "Allow" + actions = [ + "secretsmanager:GetRandomPassword", + "secretsmanager:ListSecrets", + ] + resources = ["*"] + } + + statement { + sid = "GetSecrets" + effect = "Allow" + actions = [ + "secretsmanager:GetResourcePolicy", + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret", + "secretsmanager:ListSecretVersionIds", + ] + + resources = distinct([for auth in var.auth : auth.secret_arn]) + } +} + +resource "aws_iam_role_policy" "this" { + count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 + + name = var.use_policy_name_prefix ? null : local.policy_name + name_prefix = var.use_policy_name_prefix ? "${local.policy_name}-" : null + policy = data.aws_iam_policy_document.this[0].json + role = aws_iam_role.this[0].id +} diff --git a/_sub/terraform-aws-rds-proxy/outputs.tf b/_sub/terraform-aws-rds-proxy/outputs.tf new file mode 100644 index 00000000..355b2b43 --- /dev/null +++ b/_sub/terraform-aws-rds-proxy/outputs.tf @@ -0,0 +1,95 @@ +# RDS Proxy +output "proxy_id" { + description = "The ID for the proxy" + value = try(aws_db_proxy.this[0].id, null) +} + +output "proxy_arn" { + description = "The Amazon Resource Name (ARN) for the proxy" + value = try(aws_db_proxy.this[0].arn, null) +} + +output "proxy_endpoint" { + description = "The endpoint that you can use to connect to the proxy" + value = try(aws_db_proxy.this[0].endpoint, null) +} + +# Proxy Default Target Group +output "proxy_default_target_group_id" { + description = "The ID for the default target group" + value = try(aws_db_proxy_default_target_group.this[0].id, null) +} + +output "proxy_default_target_group_arn" { + description = "The Amazon Resource Name (ARN) for the default target group" + value = try(aws_db_proxy_default_target_group.this[0].arn, null) +} + +output "proxy_default_target_group_name" { + description = "The name of the default target group" + value = try(aws_db_proxy_default_target_group.this[0].name, null) +} + +# Proxy Target +output "proxy_target_endpoint" { + description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type" + value = try(aws_db_proxy_target.db_instance[0].endpoint, aws_db_proxy_target.db_cluster[0].endpoint, null) +} + +output "proxy_target_id" { + description = "Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/)" + value = try(aws_db_proxy_target.db_instance[0].id, aws_db_proxy_target.db_cluster[0].id, null) +} + +output "proxy_target_port" { + description = "Port for the target RDS DB Instance or Aurora DB Cluster" + value = try(aws_db_proxy_target.db_instance[0].port, aws_db_proxy_target.db_cluster[0].port, null) +} + +output "proxy_target_rds_resource_id" { + description = "Identifier representing the DB Instance or DB Cluster target" + value = try(aws_db_proxy_target.db_instance[0].rds_resource_id, aws_db_proxy_target.db_cluster[0].rds_resource_id, null) +} + +output "proxy_target_target_arn" { + description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API" + value = try(aws_db_proxy_target.db_instance[0].target_arn, aws_db_proxy_target.db_cluster[0].target_arn, null) +} + +output "proxy_target_tracked_cluster_id" { + description = "DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS_INSTANCE target that is part of a DB Cluster" + value = try(aws_db_proxy_target.db_cluster[0].tracked_cluster_id, null) +} + +output "proxy_target_type" { + description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`" + value = try(aws_db_proxy_target.db_instance[0].type, aws_db_proxy_target.db_cluster[0].type, null) +} + +# DB proxy endpoints +output "db_proxy_endpoints" { + description = "Array containing the full resource object and attributes for all DB proxy endpoints created" + value = aws_db_proxy_endpoint.this +} + +# CloudWatch logs +output "log_group_arn" { + description = "The Amazon Resource Name (ARN) of the CloudWatch log group" + value = try(aws_cloudwatch_log_group.this[0].arn, null) +} + +# IAM role +output "iam_role_arn" { + description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager." + value = try(aws_iam_role.this[0].arn, null) +} + +output "iam_role_name" { + description = "IAM role name" + value = try(aws_iam_role.this[0].name, null) +} + +output "iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = try(aws_iam_role.this[0].unique_id, null) +} diff --git a/_sub/terraform-aws-rds-proxy/variables.tf b/_sub/terraform-aws-rds-proxy/variables.tf new file mode 100644 index 00000000..dd4f24e2 --- /dev/null +++ b/_sub/terraform-aws-rds-proxy/variables.tf @@ -0,0 +1,255 @@ +variable "create" { + description = "Whether cluster should be created (affects nearly all resources)" + type = bool + default = true +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +################################################################################ +# RDS Proxy +################################################################################ + +variable "name" { + description = "The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens" + type = string + default = "" +} + +variable "auth" { + description = "Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters" + type = any + default = {} +} + +variable "debug_logging" { + description = "Whether the proxy includes detailed information about SQL statements in its logs" + type = bool + default = false +} + +variable "engine_family" { + description = "The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL`" + type = string + default = "" +} + +variable "idle_client_timeout" { + description = "The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it" + type = number + default = 1800 +} + +variable "require_tls" { + description = "A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy" + type = bool + default = true +} + +variable "role_arn" { + description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager" + type = string + default = "" +} + +variable "vpc_security_group_ids" { + description = "One or more VPC security group IDs to associate with the new proxy" + type = list(string) + default = [] +} + +variable "vpc_subnet_ids" { + description = "One or more VPC subnet IDs to associate with the new proxy" + type = list(string) + default = [] +} + +variable "proxy_tags" { + description = "A map of tags to apply to the RDS Proxy" + type = map(string) + default = {} +} + +# Proxy Default Target Group +variable "connection_borrow_timeout" { + description = "The number of seconds for a proxy to wait for a connection to become available in the connection pool" + type = number + default = null +} + +variable "init_query" { + description = "One or more SQL statements for the proxy to run when opening each new database connection" + type = string + default = "" +} + +variable "max_connections_percent" { + description = "The maximum size of the connection pool for each target in a target group" + type = number + default = 90 +} + +variable "max_idle_connections_percent" { + description = "Controls how actively the proxy closes idle database connections in the connection pool" + type = number + default = 50 +} + +variable "session_pinning_filters" { + description = "Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection" + type = list(string) + default = [] +} + +# Proxy Target +variable "target_db_instance" { + description = "Determines whether DB instance is targeted by proxy" + type = bool + default = false +} + +variable "db_instance_identifier" { + description = "DB instance identifier" + type = string + default = "" +} + +variable "target_db_cluster" { + description = "Determines whether DB cluster is targeted by proxy" + type = bool + default = false +} + +variable "db_cluster_identifier" { + description = "DB cluster identifier" + type = string + default = "" +} + +# Proxy endpoints +variable "endpoints" { + description = "Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`)" + type = any + default = {} +} + +################################################################################ +# CloudWatch Logs +################################################################################ + +variable "manage_log_group" { + description = "Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist" + type = bool + default = true +} + +variable "log_group_retention_in_days" { + description = "Specifies the number of days you want to retain log events in the log group" + type = number + default = 30 +} + +variable "log_group_kms_key_id" { + description = "The ARN of the KMS Key to use when encrypting log data" + type = string + default = null +} + +variable "log_group_tags" { + description = "A map of tags to apply to the CloudWatch log group" + type = map(string) + default = {} +} + +variable "cloudwatch_log_group_skip_destroy_on_deletion" { + description = "value to skip destroy ClouwWatch log group on deletion" + type = bool + default = false +} + +################################################################################ +# IAM Role +################################################################################ + +variable "create_iam_role" { + description = "Determines whether an IAM role is created" + type = bool + default = true +} + +variable "iam_role_name" { + description = "The name of the role. If omitted, Terraform will assign a random, unique name" + type = string + default = "" +} + +variable "use_role_name_prefix" { + description = "Whether to use unique name beginning with the specified `iam_role_name`" + type = bool + default = false +} + +variable "iam_role_description" { + description = "The description of the role" + type = string + default = "" +} + +variable "iam_role_path" { + description = "The path to the role" + type = string + default = null +} + +variable "iam_role_force_detach_policies" { + description = "Specifies to force detaching any policies the role has before destroying it" + type = bool + default = true +} + +variable "iam_role_max_session_duration" { + description = "The maximum session duration (in seconds) that you want to set for the specified role" + type = number + default = 43200 # 12 hours +} + +variable "iam_role_permissions_boundary" { + description = "The ARN of the policy that is used to set the permissions boundary for the role" + type = string + default = null +} + +variable "iam_role_tags" { + description = "A map of tags to apply to the IAM role" + type = map(string) + default = {} +} + +# IAM Policy +variable "create_iam_policy" { + description = "Determines whether an IAM policy is created" + type = bool + default = true +} + +variable "iam_policy_name" { + description = "The name of the role policy. If omitted, Terraform will assign a random, unique name" + type = string + default = "" +} + +variable "use_policy_name_prefix" { + description = "Whether to use unique name beginning with the specified `iam_policy_name`" + type = bool + default = false +} + +variable "kms_key_arns" { + description = "List of KMS Key ARNs to allow access to decrypt SecretsManager secrets" + type = list(string) + default = [] +} diff --git a/_sub/terraform-aws-rds-proxy/versions.tf b/_sub/terraform-aws-rds-proxy/versions.tf new file mode 100644 index 00000000..ddfcb0e0 --- /dev/null +++ b/_sub/terraform-aws-rds-proxy/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} diff --git a/_sub/terraform-aws-rds/README.md b/_sub/terraform-aws-rds/README.md new file mode 100644 index 00000000..81ac06dc --- /dev/null +++ b/_sub/terraform-aws-rds/README.md @@ -0,0 +1,370 @@ +# AWS RDS Terraform module + +Terraform module which creates RDS resources on AWS. + +[![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) + +Root module calls these modules which can also be used separately to create independent resources: + +- [db_instance](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/modules/db_instance) - creates RDS DB instance +- [db_subnet_group](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/modules/db_subnet_group) - creates RDS DB subnet group +- [db_parameter_group](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/modules/db_parameter_group) - creates RDS DB parameter group +- [db_option_group](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/modules/db_option_group) - creates RDS DB option group + +## Usage + +```hcl +module "db" { + source = "terraform-aws-modules/rds/aws" + + identifier = "demodb" + + engine = "mysql" + engine_version = "5.7" + instance_class = "db.t3a.large" + allocated_storage = 5 + + db_name = "demodb" + username = "user" + port = "3306" + + iam_database_authentication_enabled = true + + vpc_security_group_ids = ["sg-12345678"] + + maintenance_window = "Mon:00:00-Mon:03:00" + backup_window = "03:00-06:00" + + # Enhanced Monitoring - see example for details on how to create the role + # by yourself, in case you don't want to create it automatically + monitoring_interval = "30" + monitoring_role_name = "MyRDSMonitoringRole" + create_monitoring_role = true + + tags = { + Owner = "user" + Environment = "dev" + } + + # DB subnet group + create_db_subnet_group = true + subnet_ids = ["subnet-12345678", "subnet-87654321"] + + # DB parameter group + family = "mysql5.7" + + # DB option group + major_engine_version = "5.7" + + # Database Deletion Protection + deletion_protection = true + + parameters = [ + { + name = "character_set_client" + value = "utf8mb4" + }, + { + name = "character_set_server" + value = "utf8mb4" + } + ] + + options = [ + { + option_name = "MARIADB_AUDIT_PLUGIN" + + option_settings = [ + { + name = "SERVER_AUDIT_EVENTS" + value = "CONNECT" + }, + { + name = "SERVER_AUDIT_FILE_ROTATIONS" + value = "37" + }, + ] + }, + ] +} +``` + +## Conditional creation + +The following values are provided to toggle on/off creation of the associated resources as desired: + +```hcl +module "db" { + source = "terraform-aws-modules/rds/aws" + + # Disable creation of RDS instance(s) + create_db_instance = false + + # Disable creation of option group - provide an option group or default AWS default + create_db_option_group = false + + # Disable creation of parameter group - provide a parameter group or default to AWS default + create_db_parameter_group = false + + # Enable creation of subnet group (disabled by default) + create_db_subnet_group = true + + # Enable creation of monitoring IAM role + create_monitoring_role = true + + # ... omitted +} +``` + +## Option Groups + +[Reference](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithOptionGroups.html) + +Users have the ability to: + +- Create an option group with the name provided: + +```hcl + option_group_name = "prod-instance-mysql-8.0" + option_group_use_name_prefix = false +``` + +- Create an option group using a unique prefix beginning with the name provided: + +```hcl + option_group_name = "prod-instance-mysql-8.0" +``` + +- Pass the name of an option group to use that has been created outside of the module: + +```hcl + create_db_option_group = false + option_group_name = "prod-instance-mysql-8.0" # must already exist in AWS +``` + +- Skip creating an option group for PostgreSQL entirely as that is not supported + +```hcl + engine = "postgres" + option_group_name = "prod-instance-postgresql-11.0" # this will be ignored, no option group created +``` + +- Use a default option group provided by AWS + +```hcl + create_db_option_group = false +``` + +## Parameter Groups + +[Reference](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.html) + +Users have the ability to: + +- Create a parameter group with the name provided: + +```hcl + parameter_group_name = "prod-instance-mysql-8.0" + parameter_group_use_name_prefix = false +``` + +- Create a parameter group using a unique prefix beginning with the name provided: + +```hcl + parameter_group_name = "prod-instance-mysql-8.0" +``` + +- Pass the name of a parameter group to use that has been created outside of the module: + +```hcl + create_db_parameter_group = false + parameter_group_name = "prod-instance-mysql-8.0" # must already exist in AWS +``` + +- Use a default parameter group provided by AWS + +```hcl + create_db_parameter_group = false +``` + +## Examples + +- [Complete RDS example for MSSQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-mssql) +- [Complete RDS example for MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-mysql) +- [Complete RDS example for Oracle](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-oracle) +- [Complete RDS example for PostgreSQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-postgres) +- [Enhanced monitoring example](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/enhanced-monitoring) +- [Replica RDS example for MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/replica-mysql) +- [Replica RDS example for PostgreSQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/replica-postgres) +- [S3 import example for MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/s3-import-mysql) + +## Notes + +1. This module does not create RDS security group. Use [terraform-aws-security-group](https://github.com/terraform-aws-modules/terraform-aws-security-group) module for this. +2. For an RDS instance with `storage_type` using `gp3`, be aware that `iops` and `storage_throughput` cannot be specified if the `allocated_storage` value is below a per-`engine` threshold. See the [RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#gp3-storage) for details. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [db\_instance](#module\_db\_instance) | ./modules/db_instance | n/a | +| [db\_option\_group](#module\_db\_option\_group) | ./modules/db_option_group | n/a | +| [db\_parameter\_group](#module\_db\_parameter\_group) | ./modules/db_parameter_group | n/a | +| [db\_subnet\_group](#module\_db\_subnet\_group) | ./modules/db_subnet_group | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allocated\_storage](#input\_allocated\_storage) | The allocated storage in gigabytes | `number` | `null` | no | +| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Indicates that major version upgrades are allowed. Changing this parameter does not result in an outage and the change is asynchronously applied as soon as possible | `bool` | `false` | no | +| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any database modifications are applied immediately, or during the next maintenance window | `bool` | `false` | no | +| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window | `bool` | `true` | no | +| [availability\_zone](#input\_availability\_zone) | The Availability Zone of the RDS instance | `string` | `null` | no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `null` | no | +| [backup\_window](#input\_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` | `null` | no | +| [blue\_green\_update](#input\_blue\_green\_update) | Enables low-downtime updates using RDS Blue/Green deployments. | `map(string)` | `{}` | no | +| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | `string` | `null` | no | +| [character\_set\_name](#input\_character\_set\_name) | 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 and Collations and Character Sets for Microsoft SQL Server for more information. This can only be set on creation | `string` | `null` | no | +| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | +| [cloudwatch\_log\_group\_retention\_in\_days](#input\_cloudwatch\_log\_group\_retention\_in\_days) | The number of days to retain CloudWatch logs for the DB instance | `number` | `7` | no | +| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | On delete, copy all Instance tags to the final snapshot | `bool` | `false` | no | +| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports` | `bool` | `false` | no | +| [create\_db\_instance](#input\_create\_db\_instance) | Whether to create a database instance | `bool` | `true` | no | +| [create\_db\_option\_group](#input\_create\_db\_option\_group) | Create a database option group | `bool` | `true` | no | +| [create\_db\_parameter\_group](#input\_create\_db\_parameter\_group) | Whether to create a database parameter group | `bool` | `true` | no | +| [create\_db\_subnet\_group](#input\_create\_db\_subnet\_group) | Whether to create a database subnet group | `bool` | `false` | no | +| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Create IAM role with a defined name that permits RDS to send enhanced monitoring metrics to CloudWatch Logs | `bool` | `false` | no | +| [custom\_iam\_instance\_profile](#input\_custom\_iam\_instance\_profile) | RDS custom iam instance profile | `string` | `null` | no | +| [db\_instance\_tags](#input\_db\_instance\_tags) | Additional tags for the DB instance | `map(string)` | `{}` | no | +| [db\_name](#input\_db\_name) | The DB name to create. If omitted, no database is created initially | `string` | `null` | no | +| [db\_option\_group\_tags](#input\_db\_option\_group\_tags) | Additional tags for the DB option group | `map(string)` | `{}` | no | +| [db\_parameter\_group\_tags](#input\_db\_parameter\_group\_tags) | Additional tags for the DB parameter group | `map(string)` | `{}` | no | +| [db\_subnet\_group\_description](#input\_db\_subnet\_group\_description) | Description of the DB subnet group to create | `string` | `null` | no | +| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC | `string` | `null` | no | +| [db\_subnet\_group\_tags](#input\_db\_subnet\_group\_tags) | Additional tags for the DB subnet group | `map(string)` | `{}` | no | +| [db\_subnet\_group\_use\_name\_prefix](#input\_db\_subnet\_group\_use\_name\_prefix) | Determines whether to use `subnet_group_name` as is or create a unique name beginning with the `subnet_group_name` as the prefix | `bool` | `true` | no | +| [delete\_automated\_backups](#input\_delete\_automated\_backups) | Specifies whether to remove automated backups immediately after the DB instance is deleted | `bool` | `true` | no | +| [deletion\_protection](#input\_deletion\_protection) | The database can't be deleted when this value is set to true | `bool` | `false` | no | +| [domain](#input\_domain) | The ID of the Directory Service Active Directory domain to create the instance in | `string` | `null` | no | +| [domain\_iam\_role\_name](#input\_domain\_iam\_role\_name) | (Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service | `string` | `null` | no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on engine): alert, audit, error, general, listener, slowquery, trace, postgresql (PostgreSQL), upgrade (PostgreSQL) | `list(string)` | `[]` | no | +| [engine](#input\_engine) | The database engine to use | `string` | `null` | no | +| [engine\_version](#input\_engine\_version) | The engine version to use | `string` | `null` | no | +| [family](#input\_family) | The family of the DB parameter group | `string` | `null` | no | +| [final\_snapshot\_identifier\_prefix](#input\_final\_snapshot\_identifier\_prefix) | The name which is prefixed to the final snapshot on cluster destroy | `string` | `"final"` | no | +| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or not the mappings of AWS Identity and Access Management (IAM) accounts to database accounts are enabled | `bool` | `false` | no | +| [identifier](#input\_identifier) | The name of the RDS instance | `string` | n/a | yes | +| [instance\_class](#input\_instance\_class) | The instance type of the RDS instance | `string` | `null` | no | +| [instance\_use\_identifier\_prefix](#input\_instance\_use\_identifier\_prefix) | Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix | `bool` | `false` | no | +| [iops](#input\_iops) | The amount of provisioned IOPS. Setting this implies a storage\_type of 'io1' or `gp3`. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage\_encrypted is set to true and kms\_key\_id is not specified the default KMS key created in your account will be used. Be sure to use the full ARN, not a key alias. | `string` | `null` | no | +| [license\_model](#input\_license\_model) | License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1 | `string` | `null` | no | +| [maintenance\_window](#input\_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 | +| [major\_engine\_version](#input\_major\_engine\_version) | Specifies the major version of the engine that this option group should be associated with | `string` | `null` | no | +| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager | `bool` | `true` | no | +| [master\_user\_secret\_kms\_key\_id](#input\_master\_user\_secret\_kms\_key\_id) | The key ARN, key ID, alias ARN or alias name for the KMS key to encrypt the master user password secret in Secrets Manager.
If not specified, the default KMS key for your Amazon Web Services account is used. | `string` | `null` | no | +| [max\_allocated\_storage](#input\_max\_allocated\_storage) | Specifies the value for Storage Autoscaling | `number` | `0` | no | +| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. The default is 0. Valid Values: 0, 1, 5, 10, 15, 30, 60 | `number` | `0` | no | +| [monitoring\_role\_arn](#input\_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` | `null` | no | +| [monitoring\_role\_description](#input\_monitoring\_role\_description) | Description of the monitoring IAM role | `string` | `null` | no | +| [monitoring\_role\_name](#input\_monitoring\_role\_name) | Name of the IAM role which will be created when create\_monitoring\_role is enabled | `string` | `"rds-monitoring-role"` | no | +| [monitoring\_role\_permissions\_boundary](#input\_monitoring\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the monitoring IAM role | `string` | `null` | no | +| [monitoring\_role\_use\_name\_prefix](#input\_monitoring\_role\_use\_name\_prefix) | Determines whether to use `monitoring_role_name` as is or create a unique identifier beginning with `monitoring_role_name` as the specified prefix | `bool` | `false` | no | +| [multi\_az](#input\_multi\_az) | Specifies if the RDS instance is multi-AZ | `bool` | `false` | no | +| [nchar\_character\_set\_name](#input\_nchar\_character\_set\_name) | The national character set is used in the NCHAR, NVARCHAR2, and NCLOB data types for Oracle instances. This can't be changed. | `string` | `null` | no | +| [network\_type](#input\_network\_type) | The type of network stack to use | `string` | `null` | no | +| [option\_group\_description](#input\_option\_group\_description) | The description of the option group | `string` | `null` | no | +| [option\_group\_name](#input\_option\_group\_name) | Name of the option group | `string` | `null` | no | +| [option\_group\_timeouts](#input\_option\_group\_timeouts) | Define maximum timeout for deletion of `aws_db_option_group` resource | `map(string)` | `{}` | no | +| [option\_group\_use\_name\_prefix](#input\_option\_group\_use\_name\_prefix) | Determines whether to use `option_group_name` as is or create a unique name beginning with the `option_group_name` as the prefix | `bool` | `true` | no | +| [options](#input\_options) | A list of Options to apply | `any` | `[]` | no | +| [parameter\_group\_description](#input\_parameter\_group\_description) | Description of the DB parameter group to create | `string` | `null` | no | +| [parameter\_group\_name](#input\_parameter\_group\_name) | Name of the DB parameter group to associate or create | `string` | `null` | no | +| [parameter\_group\_use\_name\_prefix](#input\_parameter\_group\_use\_name\_prefix) | Determines whether to use `parameter_group_name` as is or create a unique name beginning with the `parameter_group_name` as the prefix | `bool` | `true` | no | +| [parameters](#input\_parameters) | A list of DB parameters (map) to apply | `list(map(string))` | `[]` | no | +| [password](#input\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file.
The password provided will not be used if `manage_master_user_password` is set to true. | `string` | `null` | no | +| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Specifies whether Performance Insights are enabled | `bool` | `false` | no | +| [performance\_insights\_kms\_key\_id](#input\_performance\_insights\_kms\_key\_id) | The ARN for the KMS key to encrypt Performance Insights data | `string` | `null` | no | +| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | The amount of time in days to retain Performance Insights data. Valid values are `7`, `731` (2 years) or a multiple of `31` | `number` | `7` | no | +| [port](#input\_port) | The port on which the DB accepts connections | `string` | `null` | no | +| [publicly\_accessible](#input\_publicly\_accessible) | Bool to control if instance is publicly accessible | `bool` | `false` | no | +| [putin\_khuylo](#input\_putin\_khuylo) | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | `bool` | `true` | no | +| [replica\_mode](#input\_replica\_mode) | Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified | `string` | `null` | no | +| [replicate\_source\_db](#input\_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 | +| [restore\_to\_point\_in\_time](#input\_restore\_to\_point\_in\_time) | Restore to a point in time (MySQL is NOT supported) | `map(string)` | `null` | no | +| [s3\_import](#input\_s3\_import) | Restore from a Percona Xtrabackup in S3 (only MySQL is supported) | `map(string)` | `null` | no | +| [skip\_final\_snapshot](#input\_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 | `bool` | `false` | no | +| [snapshot\_identifier](#input\_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, e.g: rds:production-2015-06-26-06-05 | `string` | `null` | no | +| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB instance is encrypted | `bool` | `true` | no | +| [storage\_throughput](#input\_storage\_throughput) | Storage throughput value for the DB instance. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | +| [storage\_type](#input\_storage\_type) | One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter | `string` | `null` | no | +| [subnet\_ids](#input\_subnet\_ids) | A list of VPC subnet IDs | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A mapping of tags to assign to all resources | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Updated Terraform resource management timeouts. Applies to `aws_db_instance` in particular to permit resource management times | `map(string)` | `{}` | no | +| [timezone](#input\_timezone) | 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 | `string` | `null` | no | +| [username](#input\_username) | Username for the master DB user | `string` | `null` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of VPC security groups to associate | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_instance\_address](#output\_db\_instance\_address) | The address of the RDS instance | +| [db\_instance\_arn](#output\_db\_instance\_arn) | The ARN of the RDS instance | +| [db\_instance\_availability\_zone](#output\_db\_instance\_availability\_zone) | The availability zone of the RDS instance | +| [db\_instance\_ca\_cert\_identifier](#output\_db\_instance\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | +| [db\_instance\_cloudwatch\_log\_groups](#output\_db\_instance\_cloudwatch\_log\_groups) | Map of CloudWatch log groups created and their attributes | +| [db\_instance\_domain](#output\_db\_instance\_domain) | The ID of the Directory Service Active Directory domain the instance is joined to | +| [db\_instance\_domain\_iam\_role\_name](#output\_db\_instance\_domain\_iam\_role\_name) | The name of the IAM role to be used when making API calls to the Directory Service | +| [db\_instance\_endpoint](#output\_db\_instance\_endpoint) | The connection endpoint | +| [db\_instance\_engine](#output\_db\_instance\_engine) | The database engine | +| [db\_instance\_engine\_version\_actual](#output\_db\_instance\_engine\_version\_actual) | The running version of the database | +| [db\_instance\_hosted\_zone\_id](#output\_db\_instance\_hosted\_zone\_id) | The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record) | +| [db\_instance\_identifier](#output\_db\_instance\_identifier) | The RDS instance identifier | +| [db\_instance\_master\_user\_secret\_arn](#output\_db\_instance\_master\_user\_secret\_arn) | The ARN of the master user secret (Only available when manage\_master\_user\_password is set to true) | +| [db\_instance\_name](#output\_db\_instance\_name) | The database name | +| [db\_instance\_port](#output\_db\_instance\_port) | The database port | +| [db\_instance\_resource\_id](#output\_db\_instance\_resource\_id) | The RDS Resource ID of this instance | +| [db\_instance\_status](#output\_db\_instance\_status) | The RDS instance status | +| [db\_instance\_username](#output\_db\_instance\_username) | The master username for the database | +| [db\_listener\_endpoint](#output\_db\_listener\_endpoint) | Specifies the listener connection endpoint for SQL Server Always On | +| [db\_option\_group\_arn](#output\_db\_option\_group\_arn) | The ARN of the db option group | +| [db\_option\_group\_id](#output\_db\_option\_group\_id) | The db option group id | +| [db\_parameter\_group\_arn](#output\_db\_parameter\_group\_arn) | The ARN of the db parameter group | +| [db\_parameter\_group\_id](#output\_db\_parameter\_group\_id) | The db parameter group id | +| [db\_subnet\_group\_arn](#output\_db\_subnet\_group\_arn) | The ARN of the db subnet group | +| [db\_subnet\_group\_id](#output\_db\_subnet\_group\_id) | The db subnet group name | +| [enhanced\_monitoring\_iam\_role\_arn](#output\_enhanced\_monitoring\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the monitoring role | +| [enhanced\_monitoring\_iam\_role\_name](#output\_enhanced\_monitoring\_iam\_role\_name) | The name of the monitoring role | + + +## Authors + +Module is maintained by [Anton Babenko](https://github.com/antonbabenko) with help from [these awesome contributors](https://github.com/terraform-aws-modules/terraform-aws-rds/graphs/contributors). + +## License + +Apache 2 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/LICENSE) for full details. + +## Additional information for users from Russia and Belarus + +* Russia has [illegally annexed Crimea in 2014](https://en.wikipedia.org/wiki/Annexation_of_Crimea_by_the_Russian_Federation) and [brought the war in Donbas](https://en.wikipedia.org/wiki/War_in_Donbas) followed by [full-scale invasion of Ukraine in 2022](https://en.wikipedia.org/wiki/2022_Russian_invasion_of_Ukraine). +* Russia has brought sorrow and devastations to millions of Ukrainians, killed hundreds of innocent people, damaged thousands of buildings, and forced several million people to flee. +* [Putin khuylo!](https://en.wikipedia.org/wiki/Putin_khuylo!) diff --git a/_sub/terraform-aws-rds/main.tf b/_sub/terraform-aws-rds/main.tf new file mode 100644 index 00000000..19261931 --- /dev/null +++ b/_sub/terraform-aws-rds/main.tf @@ -0,0 +1,150 @@ +locals { + create_db_subnet_group = var.create_db_subnet_group + create_db_parameter_group = var.create_db_parameter_group + create_db_instance = var.create_db_instance + + ### + db_subnet_group_name = var.create_db_subnet_group ? module.db_subnet_group.db_subnet_group_id : var.db_subnet_group_name + # db_subnet_group_name = var.db_subnet_group_name # for now + ### + + parameter_group_name_id = var.create_db_parameter_group ? module.db_parameter_group.db_parameter_group_id : var.parameter_group_name + + create_db_option_group = var.create_db_option_group && var.engine != "postgres" + option_group = local.create_db_option_group ? module.db_option_group.db_option_group_id : var.option_group_name +} + +module "db_subnet_group" { + source = "./modules/db_subnet_group" + + create = local.create_db_subnet_group + + name = coalesce(var.db_subnet_group_name, var.identifier) + use_name_prefix = var.db_subnet_group_use_name_prefix + description = var.db_subnet_group_description + subnet_ids = var.subnet_ids + + tags = merge(var.tags, var.db_subnet_group_tags) +} + +module "db_parameter_group" { + source = "./modules/db_parameter_group" + + create = local.create_db_parameter_group + + name = coalesce(var.parameter_group_name, var.identifier) + use_name_prefix = var.parameter_group_use_name_prefix + description = var.parameter_group_description + family = var.family + + parameters = var.parameters + + tags = merge(var.tags, var.db_parameter_group_tags) +} + +module "db_option_group" { + source = "./modules/db_option_group" + + create = local.create_db_option_group + + name = coalesce(var.option_group_name, var.identifier) + use_name_prefix = var.option_group_use_name_prefix + option_group_description = var.option_group_description + engine_name = var.engine + major_engine_version = var.major_engine_version + + options = var.options + + timeouts = var.option_group_timeouts + + tags = merge(var.tags, var.db_option_group_tags) +} + +module "db_instance" { + source = "./modules/db_instance" + + create = local.create_db_instance + identifier = var.identifier + use_identifier_prefix = var.instance_use_identifier_prefix + + 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 + + db_name = var.db_name + username = var.username + password = var.manage_master_user_password ? null : var.password + port = var.port + domain = var.domain + domain_iam_role_name = var.domain_iam_role_name + iam_database_authentication_enabled = var.iam_database_authentication_enabled + custom_iam_instance_profile = var.custom_iam_instance_profile + manage_master_user_password = var.manage_master_user_password + master_user_secret_kms_key_id = var.master_user_secret_kms_key_id + + vpc_security_group_ids = var.vpc_security_group_ids + db_subnet_group_name = local.db_subnet_group_name + parameter_group_name = local.parameter_group_name_id + option_group_name = var.engine != "postgres" ? local.option_group : null + network_type = var.network_type + + availability_zone = var.availability_zone + multi_az = var.multi_az + iops = var.iops + storage_throughput = var.storage_throughput + publicly_accessible = var.publicly_accessible + ca_cert_identifier = var.ca_cert_identifier + + 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 + blue_green_update = var.blue_green_update + + snapshot_identifier = var.snapshot_identifier + copy_tags_to_snapshot = var.copy_tags_to_snapshot + skip_final_snapshot = var.skip_final_snapshot + final_snapshot_identifier_prefix = var.final_snapshot_identifier_prefix + + performance_insights_enabled = var.performance_insights_enabled + performance_insights_retention_period = var.performance_insights_retention_period + performance_insights_kms_key_id = var.performance_insights_enabled ? var.performance_insights_kms_key_id : null + + replicate_source_db = var.replicate_source_db + replica_mode = var.replica_mode + backup_retention_period = var.backup_retention_period + backup_window = var.backup_window + max_allocated_storage = var.max_allocated_storage + monitoring_interval = var.monitoring_interval + monitoring_role_arn = var.monitoring_role_arn + monitoring_role_name = var.monitoring_role_name + monitoring_role_use_name_prefix = var.monitoring_role_use_name_prefix + monitoring_role_description = var.monitoring_role_description + create_monitoring_role = var.create_monitoring_role + monitoring_role_permissions_boundary = var.monitoring_role_permissions_boundary + + character_set_name = var.character_set_name + nchar_character_set_name = var.nchar_character_set_name + timezone = var.timezone + + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + create_cloudwatch_log_group = var.create_cloudwatch_log_group + cloudwatch_log_group_retention_in_days = var.cloudwatch_log_group_retention_in_days + cloudwatch_log_group_kms_key_id = var.cloudwatch_log_group_kms_key_id + cloudwatch_log_group_skip_destroy_on_deletion = var.cloudwatch_log_group_skip_destroy_on_deletion + + timeouts = var.timeouts + + deletion_protection = var.deletion_protection + delete_automated_backups = var.delete_automated_backups + + restore_to_point_in_time = var.restore_to_point_in_time + s3_import = var.s3_import + + tags = merge(var.tags, var.db_instance_tags) +} diff --git a/_sub/terraform-aws-rds/modules/db_instance/README.md b/_sub/terraform-aws-rds/modules/db_instance/README.md new file mode 100644 index 00000000..05091470 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_instance/README.md @@ -0,0 +1,134 @@ +# aws_db_instance + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | +| [random](#requirement\_random) | >= 3.1 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | +| [random](#provider\_random) | >= 3.1 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_db_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance) | resource | +| [aws_iam_role.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [random_id.snapshot_identifier](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [aws_iam_policy_document.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allocated\_storage](#input\_allocated\_storage) | The allocated storage in gigabytes | `number` | `null` | no | +| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Indicates that major version upgrades are allowed. Changing this parameter does not result in an outage and the change is asynchronously applied as soon as possible | `bool` | `false` | no | +| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any database modifications are applied immediately, or during the next maintenance window | `bool` | `false` | no | +| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window | `bool` | `true` | no | +| [availability\_zone](#input\_availability\_zone) | The Availability Zone of the RDS instance | `string` | `null` | no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `null` | no | +| [backup\_window](#input\_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` | `null` | no | +| [blue\_green\_update](#input\_blue\_green\_update) | Enables low-downtime updates using RDS Blue/Green deployments. | `map(string)` | `{}` | no | +| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | `string` | `null` | no | +| [character\_set\_name](#input\_character\_set\_name) | 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 and Collations and Character Sets for Microsoft SQL Server for more information. This can only be set on creation. | `string` | `null` | no | +| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | +| [cloudwatch\_log\_group\_retention\_in\_days](#input\_cloudwatch\_log\_group\_retention\_in\_days) | The number of days to retain CloudWatch logs for the DB instance | `number` | `7` | no | +| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | On delete, copy all Instance tags to the final snapshot | `bool` | `false` | no | +| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | +| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports` | `bool` | `false` | no | +| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Create IAM role with a defined name that permits RDS to send enhanced monitoring metrics to CloudWatch Logs. | `bool` | `false` | no | +| [custom\_iam\_instance\_profile](#input\_custom\_iam\_instance\_profile) | RDS custom iam instance profile | `string` | `null` | no | +| [db\_name](#input\_db\_name) | The DB name to create. If omitted, no database is created initially | `string` | `null` | no | +| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC | `string` | `null` | no | +| [delete\_automated\_backups](#input\_delete\_automated\_backups) | Specifies whether to remove automated backups immediately after the DB instance is deleted | `bool` | `true` | no | +| [deletion\_protection](#input\_deletion\_protection) | The database can't be deleted when this value is set to true. | `bool` | `false` | no | +| [domain](#input\_domain) | The ID of the Directory Service Active Directory domain to create the instance in | `string` | `null` | no | +| [domain\_iam\_role\_name](#input\_domain\_iam\_role\_name) | (Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service | `string` | `null` | no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on engine): alert, audit, error, general, listener, slowquery, trace, postgresql (PostgreSQL), upgrade (PostgreSQL). | `list(string)` | `[]` | no | +| [engine](#input\_engine) | The database engine to use | `string` | `null` | no | +| [engine\_version](#input\_engine\_version) | The engine version to use | `string` | `null` | no | +| [final\_snapshot\_identifier\_prefix](#input\_final\_snapshot\_identifier\_prefix) | The name which is prefixed to the final snapshot on cluster destroy | `string` | `"final"` | no | +| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled | `bool` | `false` | no | +| [identifier](#input\_identifier) | The name of the RDS instance | `string` | n/a | yes | +| [instance\_class](#input\_instance\_class) | The instance type of the RDS instance | `string` | `null` | no | +| [iops](#input\_iops) | The amount of provisioned IOPS. Setting this implies a storage\_type of 'io1' or `gp3`. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage\_encrypted is set to true and kms\_key\_id is not specified the default KMS key created in your account will be used | `string` | `null` | no | +| [license\_model](#input\_license\_model) | License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1 | `string` | `null` | no | +| [maintenance\_window](#input\_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 | +| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if password is provided | `bool` | `false` | no | +| [master\_user\_secret\_kms\_key\_id](#input\_master\_user\_secret\_kms\_key\_id) | The key ARN, key ID, alias ARN or alias name for the KMS key to encrypt the master user password secret in Secrets Manager.
If not specified, the default KMS key for your Amazon Web Services account is used. | `string` | `null` | no | +| [max\_allocated\_storage](#input\_max\_allocated\_storage) | Specifies the value for Storage Autoscaling | `number` | `0` | no | +| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. The default is 0. Valid Values: 0, 1, 5, 10, 15, 30, 60. | `number` | `0` | no | +| [monitoring\_role\_arn](#input\_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` | `null` | no | +| [monitoring\_role\_description](#input\_monitoring\_role\_description) | Description of the monitoring IAM role | `string` | `null` | no | +| [monitoring\_role\_name](#input\_monitoring\_role\_name) | Name of the IAM role which will be created when create\_monitoring\_role is enabled. | `string` | `"rds-monitoring-role"` | no | +| [monitoring\_role\_permissions\_boundary](#input\_monitoring\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the monitoring IAM role | `string` | `null` | no | +| [monitoring\_role\_use\_name\_prefix](#input\_monitoring\_role\_use\_name\_prefix) | Determines whether to use `monitoring_role_name` as is or create a unique identifier beginning with `monitoring_role_name` as the specified prefix | `bool` | `false` | no | +| [multi\_az](#input\_multi\_az) | Specifies if the RDS instance is multi-AZ | `bool` | `false` | no | +| [nchar\_character\_set\_name](#input\_nchar\_character\_set\_name) | The national character set is used in the NCHAR, NVARCHAR2, and NCLOB data types for Oracle instances. This can't be changed. | `string` | `null` | no | +| [network\_type](#input\_network\_type) | The type of network stack | `string` | `null` | no | +| [option\_group\_name](#input\_option\_group\_name) | Name of the DB option group to associate. | `string` | `null` | no | +| [parameter\_group\_name](#input\_parameter\_group\_name) | Name of the DB parameter group to associate | `string` | `null` | no | +| [password](#input\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file | `string` | `null` | no | +| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Specifies whether Performance Insights are enabled | `bool` | `false` | no | +| [performance\_insights\_kms\_key\_id](#input\_performance\_insights\_kms\_key\_id) | The ARN for the KMS key to encrypt Performance Insights data. | `string` | `null` | no | +| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | The amount of time in days to retain Performance Insights data. Either 7 (7 days) or 731 (2 years). | `number` | `7` | no | +| [port](#input\_port) | The port on which the DB accepts connections | `string` | `null` | no | +| [publicly\_accessible](#input\_publicly\_accessible) | Bool to control if instance is publicly accessible | `bool` | `false` | no | +| [replica\_mode](#input\_replica\_mode) | Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified | `string` | `null` | no | +| [replicate\_source\_db](#input\_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 | +| [restore\_to\_point\_in\_time](#input\_restore\_to\_point\_in\_time) | Restore to a point in time (MySQL is NOT supported) | `map(string)` | `null` | no | +| [s3\_import](#input\_s3\_import) | Restore from a Percona Xtrabackup in S3 (only MySQL is supported) | `map(string)` | `null` | no | +| [skip\_final\_snapshot](#input\_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 | `bool` | `false` | no | +| [snapshot\_identifier](#input\_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, e.g: rds:production-2015-06-26-06-05. | `string` | `null` | no | +| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB instance is encrypted | `bool` | `true` | no | +| [storage\_throughput](#input\_storage\_throughput) | Storage throughput value for the DB instance. This setting applies only to the `gp3` storage type. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | +| [storage\_type](#input\_storage\_type) | One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter | `string` | `null` | no | +| [tags](#input\_tags) | A mapping of tags to assign to all resources | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Updated Terraform resource management timeouts. Applies to `aws_db_instance` in particular to permit resource management times | `map(string)` | `{}` | no | +| [timezone](#input\_timezone) | 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. | `string` | `null` | no | +| [use\_identifier\_prefix](#input\_use\_identifier\_prefix) | Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix | `bool` | `false` | no | +| [username](#input\_username) | Username for the master DB user | `string` | `null` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of VPC security groups to associate | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_instance\_address](#output\_db\_instance\_address) | The address of the RDS instance | +| [db\_instance\_arn](#output\_db\_instance\_arn) | The ARN of the RDS instance | +| [db\_instance\_availability\_zone](#output\_db\_instance\_availability\_zone) | The availability zone of the RDS instance | +| [db\_instance\_ca\_cert\_identifier](#output\_db\_instance\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | +| [db\_instance\_cloudwatch\_log\_groups](#output\_db\_instance\_cloudwatch\_log\_groups) | Map of CloudWatch log groups created and their attributes | +| [db\_instance\_domain](#output\_db\_instance\_domain) | The ID of the Directory Service Active Directory domain the instance is joined to | +| [db\_instance\_domain\_iam\_role\_name](#output\_db\_instance\_domain\_iam\_role\_name) | The name of the IAM role to be used when making API calls to the Directory Service | +| [db\_instance\_endpoint](#output\_db\_instance\_endpoint) | The connection endpoint | +| [db\_instance\_engine](#output\_db\_instance\_engine) | The database engine | +| [db\_instance\_engine\_version\_actual](#output\_db\_instance\_engine\_version\_actual) | The running version of the database | +| [db\_instance\_hosted\_zone\_id](#output\_db\_instance\_hosted\_zone\_id) | The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record) | +| [db\_instance\_identifier](#output\_db\_instance\_identifier) | The RDS instance identifier | +| [db\_instance\_master\_user\_secret\_arn](#output\_db\_instance\_master\_user\_secret\_arn) | The ARN of the master user secret (Only available when manage\_master\_user\_password is set to true) | +| [db\_instance\_name](#output\_db\_instance\_name) | The database name | +| [db\_instance\_port](#output\_db\_instance\_port) | The database port | +| [db\_instance\_resource\_id](#output\_db\_instance\_resource\_id) | The RDS Resource ID of this instance | +| [db\_instance\_status](#output\_db\_instance\_status) | The RDS instance status | +| [db\_instance\_username](#output\_db\_instance\_username) | The master username for the database | +| [db\_listener\_endpoint](#output\_db\_listener\_endpoint) | Specifies the listener connection endpoint for SQL Server Always On | +| [enhanced\_monitoring\_iam\_role\_arn](#output\_enhanced\_monitoring\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the monitoring role | +| [enhanced\_monitoring\_iam\_role\_name](#output\_enhanced\_monitoring\_iam\_role\_name) | The name of the monitoring role | + diff --git a/_sub/terraform-aws-rds/modules/db_instance/main.tf b/_sub/terraform-aws-rds/modules/db_instance/main.tf new file mode 100644 index 00000000..3e013e35 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_instance/main.tf @@ -0,0 +1,200 @@ +locals { + monitoring_role_arn = var.create_monitoring_role ? aws_iam_role.enhanced_monitoring[0].arn : var.monitoring_role_arn + + final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.final_snapshot_identifier_prefix}-${var.identifier}-${try(random_id.snapshot_identifier[0].hex, "")}" + + identifier = var.use_identifier_prefix ? null : var.identifier + identifier_prefix = var.use_identifier_prefix ? "${var.identifier}-" : null + + monitoring_role_name = var.monitoring_role_use_name_prefix ? null : var.monitoring_role_name + monitoring_role_name_prefix = var.monitoring_role_use_name_prefix ? "${var.monitoring_role_name}-" : null + + # Replicas will use source metadata + is_replica = var.replicate_source_db != null +} + +# Ref. https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces +data "aws_partition" "current" {} + +resource "random_id" "snapshot_identifier" { + count = var.create && !var.skip_final_snapshot ? 1 : 0 + + keepers = { + id = var.identifier + } + + byte_length = 4 +} + +resource "aws_db_instance" "this" { + count = var.create ? 1 : 0 + + identifier = local.identifier + identifier_prefix = local.identifier_prefix + + engine = local.is_replica ? null : var.engine + engine_version = var.engine_version + instance_class = var.instance_class + allocated_storage = local.is_replica ? null : 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 + + db_name = var.db_name + username = !local.is_replica ? var.username : null + password = !local.is_replica && var.manage_master_user_password ? null : var.password + port = var.port + domain = var.domain + domain_iam_role_name = var.domain_iam_role_name + iam_database_authentication_enabled = var.iam_database_authentication_enabled + custom_iam_instance_profile = var.custom_iam_instance_profile + manage_master_user_password = !local.is_replica && var.manage_master_user_password ? var.manage_master_user_password : null + master_user_secret_kms_key_id = !local.is_replica && var.manage_master_user_password ? var.master_user_secret_kms_key_id : null + + 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 + option_group_name = var.option_group_name + network_type = var.network_type + + availability_zone = var.availability_zone + multi_az = var.multi_az + iops = var.iops + storage_throughput = var.storage_throughput + publicly_accessible = var.publicly_accessible + ca_cert_identifier = var.ca_cert_identifier + + 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 + + # https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html + dynamic "blue_green_update" { + for_each = length(var.blue_green_update) > 0 ? [var.blue_green_update] : [] + + content { + enabled = try(blue_green_update.value.enabled, null) + } + } + + snapshot_identifier = var.snapshot_identifier + copy_tags_to_snapshot = var.copy_tags_to_snapshot + skip_final_snapshot = var.skip_final_snapshot + final_snapshot_identifier = local.final_snapshot_identifier + + performance_insights_enabled = var.performance_insights_enabled + performance_insights_retention_period = var.performance_insights_enabled ? var.performance_insights_retention_period : null + performance_insights_kms_key_id = var.performance_insights_enabled ? var.performance_insights_kms_key_id : null + + replicate_source_db = var.replicate_source_db + replica_mode = var.replica_mode + backup_retention_period = length(var.blue_green_update) > 0 ? coalesce(var.backup_retention_period, 1) : var.backup_retention_period + backup_window = var.backup_window + max_allocated_storage = var.max_allocated_storage + monitoring_interval = var.monitoring_interval + monitoring_role_arn = var.monitoring_interval > 0 ? local.monitoring_role_arn : null + + character_set_name = var.character_set_name + nchar_character_set_name = var.nchar_character_set_name + timezone = var.timezone + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + + deletion_protection = var.deletion_protection + delete_automated_backups = var.delete_automated_backups + + dynamic "restore_to_point_in_time" { + for_each = var.restore_to_point_in_time != null ? [var.restore_to_point_in_time] : [] + + content { + restore_time = lookup(restore_to_point_in_time.value, "restore_time", null) + source_db_instance_automated_backups_arn = lookup(restore_to_point_in_time.value, "source_db_instance_automated_backups_arn", null) + source_db_instance_identifier = lookup(restore_to_point_in_time.value, "source_db_instance_identifier", null) + source_dbi_resource_id = lookup(restore_to_point_in_time.value, "source_dbi_resource_id", null) + use_latest_restorable_time = lookup(restore_to_point_in_time.value, "use_latest_restorable_time", null) + } + } + + dynamic "s3_import" { + for_each = var.s3_import != null ? [var.s3_import] : [] + + content { + source_engine = "mysql" + source_engine_version = s3_import.value.source_engine_version + bucket_name = s3_import.value.bucket_name + bucket_prefix = lookup(s3_import.value, "bucket_prefix", null) + ingestion_role = s3_import.value.ingestion_role + } + } + + tags = var.tags + + depends_on = [aws_cloudwatch_log_group.this] + + timeouts { + create = lookup(var.timeouts, "create", null) + delete = lookup(var.timeouts, "delete", null) + update = lookup(var.timeouts, "update", null) + } + + # Note: do not add `latest_restorable_time` to `ignore_changes` + # https://github.com/terraform-aws-modules/terraform-aws-rds/issues/478 +} + +################################################################################ +# CloudWatch Log Group +################################################################################ + +# Log groups will not be created if using an identifier prefix ?? +resource "aws_cloudwatch_log_group" "this" { + # for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log if var.create && var.create_cloudwatch_log_group && !var.use_identifier_prefix]) + for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log if var.create && var.create_cloudwatch_log_group]) + + name = "/aws/rds/instance/${var.identifier}/${each.value}" # it is not possible to use the identifier_prefix here since it is not known at plan time and we can't have cyclic reference to the db instance resource + retention_in_days = var.cloudwatch_log_group_retention_in_days + kms_key_id = var.cloudwatch_log_group_kms_key_id + skip_destroy = var.cloudwatch_log_group_skip_destroy_on_deletion + tags = var.tags +} + +################################################################################ +# Enhanced monitoring +################################################################################ + +data "aws_iam_policy_document" "enhanced_monitoring" { + statement { + actions = [ + "sts:AssumeRole", + ] + + principals { + type = "Service" + identifiers = ["monitoring.rds.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "enhanced_monitoring" { + count = var.create_monitoring_role ? 1 : 0 + + name = local.monitoring_role_name + name_prefix = local.monitoring_role_name_prefix + assume_role_policy = data.aws_iam_policy_document.enhanced_monitoring.json + description = var.monitoring_role_description + permissions_boundary = var.monitoring_role_permissions_boundary + path = var.monitoring_iam_role_path + tags = merge( + { + "Name" = format("%s", var.monitoring_role_name) + }, + var.tags, + ) +} + +resource "aws_iam_role_policy_attachment" "enhanced_monitoring" { + count = var.create_monitoring_role ? 1 : 0 + + role = aws_iam_role.enhanced_monitoring[0].name + policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" +} diff --git a/_sub/terraform-aws-rds/modules/db_instance/outputs.tf b/_sub/terraform-aws-rds/modules/db_instance/outputs.tf new file mode 100644 index 00000000..de06eb57 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_instance/outputs.tf @@ -0,0 +1,109 @@ +output "enhanced_monitoring_iam_role_name" { + description = "The name of the monitoring role" + value = try(aws_iam_role.enhanced_monitoring[0].name, null) +} + +output "enhanced_monitoring_iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the monitoring role" + value = try(aws_iam_role.enhanced_monitoring[0].arn, null) +} + +output "db_instance_address" { + description = "The address of the RDS instance" + value = try(aws_db_instance.this[0].address, null) +} + +output "db_instance_arn" { + description = "The ARN of the RDS instance" + value = try(aws_db_instance.this[0].arn, null) +} + +output "db_instance_availability_zone" { + description = "The availability zone of the RDS instance" + value = try(aws_db_instance.this[0].availability_zone, null) +} + +output "db_instance_endpoint" { + description = "The connection endpoint" + value = try(aws_db_instance.this[0].endpoint, null) +} + +output "db_listener_endpoint" { + description = "Specifies the listener connection endpoint for SQL Server Always On" + value = try(aws_db_instance.this[0].listener_endpoint, null) +} + +output "db_instance_engine" { + description = "The database engine" + value = try(aws_db_instance.this[0].engine, null) +} + +output "db_instance_engine_version_actual" { + description = "The running version of the database" + value = try(aws_db_instance.this[0].engine_version_actual, null) +} + +output "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 = try(aws_db_instance.this[0].hosted_zone_id, null) +} + +output "db_instance_identifier" { + description = "The RDS instance identifier" + value = try(aws_db_instance.this[0].identifier, null) +} + +output "db_instance_resource_id" { + description = "The RDS Resource ID of this instance" + value = try(aws_db_instance.this[0].resource_id, null) +} + +output "db_instance_status" { + description = "The RDS instance status" + value = try(aws_db_instance.this[0].status, null) +} + +output "db_instance_name" { + description = "The database name" + value = try(aws_db_instance.this[0].db_name, null) +} + +output "db_instance_username" { + description = "The master username for the database" + value = try(aws_db_instance.this[0].username, null) + sensitive = true +} + +output "db_instance_port" { + description = "The database port" + value = try(aws_db_instance.this[0].port, null) +} + +output "db_instance_ca_cert_identifier" { + description = "Specifies the identifier of the CA certificate for the DB instance" + value = try(aws_db_instance.this[0].ca_cert_identifier, null) +} + +output "db_instance_domain" { + description = "The ID of the Directory Service Active Directory domain the instance is joined to" + value = try(aws_db_instance.this[0].domain, null) +} + +output "db_instance_domain_iam_role_name" { + description = "The name of the IAM role to be used when making API calls to the Directory Service" + value = try(aws_db_instance.this[0].domain_iam_role_name, null) +} + +output "db_instance_master_user_secret_arn" { + description = "The ARN of the master user secret (Only available when manage_master_user_password is set to true)" + value = try(aws_db_instance.this[0].master_user_secret[0].secret_arn, null) +} + +################################################################################ +# CloudWatch Log Group +################################################################################ + +output "db_instance_cloudwatch_log_groups" { + description = "Map of CloudWatch log groups created and their attributes" + value = aws_cloudwatch_log_group.this +} diff --git a/_sub/terraform-aws-rds/modules/db_instance/variables.tf b/_sub/terraform-aws-rds/modules/db_instance/variables.tf new file mode 100644 index 00000000..06d75222 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_instance/variables.tf @@ -0,0 +1,431 @@ +variable "create" { + description = "Whether to create this resource or not?" + type = bool + default = true +} + +variable "identifier" { + description = "The name of the RDS instance" + type = string +} +variable "custom_iam_instance_profile" { + description = "RDS custom iam instance profile" + type = string + default = null +} + +variable "use_identifier_prefix" { + description = "Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix" + type = bool + default = false +} + +variable "allocated_storage" { + description = "The allocated storage in gigabytes" + type = number + default = null +} + +variable "storage_type" { + description = "One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter" + type = string + default = null +} + +variable "storage_throughput" { + description = "Storage throughput value for the DB instance. This setting applies only to the `gp3` storage type. See `notes` for limitations regarding this variable for `gp3`" + type = number + default = null +} + +variable "storage_encrypted" { + description = "Specifies whether the DB instance is encrypted" + type = bool + default = true +} + +variable "kms_key_id" { + description = "The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage_encrypted is set to true and kms_key_id is not specified the default KMS key created in your account will be used" + type = string + default = null +} + +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." + type = string + default = null +} + +variable "license_model" { + description = "License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1" + type = string + default = null +} + +variable "replica_mode" { + description = "Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified" + type = string + default = null +} + +variable "iam_database_authentication_enabled" { + description = "Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled" + type = bool + default = false +} + +variable "domain" { + description = "The ID of the Directory Service Active Directory domain to create the instance in" + type = string + default = null +} + +variable "domain_iam_role_name" { + description = "(Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service" + type = string + default = null +} + +variable "engine" { + description = "The database engine to use" + type = string + default = null +} + +variable "engine_version" { + description = "The engine version to use" + type = string + default = null +} + +variable "instance_class" { + description = "The instance type of the RDS instance" + type = string + default = null +} + +variable "db_name" { + description = "The DB name to create. If omitted, no database is created initially" + type = string + default = null +} + +variable "username" { + description = "Username for the master DB user" + type = string + default = null +} + +variable "password" { + description = "Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file" + type = string + default = null +} + +variable "manage_master_user_password" { + description = "Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if password is provided" + type = bool + default = false +} + +variable "master_user_secret_kms_key_id" { + description = < +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_db_option_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_option_group) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | +| [engine\_name](#input\_engine\_name) | Specifies the name of the engine that this option group should be associated with | `string` | `null` | no | +| [major\_engine\_version](#input\_major\_engine\_version) | Specifies the major version of the engine that this option group should be associated with | `string` | `null` | no | +| [name](#input\_name) | The name of the option group | `string` | `""` | no | +| [option\_group\_description](#input\_option\_group\_description) | The description of the option group | `string` | `null` | no | +| [options](#input\_options) | A list of Options to apply | `any` | `[]` | no | +| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Define maximum timeout for deletion of `aws_db_option_group` resource | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix | `bool` | `true` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_option\_group\_arn](#output\_db\_option\_group\_arn) | The ARN of the db option group | +| [db\_option\_group\_id](#output\_db\_option\_group\_id) | The db option group id | + diff --git a/_sub/terraform-aws-rds/modules/db_option_group/main.tf b/_sub/terraform-aws-rds/modules/db_option_group/main.tf new file mode 100644 index 00000000..6ae35840 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_option_group/main.tf @@ -0,0 +1,50 @@ +locals { + name = var.use_name_prefix ? null : var.name + name_prefix = var.use_name_prefix ? "${var.name}-" : null + + description = coalesce(var.option_group_description, format("%s option group", var.name)) +} + +resource "aws_db_option_group" "this" { + count = var.create ? 1 : 0 + + name = local.name + name_prefix = local.name_prefix + option_group_description = local.description + engine_name = var.engine_name + major_engine_version = var.major_engine_version + + dynamic "option" { + for_each = var.options + content { + option_name = option.value.option_name + port = lookup(option.value, "port", null) + version = lookup(option.value, "version", null) + db_security_group_memberships = lookup(option.value, "db_security_group_memberships", null) + vpc_security_group_memberships = lookup(option.value, "vpc_security_group_memberships", null) + + dynamic "option_settings" { + for_each = lookup(option.value, "option_settings", []) + content { + name = lookup(option_settings.value, "name", null) + value = lookup(option_settings.value, "value", null) + } + } + } + } + + tags = merge( + var.tags, + { + "Name" = var.name + }, + ) + + timeouts { + delete = lookup(var.timeouts, "delete", null) + } + + lifecycle { + create_before_destroy = true + } +} diff --git a/_sub/terraform-aws-rds/modules/db_option_group/outputs.tf b/_sub/terraform-aws-rds/modules/db_option_group/outputs.tf new file mode 100644 index 00000000..377e169a --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_option_group/outputs.tf @@ -0,0 +1,9 @@ +output "db_option_group_id" { + description = "The db option group id" + value = try(aws_db_option_group.this[0].id, null) +} + +output "db_option_group_arn" { + description = "The ARN of the db option group" + value = try(aws_db_option_group.this[0].arn, null) +} diff --git a/_sub/terraform-aws-rds/modules/db_option_group/variables.tf b/_sub/terraform-aws-rds/modules/db_option_group/variables.tf new file mode 100644 index 00000000..de4be194 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_option_group/variables.tf @@ -0,0 +1,53 @@ +variable "create" { + description = "Whether to create this resource or not?" + type = bool + default = true +} + +variable "name" { + description = "The name of the option group" + type = string + default = "" +} + +variable "use_name_prefix" { + description = "Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix" + type = bool + default = true +} + +variable "option_group_description" { + description = "The description of the option group" + type = string + default = null +} + +variable "engine_name" { + description = "Specifies the name of the engine that this option group should be associated with" + type = string + default = null +} + +variable "major_engine_version" { + description = "Specifies the major version of the engine that this option group should be associated with" + type = string + default = null +} + +variable "options" { + description = "A list of Options to apply" + type = any + default = [] +} + +variable "timeouts" { + description = "Define maximum timeout for deletion of `aws_db_option_group` resource" + type = map(string) + default = {} +} + +variable "tags" { + description = "A mapping of tags to assign to the resource" + type = map(string) + default = {} +} diff --git a/_sub/terraform-aws-rds/modules/db_option_group/versions.tf b/_sub/terraform-aws-rds/modules/db_option_group/versions.tf new file mode 100644 index 00000000..ddfcb0e0 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_option_group/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} diff --git a/_sub/terraform-aws-rds/modules/db_parameter_group/README.md b/_sub/terraform-aws-rds/modules/db_parameter_group/README.md new file mode 100644 index 00000000..56e16577 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_parameter_group/README.md @@ -0,0 +1,45 @@ +# aws_db_parameter_group + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_db_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | +| [description](#input\_description) | The description of the DB parameter group | `string` | `null` | no | +| [family](#input\_family) | The family of the DB parameter group | `string` | `null` | no | +| [name](#input\_name) | The name of the DB parameter group | `string` | `""` | no | +| [parameters](#input\_parameters) | A list of DB parameter maps to apply | `list(map(string))` | `[]` | no | +| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix | `bool` | `true` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_parameter\_group\_arn](#output\_db\_parameter\_group\_arn) | The ARN of the db parameter group | +| [db\_parameter\_group\_id](#output\_db\_parameter\_group\_id) | The db parameter group id | + diff --git a/_sub/terraform-aws-rds/modules/db_parameter_group/main.tf b/_sub/terraform-aws-rds/modules/db_parameter_group/main.tf new file mode 100644 index 00000000..94acbe5e --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_parameter_group/main.tf @@ -0,0 +1,35 @@ +locals { + name = var.use_name_prefix ? null : var.name + name_prefix = var.use_name_prefix ? "${var.name}-" : null + + description = coalesce(var.description, format("%s parameter group", var.name)) +} + +resource "aws_db_parameter_group" "this" { + count = var.create ? 1 : 0 + + name = local.name + name_prefix = local.name_prefix + description = local.description + family = var.family + + dynamic "parameter" { + for_each = var.parameters + content { + name = parameter.value.name + value = parameter.value.value + apply_method = lookup(parameter.value, "apply_method", null) + } + } + + tags = merge( + var.tags, + { + "Name" = var.name + }, + ) + + lifecycle { + create_before_destroy = true + } +} diff --git a/_sub/terraform-aws-rds/modules/db_parameter_group/outputs.tf b/_sub/terraform-aws-rds/modules/db_parameter_group/outputs.tf new file mode 100644 index 00000000..0ea46412 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_parameter_group/outputs.tf @@ -0,0 +1,9 @@ +output "db_parameter_group_id" { + description = "The db parameter group id" + value = try(aws_db_parameter_group.this[0].id, null) +} + +output "db_parameter_group_arn" { + description = "The ARN of the db parameter group" + value = try(aws_db_parameter_group.this[0].arn, null) +} diff --git a/_sub/terraform-aws-rds/modules/db_parameter_group/variables.tf b/_sub/terraform-aws-rds/modules/db_parameter_group/variables.tf new file mode 100644 index 00000000..b7b7af9f --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_parameter_group/variables.tf @@ -0,0 +1,41 @@ +variable "create" { + description = "Whether to create this resource or not?" + type = bool + default = true +} + +variable "name" { + description = "The name of the DB parameter group" + type = string + default = "" +} + +variable "use_name_prefix" { + description = "Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix" + type = bool + default = true +} + +variable "description" { + description = "The description of the DB parameter group" + type = string + default = null +} + +variable "family" { + description = "The family of the DB parameter group" + type = string + default = null +} + +variable "parameters" { + description = "A list of DB parameter maps to apply" + type = list(map(string)) + default = [] +} + +variable "tags" { + description = "A mapping of tags to assign to the resource" + type = map(string) + default = {} +} diff --git a/_sub/terraform-aws-rds/modules/db_parameter_group/versions.tf b/_sub/terraform-aws-rds/modules/db_parameter_group/versions.tf new file mode 100644 index 00000000..ddfcb0e0 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_parameter_group/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/README.md b/_sub/terraform-aws-rds/modules/db_subnet_group/README.md new file mode 100644 index 00000000..68a1d5ff --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_subnet_group/README.md @@ -0,0 +1,44 @@ +# aws_db_subnet_group + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_db_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_subnet_group) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | +| [description](#input\_description) | The description of the DB subnet group | `string` | `null` | no | +| [name](#input\_name) | The name of the DB subnet group | `string` | `""` | no | +| [subnet\_ids](#input\_subnet\_ids) | A list of VPC subnet IDs | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix | `bool` | `true` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_subnet\_group\_arn](#output\_db\_subnet\_group\_arn) | The ARN of the db subnet group | +| [db\_subnet\_group\_id](#output\_db\_subnet\_group\_id) | The db subnet group name | + diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/main.tf b/_sub/terraform-aws-rds/modules/db_subnet_group/main.tf new file mode 100644 index 00000000..6eecd88a --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_subnet_group/main.tf @@ -0,0 +1,22 @@ +locals { + name = var.use_name_prefix ? null : var.name + name_prefix = var.use_name_prefix ? "${var.name}-" : null + + description = coalesce(var.description, format("%s subnet group", var.name)) +} + +resource "aws_db_subnet_group" "this" { + count = var.create ? 1 : 0 + + name = local.name + name_prefix = local.name_prefix + description = local.description + subnet_ids = var.subnet_ids + + tags = merge( + var.tags, + { + "Name" = var.name + }, + ) +} diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/outputs.tf b/_sub/terraform-aws-rds/modules/db_subnet_group/outputs.tf new file mode 100644 index 00000000..dd92fe8b --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_subnet_group/outputs.tf @@ -0,0 +1,9 @@ +output "db_subnet_group_id" { + description = "The db subnet group name" + value = try(aws_db_subnet_group.this[0].id, null) +} + +output "db_subnet_group_arn" { + description = "The ARN of the db subnet group" + value = try(aws_db_subnet_group.this[0].arn, null) +} diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/variables.tf b/_sub/terraform-aws-rds/modules/db_subnet_group/variables.tf new file mode 100644 index 00000000..48185ab4 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_subnet_group/variables.tf @@ -0,0 +1,35 @@ +variable "create" { + description = "Whether to create this resource or not?" + type = bool + default = true +} + +variable "name" { + description = "The name of the DB subnet group" + type = string + default = "" +} + +variable "use_name_prefix" { + description = "Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix" + type = bool + default = true +} + +variable "description" { + description = "The description of the DB subnet group" + type = string + default = null +} + +variable "subnet_ids" { + description = "A list of VPC subnet IDs" + type = list(string) + default = [] +} + +variable "tags" { + description = "A mapping of tags to assign to the resource" + type = map(string) + default = {} +} diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/versions.tf b/_sub/terraform-aws-rds/modules/db_subnet_group/versions.tf new file mode 100644 index 00000000..ddfcb0e0 --- /dev/null +++ b/_sub/terraform-aws-rds/modules/db_subnet_group/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} diff --git a/_sub/terraform-aws-rds/outputs.tf b/_sub/terraform-aws-rds/outputs.tf new file mode 100644 index 00000000..f9c771ec --- /dev/null +++ b/_sub/terraform-aws-rds/outputs.tf @@ -0,0 +1,140 @@ +output "enhanced_monitoring_iam_role_name" { + description = "The name of the monitoring role" + value = module.db_instance.enhanced_monitoring_iam_role_name +} + +output "enhanced_monitoring_iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the monitoring role" + value = module.db_instance.enhanced_monitoring_iam_role_arn +} + +output "db_instance_address" { + description = "The address of the RDS instance" + value = module.db_instance.db_instance_address +} + +output "db_instance_arn" { + description = "The ARN of the RDS instance" + value = module.db_instance.db_instance_arn +} + +output "db_instance_availability_zone" { + description = "The availability zone of the RDS instance" + value = module.db_instance.db_instance_availability_zone +} + +output "db_instance_endpoint" { + description = "The connection endpoint" + value = module.db_instance.db_instance_endpoint +} + +output "db_listener_endpoint" { + description = "Specifies the listener connection endpoint for SQL Server Always On" + value = module.db_instance.db_listener_endpoint +} + +output "db_instance_engine" { + description = "The database engine" + value = module.db_instance.db_instance_engine +} + +output "db_instance_engine_version_actual" { + description = "The running version of the database" + value = module.db_instance.db_instance_engine_version_actual +} + +output "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_instance.db_instance_hosted_zone_id +} + +output "db_instance_identifier" { + description = "The RDS instance identifier" + value = module.db_instance.db_instance_identifier +} + +output "db_instance_resource_id" { + description = "The RDS Resource ID of this instance" + value = module.db_instance.db_instance_resource_id +} + +output "db_instance_status" { + description = "The RDS instance status" + value = module.db_instance.db_instance_status +} + +output "db_instance_name" { + description = "The database name" + value = module.db_instance.db_instance_name +} + +output "db_instance_username" { + description = "The master username for the database" + value = module.db_instance.db_instance_username + sensitive = true +} + +output "db_instance_domain" { + description = "The ID of the Directory Service Active Directory domain the instance is joined to" + value = module.db_instance.db_instance_domain +} + +output "db_instance_domain_iam_role_name" { + description = "The name of the IAM role to be used when making API calls to the Directory Service" + value = module.db_instance.db_instance_domain_iam_role_name +} + +output "db_instance_port" { + description = "The database port" + value = module.db_instance.db_instance_port +} + +output "db_instance_ca_cert_identifier" { + description = "Specifies the identifier of the CA certificate for the DB instance" + value = module.db_instance.db_instance_ca_cert_identifier +} + +output "db_instance_master_user_secret_arn" { + description = "The ARN of the master user secret (Only available when manage_master_user_password is set to true)" + value = module.db_instance.db_instance_master_user_secret_arn +} + +output "db_subnet_group_id" { + description = "The db subnet group name" + value = module.db_subnet_group.db_subnet_group_id +} + +output "db_subnet_group_arn" { + description = "The ARN of the db subnet group" + value = module.db_subnet_group.db_subnet_group_arn +} + +output "db_parameter_group_id" { + description = "The db parameter group id" + value = module.db_parameter_group.db_parameter_group_id +} + +output "db_parameter_group_arn" { + description = "The ARN of the db parameter group" + value = module.db_parameter_group.db_parameter_group_arn +} + +# DB option group +output "db_option_group_id" { + description = "The db option group id" + value = module.db_option_group.db_option_group_id +} + +output "db_option_group_arn" { + description = "The ARN of the db option group" + value = module.db_option_group.db_option_group_arn +} + +################################################################################ +# CloudWatch Log Group +################################################################################ + +output "db_instance_cloudwatch_log_groups" { + description = "Map of CloudWatch log groups created and their attributes" + value = module.db_instance.db_instance_cloudwatch_log_groups +} diff --git a/_sub/terraform-aws-rds/variables.tf b/_sub/terraform-aws-rds/variables.tf new file mode 100644 index 00000000..bbbcdb8c --- /dev/null +++ b/_sub/terraform-aws-rds/variables.tf @@ -0,0 +1,552 @@ +variable "identifier" { + description = "The name of the RDS instance" + type = string +} + +variable "instance_use_identifier_prefix" { + description = "Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix" + type = bool + default = false +} + +variable "custom_iam_instance_profile" { + description = "RDS custom iam instance profile" + type = string + default = null +} + +variable "allocated_storage" { + description = "The allocated storage in gigabytes" + type = number + default = null +} + +variable "storage_type" { + description = "One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter" + type = string + default = null +} + +variable "storage_throughput" { + description = "Storage throughput value for the DB instance. See `notes` for limitations regarding this variable for `gp3`" + type = number + default = null +} + +variable "storage_encrypted" { + description = "Specifies whether the DB instance is encrypted" + type = bool + default = true +} + +variable "kms_key_id" { + description = "The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage_encrypted is set to true and kms_key_id is not specified the default KMS key created in your account will be used. Be sure to use the full ARN, not a key alias." + type = string + default = null +} + +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" + type = string + default = null +} + +variable "license_model" { + description = "License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1" + type = string + default = null +} + +variable "replica_mode" { + description = "Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified" + type = string + default = null +} + +variable "iam_database_authentication_enabled" { + description = "Specifies whether or not the mappings of AWS Identity and Access Management (IAM) accounts to database accounts are enabled" + type = bool + default = false +} + +variable "domain" { + description = "The ID of the Directory Service Active Directory domain to create the instance in" + type = string + default = null +} + +variable "domain_iam_role_name" { + description = "(Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service" + type = string + default = null +} + +variable "engine" { + description = "The database engine to use" + type = string + default = null +} + +variable "engine_version" { + description = "The engine version to use" + type = string + default = null +} + +variable "skip_final_snapshot" { + description = "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" + type = bool + default = false +} + +variable "snapshot_identifier" { + description = "Specifies whether or not to create this database from a snapshot. This correlates to the snapshot ID you'd find in the RDS console, e.g: rds:production-2015-06-26-06-05" + type = string + default = null +} + +variable "copy_tags_to_snapshot" { + description = "On delete, copy all Instance tags to the final snapshot" + type = bool + default = false +} + +variable "final_snapshot_identifier_prefix" { + description = "The name which is prefixed to the final snapshot on cluster destroy" + type = string + default = "final" +} + +variable "instance_class" { + description = "The instance type of the RDS instance" + type = string + default = null +} + +variable "db_name" { + description = "The DB name to create. If omitted, no database is created initially" + type = string + default = null +} + +variable "username" { + description = "Username for the master DB user" + type = string + default = null +} + +variable "password" { + description = < Date: Fri, 27 Oct 2023 08:03:27 +0000 Subject: [PATCH 03/12] terraform-docs: automated action --- README.md | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fe6f0377..6e98c699 100644 --- a/README.md +++ b/README.md @@ -3,5 +3,170 @@ Terraform module for AWS RDS instances # Documentation -{{ .Content }} +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3.0, < 2.0.0 | +| [aws](#requirement\_aws) | ~> 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [random](#provider\_random) | n/a | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [cluster](#module\_cluster) | ./_sub/terraform-aws-rds-aurora | n/a | +| [db](#module\_db) | ./_sub/terraform-aws-rds | n/a | +| [db\_proxy](#module\_db\_proxy) | ./_sub/terraform-aws-rds-proxy | n/a | + +## Resources + +| Name | Type | +|------|------| +| [random_id.snapshot_identifier](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allocated\_storage](#input\_allocated\_storage) | The allocated storage in gigabytes | `number` | `null` | no | +| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Indicates that major version upgrades are allowed. Changing this parameter does not result in an outage and the change is asynchronously applied as soon as possible | `bool` | `false` | no | +| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any database modifications are applied immediately, or during the next maintenance window | `bool` | `false` | no | +| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window | `bool` | `true` | no | +| [availability\_zone](#input\_availability\_zone) | The Availability Zone of the RDS instance | `string` | `null` | no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `null` | no | +| [backup\_window](#input\_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` | `null` | no | +| [blue\_green\_update](#input\_blue\_green\_update) | Enables low-downtime updates using RDS Blue/Green deployments. | `map(string)` | `{}` | no | +| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | `string` | `null` | no | +| [character\_set\_name](#input\_character\_set\_name) | 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 and Collations and Character Sets for Microsoft SQL Server for more information. This can only be set on creation | `string` | `null` | no | +| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | +| [cloudwatch\_log\_group\_retention\_in\_days](#input\_cloudwatch\_log\_group\_retention\_in\_days) | The number of days to retain CloudWatch logs for the DB instance | `number` | `7` | no | +| [cluster\_activity\_stream\_kms\_key\_id](#input\_cluster\_activity\_stream\_kms\_key\_id) | The AWS KMS key identifier for encrypting messages in the database activity stream | `string` | `null` | no | +| [cluster\_activity\_stream\_mode](#input\_cluster\_activity\_stream\_mode) | Specifies the mode of the database activity stream. Database events such as a change or access generate an activity stream event. One of: sync, async | `string` | `null` | no | +| [cluster\_autoscaling\_enabled](#input\_cluster\_autoscaling\_enabled) | Determines whether autoscaling of the cluster read replicas is enabled | `bool` | `false` | no | +| [cluster\_autoscaling\_max\_capacity](#input\_cluster\_autoscaling\_max\_capacity) | Maximum number of read replicas permitted when autoscaling is enabled | `number` | `2` | no | +| [cluster\_autoscaling\_min\_capacity](#input\_cluster\_autoscaling\_min\_capacity) | Minimum number of read replicas permitted when autoscaling is enabled | `number` | `0` | no | +| [cluster\_autoscaling\_policy\_name](#input\_cluster\_autoscaling\_policy\_name) | Autoscaling policy name | `string` | `"target-metric"` | no | +| [cluster\_autoscaling\_scale\_in\_cooldown](#input\_cluster\_autoscaling\_scale\_in\_cooldown) | Cooldown in seconds before allowing further scaling operations after a scale in | `number` | `300` | no | +| [cluster\_autoscaling\_scale\_out\_cooldown](#input\_cluster\_autoscaling\_scale\_out\_cooldown) | Cooldown in seconds before allowing further scaling operations after a scale out | `number` | `300` | no | +| [cluster\_autoscaling\_target\_connections](#input\_cluster\_autoscaling\_target\_connections) | Average number of connections threshold which will initiate autoscaling. Default value is 70% of db.r4/r5/r6g.large's default max\_connections | `number` | `700` | no | +| [cluster\_autoscaling\_target\_cpu](#input\_cluster\_autoscaling\_target\_cpu) | CPU threshold which will initiate autoscaling | `number` | `70` | no | +| [cluster\_availability\_zones](#input\_cluster\_availability\_zones) | List of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created. RDS automatically assigns 3 AZs if less than 3 AZs are configured, which will show as a difference requiring resource recreation next Terraform apply | `list(string)` | `null` | no | +| [cluster\_backtrack\_window](#input\_cluster\_backtrack\_window) | The target backtrack window, in seconds. Only available for `aurora` engine currently. To disable backtracking, set this value to 0. Must be between 0 and 259200 (72 hours) | `number` | `null` | no | +| [cluster\_db\_instance\_count](#input\_cluster\_db\_instance\_count) | n/a | `number` | n/a | yes | +| [cluster\_enable\_global\_write\_forwarding](#input\_cluster\_enable\_global\_write\_forwarding) | Whether cluster should forward writes to an associated global cluster. Applied to secondary clusters to enable them to forward writes to an `aws_rds_global_cluster`'s primary cluster | `bool` | `null` | no | +| [cluster\_enable\_http\_endpoint](#input\_cluster\_enable\_http\_endpoint) | Enable HTTP endpoint (data API). Only valid when engine\_mode is set to `serverless` | `bool` | `null` | no | +| [cluster\_endpoints](#input\_cluster\_endpoints) | Map of additional cluster endpoints and their attributes to be created | `any` | `{}` | no | +| [cluster\_engine\_mode](#input\_cluster\_engine\_mode) | The database engine mode. Valid values: `global`, `multimaster`, `parallelquery`, `provisioned`, `serverless`. Defaults to: `provisioned` | `string` | `"provisioned"` | no | +| [cluster\_engine\_native\_audit\_fields\_included](#input\_cluster\_engine\_native\_audit\_fields\_included) | Specifies whether the database activity stream includes engine-native audit fields. This option only applies to an Oracle DB instance. By default, no engine-native audit fields are included | `bool` | `false` | no | +| [cluster\_global\_cluster\_identifier](#input\_cluster\_global\_cluster\_identifier) | The global cluster identifier specified on `aws_rds_global_cluster` | `string` | `null` | no | +| [cluster\_iam\_roles](#input\_cluster\_iam\_roles) | Map of IAM roles and supported feature names to associate with the cluster | `map(map(string))` | `{}` | no | +| [cluster\_instances](#input\_cluster\_instances) | Map of cluster instances and any specific/overriding attributes to be created | `any` | `{}` | no | +| [cluster\_instances\_use\_identifier\_prefix](#input\_cluster\_instances\_use\_identifier\_prefix) | Determines whether cluster instance identifiers are used as prefixes | `bool` | `false` | no | +| [cluster\_is\_primary\_cluster](#input\_cluster\_is\_primary\_cluster) | Determines whether cluster is primary cluster with writer instance (set to `false` for global cluster and replica clusters) | `bool` | `true` | no | +| [cluster\_members](#input\_cluster\_members) | List of RDS Instances that are a part of this cluster | `list(string)` | `null` | no | +| [cluster\_predefined\_metric\_type](#input\_cluster\_predefined\_metric\_type) | The metric type to scale on. Valid values are `RDSReaderAverageCPUUtilization` and `RDSReaderAverageDatabaseConnections` | `string` | `"RDSReaderAverageCPUUtilization"` | no | +| [cluster\_replication\_source\_identifier](#input\_cluster\_replication\_source\_identifier) | ARN of a source DB cluster or DB instance if this DB cluster is to be created as a Read Replica | `string` | `null` | no | +| [cluster\_scaling\_configuration](#input\_cluster\_scaling\_configuration) | Map of nested attributes with scaling properties. Only valid when `engine_mode` is set to `serverless` | `map(string)` | `{}` | no | +| [cluster\_serverlessv2\_scaling\_configuration](#input\_cluster\_serverlessv2\_scaling\_configuration) | Map of nested attributes with serverless v2 scaling properties. Only valid when `engine_mode` is set to `provisioned` | `map(string)` | `{}` | no | +| [cluster\_source\_region](#input\_cluster\_source\_region) | The source region for an encrypted replica DB cluster | `string` | `null` | no | +| [cluster\_tags](#input\_cluster\_tags) | A map of tags to add to only the cluster. Used for AWS Instance Scheduler tagging | `map(string)` | `{}` | no | +| [cluster\_timeouts](#input\_cluster\_timeouts) | Create, update, and delete timeout configurations for the cluster | `map(string)` | `{}` | no | +| [cluster\_use\_name\_prefix](#input\_cluster\_use\_name\_prefix) | Whether to use `name` as a prefix for the cluster | `bool` | `false` | no | +| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | On delete, copy all Instance tags to the final snapshot | `bool` | `false` | no | +| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports` | `bool` | `false` | no | +| [create\_db\_cluster\_activity\_stream](#input\_create\_db\_cluster\_activity\_stream) | Determines whether a cluster activity stream is created. | `bool` | `false` | no | +| [create\_db\_instance](#input\_create\_db\_instance) | Whether to create a database instance | `bool` | `true` | no | +| [create\_db\_option\_group](#input\_create\_db\_option\_group) | Create a database option group | `bool` | `true` | no | +| [create\_db\_parameter\_group](#input\_create\_db\_parameter\_group) | Whether to create a database parameter group | `bool` | `true` | no | +| [create\_db\_subnet\_group](#input\_create\_db\_subnet\_group) | Whether to create a database subnet group | `bool` | `false` | no | +| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Create IAM role with a defined name that permits RDS to send enhanced monitoring metrics to CloudWatch Logs | `bool` | `false` | no | +| [custom\_iam\_instance\_profile](#input\_custom\_iam\_instance\_profile) | RDS custom iam instance profile | `string` | `null` | no | +| [db\_instance\_tags](#input\_db\_instance\_tags) | Additional tags for the DB instance | `map(string)` | `{}` | no | +| [db\_name](#input\_db\_name) | The DB name to create. If omitted, no database is created initially | `string` | `null` | no | +| [db\_option\_group\_tags](#input\_db\_option\_group\_tags) | Additional tags for the DB option group | `map(string)` | `{}` | no | +| [db\_parameter\_group\_tags](#input\_db\_parameter\_group\_tags) | Additional tags for the DB parameter group | `map(string)` | `{}` | no | +| [db\_subnet\_group\_description](#input\_db\_subnet\_group\_description) | Description of the DB subnet group to create | `string` | `null` | no | +| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC | `string` | n/a | yes | +| [db\_subnet\_group\_tags](#input\_db\_subnet\_group\_tags) | Additional tags for the DB subnet group | `map(string)` | `{}` | no | +| [db\_subnet\_group\_use\_name\_prefix](#input\_db\_subnet\_group\_use\_name\_prefix) | Determines whether to use `subnet_group_name` as is or create a unique name beginning with the `subnet_group_name` as the prefix | `bool` | `true` | no | +| [delete\_automated\_backups](#input\_delete\_automated\_backups) | Specifies whether to remove automated backups immediately after the DB instance is deleted | `bool` | `true` | no | +| [deletion\_protection](#input\_deletion\_protection) | The database can't be deleted when this value is set to true | `bool` | `false` | no | +| [domain](#input\_domain) | The ID of the Directory Service Active Directory domain to create the instance in | `string` | `null` | no | +| [domain\_iam\_role\_name](#input\_domain\_iam\_role\_name) | (Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service | `string` | `null` | no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on engine): alert, audit, error, general, listener, slowquery, trace, postgresql (PostgreSQL), upgrade (PostgreSQL) | `list(string)` | `[]` | no | +| [engine](#input\_engine) | The database engine to use | `string` | `"postgres"` | no | +| [engine\_version](#input\_engine\_version) | The engine version to use | `string` | `"14"` | no | +| [family](#input\_family) | The family of the DB parameter group | `string` | `null` | no | +| [final\_snapshot\_identifier\_prefix](#input\_final\_snapshot\_identifier\_prefix) | The name which is prefixed to the final snapshot on cluster destroy | `string` | `"final"` | no | +| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or not the mappings of AWS Identity and Access Management (IAM) accounts to database accounts are enabled | `bool` | `false` | no | +| [identifier](#input\_identifier) | The name of the RDS instance | `string` | n/a | yes | +| [idle\_client\_timeout](#input\_idle\_client\_timeout) | Idle client timeout of the RDS proxy (keep connection alive) | `number` | `1800` | no | +| [include\_proxy](#input\_include\_proxy) | Optionally include proxy to help manage database connections | `bool` | `false` | no | +| [instance\_class](#input\_instance\_class) | The instance type of the RDS instance | `string` | `null` | no | +| [instance\_use\_identifier\_prefix](#input\_instance\_use\_identifier\_prefix) | Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix | `bool` | `false` | no | +| [iops](#input\_iops) | The amount of provisioned IOPS. Setting this implies a storage\_type of 'io1' or `gp3`. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | +| [is\_db\_cluster](#input\_is\_db\_cluster) | n/a | `bool` | `false` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage\_encrypted is set to true and kms\_key\_id is not specified the default KMS key created in your account will be used. Be sure to use the full ARN, not a key alias. | `string` | `null` | no | +| [license\_model](#input\_license\_model) | License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1 | `string` | `null` | no | +| [maintenance\_window](#input\_maintenance\_window) | The window to perform maintenance in. Syntax: 'ddd:hh24:mi-ddd:hh24:mi'. Eg: 'Mon:00:00-Mon:03:00' | `string` | `"Sat:21:00-Sun:01:00"` | no | +| [major\_engine\_version](#input\_major\_engine\_version) | Specifies the major version of the engine that this option group should be associated with | `string` | `"14"` | no | +| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager | `bool` | `true` | no | +| [master\_user\_secret\_kms\_key\_id](#input\_master\_user\_secret\_kms\_key\_id) | The key ARN, key ID, alias ARN or alias name for the KMS key to encrypt the master user password secret in Secrets Manager.
If not specified, the default KMS key for your Amazon Web Services account is used. | `string` | `null` | no | +| [max\_allocated\_storage](#input\_max\_allocated\_storage) | Specifies the value for Storage Autoscaling | `number` | `0` | no | +| [monitoring\_iam\_role\_path](#input\_monitoring\_iam\_role\_path) | Path for the monitoring role | `string` | `null` | no | +| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. The default is 0. Valid Values: 0, 1, 5, 10, 15, 30, 60 | `number` | `0` | no | +| [monitoring\_role\_arn](#input\_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` | `null` | no | +| [monitoring\_role\_description](#input\_monitoring\_role\_description) | Description of the monitoring IAM role | `string` | `null` | no | +| [monitoring\_role\_name](#input\_monitoring\_role\_name) | Name of the IAM role which will be created when create\_monitoring\_role is enabled | `string` | `null` | no | +| [monitoring\_role\_permissions\_boundary](#input\_monitoring\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the monitoring IAM role | `string` | `null` | no | +| [monitoring\_role\_use\_name\_prefix](#input\_monitoring\_role\_use\_name\_prefix) | Determines whether to use `monitoring_role_name` as is or create a unique identifier beginning with `monitoring_role_name` as the specified prefix | `bool` | `false` | no | +| [multi\_az](#input\_multi\_az) | Specifies if the RDS instance is multi-AZ | `bool` | `false` | no | +| [nchar\_character\_set\_name](#input\_nchar\_character\_set\_name) | The national character set is used in the NCHAR, NVARCHAR2, and NCLOB data types for Oracle instances. This can't be changed. | `string` | `null` | no | +| [network\_type](#input\_network\_type) | The type of network stack to use | `string` | `null` | no | +| [option\_group\_description](#input\_option\_group\_description) | The description of the option group | `string` | `null` | no | +| [option\_group\_name](#input\_option\_group\_name) | Name of the option group | `string` | `null` | no | +| [option\_group\_timeouts](#input\_option\_group\_timeouts) | Define maximum timeout for deletion of `aws_db_option_group` resource | `map(string)` | `{}` | no | +| [option\_group\_use\_name\_prefix](#input\_option\_group\_use\_name\_prefix) | Determines whether to use `option_group_name` as is or create a unique name beginning with the `option_group_name` as the prefix | `bool` | `true` | no | +| [options](#input\_options) | A list of Options to apply | `any` | `[]` | no | +| [parameter\_group\_description](#input\_parameter\_group\_description) | Description of the DB parameter group to create | `string` | `null` | no | +| [parameter\_group\_name](#input\_parameter\_group\_name) | Name of the DB parameter group to associate or create | `string` | `null` | no | +| [parameter\_group\_use\_name\_prefix](#input\_parameter\_group\_use\_name\_prefix) | Determines whether to use `parameter_group_name` as is or create a unique name beginning with the `parameter_group_name` as the prefix | `bool` | `true` | no | +| [parameters](#input\_parameters) | A list of DB parameters (map) to apply | `list(map(string))` | `[]` | no | +| [password](#input\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file.
The password provided will not be used if `manage_master_user_password` is set to true. | `string` | `null` | no | +| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Specifies whether Performance Insights are enabled | `bool` | `false` | no | +| [performance\_insights\_kms\_key\_id](#input\_performance\_insights\_kms\_key\_id) | The ARN for the KMS key to encrypt Performance Insights data | `string` | `null` | no | +| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | The amount of time in days to retain Performance Insights data. Valid values are `7`, `731` (2 years) or a multiple of `31` | `number` | `7` | no | +| [port](#input\_port) | The port on which the DB accepts connections | `string` | `"5432"` | no | +| [proxy\_debug\_logging](#input\_proxy\_debug\_logging) | Turn on debug logging for the proxy | `bool` | `false` | no | +| [proxy\_engine\_family](#input\_proxy\_engine\_family) | Engine family of the RDS proxy. Default: POSTGRESQL | `string` | `"POSTGRESQL"` | no | +| [proxy\_name](#input\_proxy\_name) | Name of the RDS proxy. Will be auto-generated if not specified | `string` | `null` | no | +| [proxy\_require\_tls](#input\_proxy\_require\_tls) | Require tls on the RDS proxy. Default: true | `bool` | `true` | no | +| [publicly\_accessible](#input\_publicly\_accessible) | Bool to control if instance is publicly accessible | `bool` | `false` | no | +| [rds\_proxy\_security\_group\_ids](#input\_rds\_proxy\_security\_group\_ids) | n/a | `list(string)` | `[]` | no | +| [replica\_mode](#input\_replica\_mode) | Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified | `string` | `null` | no | +| [replicate\_source\_db](#input\_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 | +| [restore\_to\_point\_in\_time](#input\_restore\_to\_point\_in\_time) | Restore to a point in time (MySQL is NOT supported) | `map(string)` | `null` | no | +| [s3\_import](#input\_s3\_import) | Restore from a Percona Xtrabackup in S3 (only MySQL is supported) | `map(string)` | `null` | no | +| [skip\_final\_snapshot](#input\_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 | `bool` | `true` | no | +| [snapshot\_identifier](#input\_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, e.g: rds:production-2015-06-26-06-05 | `string` | `null` | no | +| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB instance is encrypted | `bool` | `true` | no | +| [storage\_throughput](#input\_storage\_throughput) | Storage throughput value for the DB instance. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | +| [storage\_type](#input\_storage\_type) | One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter | `string` | `"gp2"` | no | +| [subnet\_ids](#input\_subnet\_ids) | A list of VPC subnet IDs | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A mapping of tags to assign to all resources | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Updated Terraform resource management timeouts. Applies to `aws_db_instance` in particular to permit resource management times | `map(string)` | `{}` | no | +| [timezone](#input\_timezone) | 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 | `string` | `null` | no | +| [username](#input\_username) | Username for the master DB user | `string` | `null` | no | +| [vpc\_id](#input\_vpc\_id) | n/a | `string` | `null` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of VPC security groups to associate | `list(string)` | `[]` | no | + +## Outputs + +No outputs. From 82e2925997667fcb5e88ddf4d11eb030522efa47 Mon Sep 17 00:00:00 2001 From: samidbb Date: Thu, 2 Nov 2023 22:22:40 +0100 Subject: [PATCH 04/12] refactor initiated --- main.tf | 607 +++++++-------- new_modules/cluster_parameter_group/main.tf | 24 + .../cluster_parameter_group/outputs.tf | 9 + .../cluster_parameter_group/variables.tf | 41 + .../cluster_parameter_group/versions.tf | 15 + new_modules/db_cloudwatch_log_groups/main.tf | 9 + .../db_cloudwatch_log_groups/outputs.tf | 8 + new_modules/db_cloudwatch_log_groups/vars.tf | 40 + .../db_cloudwatch_log_groups/versions.tf | 15 + .../db_enhanced_monitoring_role/main.tf | 40 + .../db_enhanced_monitoring_role/outputs.tf | 9 + .../db_enhanced_monitoring_role/variables.tf | 58 ++ new_modules/db_instance/README.md | 134 ++++ new_modules/db_instance/main.tf | 150 ++++ new_modules/db_instance/outputs.tf | 100 +++ new_modules/db_instance/variables.tf | 431 +++++++++++ new_modules/db_instance/versions.tf | 15 + new_modules/db_parameter_group/README.md | 45 ++ new_modules/db_parameter_group/main.tf | 33 + new_modules/db_parameter_group/outputs.tf | 9 + new_modules/db_parameter_group/variables.tf | 41 + new_modules/db_parameter_group/versions.tf | 10 + new_modules/db_subnet_group/README.md | 44 ++ new_modules/db_subnet_group/main.tf | 22 + new_modules/db_subnet_group/outputs.tf | 9 + new_modules/db_subnet_group/variables.tf | 35 + new_modules/db_subnet_group/versions.tf | 10 + new_modules/rds-aurora/README.md | 422 +++++++++++ new_modules/rds-aurora/main.tf | 322 ++++++++ new_modules/rds-aurora/outputs.tf | 186 +++++ new_modules/rds-aurora/variables.tf | 712 ++++++++++++++++++ new_modules/rds-aurora/versions.tf | 10 + new_modules/rds-proxy/README.md | 165 ++++ new_modules/rds-proxy/main.tf | 188 +++++ new_modules/rds-proxy/outputs.tf | 95 +++ new_modules/rds-proxy/variables.tf | 255 +++++++ new_modules/rds-proxy/versions.tf | 10 + variables.tf | 27 +- 38 files changed, 4012 insertions(+), 343 deletions(-) create mode 100644 new_modules/cluster_parameter_group/main.tf create mode 100644 new_modules/cluster_parameter_group/outputs.tf create mode 100644 new_modules/cluster_parameter_group/variables.tf create mode 100644 new_modules/cluster_parameter_group/versions.tf create mode 100644 new_modules/db_cloudwatch_log_groups/main.tf create mode 100644 new_modules/db_cloudwatch_log_groups/outputs.tf create mode 100644 new_modules/db_cloudwatch_log_groups/vars.tf create mode 100644 new_modules/db_cloudwatch_log_groups/versions.tf create mode 100644 new_modules/db_enhanced_monitoring_role/main.tf create mode 100644 new_modules/db_enhanced_monitoring_role/outputs.tf create mode 100644 new_modules/db_enhanced_monitoring_role/variables.tf create mode 100644 new_modules/db_instance/README.md create mode 100644 new_modules/db_instance/main.tf create mode 100644 new_modules/db_instance/outputs.tf create mode 100644 new_modules/db_instance/variables.tf create mode 100644 new_modules/db_instance/versions.tf create mode 100644 new_modules/db_parameter_group/README.md create mode 100644 new_modules/db_parameter_group/main.tf create mode 100644 new_modules/db_parameter_group/outputs.tf create mode 100644 new_modules/db_parameter_group/variables.tf create mode 100644 new_modules/db_parameter_group/versions.tf create mode 100644 new_modules/db_subnet_group/README.md create mode 100644 new_modules/db_subnet_group/main.tf create mode 100644 new_modules/db_subnet_group/outputs.tf create mode 100644 new_modules/db_subnet_group/variables.tf create mode 100644 new_modules/db_subnet_group/versions.tf create mode 100644 new_modules/rds-aurora/README.md create mode 100644 new_modules/rds-aurora/main.tf create mode 100644 new_modules/rds-aurora/outputs.tf create mode 100644 new_modules/rds-aurora/variables.tf create mode 100644 new_modules/rds-aurora/versions.tf create mode 100644 new_modules/rds-proxy/README.md create mode 100644 new_modules/rds-proxy/main.tf create mode 100644 new_modules/rds-proxy/outputs.tf create mode 100644 new_modules/rds-proxy/variables.tf create mode 100644 new_modules/rds-proxy/versions.tf diff --git a/main.tf b/main.tf index 8a74fa9f..0aeadce3 100644 --- a/main.tf +++ b/main.tf @@ -1,321 +1,300 @@ -# generate terraform resources for rds locals { - # deploy_options_group = var.engine != "postgres" + ######################################################################## + # Parameter group + ######################################################################## + create_db_parameter_group = true + # parameter_group_name_id = local.create_db_parameter_group ? module.db_parameter_group.db_parameter_group_id : var.parameter_group_name + pramater_group_family = local.create_db_parameter_group && var.parameter_group_family == null ? "${var.engine}${var.major_engine_version}" : var.parameter_group_family + parameters = [ + # { + # name = "log_min_duration_statement" + # value = 4000 + # apply_method = "immediate" + # }, + { + name = "log_statement" + value = "all" + apply_method = "immediate" + }, + { + name = "log_min_duration_statement" # maybe this is not relevant or maybe it is + value = 5 + apply_method = "immediate" + } + # , { + # name = "rds.force_ssl" + # value = 1 + # apply_method = "immediate" + # } + ] + + ######################################################################## + # Subnet group + ######################################################################## + create_db_subnet_group = true + db_subnet_group_name = local.create_db_subnet_group ? module.db_subnet_group[0].db_subnet_group_id : var.db_subnet_group_name + + ######################################################################## + # Enhanced Monitoring + ######################################################################## + create_monitoring_role = var.monitoring_interval > 0 + monitoring_role_name = local.create_monitoring_role && var.monitoring_role_name == null ? "${var.identifier}-rds-enhanced-monitoring" : var.monitoring_role_name + monitoring_role_description = var.create_monitoring_role && var.monitoring_role_description == null ? "Role for enhanced monitoring of RDS instance ${var.identifier}" : var.monitoring_role_description + + ######################################################################## + # CloudWatch log group config + ######################################################################## + create_cloudwatch_log_group = length(var.enabled_cloudwatch_logs_exports) > 0 + cloudwatch_log_group_skip_destroy_on_deletion = true + + ######################################################################## + # DB Proxy configuration + ######################################################################## + proxy_name = var.proxy_name == null ? "${var.identifier}" : var.proxy_name + db_proxy_secret_arn = null #(var.is_db_cluster || local.is_serverless) ? coalesce(try(module.db_cluster[0].cluster_master_user_secret_arn,null), try(module.db_cluster_serverless[0].cluster_master_user_secret_arn,null)) : module.db_instance[0].db_instance_master_user_secret_arn + + proxy_auth_config = { + (var.username) = { + description = "Proxy user for ${var.username}" + secret_arn = local.db_proxy_secret_arn # aws_secretsmanager_secret.superuser.arn + } + } - # is_multi_az_cluster = var.is_multi_az_cluster ? create_multi_az_db_cluster : create_db_instance - instance_class = var.instance_class - final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.final_snapshot_identifier_prefix}-${var.identifier}-${try(random_id.snapshot_identifier[0].hex, "")}" + ######################################################################## + # Instance configs + ######################################################################## + instance_class = var.instance_class + storage_type = var.is_db_cluster ? "io1" : var.storage_type + storage_size = var.allocated_storage == null && var.storage_type == "gp2" ? 5 : var.allocated_storage # Console suggests 20 GB as minumum storage + cluster_storage_size = var.is_db_cluster && local.storage_type == "io1" && var.iops == null ? 100 : var.allocated_storage # Console suggests 100 GB as minimum storage for io1 + iops = var.iops == null && local.storage_type == "io1" ? 1000 : var.iops # The minimum value is 1,000 IOPS and the maximum value is 256,000 IOPS. The IOPS to GiB ratio must be between 0.5 and 50 + backup_retention_period = var.backup_retention_period == null ? 0 : var.backup_retention_period - storage_size = var.allocated_storage == null && var.storage_type == "gp2" ? 5 : var.allocated_storage # Console suggests 20 GB as minumum storage + is_serverless = true - storage_type = var.is_db_cluster ? "io1" : var.storage_type - cluster_storage_size = var.is_db_cluster && local.storage_type == "io1" && var.iops == null ? 100 : var.allocated_storage # Console suggests 100 GB as minimum storage for io1 - iops = var.iops == null && local.storage_type == "io1" ? 1000 : var.iops # The minimum value is 1,000 IOPS and the maximum value is 256,000 IOPS. The IOPS to GiB ratio must be between 0.5 and 50 - monitoring_role_name = var.create_monitoring_role && var.monitoring_role_name == null ? "${var.identifier}-rds-enhanced-monitoring" : var.monitoring_role_name - monitoring_role_description = var.create_monitoring_role && var.monitoring_role_description == null ? "Role for enhanced monitoring of RDS instance ${var.identifier}" : var.monitoring_role_description + final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.final_snapshot_identifier_prefix}-${var.identifier}-${try(random_id.snapshot_identifier[0].hex, "")}" +} - create_cloudwatch_log_group = length(var.enabled_cloudwatch_logs_exports) > 0 +resource "random_id" "snapshot_identifier" { + count = !var.skip_final_snapshot ? 1 : 0 - cloudwatch_log_group_skip_destroy_on_deletion = true + keepers = { + id = var.identifier + } - parameter_group_name = var.create_db_parameter_group && var.parameter_group_name == null ? "${var.identifier}-rds-parameters" : var.parameter_group_name + byte_length = 4 +} - family = var.create_db_parameter_group && var.family == null ? "postgres${var.engine}" : var.family +# Create a parameter group by default to contain the options we need +module "db_parameter_group" { + source = "./new_modules/db_parameter_group" + count = local.create_db_parameter_group ? 1: 0 + name = var.identifier + use_name_prefix = false #var.parameter_group_use_name_prefix + description = var.parameter_group_description + family = local.pramater_group_family + parameters = local.parameters + tags = merge(var.tags, var.db_parameter_group_tags) # additional tagging for parameter group? +} - # DB Proxy configuration - proxy_name = var.proxy_name == null ? "${var.identifier}" : var.proxy_name - db_proxy_secret_arn = var.is_db_cluster ? module.cluster[0].cluster_master_user_secret_arn : module.db[0].db_instance_master_user_secret_arn - # proxy_auth_config = { - # auth_scheme = "SECRETS" - # iam_auth = "DISABLED" - # secret_arn = local.db_proxy_secret_arn - # } - proxy_auth_config = { - (var.username) = { - description = "Proxy user for ${var.username}" - secret_arn = local.db_proxy_secret_arn # aws_secretsmanager_secret.superuser.arn - } - } +module "db_subnet_group" { + source = "./new_modules/db_subnet_group" + count = local.create_db_subnet_group ? 1 : 0 + name = coalesce(var.db_subnet_group_name, var.identifier) + use_name_prefix = var.db_subnet_group_use_name_prefix + description = var.db_subnet_group_description + subnet_ids = var.subnet_ids + tags = merge(var.tags, var.db_subnet_group_tags) } -resource "random_id" "snapshot_identifier" { - count = !var.skip_final_snapshot ? 1 : 0 - keepers = { - id = var.identifier - } +module "cw_log_group" { + source = "./new_modules/db_cloudwatch_log_groups" + count = local.create_cloudwatch_log_group ? 1 : 0 + db_identifier = var.identifier + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + cloudwatch_log_group_retention_in_days = var.cloudwatch_log_group_retention_in_days + cloudwatch_log_group_kms_key_id = var.cloudwatch_log_group_kms_key_id + cloudwatch_log_group_skip_destroy_on_deletion = local.cloudwatch_log_group_skip_destroy_on_deletion +} - byte_length = 4 +module "enhanced_monitoring_iam_role" { + source = "./new_modules/db_enhanced_monitoring_role" + count = local.create_monitoring_role ? 1 : 0 + monitoring_role_name = local.monitoring_role_name + monitoring_role_use_name_prefix = var.monitoring_role_use_name_prefix + monitoring_role_description = local.monitoring_role_description + monitoring_role_permissions_boundary = var.monitoring_role_permissions_boundary +} + +module "db_instance" { + source = "./new_modules/db_instance" + + count = !var.is_db_cluster && local.is_serverless ? 1 : 0 + identifier = var.identifier + use_identifier_prefix = var.instance_use_identifier_prefix + engine = var.engine + engine_version = var.engine_version + instance_class = var.instance_class + allocated_storage = local.storage_size + storage_type = local.storage_type + storage_encrypted = var.storage_encrypted + kms_key_id = var.kms_key_id + license_model = var.license_model + + db_name = var.db_name + username = var.username + password = var.manage_master_user_password ? null : var.password # TODO: Move to locals + port = var.port + domain = var.domain + domain_iam_role_name = var.domain_iam_role_name + iam_database_authentication_enabled = var.iam_database_authentication_enabled + custom_iam_instance_profile = var.custom_iam_instance_profile + manage_master_user_password = var.manage_master_user_password + master_user_secret_kms_key_id = var.master_user_secret_kms_key_id + + vpc_security_group_ids = var.vpc_security_group_ids + db_subnet_group_name = local.db_subnet_group_name + parameter_group_name = module.db_parameter_group[0].db_parameter_group_id + option_group_name = null # var.engine != "postgres" ? local.option_group : null + network_type = var.network_type + + availability_zone = var.availability_zone + multi_az = var.multi_az + iops = var.iops + storage_throughput = var.storage_throughput + publicly_accessible = var.publicly_accessible + ca_cert_identifier = var.ca_cert_identifier + + 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 + blue_green_update = var.blue_green_update + + snapshot_identifier = var.snapshot_identifier + copy_tags_to_snapshot = var.copy_tags_to_snapshot + skip_final_snapshot = var.skip_final_snapshot + final_snapshot_identifier_prefix = var.final_snapshot_identifier_prefix + + performance_insights_enabled = var.performance_insights_enabled + performance_insights_retention_period = var.performance_insights_retention_period + performance_insights_kms_key_id = var.performance_insights_enabled ? var.performance_insights_kms_key_id : null + + replicate_source_db = var.replicate_source_db + replica_mode = var.replica_mode + backup_retention_period = local.backup_retention_period + backup_window = var.backup_window + max_allocated_storage = var.max_allocated_storage + monitoring_interval = var.monitoring_interval + monitoring_role_arn = module.enhanced_monitoring_iam_role[0].enhanced_monitoring_iam_role_arn + + character_set_name = var.character_set_name + nchar_character_set_name = var.nchar_character_set_name + timezone = var.timezone + + timeouts = var.timeouts + + deletion_protection = var.deletion_protection + delete_automated_backups = var.delete_automated_backups + + restore_to_point_in_time = var.restore_to_point_in_time + s3_import = var.s3_import + + tags = merge(var.tags, var.db_instance_tags) } -# Focus on exposing required variables -# and use default values for optional ones -# Provide options for providing abstraction on top of the resourc - -# resource "aws_rds_cluster" "default" { -# cluster_identifier = "aurora-cluster-demo" -# engine = "aurora-mysql" -# engine_version = "5.7.mysql_aurora.2.03.2" -# availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] -# database_name = "mydb" -# master_username = "foo" -# master_password = "bar" -# backup_retention_period = 5 -# preferred_backup_window = "07:00-09:00" -# # tags = var.tags_group1 -# } - -module "db" { - count = var.is_db_cluster ? 0 : 1 - - source = "./_sub/terraform-aws-rds" - - identifier = var.identifier - - create_db_parameter_group = var.create_db_parameter_group # Disabled for now - - instance_class = local.instance_class - - skip_final_snapshot = var.skip_final_snapshot - create_db_instance = var.create_db_instance - - instance_use_identifier_prefix = var.instance_use_identifier_prefix - custom_iam_instance_profile = var.custom_iam_instance_profile - allocated_storage = local.storage_size # var.allocated_storage - storage_type = var.storage_type - storage_throughput = var.storage_throughput - storage_encrypted = var.storage_encrypted - kms_key_id = var.kms_key_id - replicate_source_db = var.replicate_source_db - license_model = var.license_model - replica_mode = var.replica_mode - iam_database_authentication_enabled = var.iam_database_authentication_enabled - domain = var.domain - domain_iam_role_name = var.domain_iam_role_name - engine = var.engine # - engine_version = var.engine_version - snapshot_identifier = var.snapshot_identifier - copy_tags_to_snapshot = var.copy_tags_to_snapshot - final_snapshot_identifier_prefix = var.final_snapshot_identifier_prefix - db_name = var.db_name - username = var.username - password = var.password - manage_master_user_password = var.manage_master_user_password - master_user_secret_kms_key_id = var.master_user_secret_kms_key_id - port = var.port - vpc_security_group_ids = var.vpc_security_group_ids - availability_zone = var.availability_zone - multi_az = var.multi_az - iops = var.iops - publicly_accessible = true - monitoring_interval = var.monitoring_interval - monitoring_role_arn = var.monitoring_role_arn - monitoring_role_name = local.monitoring_role_name - monitoring_role_use_name_prefix = var.monitoring_role_use_name_prefix - monitoring_role_description = local.monitoring_role_description - create_monitoring_role = var.create_monitoring_role - monitoring_role_permissions_boundary = var.monitoring_role_permissions_boundary - 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 - blue_green_update = var.blue_green_update - backup_retention_period = var.backup_retention_period - backup_window = var.backup_window - restore_to_point_in_time = var.restore_to_point_in_time - s3_import = var.s3_import - tags = var.tags - db_instance_tags = var.db_instance_tags - db_option_group_tags = var.db_option_group_tags - db_parameter_group_tags = var.db_parameter_group_tags - db_subnet_group_tags = var.db_subnet_group_tags - create_db_subnet_group = var.create_db_subnet_group # we don't want to create db_subnet_group by default ?? - db_subnet_group_name = var.db_subnet_group_name - db_subnet_group_use_name_prefix = var.db_subnet_group_use_name_prefix # we don't want to create db_subnet_group - db_subnet_group_description = var.db_subnet_group_description # we don't want to create db_subnet_group - subnet_ids = var.subnet_ids # we don't want to create db_subnet_group ?? - parameter_group_name = local.parameter_group_name - parameter_group_use_name_prefix = var.parameter_group_use_name_prefix - parameter_group_description = var.parameter_group_description - family = local.family - parameters = var.parameters - option_group_name = var.option_group_name - option_group_use_name_prefix = var.option_group_use_name_prefix - option_group_description = var.option_group_description - major_engine_version = var.option_group_description - options = var.options - timezone = var.timezone - character_set_name = var.character_set_name - nchar_character_set_name = var.nchar_character_set_name - enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports - timeouts = var.timeouts - option_group_timeouts = var.option_group_timeouts - deletion_protection = var.deletion_protection - performance_insights_enabled = var.performance_insights_enabled - performance_insights_retention_period = var.performance_insights_retention_period - performance_insights_kms_key_id = var.performance_insights_kms_key_id - max_allocated_storage = var.max_allocated_storage - ca_cert_identifier = var.ca_cert_identifier - delete_automated_backups = var.delete_automated_backups - network_type = var.network_type - create_cloudwatch_log_group = local.create_cloudwatch_log_group - cloudwatch_log_group_retention_in_days = var.cloudwatch_log_group_retention_in_days - cloudwatch_log_group_kms_key_id = var.cloudwatch_log_group_kms_key_id - - cloudwatch_log_group_skip_destroy_on_deletion = local.cloudwatch_log_group_skip_destroy_on_deletion # not woeking?? - monitoring_iam_role_path = var.monitoring_iam_role_path +module "cluster_parameters" { + source = "./new_modules/cluster_parameter_group" + count = var.is_db_cluster ? 1 : 0 + + db_cluster_parameter_group_name = "${var.identifier}" + db_cluster_parameter_group_family = local.pramater_group_family + db_cluster_parameter_group_description = "${var.identifier} DB parameter cluster group" + db_cluster_parameter_group_parameters = [ + { + name = "rds.force_ssl" + value = 1 + apply_method = "immediate" + } + ] +} + +module "db_cluster" { # Multi-AZ DB Cluster + source = "./new_modules/rds-aurora" + count = var.is_db_cluster && !local.is_serverless ? 1 : 0 + name = var.identifier + cluster_use_name_prefix = var.cluster_use_name_prefix + engine = var.engine + engine_version = var.engine_version + + db_subnet_group_name = local.db_subnet_group_name + + storage_type = local.storage_type + allocated_storage = local.storage_size + + iops = local.iops + backup_retention_period = null # local.backup_retention_period + db_cluster_instance_class = var.instance_class + + master_username = var.username + master_password = var.password + manage_master_user_password = var.manage_master_user_password + + apply_immediately = var.apply_immediately + db_cluster_parameter_group_name = module.cluster_parameters[0].db_cluster_parameter_group_id + + vpc_security_group_ids = var.vpc_security_group_ids + + skip_final_snapshot = var.skip_final_snapshot } -module "cluster" { - count = var.is_db_cluster ? 1 : 0 - source = "./_sub/terraform-aws-rds-aurora" - - - name = var.identifier - - # engine = var.engine - # engine_version = var.engine_version - - - # master_username = var.username - # master_password = var.password - # manage_master_user_password = var.manage_master_user_password - - tags = var.tags - create_db_subnet_group = var.create_db_subnet_group - db_subnet_group_name = var.db_subnet_group_name - - subnets = var.subnet_ids # we don't want to create db_subnet_group ? - is_primary_cluster = var.cluster_is_primary_cluster - cluster_use_name_prefix = var.cluster_use_name_prefix - allocated_storage = local.cluster_storage_size - allow_major_version_upgrade = var.allow_major_version_upgrade - apply_immediately = var.apply_immediately - availability_zones = var.cluster_availability_zones - backup_retention_period = var.backup_retention_period - backtrack_window = var.cluster_backtrack_window - cluster_members = var.cluster_members - copy_tags_to_snapshot = var.copy_tags_to_snapshot - database_name = var.db_name - db_cluster_instance_class = local.instance_class - db_cluster_db_instance_parameter_group_name = var.parameter_group_name # ? - deletion_protection = var.deletion_protection - enable_global_write_forwarding = var.cluster_enable_global_write_forwarding - enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports - enable_http_endpoint = var.cluster_enable_http_endpoint - engine = var.engine - engine_mode = var.cluster_engine_mode - engine_version = var.engine_version - final_snapshot_identifier = local.final_snapshot_identifier # update var! - global_cluster_identifier = var.cluster_global_cluster_identifier - iam_database_authentication_enabled = var.iam_database_authentication_enabled - iops = local.iops - kms_key_id = var.kms_key_id - manage_master_user_password = var.manage_master_user_password - master_user_secret_kms_key_id = var.master_user_secret_kms_key_id - master_password = var.password - master_username = var.username - network_type = var.network_type - port = var.port - preferred_backup_window = var.backup_window - preferred_maintenance_window = var.maintenance_window - replication_source_identifier = var.cluster_replication_source_identifier - restore_to_point_in_time = var.restore_to_point_in_time == null ? {} : var.restore_to_point_in_time - s3_import = var.s3_import == null ? {} : var.s3_import - scaling_configuration = var.cluster_scaling_configuration # serverlessv2_scaling_configuration - serverlessv2_scaling_configuration = var.cluster_serverlessv2_scaling_configuration - skip_final_snapshot = var.skip_final_snapshot - snapshot_identifier = var.snapshot_identifier - source_region = var.cluster_source_region - storage_encrypted = var.storage_encrypted - storage_type = local.storage_type - cluster_tags = var.cluster_tags # maybe not needed - vpc_security_group_ids = var.vpc_security_group_ids - cluster_timeouts = var.cluster_timeouts - instances = var.cluster_instances - auto_minor_version_upgrade = var.auto_minor_version_upgrade - ca_cert_identifier = var.ca_cert_identifier - db_parameter_group_name = var.parameter_group_name # ? - instances_use_identifier_prefix = var.cluster_instances_use_identifier_prefix - instance_class = local.instance_class - monitoring_interval = var.monitoring_interval - performance_insights_enabled = var.performance_insights_enabled - performance_insights_kms_key_id = var.performance_insights_kms_key_id - performance_insights_retention_period = var.performance_insights_retention_period - publicly_accessible = var.publicly_accessible - instance_timeouts = var.timeouts - endpoints = var.cluster_endpoints - iam_roles = var.cluster_iam_roles - create_monitoring_role = var.create_monitoring_role - monitoring_role_arn = var.monitoring_role_arn - iam_role_name = var.monitoring_role_arn - iam_role_use_name_prefix = var.monitoring_role_use_name_prefix - iam_role_description = var.monitoring_role_description - iam_role_path = var.monitoring_iam_role_path - iam_role_managed_policy_arns = null #var.iam_role_managed_policy_arns - iam_role_permissions_boundary = var.monitoring_role_permissions_boundary - iam_role_force_detach_policies = null #var.iam_role_force_detach_policies - iam_role_max_session_duration = null # var.iam_role_max_session_duration - autoscaling_enabled = var.cluster_autoscaling_enabled - autoscaling_max_capacity = var.cluster_autoscaling_max_capacity - autoscaling_min_capacity = var.cluster_autoscaling_min_capacity - autoscaling_policy_name = var.cluster_autoscaling_policy_name - predefined_metric_type = var.cluster_predefined_metric_type - autoscaling_scale_in_cooldown = var.cluster_autoscaling_scale_in_cooldown - autoscaling_scale_out_cooldown = var.cluster_autoscaling_scale_out_cooldown - autoscaling_target_cpu = var.cluster_autoscaling_target_cpu - autoscaling_target_connections = var.cluster_autoscaling_target_connections - # create_security_group = var.create_security_group # Create a generic security group for RDS and Aurora - # security_group_name = var.security_group_name - # security_group_use_name_prefix = var.security_group_use_name_prefix - # security_group_description = var.security_group_description - # vpc_id = var.vpc_id - # security_group_rules = var.security_group_rules - # security_group_tags = var.security_group_tags - - # create_db_cluster_parameter_group = var.create_db_cluster_parameter_group # ? - # db_cluster_parameter_group_name = var.db_cluster_parameter_group_name # ? - # db_cluster_parameter_group_use_name_prefix = var.db_cluster_parameter_group_use_name_prefix - # db_cluster_parameter_group_description = var.db_cluster_parameter_group_description - # db_cluster_parameter_group_family = var.db_cluster_parameter_group_family - # db_cluster_parameter_group_parameters = var.db_cluster_parameter_group_parameters - # create_db_parameter_group = var.create_db_parameter_group - # db_parameter_group_use_name_prefix = var.db_parameter_group_use_name_prefix - # db_parameter_group_description = var.db_parameter_group_description - # db_parameter_group_family = var.db_parameter_group_family - # db_parameter_group_parameters = var.db_parameter_group_parameters - create_cloudwatch_log_group = local.create_cloudwatch_log_group - cloudwatch_log_group_retention_in_days = var.cloudwatch_log_group_retention_in_days - cloudwatch_log_group_kms_key_id = var.cloudwatch_log_group_kms_key_id - create_db_cluster_activity_stream = var.create_db_cluster_activity_stream - db_cluster_activity_stream_mode = var.cluster_activity_stream_mode - db_cluster_activity_stream_kms_key_id = var.cluster_activity_stream_kms_key_id - engine_native_audit_fields_included = var.cluster_engine_native_audit_fields_included - -cluster_db_instance_count = var.cluster_db_instance_count -# vpc_id = module.vpc.vpc_id -# db_subnet_group_name = module.vpc.database_subnet_group_name - -# enabled_cloudwatch_logs_exports = ["postgresql"] - -# # Multi-AZ -# availability_zones = module.vpc.azs -# allocated_storage = 256 -# db_cluster_instance_class = "db.r6gd.large" -# iops = 2500 -# storage_type = "io1" - -# skip_final_snapshot = true - -# tags = local.tags + +module "db_cluster_serverless" { + source = "./new_modules/rds-aurora" + count = local.is_serverless ? 1 : 0 + name = "${var.identifier}-postgresqlv2" + engine = "aurora-postgresql" #data.aws_rds_engine_version.postgresql.engine + engine_mode = "provisioned" + engine_version = "14.5" # data.aws_rds_engine_version.postgresql.version + storage_encrypted = true + master_username = var.username + manage_master_user_password = var.manage_master_user_password + + db_subnet_group_name = local.db_subnet_group_name + + vpc_security_group_ids = var.vpc_security_group_ids + + monitoring_interval = 60 + monitoring_role_arn = module.enhanced_monitoring_iam_role[0].enhanced_monitoring_iam_role_arn + + apply_immediately = true + skip_final_snapshot = true + + serverlessv2_scaling_configuration = { + min_capacity = 2 + max_capacity = 10 + } + + instance_class = "db.serverless" + instances = { + one = {} + two = {} + } + + tags = var.tags } -module "db_proxy" { - source = "./_sub/terraform-aws-rds-proxy" + + + + +module "db_proxy" { # What is endpoints? specifc endpoints for read and or writes? + source = "./new_modules/rds-proxy" create = var.include_proxy tags = var.tags @@ -361,42 +340,4 @@ module "db_proxy" { # depends_on = [ module.cluster, module.db ] } -## DB Proxy resources - - - - - - - -# -# lightweight_db -# major_engine_version -# resource "aws_rds_cluster" "example" { -# cluster_identifier = "example" -# availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] -# engine = "mysql" -# db_cluster_instance_class = "db.r6gd.xlarge" -# storage_type = "io1" -# allocated_storage = 100 -# iops = 1000 -# master_username = "test" -# master_password = "mustbeeightcharaters" -# } - - # Defaults -# Storage types: -# gp2 vs gp3 and iOPS and pricing - - - -# The main difference between gp2 and gp3, however, is gp3's decoupling of IOPS, throughput, and volume size. This flexibility – the ability to configure each piece independently – is where the savings come in. On the opposite end of the spectrum, gp2 is quite inflexible - -# gp3 offers SSD-performance at a 20% lower cost per GB than gp2 volumes. Furthermore, by decoupling storage performance from capacity, you can easily provision higher IOPS and throughput without the need to provision additional block storage capacity, thereby improving performance and reducing costs. - -# Source: -# - google search "gp2 vs gp3" -# - https://aws.amazon.com/ebs/pricing/ -# - https://aws.amazon.com/ebs/volume-types/ -# - https://repost.aws/knowledge-center/ebs-volume-type-differences \ No newline at end of file diff --git a/new_modules/cluster_parameter_group/main.tf b/new_modules/cluster_parameter_group/main.tf new file mode 100644 index 00000000..af4605ad --- /dev/null +++ b/new_modules/cluster_parameter_group/main.tf @@ -0,0 +1,24 @@ + + +resource "aws_rds_cluster_parameter_group" "this" { + name = var.db_cluster_parameter_group_use_name_prefix ? null : var.db_cluster_parameter_group_name + name_prefix = var.db_cluster_parameter_group_use_name_prefix ? "${var.db_cluster_parameter_group_name}-" : null + description = var.db_cluster_parameter_group_description + family = var.db_cluster_parameter_group_family + + dynamic "parameter" { + for_each = var.db_cluster_parameter_group_parameters + + content { + name = parameter.value.name + value = parameter.value.value + apply_method = try(parameter.value.apply_method, "immediate") + } + } + + lifecycle { + create_before_destroy = true + } + + tags = var.tags +} \ No newline at end of file diff --git a/new_modules/cluster_parameter_group/outputs.tf b/new_modules/cluster_parameter_group/outputs.tf new file mode 100644 index 00000000..80d84bd8 --- /dev/null +++ b/new_modules/cluster_parameter_group/outputs.tf @@ -0,0 +1,9 @@ +output "db_cluster_parameter_group_arn" { + description = "The ARN of the DB cluster parameter group created" + value = try(aws_rds_cluster_parameter_group.this.arn, null) +} + +output "db_cluster_parameter_group_id" { + description = "The ID of the DB cluster parameter group created" + value = try(aws_rds_cluster_parameter_group.this.id, null) +} diff --git a/new_modules/cluster_parameter_group/variables.tf b/new_modules/cluster_parameter_group/variables.tf new file mode 100644 index 00000000..25010f41 --- /dev/null +++ b/new_modules/cluster_parameter_group/variables.tf @@ -0,0 +1,41 @@ +variable "create_db_cluster_parameter_group" { + description = "Determines whether a cluster parameter should be created or use existing" + type = bool + default = false +} + +variable "db_cluster_parameter_group_name" { + description = "The name of the DB cluster parameter group" + type = string + default = null +} + +variable "db_cluster_parameter_group_use_name_prefix" { + description = "Determines whether the DB cluster parameter group name is used as a prefix" + type = bool + default = false +} + +variable "db_cluster_parameter_group_description" { + description = "The description of the DB cluster parameter group. Defaults to \"Managed by Terraform\"" + type = string + default = null +} + +variable "db_cluster_parameter_group_family" { + description = "The family of the DB cluster parameter group" + type = string + default = "" +} + +variable "db_cluster_parameter_group_parameters" { + description = "A list of DB cluster parameters to apply. Note that parameters may differ from a family to an other" + type = list(map(string)) + default = [] +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} \ No newline at end of file diff --git a/new_modules/cluster_parameter_group/versions.tf b/new_modules/cluster_parameter_group/versions.tf new file mode 100644 index 00000000..8f85fe99 --- /dev/null +++ b/new_modules/cluster_parameter_group/versions.tf @@ -0,0 +1,15 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + + random = { + source = "hashicorp/random" + version = ">= 3.1" + } + } +} diff --git a/new_modules/db_cloudwatch_log_groups/main.tf b/new_modules/db_cloudwatch_log_groups/main.tf new file mode 100644 index 00000000..b4be3255 --- /dev/null +++ b/new_modules/db_cloudwatch_log_groups/main.tf @@ -0,0 +1,9 @@ +resource "aws_cloudwatch_log_group" "this" { + for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log]) + + name = "/aws/rds/instance/${var.db_identifier}/${each.value}" # it is not possible to use the identifier_prefix here since it is not known at plan time and we can't have cyclic reference to the db instance resource + retention_in_days = var.cloudwatch_log_group_retention_in_days + kms_key_id = var.cloudwatch_log_group_kms_key_id + skip_destroy = var.cloudwatch_log_group_skip_destroy_on_deletion + tags = var.tags +} \ No newline at end of file diff --git a/new_modules/db_cloudwatch_log_groups/outputs.tf b/new_modules/db_cloudwatch_log_groups/outputs.tf new file mode 100644 index 00000000..c131f108 --- /dev/null +++ b/new_modules/db_cloudwatch_log_groups/outputs.tf @@ -0,0 +1,8 @@ +################################################################################ +# CloudWatch Log Group +################################################################################ + +output "db_instance_cloudwatch_log_groups" { + description = "Map of CloudWatch log groups created and their attributes" + value = aws_cloudwatch_log_group.this +} diff --git a/new_modules/db_cloudwatch_log_groups/vars.tf b/new_modules/db_cloudwatch_log_groups/vars.tf new file mode 100644 index 00000000..e486efa0 --- /dev/null +++ b/new_modules/db_cloudwatch_log_groups/vars.tf @@ -0,0 +1,40 @@ +variable "create" { + description = "Whether to create this resource or not?" + type = bool + default = true +} + +variable "db_identifier" { + description = "The name of the RDS instance" + type = string +} + +variable "enabled_cloudwatch_logs_exports" { + description = "List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on engine): alert, audit, error, general, listener, slowquery, trace, postgresql (PostgreSQL), upgrade (PostgreSQL)." + type = list(string) + default = [] +} + +variable "cloudwatch_log_group_retention_in_days" { + description = "The number of days to retain CloudWatch logs for the DB instance" + type = number + default = 7 +} + +variable "cloudwatch_log_group_kms_key_id" { + description = "The ARN of the KMS Key to use when encrypting log data" + type = string + default = null +} + +variable "cloudwatch_log_group_skip_destroy_on_deletion" { + description = "value to skip destroy ClouwWatch log group on deletion" + type = bool + default = false +} + +variable "tags" { + description = "A mapping of tags to assign to all resources" + type = map(string) + default = {} +} diff --git a/new_modules/db_cloudwatch_log_groups/versions.tf b/new_modules/db_cloudwatch_log_groups/versions.tf new file mode 100644 index 00000000..8f85fe99 --- /dev/null +++ b/new_modules/db_cloudwatch_log_groups/versions.tf @@ -0,0 +1,15 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + + random = { + source = "hashicorp/random" + version = ">= 3.1" + } + } +} diff --git a/new_modules/db_enhanced_monitoring_role/main.tf b/new_modules/db_enhanced_monitoring_role/main.tf new file mode 100644 index 00000000..44c761f0 --- /dev/null +++ b/new_modules/db_enhanced_monitoring_role/main.tf @@ -0,0 +1,40 @@ +locals { + monitoring_role_name = var.monitoring_role_use_name_prefix ? null : var.monitoring_role_name + monitoring_role_name_prefix = var.monitoring_role_use_name_prefix ? "${var.monitoring_role_name}-" : null +} + +# Ref. https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces +data "aws_partition" "current" {} + +data "aws_iam_policy_document" "enhanced_monitoring" { + statement { + actions = [ + "sts:AssumeRole", + ] + + principals { + type = "Service" + identifiers = ["monitoring.rds.amazonaws.com"] + } + } +} + +resource "aws_iam_role" "enhanced_monitoring" { + name = local.monitoring_role_name + name_prefix = local.monitoring_role_name_prefix + assume_role_policy = data.aws_iam_policy_document.enhanced_monitoring.json + description = var.monitoring_role_description + permissions_boundary = var.monitoring_role_permissions_boundary + path = var.monitoring_iam_role_path + tags = merge( + { + "Name" = format("%s", var.monitoring_role_name) + }, + var.tags, + ) +} + +resource "aws_iam_role_policy_attachment" "enhanced_monitoring" { + role = aws_iam_role.enhanced_monitoring.name + policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" +} diff --git a/new_modules/db_enhanced_monitoring_role/outputs.tf b/new_modules/db_enhanced_monitoring_role/outputs.tf new file mode 100644 index 00000000..6be8ac1d --- /dev/null +++ b/new_modules/db_enhanced_monitoring_role/outputs.tf @@ -0,0 +1,9 @@ +output "enhanced_monitoring_iam_role_name" { + description = "The name of the monitoring role" + value = try(aws_iam_role.enhanced_monitoring.name, null) +} + +output "enhanced_monitoring_iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the monitoring role" + value = try(aws_iam_role.enhanced_monitoring.arn, null) +} \ No newline at end of file diff --git a/new_modules/db_enhanced_monitoring_role/variables.tf b/new_modules/db_enhanced_monitoring_role/variables.tf new file mode 100644 index 00000000..b509f88b --- /dev/null +++ b/new_modules/db_enhanced_monitoring_role/variables.tf @@ -0,0 +1,58 @@ +variable "tags" { + description = "A mapping of tags to assign to all resources" + type = map(string) + default = {} +} + +variable "monitoring_role_arn" { + description = "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." + type = string + default = null +} + +variable "monitoring_role_name" { + description = "Name of the IAM role which will be created when create_monitoring_role is enabled." + type = string + default = "rds-monitoring-role" +} + +variable "monitoring_role_use_name_prefix" { + description = "Determines whether to use `monitoring_role_name` as is or create a unique identifier beginning with `monitoring_role_name` as the specified prefix" + type = bool + default = false +} + +variable "monitoring_role_description" { + description = "Description of the monitoring IAM role" + type = string + default = null +} + +variable "monitoring_role_permissions_boundary" { + description = "ARN of the policy that is used to set the permissions boundary for the monitoring IAM role" + type = string + default = null +} + +variable "monitoring_iam_role_path" { + description = "Path for the monitoring role" + type = string + default = null +} + + + + + + +variable "iam_role_force_detach_policies" { # useful? + description = "Whether to force detaching any policies the monitoring role has before destroying it" + type = bool + default = null +} + +variable "iam_role_max_session_duration" { # useful? + description = "Maximum session duration (in seconds) that you want to set for the monitoring role" + type = number + default = null +} \ No newline at end of file diff --git a/new_modules/db_instance/README.md b/new_modules/db_instance/README.md new file mode 100644 index 00000000..05091470 --- /dev/null +++ b/new_modules/db_instance/README.md @@ -0,0 +1,134 @@ +# aws_db_instance + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | +| [random](#requirement\_random) | >= 3.1 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | +| [random](#provider\_random) | >= 3.1 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_db_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance) | resource | +| [aws_iam_role.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [random_id.snapshot_identifier](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [aws_iam_policy_document.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allocated\_storage](#input\_allocated\_storage) | The allocated storage in gigabytes | `number` | `null` | no | +| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Indicates that major version upgrades are allowed. Changing this parameter does not result in an outage and the change is asynchronously applied as soon as possible | `bool` | `false` | no | +| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any database modifications are applied immediately, or during the next maintenance window | `bool` | `false` | no | +| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window | `bool` | `true` | no | +| [availability\_zone](#input\_availability\_zone) | The Availability Zone of the RDS instance | `string` | `null` | no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `null` | no | +| [backup\_window](#input\_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` | `null` | no | +| [blue\_green\_update](#input\_blue\_green\_update) | Enables low-downtime updates using RDS Blue/Green deployments. | `map(string)` | `{}` | no | +| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | `string` | `null` | no | +| [character\_set\_name](#input\_character\_set\_name) | 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 and Collations and Character Sets for Microsoft SQL Server for more information. This can only be set on creation. | `string` | `null` | no | +| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | +| [cloudwatch\_log\_group\_retention\_in\_days](#input\_cloudwatch\_log\_group\_retention\_in\_days) | The number of days to retain CloudWatch logs for the DB instance | `number` | `7` | no | +| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | On delete, copy all Instance tags to the final snapshot | `bool` | `false` | no | +| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | +| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports` | `bool` | `false` | no | +| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Create IAM role with a defined name that permits RDS to send enhanced monitoring metrics to CloudWatch Logs. | `bool` | `false` | no | +| [custom\_iam\_instance\_profile](#input\_custom\_iam\_instance\_profile) | RDS custom iam instance profile | `string` | `null` | no | +| [db\_name](#input\_db\_name) | The DB name to create. If omitted, no database is created initially | `string` | `null` | no | +| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC | `string` | `null` | no | +| [delete\_automated\_backups](#input\_delete\_automated\_backups) | Specifies whether to remove automated backups immediately after the DB instance is deleted | `bool` | `true` | no | +| [deletion\_protection](#input\_deletion\_protection) | The database can't be deleted when this value is set to true. | `bool` | `false` | no | +| [domain](#input\_domain) | The ID of the Directory Service Active Directory domain to create the instance in | `string` | `null` | no | +| [domain\_iam\_role\_name](#input\_domain\_iam\_role\_name) | (Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service | `string` | `null` | no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on engine): alert, audit, error, general, listener, slowquery, trace, postgresql (PostgreSQL), upgrade (PostgreSQL). | `list(string)` | `[]` | no | +| [engine](#input\_engine) | The database engine to use | `string` | `null` | no | +| [engine\_version](#input\_engine\_version) | The engine version to use | `string` | `null` | no | +| [final\_snapshot\_identifier\_prefix](#input\_final\_snapshot\_identifier\_prefix) | The name which is prefixed to the final snapshot on cluster destroy | `string` | `"final"` | no | +| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled | `bool` | `false` | no | +| [identifier](#input\_identifier) | The name of the RDS instance | `string` | n/a | yes | +| [instance\_class](#input\_instance\_class) | The instance type of the RDS instance | `string` | `null` | no | +| [iops](#input\_iops) | The amount of provisioned IOPS. Setting this implies a storage\_type of 'io1' or `gp3`. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage\_encrypted is set to true and kms\_key\_id is not specified the default KMS key created in your account will be used | `string` | `null` | no | +| [license\_model](#input\_license\_model) | License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1 | `string` | `null` | no | +| [maintenance\_window](#input\_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 | +| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if password is provided | `bool` | `false` | no | +| [master\_user\_secret\_kms\_key\_id](#input\_master\_user\_secret\_kms\_key\_id) | The key ARN, key ID, alias ARN or alias name for the KMS key to encrypt the master user password secret in Secrets Manager.
If not specified, the default KMS key for your Amazon Web Services account is used. | `string` | `null` | no | +| [max\_allocated\_storage](#input\_max\_allocated\_storage) | Specifies the value for Storage Autoscaling | `number` | `0` | no | +| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. The default is 0. Valid Values: 0, 1, 5, 10, 15, 30, 60. | `number` | `0` | no | +| [monitoring\_role\_arn](#input\_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` | `null` | no | +| [monitoring\_role\_description](#input\_monitoring\_role\_description) | Description of the monitoring IAM role | `string` | `null` | no | +| [monitoring\_role\_name](#input\_monitoring\_role\_name) | Name of the IAM role which will be created when create\_monitoring\_role is enabled. | `string` | `"rds-monitoring-role"` | no | +| [monitoring\_role\_permissions\_boundary](#input\_monitoring\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the monitoring IAM role | `string` | `null` | no | +| [monitoring\_role\_use\_name\_prefix](#input\_monitoring\_role\_use\_name\_prefix) | Determines whether to use `monitoring_role_name` as is or create a unique identifier beginning with `monitoring_role_name` as the specified prefix | `bool` | `false` | no | +| [multi\_az](#input\_multi\_az) | Specifies if the RDS instance is multi-AZ | `bool` | `false` | no | +| [nchar\_character\_set\_name](#input\_nchar\_character\_set\_name) | The national character set is used in the NCHAR, NVARCHAR2, and NCLOB data types for Oracle instances. This can't be changed. | `string` | `null` | no | +| [network\_type](#input\_network\_type) | The type of network stack | `string` | `null` | no | +| [option\_group\_name](#input\_option\_group\_name) | Name of the DB option group to associate. | `string` | `null` | no | +| [parameter\_group\_name](#input\_parameter\_group\_name) | Name of the DB parameter group to associate | `string` | `null` | no | +| [password](#input\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file | `string` | `null` | no | +| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Specifies whether Performance Insights are enabled | `bool` | `false` | no | +| [performance\_insights\_kms\_key\_id](#input\_performance\_insights\_kms\_key\_id) | The ARN for the KMS key to encrypt Performance Insights data. | `string` | `null` | no | +| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | The amount of time in days to retain Performance Insights data. Either 7 (7 days) or 731 (2 years). | `number` | `7` | no | +| [port](#input\_port) | The port on which the DB accepts connections | `string` | `null` | no | +| [publicly\_accessible](#input\_publicly\_accessible) | Bool to control if instance is publicly accessible | `bool` | `false` | no | +| [replica\_mode](#input\_replica\_mode) | Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified | `string` | `null` | no | +| [replicate\_source\_db](#input\_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 | +| [restore\_to\_point\_in\_time](#input\_restore\_to\_point\_in\_time) | Restore to a point in time (MySQL is NOT supported) | `map(string)` | `null` | no | +| [s3\_import](#input\_s3\_import) | Restore from a Percona Xtrabackup in S3 (only MySQL is supported) | `map(string)` | `null` | no | +| [skip\_final\_snapshot](#input\_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 | `bool` | `false` | no | +| [snapshot\_identifier](#input\_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, e.g: rds:production-2015-06-26-06-05. | `string` | `null` | no | +| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB instance is encrypted | `bool` | `true` | no | +| [storage\_throughput](#input\_storage\_throughput) | Storage throughput value for the DB instance. This setting applies only to the `gp3` storage type. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | +| [storage\_type](#input\_storage\_type) | One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter | `string` | `null` | no | +| [tags](#input\_tags) | A mapping of tags to assign to all resources | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | Updated Terraform resource management timeouts. Applies to `aws_db_instance` in particular to permit resource management times | `map(string)` | `{}` | no | +| [timezone](#input\_timezone) | 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. | `string` | `null` | no | +| [use\_identifier\_prefix](#input\_use\_identifier\_prefix) | Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix | `bool` | `false` | no | +| [username](#input\_username) | Username for the master DB user | `string` | `null` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of VPC security groups to associate | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_instance\_address](#output\_db\_instance\_address) | The address of the RDS instance | +| [db\_instance\_arn](#output\_db\_instance\_arn) | The ARN of the RDS instance | +| [db\_instance\_availability\_zone](#output\_db\_instance\_availability\_zone) | The availability zone of the RDS instance | +| [db\_instance\_ca\_cert\_identifier](#output\_db\_instance\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | +| [db\_instance\_cloudwatch\_log\_groups](#output\_db\_instance\_cloudwatch\_log\_groups) | Map of CloudWatch log groups created and their attributes | +| [db\_instance\_domain](#output\_db\_instance\_domain) | The ID of the Directory Service Active Directory domain the instance is joined to | +| [db\_instance\_domain\_iam\_role\_name](#output\_db\_instance\_domain\_iam\_role\_name) | The name of the IAM role to be used when making API calls to the Directory Service | +| [db\_instance\_endpoint](#output\_db\_instance\_endpoint) | The connection endpoint | +| [db\_instance\_engine](#output\_db\_instance\_engine) | The database engine | +| [db\_instance\_engine\_version\_actual](#output\_db\_instance\_engine\_version\_actual) | The running version of the database | +| [db\_instance\_hosted\_zone\_id](#output\_db\_instance\_hosted\_zone\_id) | The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record) | +| [db\_instance\_identifier](#output\_db\_instance\_identifier) | The RDS instance identifier | +| [db\_instance\_master\_user\_secret\_arn](#output\_db\_instance\_master\_user\_secret\_arn) | The ARN of the master user secret (Only available when manage\_master\_user\_password is set to true) | +| [db\_instance\_name](#output\_db\_instance\_name) | The database name | +| [db\_instance\_port](#output\_db\_instance\_port) | The database port | +| [db\_instance\_resource\_id](#output\_db\_instance\_resource\_id) | The RDS Resource ID of this instance | +| [db\_instance\_status](#output\_db\_instance\_status) | The RDS instance status | +| [db\_instance\_username](#output\_db\_instance\_username) | The master username for the database | +| [db\_listener\_endpoint](#output\_db\_listener\_endpoint) | Specifies the listener connection endpoint for SQL Server Always On | +| [enhanced\_monitoring\_iam\_role\_arn](#output\_enhanced\_monitoring\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the monitoring role | +| [enhanced\_monitoring\_iam\_role\_name](#output\_enhanced\_monitoring\_iam\_role\_name) | The name of the monitoring role | + diff --git a/new_modules/db_instance/main.tf b/new_modules/db_instance/main.tf new file mode 100644 index 00000000..76fff656 --- /dev/null +++ b/new_modules/db_instance/main.tf @@ -0,0 +1,150 @@ +locals { + + final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.final_snapshot_identifier_prefix}-${var.identifier}-${try(random_id.snapshot_identifier[0].hex, "")}" + + identifier = var.use_identifier_prefix ? null : var.identifier + identifier_prefix = var.use_identifier_prefix ? "${var.identifier}-" : null + + # Replicas will use source metadata + is_replica = var.replicate_source_db != null +} + +resource "random_id" "snapshot_identifier" { + count = !var.skip_final_snapshot ? 1 : 0 + + keepers = { + id = var.identifier + } + + byte_length = 4 +} + +resource "aws_db_instance" "this" { + identifier = local.identifier + identifier_prefix = local.identifier_prefix + + engine = local.is_replica ? null : var.engine + engine_version = var.engine_version + instance_class = var.instance_class + allocated_storage = local.is_replica ? null : 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 + + db_name = var.db_name + username = !local.is_replica ? var.username : null + password = !local.is_replica && var.manage_master_user_password ? null : var.password + port = var.port + domain = var.domain + domain_iam_role_name = var.domain_iam_role_name + iam_database_authentication_enabled = var.iam_database_authentication_enabled + custom_iam_instance_profile = var.custom_iam_instance_profile + manage_master_user_password = !local.is_replica && var.manage_master_user_password ? var.manage_master_user_password : null + master_user_secret_kms_key_id = !local.is_replica && var.manage_master_user_password ? var.master_user_secret_kms_key_id : null + + 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 + option_group_name = var.option_group_name + network_type = var.network_type + + availability_zone = var.availability_zone + multi_az = var.multi_az + iops = var.iops + storage_throughput = var.storage_throughput + publicly_accessible = var.publicly_accessible + ca_cert_identifier = var.ca_cert_identifier + + 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 + + # https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html + dynamic "blue_green_update" { + for_each = length(var.blue_green_update) > 0 ? [var.blue_green_update] : [] + + content { + enabled = try(blue_green_update.value.enabled, null) + } + } + + snapshot_identifier = var.snapshot_identifier + copy_tags_to_snapshot = var.copy_tags_to_snapshot + skip_final_snapshot = var.skip_final_snapshot + final_snapshot_identifier = local.final_snapshot_identifier + + performance_insights_enabled = var.performance_insights_enabled + performance_insights_retention_period = var.performance_insights_enabled ? var.performance_insights_retention_period : null + performance_insights_kms_key_id = var.performance_insights_enabled ? var.performance_insights_kms_key_id : null + + replicate_source_db = var.replicate_source_db + replica_mode = var.replica_mode + backup_retention_period = length(var.blue_green_update) > 0 ? coalesce(var.backup_retention_period, 1) : var.backup_retention_period + backup_window = var.backup_window + max_allocated_storage = var.max_allocated_storage + monitoring_interval = var.monitoring_interval + monitoring_role_arn = var.monitoring_interval > 0 ? var.monitoring_role_arn : null + + character_set_name = var.character_set_name + nchar_character_set_name = var.nchar_character_set_name + timezone = var.timezone + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + + deletion_protection = var.deletion_protection + delete_automated_backups = var.delete_automated_backups + + dynamic "restore_to_point_in_time" { + for_each = var.restore_to_point_in_time != null ? [var.restore_to_point_in_time] : [] + + content { + restore_time = lookup(restore_to_point_in_time.value, "restore_time", null) + source_db_instance_automated_backups_arn = lookup(restore_to_point_in_time.value, "source_db_instance_automated_backups_arn", null) + source_db_instance_identifier = lookup(restore_to_point_in_time.value, "source_db_instance_identifier", null) + source_dbi_resource_id = lookup(restore_to_point_in_time.value, "source_dbi_resource_id", null) + use_latest_restorable_time = lookup(restore_to_point_in_time.value, "use_latest_restorable_time", null) + } + } + + dynamic "s3_import" { + for_each = var.s3_import != null ? [var.s3_import] : [] + + content { + source_engine = "mysql" + source_engine_version = s3_import.value.source_engine_version + bucket_name = s3_import.value.bucket_name + bucket_prefix = lookup(s3_import.value, "bucket_prefix", null) + ingestion_role = s3_import.value.ingestion_role + } + } + + tags = var.tags + + # depends_on = [aws_cloudwatch_log_group.this] + + timeouts { + create = lookup(var.timeouts, "create", null) + delete = lookup(var.timeouts, "delete", null) + update = lookup(var.timeouts, "update", null) + } + + # Note: do not add `latest_restorable_time` to `ignore_changes` + # https://github.com/terraform-aws-modules/terraform-aws-rds/issues/478 +} + +# ################################################################################ +# # CloudWatch Log Group +# ################################################################################ + +# # Log groups will not be created if using an identifier prefix ?? +# resource "aws_cloudwatch_log_group" "this" { +# # for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log if var.create && var.create_cloudwatch_log_group && !var.use_identifier_prefix]) +# for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log if var.create && var.create_cloudwatch_log_group]) + +# name = "/aws/rds/instance/${var.identifier}/${each.value}" # it is not possible to use the identifier_prefix here since it is not known at plan time and we can't have cyclic reference to the db instance resource +# retention_in_days = var.cloudwatch_log_group_retention_in_days +# kms_key_id = var.cloudwatch_log_group_kms_key_id +# skip_destroy = var.cloudwatch_log_group_skip_destroy_on_deletion +# tags = var.tags +# } diff --git a/new_modules/db_instance/outputs.tf b/new_modules/db_instance/outputs.tf new file mode 100644 index 00000000..e8733c8a --- /dev/null +++ b/new_modules/db_instance/outputs.tf @@ -0,0 +1,100 @@ +# output "enhanced_monitoring_iam_role_name" { +# description = "The name of the monitoring role" +# value = try(aws_iam_role.enhanced_monitoring[0].name, null) +# } + +# output "enhanced_monitoring_iam_role_arn" { +# description = "The Amazon Resource Name (ARN) specifying the monitoring role" +# value = try(aws_iam_role.enhanced_monitoring[0].arn, null) +# } + +output "db_instance_address" { + description = "The address of the RDS instance" + value = try(aws_db_instance.this.address, null) +} + +output "db_instance_arn" { + description = "The ARN of the RDS instance" + value = try(aws_db_instance.this.arn, null) +} + +output "db_instance_availability_zone" { + description = "The availability zone of the RDS instance" + value = try(aws_db_instance.this.availability_zone, null) +} + +output "db_instance_endpoint" { + description = "The connection endpoint" + value = try(aws_db_instance.this.endpoint, null) +} + +output "db_listener_endpoint" { + description = "Specifies the listener connection endpoint for SQL Server Always On" + value = try(aws_db_instance.this.listener_endpoint, null) +} + +output "db_instance_engine" { + description = "The database engine" + value = try(aws_db_instance.this.engine, null) +} + +output "db_instance_engine_version_actual" { + description = "The running version of the database" + value = try(aws_db_instance.this.engine_version_actual, null) +} + +output "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 = try(aws_db_instance.this.hosted_zone_id, null) +} + +output "db_instance_identifier" { + description = "The RDS instance identifier" + value = try(aws_db_instance.this.identifier, null) +} + +output "db_instance_resource_id" { + description = "The RDS Resource ID of this instance" + value = try(aws_db_instance.this.resource_id, null) +} + +output "db_instance_status" { + description = "The RDS instance status" + value = try(aws_db_instance.this.status, null) +} + +output "db_instance_name" { + description = "The database name" + value = try(aws_db_instance.this.db_name, null) +} + +output "db_instance_username" { + description = "The master username for the database" + value = try(aws_db_instance.this.username, null) + sensitive = true +} + +output "db_instance_port" { + description = "The database port" + value = try(aws_db_instance.this.port, null) +} + +output "db_instance_ca_cert_identifier" { + description = "Specifies the identifier of the CA certificate for the DB instance" + value = try(aws_db_instance.this.ca_cert_identifier, null) +} + +output "db_instance_domain" { + description = "The ID of the Directory Service Active Directory domain the instance is joined to" + value = try(aws_db_instance.this.domain, null) +} + +output "db_instance_domain_iam_role_name" { + description = "The name of the IAM role to be used when making API calls to the Directory Service" + value = try(aws_db_instance.this.domain_iam_role_name, null) +} + +output "db_instance_master_user_secret_arn" { + description = "The ARN of the master user secret (Only available when manage_master_user_password is set to true)" + value = try(aws_db_instance.this.master_user_secret[0].secret_arn, null) +} \ No newline at end of file diff --git a/new_modules/db_instance/variables.tf b/new_modules/db_instance/variables.tf new file mode 100644 index 00000000..dc82695d --- /dev/null +++ b/new_modules/db_instance/variables.tf @@ -0,0 +1,431 @@ +# variable "create" { +# description = "Whether to create this resource or not?" +# type = bool +# default = true +# } + +variable "identifier" { + description = "The name of the RDS instance" + type = string +} +variable "custom_iam_instance_profile" { + description = "RDS custom iam instance profile" + type = string + default = null +} + +variable "use_identifier_prefix" { + description = "Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix" + type = bool + default = false +} + +variable "allocated_storage" { + description = "The allocated storage in gigabytes" + type = number + default = null +} + +variable "storage_type" { + description = "One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter" + type = string + default = null +} + +variable "storage_throughput" { + description = "Storage throughput value for the DB instance. This setting applies only to the `gp3` storage type. See `notes` for limitations regarding this variable for `gp3`" + type = number + default = null +} + +variable "storage_encrypted" { + description = "Specifies whether the DB instance is encrypted" + type = bool + default = true +} + +variable "kms_key_id" { + description = "The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage_encrypted is set to true and kms_key_id is not specified the default KMS key created in your account will be used" + type = string + default = null +} + +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." + type = string + default = null +} + +variable "license_model" { + description = "License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1" + type = string + default = null +} + +variable "replica_mode" { + description = "Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified" + type = string + default = null +} + +variable "iam_database_authentication_enabled" { + description = "Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled" + type = bool + default = false +} + +variable "domain" { + description = "The ID of the Directory Service Active Directory domain to create the instance in" + type = string + default = null +} + +variable "domain_iam_role_name" { + description = "(Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service" + type = string + default = null +} + +variable "engine" { + description = "The database engine to use" + type = string + default = null +} + +variable "engine_version" { + description = "The engine version to use" + type = string + default = null +} + +variable "instance_class" { + description = "The instance type of the RDS instance" + type = string + default = null +} + +variable "db_name" { + description = "The DB name to create. If omitted, no database is created initially" + type = string + default = null +} + +variable "username" { + description = "Username for the master DB user" + type = string + default = null +} + +variable "password" { + description = "Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file" + type = string + default = null +} + +variable "manage_master_user_password" { + description = "Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if password is provided" + type = bool + default = false +} + +variable "master_user_secret_kms_key_id" { + description = < +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_db_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | +| [description](#input\_description) | The description of the DB parameter group | `string` | `null` | no | +| [family](#input\_family) | The family of the DB parameter group | `string` | `null` | no | +| [name](#input\_name) | The name of the DB parameter group | `string` | `""` | no | +| [parameters](#input\_parameters) | A list of DB parameter maps to apply | `list(map(string))` | `[]` | no | +| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix | `bool` | `true` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_parameter\_group\_arn](#output\_db\_parameter\_group\_arn) | The ARN of the db parameter group | +| [db\_parameter\_group\_id](#output\_db\_parameter\_group\_id) | The db parameter group id | + diff --git a/new_modules/db_parameter_group/main.tf b/new_modules/db_parameter_group/main.tf new file mode 100644 index 00000000..93e609d1 --- /dev/null +++ b/new_modules/db_parameter_group/main.tf @@ -0,0 +1,33 @@ +locals { + name = var.use_name_prefix ? null : var.name + name_prefix = var.use_name_prefix ? "${var.name}-" : null + + description = coalesce(var.description, format("%s parameter group", var.name)) +} + +resource "aws_db_parameter_group" "this" { + name = local.name + name_prefix = local.name_prefix + description = local.description + family = var.family + + dynamic "parameter" { + for_each = var.parameters + content { + name = parameter.value.name + value = parameter.value.value + apply_method = lookup(parameter.value, "apply_method", null) + } + } + + tags = merge( + var.tags, + { + "Name" = var.name + }, + ) + + lifecycle { + create_before_destroy = true + } +} diff --git a/new_modules/db_parameter_group/outputs.tf b/new_modules/db_parameter_group/outputs.tf new file mode 100644 index 00000000..3376f7eb --- /dev/null +++ b/new_modules/db_parameter_group/outputs.tf @@ -0,0 +1,9 @@ +output "db_parameter_group_id" { + description = "The db parameter group id" + value = try(aws_db_parameter_group.this.id, null) +} + +output "db_parameter_group_arn" { + description = "The ARN of the db parameter group" + value = try(aws_db_parameter_group.this.arn, null) +} diff --git a/new_modules/db_parameter_group/variables.tf b/new_modules/db_parameter_group/variables.tf new file mode 100644 index 00000000..b7b7af9f --- /dev/null +++ b/new_modules/db_parameter_group/variables.tf @@ -0,0 +1,41 @@ +variable "create" { + description = "Whether to create this resource or not?" + type = bool + default = true +} + +variable "name" { + description = "The name of the DB parameter group" + type = string + default = "" +} + +variable "use_name_prefix" { + description = "Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix" + type = bool + default = true +} + +variable "description" { + description = "The description of the DB parameter group" + type = string + default = null +} + +variable "family" { + description = "The family of the DB parameter group" + type = string + default = null +} + +variable "parameters" { + description = "A list of DB parameter maps to apply" + type = list(map(string)) + default = [] +} + +variable "tags" { + description = "A mapping of tags to assign to the resource" + type = map(string) + default = {} +} diff --git a/new_modules/db_parameter_group/versions.tf b/new_modules/db_parameter_group/versions.tf new file mode 100644 index 00000000..ddfcb0e0 --- /dev/null +++ b/new_modules/db_parameter_group/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} diff --git a/new_modules/db_subnet_group/README.md b/new_modules/db_subnet_group/README.md new file mode 100644 index 00000000..68a1d5ff --- /dev/null +++ b/new_modules/db_subnet_group/README.md @@ -0,0 +1,44 @@ +# aws_db_subnet_group + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_db_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_subnet_group) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | +| [description](#input\_description) | The description of the DB subnet group | `string` | `null` | no | +| [name](#input\_name) | The name of the DB subnet group | `string` | `""` | no | +| [subnet\_ids](#input\_subnet\_ids) | A list of VPC subnet IDs | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | +| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix | `bool` | `true` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_subnet\_group\_arn](#output\_db\_subnet\_group\_arn) | The ARN of the db subnet group | +| [db\_subnet\_group\_id](#output\_db\_subnet\_group\_id) | The db subnet group name | + diff --git a/new_modules/db_subnet_group/main.tf b/new_modules/db_subnet_group/main.tf new file mode 100644 index 00000000..316744c1 --- /dev/null +++ b/new_modules/db_subnet_group/main.tf @@ -0,0 +1,22 @@ +locals { + name = var.use_name_prefix ? null : var.name + name_prefix = var.use_name_prefix ? "${var.name}-" : null + + description = coalesce(var.description, format("%s subnet group", var.name)) +} + +resource "aws_db_subnet_group" "this" { + # count = var.create ? 1 : 0 + + name = local.name + name_prefix = local.name_prefix + description = local.description + subnet_ids = var.subnet_ids + + tags = merge( + var.tags, + { + "Name" = var.name + }, + ) +} diff --git a/new_modules/db_subnet_group/outputs.tf b/new_modules/db_subnet_group/outputs.tf new file mode 100644 index 00000000..5a5efca1 --- /dev/null +++ b/new_modules/db_subnet_group/outputs.tf @@ -0,0 +1,9 @@ +output "db_subnet_group_id" { + description = "The db subnet group name" + value = try(aws_db_subnet_group.this.id, null) +} + +output "db_subnet_group_arn" { + description = "The ARN of the db subnet group" + value = try(aws_db_subnet_group.this.arn, null) +} diff --git a/new_modules/db_subnet_group/variables.tf b/new_modules/db_subnet_group/variables.tf new file mode 100644 index 00000000..48185ab4 --- /dev/null +++ b/new_modules/db_subnet_group/variables.tf @@ -0,0 +1,35 @@ +variable "create" { + description = "Whether to create this resource or not?" + type = bool + default = true +} + +variable "name" { + description = "The name of the DB subnet group" + type = string + default = "" +} + +variable "use_name_prefix" { + description = "Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix" + type = bool + default = true +} + +variable "description" { + description = "The description of the DB subnet group" + type = string + default = null +} + +variable "subnet_ids" { + description = "A list of VPC subnet IDs" + type = list(string) + default = [] +} + +variable "tags" { + description = "A mapping of tags to assign to the resource" + type = map(string) + default = {} +} diff --git a/new_modules/db_subnet_group/versions.tf b/new_modules/db_subnet_group/versions.tf new file mode 100644 index 00000000..ddfcb0e0 --- /dev/null +++ b/new_modules/db_subnet_group/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} diff --git a/new_modules/rds-aurora/README.md b/new_modules/rds-aurora/README.md new file mode 100644 index 00000000..26451203 --- /dev/null +++ b/new_modules/rds-aurora/README.md @@ -0,0 +1,422 @@ +# AWS RDS Aurora Terraform module + +Terraform module which creates AWS RDS Aurora resources. + +[![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) + +## Available Features + +- Autoscaling of read-replicas +- Global cluster +- Enhanced monitoring +- Serverless cluster (v1 and v2) +- Import from S3 +- Fine grained control of individual cluster instances +- Custom endpoints +- RDS multi-AZ support (not Aurora) + +## Usage + +```hcl +module "cluster" { + source = "terraform-aws-modules/rds-aurora/aws" + + name = "test-aurora-db-postgres96" + engine = "aurora-postgresql" + engine_version = "14.5" + instance_class = "db.r6g.large" + instances = { + one = {} + 2 = { + instance_class = "db.r6g.2xlarge" + } + } + + vpc_id = "vpc-12345678" + db_subnet_group_name = "db-subnet-group" + security_group_rules = { + ex1_ingress = { + cidr_blocks = ["10.20.0.0/20"] + } + ex1_ingress = { + source_security_group_id = "sg-12345678" + } + } + + storage_encrypted = true + apply_immediately = true + monitoring_interval = 10 + + enabled_cloudwatch_logs_exports = ["postgresql"] + + tags = { + Environment = "dev" + Terraform = "true" + } +} +``` + +### Cluster Instance Configuration + +There are a couple different configuration methods that can be used to create instances within the cluster: + +ℹ️ Only the pertinent attributes are shown for brevity + +1. Create homogenous cluster of any number of instances + + - Resources created: + - Writer: 1 + - Reader(s): 2 + +```hcl + instance_class = "db.r6g.large" + instances = { + one = {} + two = {} + three = {} + } +``` + +2. Create homogenous cluster of instances w/ autoscaling enabled. This is redundant and we'll show why in the next example. + + - Resources created: + - Writer: 1 + - Reader(s): + - At least 4 readers (2 created directly, 2 created by appautoscaling) + - At most 7 reader instances (2 created directly, 5 created by appautoscaling) + +ℹ️ Autoscaling uses the instance class specified by `instance_class`. + +```hcl + instance_class = "db.r6g.large" + instances = { + one = {} + two = {} + three = {} + } + + autoscaling_enabled = true + autoscaling_min_capacity = 2 + autoscaling_max_capacity = 5 +``` + +3. Create homogeneous cluster scaled via autoscaling. At least one instance (writer) is required + + - Resources created: + - Writer: 1 + - Reader(s): + - At least 1 reader + - At most 5 readers + +```hcl + instance_class = "db.r6g.large" + instances = { + one = {} + } + + autoscaling_enabled = true + autoscaling_min_capacity = 1 + autoscaling_max_capacity = 5 +``` + +4. Create heterogenous cluster to support mixed-use workloads + + It is common in this configuration to independently control the instance `promotion_tier` paired with `endpoints` to create custom endpoints directed at select instances or instance groups. + + - Resources created: + - Writer: 1 + - Readers: 2 + +```hcl + instance_class = "db.r5.large" + instances = { + one = { + instance_class = "db.r5.2xlarge" + publicly_accessible = true + } + two = { + identifier = "static-member-1" + instance_class = "db.r5.2xlarge" + } + three = { + identifier = "excluded-member-1" + instance_class = "db.r5.large" + promotion_tier = 15 + } + } +``` + +5. Create heterogenous cluster to support mixed-use workloads w/ autoscaling enabled + + - Resources created: + - Writer: 1 + - Reader(s): + - At least 3 readers (2 created directly, 1 created through appautoscaling) + - At most 7 readers (2 created directly, 5 created through appautoscaling) + +ℹ️ Autoscaling uses the instance class specified by `instance_class`. + +```hcl + instance_class = "db.r5.large" + instances = { + one = { + instance_class = "db.r5.2xlarge" + publicly_accessible = true + } + two = { + identifier = "static-member-1" + instance_class = "db.r5.2xlarge" + } + three = { + identifier = "excluded-member-1" + instance_class = "db.r5.large" + promotion_tier = 15 + } + } + + autoscaling_enabled = true + autoscaling_min_capacity = 1 + autoscaling_max_capacity = 5 +``` + +## Conditional Creation + +The following values are provided to toggle on/off creation of the associated resources as desired: + +```hcl +# This RDS cluster will not be created +module "cluster" { + source = "terraform-aws-modules/rds-aurora/aws" + + # Disable creation of cluster and all resources + create = false + + # Disable creation of subnet group - provide a subnet group + create_db_subnet_group = false + + # Disable creation of security group - provide a security group + create_security_group = false + + # Disable creation of monitoring IAM role - provide a role ARN + create_monitoring_role = false + + # ... omitted +} +``` + +## Examples + +- [Autoscaling](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/autoscaling): A PostgreSQL cluster with enhanced monitoring and autoscaling enabled +- [Global Cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/global-cluster): A PostgreSQL global cluster with clusters provisioned in two different region +- [Multi-AZ](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/multi-az): A multi-AZ RDS cluster (not using Aurora engine) +- [MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/mysql): A simple MySQL cluster +- [PostgreSQL](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/postgresql): A simple PostgreSQL cluster +- [S3 Import](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/s3-import): A MySQL cluster created from a Percona Xtrabackup stored in S3 +- [Serverless](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/serverless): Serverless V1 and V2 (PostgreSQL and MySQL) + +## Documentation + +Terraform documentation is generated automatically using [pre-commit hooks](http://www.pre-commit.com/). Follow installation instructions [here](https://pre-commit.com/#install). + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.67 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.67 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_appautoscaling_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_policy) | resource | +| [aws_appautoscaling_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_target) | resource | +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_db_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource | +| [aws_db_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_subnet_group) | resource | +| [aws_iam_role.rds_enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.rds_enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_rds_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster) | resource | +| [aws_rds_cluster_activity_stream.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_activity_stream) | resource | +| [aws_rds_cluster_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_endpoint) | resource | +| [aws_rds_cluster_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_instance) | resource | +| [aws_rds_cluster_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_parameter_group) | resource | +| [aws_rds_cluster_role_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_role_association) | resource | +| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_iam_policy_document.monitoring_rds_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allocated\_storage](#input\_allocated\_storage) | The amount of storage in gibibytes (GiB) to allocate to each DB instance in the Multi-AZ DB cluster. (This setting is required to create a Multi-AZ DB cluster) | `number` | `null` | no | +| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Enable to allow major engine version upgrades when changing engine versions. Defaults to `false` | `bool` | `false` | no | +| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any cluster modifications are applied immediately, or during the next maintenance window. Default is `false` | `bool` | `null` | no | +| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. Default `true` | `bool` | `null` | no | +| [autoscaling\_enabled](#input\_autoscaling\_enabled) | Determines whether autoscaling of the cluster read replicas is enabled | `bool` | `false` | no | +| [autoscaling\_max\_capacity](#input\_autoscaling\_max\_capacity) | Maximum number of read replicas permitted when autoscaling is enabled | `number` | `2` | no | +| [autoscaling\_min\_capacity](#input\_autoscaling\_min\_capacity) | Minimum number of read replicas permitted when autoscaling is enabled | `number` | `0` | no | +| [autoscaling\_policy\_name](#input\_autoscaling\_policy\_name) | Autoscaling policy name | `string` | `"target-metric"` | no | +| [autoscaling\_scale\_in\_cooldown](#input\_autoscaling\_scale\_in\_cooldown) | Cooldown in seconds before allowing further scaling operations after a scale in | `number` | `300` | no | +| [autoscaling\_scale\_out\_cooldown](#input\_autoscaling\_scale\_out\_cooldown) | Cooldown in seconds before allowing further scaling operations after a scale out | `number` | `300` | no | +| [autoscaling\_target\_connections](#input\_autoscaling\_target\_connections) | Average number of connections threshold which will initiate autoscaling. Default value is 70% of db.r4/r5/r6g.large's default max\_connections | `number` | `700` | no | +| [autoscaling\_target\_cpu](#input\_autoscaling\_target\_cpu) | CPU threshold which will initiate autoscaling | `number` | `70` | no | +| [availability\_zones](#input\_availability\_zones) | List of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created. RDS automatically assigns 3 AZs if less than 3 AZs are configured, which will show as a difference requiring resource recreation next Terraform apply | `list(string)` | `null` | no | +| [backtrack\_window](#input\_backtrack\_window) | The target backtrack window, in seconds. Only available for `aurora` engine currently. To disable backtracking, set this value to 0. Must be between 0 and 259200 (72 hours) | `number` | `null` | no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for. Default `7` | `number` | `7` | no | +| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | The identifier of the CA certificate for the DB instance | `string` | `null` | no | +| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | +| [cloudwatch\_log\_group\_retention\_in\_days](#input\_cloudwatch\_log\_group\_retention\_in\_days) | The number of days to retain CloudWatch logs for the DB instance | `number` | `7` | no | +| [cluster\_members](#input\_cluster\_members) | List of RDS Instances that are a part of this cluster | `list(string)` | `null` | no | +| [cluster\_tags](#input\_cluster\_tags) | A map of tags to add to only the cluster. Used for AWS Instance Scheduler tagging | `map(string)` | `{}` | no | +| [cluster\_timeouts](#input\_cluster\_timeouts) | Create, update, and delete timeout configurations for the cluster | `map(string)` | `{}` | no | +| [cluster\_use\_name\_prefix](#input\_cluster\_use\_name\_prefix) | Whether to use `name` as a prefix for the cluster | `bool` | `false` | no | +| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | Copy all Cluster `tags` to snapshots | `bool` | `null` | no | +| [create](#input\_create) | Whether cluster should be created (affects nearly all resources) | `bool` | `true` | no | +| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports` | `bool` | `false` | no | +| [create\_db\_cluster\_activity\_stream](#input\_create\_db\_cluster\_activity\_stream) | Determines whether a cluster activity stream is created. | `bool` | `false` | no | +| [create\_db\_cluster\_parameter\_group](#input\_create\_db\_cluster\_parameter\_group) | Determines whether a cluster parameter should be created or use existing | `bool` | `false` | no | +| [create\_db\_parameter\_group](#input\_create\_db\_parameter\_group) | Determines whether a DB parameter should be created or use existing | `bool` | `false` | no | +| [create\_db\_subnet\_group](#input\_create\_db\_subnet\_group) | Determines whether to create the database subnet group or use existing | `bool` | `false` | no | +| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Determines whether to create the IAM role for RDS enhanced monitoring | `bool` | `true` | no | +| [create\_security\_group](#input\_create\_security\_group) | Determines whether to create security group for RDS cluster | `bool` | `true` | no | +| [database\_name](#input\_database\_name) | Name for an automatically created database on cluster creation | `string` | `null` | no | +| [db\_cluster\_activity\_stream\_kms\_key\_id](#input\_db\_cluster\_activity\_stream\_kms\_key\_id) | The AWS KMS key identifier for encrypting messages in the database activity stream | `string` | `null` | no | +| [db\_cluster\_activity\_stream\_mode](#input\_db\_cluster\_activity\_stream\_mode) | Specifies the mode of the database activity stream. Database events such as a change or access generate an activity stream event. One of: sync, async | `string` | `null` | no | +| [db\_cluster\_db\_instance\_parameter\_group\_name](#input\_db\_cluster\_db\_instance\_parameter\_group\_name) | Instance parameter group to associate with all instances of the DB cluster. The `db_cluster_db_instance_parameter_group_name` is only valid in combination with `allow_major_version_upgrade` | `string` | `null` | no | +| [db\_cluster\_instance\_class](#input\_db\_cluster\_instance\_class) | The compute and memory capacity of each DB instance in the Multi-AZ DB cluster, for example db.m6g.xlarge. Not all DB instance classes are available in all AWS Regions, or for all database engines | `string` | `null` | no | +| [db\_cluster\_parameter\_group\_description](#input\_db\_cluster\_parameter\_group\_description) | The description of the DB cluster parameter group. Defaults to "Managed by Terraform" | `string` | `null` | no | +| [db\_cluster\_parameter\_group\_family](#input\_db\_cluster\_parameter\_group\_family) | The family of the DB cluster parameter group | `string` | `""` | no | +| [db\_cluster\_parameter\_group\_name](#input\_db\_cluster\_parameter\_group\_name) | The name of the DB cluster parameter group | `string` | `null` | no | +| [db\_cluster\_parameter\_group\_parameters](#input\_db\_cluster\_parameter\_group\_parameters) | A list of DB cluster parameters to apply. Note that parameters may differ from a family to an other | `list(map(string))` | `[]` | no | +| [db\_cluster\_parameter\_group\_use\_name\_prefix](#input\_db\_cluster\_parameter\_group\_use\_name\_prefix) | Determines whether the DB cluster parameter group name is used as a prefix | `bool` | `true` | no | +| [db\_parameter\_group\_description](#input\_db\_parameter\_group\_description) | The description of the DB parameter group. Defaults to "Managed by Terraform" | `string` | `null` | no | +| [db\_parameter\_group\_family](#input\_db\_parameter\_group\_family) | The family of the DB parameter group | `string` | `""` | no | +| [db\_parameter\_group\_name](#input\_db\_parameter\_group\_name) | The name of the DB parameter group | `string` | `null` | no | +| [db\_parameter\_group\_parameters](#input\_db\_parameter\_group\_parameters) | A list of DB parameters to apply. Note that parameters may differ from a family to an other | `list(map(string))` | `[]` | no | +| [db\_parameter\_group\_use\_name\_prefix](#input\_db\_parameter\_group\_use\_name\_prefix) | Determines whether the DB parameter group name is used as a prefix | `bool` | `true` | no | +| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | The name of the subnet group name (existing or created) | `string` | `""` | no | +| [deletion\_protection](#input\_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` | `null` | no | +| [enable\_global\_write\_forwarding](#input\_enable\_global\_write\_forwarding) | Whether cluster should forward writes to an associated global cluster. Applied to secondary clusters to enable them to forward writes to an `aws_rds_global_cluster`'s primary cluster | `bool` | `null` | no | +| [enable\_http\_endpoint](#input\_enable\_http\_endpoint) | Enable HTTP endpoint (data API). Only valid when engine\_mode is set to `serverless` | `bool` | `null` | no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | Set of log types to export to cloudwatch. If omitted, no logs will be exported. The following log types are supported: `audit`, `error`, `general`, `slowquery`, `postgresql` | `list(string)` | `[]` | no | +| [endpoints](#input\_endpoints) | Map of additional cluster endpoints and their attributes to be created | `any` | `{}` | no | +| [engine](#input\_engine) | The name of the database engine to be used for this DB cluster. Defaults to `aurora`. Valid Values: `aurora`, `aurora-mysql`, `aurora-postgresql` | `string` | `null` | no | +| [engine\_mode](#input\_engine\_mode) | The database engine mode. Valid values: `global`, `multimaster`, `parallelquery`, `provisioned`, `serverless`. Defaults to: `provisioned` | `string` | `"provisioned"` | no | +| [engine\_native\_audit\_fields\_included](#input\_engine\_native\_audit\_fields\_included) | Specifies whether the database activity stream includes engine-native audit fields. This option only applies to an Oracle DB instance. By default, no engine-native audit fields are included | `bool` | `false` | no | +| [engine\_version](#input\_engine\_version) | The database engine version. Updating this argument results in an outage | `string` | `null` | no | +| [final\_snapshot\_identifier](#input\_final\_snapshot\_identifier) | The name of your final DB snapshot when this DB cluster is deleted. If omitted, no final snapshot will be made | `string` | `null` | no | +| [global\_cluster\_identifier](#input\_global\_cluster\_identifier) | The global cluster identifier specified on `aws_rds_global_cluster` | `string` | `null` | no | +| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled | `bool` | `null` | no | +| [iam\_role\_description](#input\_iam\_role\_description) | Description of the monitoring role | `string` | `null` | no | +| [iam\_role\_force\_detach\_policies](#input\_iam\_role\_force\_detach\_policies) | Whether to force detaching any policies the monitoring role has before destroying it | `bool` | `null` | no | +| [iam\_role\_managed\_policy\_arns](#input\_iam\_role\_managed\_policy\_arns) | Set of exclusive IAM managed policy ARNs to attach to the monitoring role | `list(string)` | `null` | no | +| [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | Maximum session duration (in seconds) that you want to set for the monitoring role | `number` | `null` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | Friendly name of the monitoring role | `string` | `null` | no | +| [iam\_role\_path](#input\_iam\_role\_path) | Path for the monitoring role | `string` | `null` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the policy that is used to set the permissions boundary for the monitoring role | `string` | `null` | no | +| [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether to use `iam_role_name` as is or create a unique name beginning with the `iam_role_name` as the prefix | `bool` | `false` | no | +| [iam\_roles](#input\_iam\_roles) | Map of IAM roles and supported feature names to associate with the cluster | `map(map(string))` | `{}` | no | +| [instance\_class](#input\_instance\_class) | Instance type to use at master instance. Note: if `autoscaling_enabled` is `true`, this will be the same instance class used on instances created by autoscaling | `string` | `""` | no | +| [instance\_timeouts](#input\_instance\_timeouts) | Create, update, and delete timeout configurations for the cluster instance(s) | `map(string)` | `{}` | no | +| [instances](#input\_instances) | Map of cluster instances and any specific/overriding attributes to be created | `any` | `{}` | no | +| [instances\_use\_identifier\_prefix](#input\_instances\_use\_identifier\_prefix) | Determines whether cluster instance identifiers are used as prefixes | `bool` | `false` | no | +| [iops](#input\_iops) | The amount of Provisioned IOPS (input/output operations per second) to be initially allocated for each DB instance in the Multi-AZ DB cluster | `number` | `null` | no | +| [is\_primary\_cluster](#input\_is\_primary\_cluster) | Determines whether cluster is primary cluster with writer instance (set to `false` for global cluster and replica clusters) | `bool` | `true` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to `true` | `string` | `null` | no | +| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if `master_password` is provided | `bool` | `true` | no | +| [master\_password](#input\_master\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file. Required unless `manage_master_user_password` is set to `true` or unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database | `string` | `null` | no | +| [master\_user\_secret\_kms\_key\_id](#input\_master\_user\_secret\_kms\_key\_id) | The Amazon Web Services KMS key identifier is the key ARN, key ID, alias ARN, or alias name for the KMS key | `string` | `null` | no | +| [master\_username](#input\_master\_username) | Username for the master DB user. Required unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database | `string` | `null` | no | +| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for instances. Set to `0` to disable. Default is `0` | `number` | `0` | no | +| [monitoring\_role\_arn](#input\_monitoring\_role\_arn) | IAM role used by RDS to send enhanced monitoring metrics to CloudWatch | `string` | `""` | no | +| [name](#input\_name) | Name used across resources created | `string` | `""` | no | +| [network\_type](#input\_network\_type) | The type of network stack to use (IPV4 or DUAL) | `string` | `null` | no | +| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Specifies whether Performance Insights is enabled or not | `bool` | `null` | no | +| [performance\_insights\_kms\_key\_id](#input\_performance\_insights\_kms\_key\_id) | The ARN for the KMS key to encrypt Performance Insights data | `string` | `null` | no | +| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | Amount of time in days to retain Performance Insights data. Either 7 (7 days) or 731 (2 years) | `number` | `null` | no | +| [port](#input\_port) | The port on which the DB accepts connections | `string` | `null` | no | +| [predefined\_metric\_type](#input\_predefined\_metric\_type) | The metric type to scale on. Valid values are `RDSReaderAverageCPUUtilization` and `RDSReaderAverageDatabaseConnections` | `string` | `"RDSReaderAverageCPUUtilization"` | no | +| [preferred\_backup\_window](#input\_preferred\_backup\_window) | The daily time range during which automated backups are created if automated backups are enabled using the `backup_retention_period` parameter. Time in UTC | `string` | `"02:00-03:00"` | no | +| [preferred\_maintenance\_window](#input\_preferred\_maintenance\_window) | The weekly time range during which system maintenance can occur, in (UTC) | `string` | `"sun:05:00-sun:06:00"` | no | +| [publicly\_accessible](#input\_publicly\_accessible) | Determines whether instances are publicly accessible. Default `false` | `bool` | `null` | no | +| [putin\_khuylo](#input\_putin\_khuylo) | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | `bool` | `true` | no | +| [replication\_source\_identifier](#input\_replication\_source\_identifier) | ARN of a source DB cluster or DB instance if this DB cluster is to be created as a Read Replica | `string` | `null` | no | +| [restore\_to\_point\_in\_time](#input\_restore\_to\_point\_in\_time) | Map of nested attributes for cloning Aurora cluster | `map(string)` | `{}` | no | +| [s3\_import](#input\_s3\_import) | Configuration map used to restore from a Percona Xtrabackup in S3 (only MySQL is supported) | `map(string)` | `{}` | no | +| [scaling\_configuration](#input\_scaling\_configuration) | Map of nested attributes with scaling properties. Only valid when `engine_mode` is set to `serverless` | `map(string)` | `{}` | no | +| [security\_group\_description](#input\_security\_group\_description) | The description of the security group. If value is set to empty string it will contain cluster name in the description | `string` | `null` | no | +| [security\_group\_name](#input\_security\_group\_name) | The security group name. Default value is (`var.name`) | `string` | `""` | no | +| [security\_group\_rules](#input\_security\_group\_rules) | Map of security group rules to add to the cluster security group created | `any` | `{}` | no | +| [security\_group\_tags](#input\_security\_group\_tags) | Additional tags for the security group | `map(string)` | `{}` | no | +| [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`var.name`) is used as a prefix | `bool` | `true` | no | +| [serverlessv2\_scaling\_configuration](#input\_serverlessv2\_scaling\_configuration) | Map of nested attributes with serverless v2 scaling properties. Only valid when `engine_mode` is set to `provisioned` | `map(string)` | `{}` | no | +| [skip\_final\_snapshot](#input\_skip\_final\_snapshot) | Determines whether a final snapshot is created before the cluster is deleted. If true is specified, no snapshot is created | `bool` | `false` | no | +| [snapshot\_identifier](#input\_snapshot\_identifier) | Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot | `string` | `null` | no | +| [source\_region](#input\_source\_region) | The source region for an encrypted replica DB cluster | `string` | `null` | no | +| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB cluster is encrypted. The default is `true` | `bool` | `true` | no | +| [storage\_type](#input\_storage\_type) | Determines the storage type for the DB cluster. Optional for Single-AZ, required for Multi-AZ DB clusters. Valid values for Single-AZ: `aurora`, `""` (default, both refer to Aurora Standard), `aurora-iopt1` (Aurora I/O Optimized). Valid values for Multi-AZ: `io1` (default). | `string` | `null` | no | +| [subnets](#input\_subnets) | List of subnet IDs used by database subnet group created | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | `""` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of VPC security groups to associate to the cluster in addition to the security group created | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [additional\_cluster\_endpoints](#output\_additional\_cluster\_endpoints) | A map of additional cluster endpoints and their attributes | +| [cluster\_arn](#output\_cluster\_arn) | Amazon Resource Name (ARN) of cluster | +| [cluster\_database\_name](#output\_cluster\_database\_name) | Name for an automatically created database on cluster creation | +| [cluster\_endpoint](#output\_cluster\_endpoint) | Writer endpoint for the cluster | +| [cluster\_engine\_version\_actual](#output\_cluster\_engine\_version\_actual) | The running version of the cluster database | +| [cluster\_hosted\_zone\_id](#output\_cluster\_hosted\_zone\_id) | The Route53 Hosted Zone ID of the endpoint | +| [cluster\_id](#output\_cluster\_id) | The RDS Cluster Identifier | +| [cluster\_instances](#output\_cluster\_instances) | A map of cluster instances and their attributes | +| [cluster\_master\_password](#output\_cluster\_master\_password) | The database master password | +| [cluster\_master\_user\_secret](#output\_cluster\_master\_user\_secret) | The generated database master user secret when `manage_master_user_password` is set to `true` | +| [cluster\_master\_username](#output\_cluster\_master\_username) | The database master username | +| [cluster\_members](#output\_cluster\_members) | List of RDS Instances that are a part of this cluster | +| [cluster\_port](#output\_cluster\_port) | The database port | +| [cluster\_reader\_endpoint](#output\_cluster\_reader\_endpoint) | A read-only endpoint for the cluster, automatically load-balanced across replicas | +| [cluster\_resource\_id](#output\_cluster\_resource\_id) | The RDS Cluster Resource ID | +| [cluster\_role\_associations](#output\_cluster\_role\_associations) | A map of IAM roles associated with the cluster and their attributes | +| [db\_cluster\_activity\_stream\_kinesis\_stream\_name](#output\_db\_cluster\_activity\_stream\_kinesis\_stream\_name) | The name of the Amazon Kinesis data stream to be used for the database activity stream | +| [db\_cluster\_cloudwatch\_log\_groups](#output\_db\_cluster\_cloudwatch\_log\_groups) | Map of CloudWatch log groups created and their attributes | +| [db\_cluster\_parameter\_group\_arn](#output\_db\_cluster\_parameter\_group\_arn) | The ARN of the DB cluster parameter group created | +| [db\_cluster\_parameter\_group\_id](#output\_db\_cluster\_parameter\_group\_id) | The ID of the DB cluster parameter group created | +| [db\_parameter\_group\_arn](#output\_db\_parameter\_group\_arn) | The ARN of the DB parameter group created | +| [db\_parameter\_group\_id](#output\_db\_parameter\_group\_id) | The ID of the DB parameter group created | +| [db\_subnet\_group\_name](#output\_db\_subnet\_group\_name) | The db subnet group name | +| [enhanced\_monitoring\_iam\_role\_arn](#output\_enhanced\_monitoring\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the enhanced monitoring role | +| [enhanced\_monitoring\_iam\_role\_name](#output\_enhanced\_monitoring\_iam\_role\_name) | The name of the enhanced monitoring role | +| [enhanced\_monitoring\_iam\_role\_unique\_id](#output\_enhanced\_monitoring\_iam\_role\_unique\_id) | Stable and unique string identifying the enhanced monitoring role | +| [security\_group\_id](#output\_security\_group\_id) | The security group ID of the cluster | + + +## Authors + +Module is maintained by [Anton Babenko](https://github.com/antonbabenko) with help from [these awesome contributors](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/graphs/contributors). + +## License + +Apache 2 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/LICENSE) for full details. + +## Additional information for users from Russia and Belarus + +* Russia has [illegally annexed Crimea in 2014](https://en.wikipedia.org/wiki/Annexation_of_Crimea_by_the_Russian_Federation) and [brought the war in Donbas](https://en.wikipedia.org/wiki/War_in_Donbas) followed by [full-scale invasion of Ukraine in 2022](https://en.wikipedia.org/wiki/2022_Russian_invasion_of_Ukraine). +* Russia has brought sorrow and devastations to millions of Ukrainians, killed hundreds of innocent people, damaged thousands of buildings, and forced several million people to flee. +* [Putin khuylo!](https://en.wikipedia.org/wiki/Putin_khuylo!) diff --git a/new_modules/rds-aurora/main.tf b/new_modules/rds-aurora/main.tf new file mode 100644 index 00000000..2666e26c --- /dev/null +++ b/new_modules/rds-aurora/main.tf @@ -0,0 +1,322 @@ +locals { + port = coalesce(var.port, (var.engine == "aurora-postgresql" || var.engine == "postgres" ? 5432 : 3306)) + + security_group_name = try(coalesce(var.security_group_name, var.name), "") + + backtrack_window = (var.engine == "aurora-mysql" || var.engine == "aurora") && var.engine_mode != "serverless" ? var.backtrack_window : 0 + + is_serverless = var.engine_mode == "serverless" +} + +################################################################################ +# Cluster +################################################################################ + +resource "aws_rds_cluster" "this" { + allocated_storage = var.allocated_storage + allow_major_version_upgrade = var.allow_major_version_upgrade + apply_immediately = var.apply_immediately + availability_zones = var.availability_zones + backup_retention_period = var.backup_retention_period + backtrack_window = local.backtrack_window + cluster_identifier = var.cluster_use_name_prefix ? null : var.name + cluster_identifier_prefix = var.cluster_use_name_prefix ? "${var.name}-" : null + cluster_members = var.cluster_members + copy_tags_to_snapshot = var.copy_tags_to_snapshot + database_name = var.is_primary_cluster ? var.database_name : null + db_cluster_instance_class = var.db_cluster_instance_class + db_cluster_parameter_group_name = var.db_cluster_parameter_group_name + db_instance_parameter_group_name = var.allow_major_version_upgrade ? var.db_cluster_db_instance_parameter_group_name : null + db_subnet_group_name = var.db_subnet_group_name + deletion_protection = var.deletion_protection + enable_global_write_forwarding = var.enable_global_write_forwarding + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + enable_http_endpoint = var.enable_http_endpoint + engine = var.engine + engine_mode = var.engine_mode + engine_version = var.engine_version + final_snapshot_identifier = var.final_snapshot_identifier + global_cluster_identifier = var.global_cluster_identifier + iam_database_authentication_enabled = var.iam_database_authentication_enabled + # iam_roles has been removed from this resource and instead will be used with aws_rds_cluster_role_association below to avoid conflicts per docs + iops = var.iops + kms_key_id = var.kms_key_id + manage_master_user_password = var.global_cluster_identifier == null && var.manage_master_user_password ? var.manage_master_user_password : null + master_user_secret_kms_key_id = var.global_cluster_identifier == null && var.manage_master_user_password ? var.master_user_secret_kms_key_id : null + master_password = var.is_primary_cluster && !var.manage_master_user_password ? var.master_password : null + master_username = var.is_primary_cluster ? var.master_username : null + network_type = var.network_type + port = local.port + preferred_backup_window = local.is_serverless ? null : var.preferred_backup_window + preferred_maintenance_window = local.is_serverless ? null : var.preferred_maintenance_window + replication_source_identifier = var.replication_source_identifier + + dynamic "restore_to_point_in_time" { + for_each = length(var.restore_to_point_in_time) > 0 ? [var.restore_to_point_in_time] : [] + + content { + restore_to_time = try(restore_to_point_in_time.value.restore_to_time, null) + restore_type = try(restore_to_point_in_time.value.restore_type, null) + source_cluster_identifier = restore_to_point_in_time.value.source_cluster_identifier + use_latest_restorable_time = try(restore_to_point_in_time.value.use_latest_restorable_time, null) + } + } + + dynamic "s3_import" { + for_each = length(var.s3_import) > 0 && !local.is_serverless ? [var.s3_import] : [] + + content { + bucket_name = s3_import.value.bucket_name + bucket_prefix = try(s3_import.value.bucket_prefix, null) + ingestion_role = s3_import.value.ingestion_role + source_engine = "mysql" + source_engine_version = s3_import.value.source_engine_version + } + } + + dynamic "scaling_configuration" { + for_each = length(var.scaling_configuration) > 0 && local.is_serverless ? [var.scaling_configuration] : [] + + content { + auto_pause = try(scaling_configuration.value.auto_pause, null) + max_capacity = try(scaling_configuration.value.max_capacity, null) + min_capacity = try(scaling_configuration.value.min_capacity, null) + seconds_until_auto_pause = try(scaling_configuration.value.seconds_until_auto_pause, null) + timeout_action = try(scaling_configuration.value.timeout_action, null) + } + } + + dynamic "serverlessv2_scaling_configuration" { + for_each = length(var.serverlessv2_scaling_configuration) > 0 && var.engine_mode == "provisioned" ? [var.serverlessv2_scaling_configuration] : [] + + content { + max_capacity = serverlessv2_scaling_configuration.value.max_capacity + min_capacity = serverlessv2_scaling_configuration.value.min_capacity + } + } + + skip_final_snapshot = var.skip_final_snapshot + snapshot_identifier = var.snapshot_identifier + source_region = var.source_region + storage_encrypted = var.storage_encrypted + storage_type = var.storage_type + tags = merge(var.tags, var.cluster_tags) + vpc_security_group_ids =var.vpc_security_group_ids # compact(concat([try(aws_security_group.this[0].id, "")], var.vpc_security_group_ids)) + + timeouts { + create = try(var.cluster_timeouts.create, null) + update = try(var.cluster_timeouts.update, null) + delete = try(var.cluster_timeouts.delete, null) + } + + lifecycle { + ignore_changes = [ + # See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster#replication_source_identifier + # Since this is used either in read-replica clusters or global clusters, this should be acceptable to specify + replication_source_identifier, + # See docs here https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_global_cluster#new-global-cluster-from-existing-db-cluster + global_cluster_identifier, + snapshot_identifier, + ] + } + + # depends_on = [aws_cloudwatch_log_group.this] +} + +################################################################################ +# Cluster Instance(s) +################################################################################ + + +# TODO: remove the map and use count instead as in https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_instance#example-usage +# and here: https://dev.azure.com/dfds/Phoenix/_git/aws-modules-rds?path=/modules/db_cluster/main.tf&_a=contents&version=GBmaster +# resource "aws_rds_cluster_instance" "this" { +# count = local.create && !local.is_serverless ? var.cluster_db_instance_count : 0 + +# apply_immediately = var.apply_immediately +# auto_minor_version_upgrade = var.auto_minor_version_upgrade +# availability_zone = null # var.availability_zone +# ca_cert_identifier = var.ca_cert_identifier +# cluster_identifier = aws_rds_cluster.this[0].id +# copy_tags_to_snapshot = var.copy_tags_to_snapshot +# db_parameter_group_name = var.create_db_parameter_group ? aws_db_parameter_group.this[0].id : var.db_parameter_group_name +# db_subnet_group_name = local.db_subnet_group_name +# engine = var.engine +# engine_version = var.engine_version +# identifier = null #var.name +# identifier_prefix = "${var.name}-${count.index}-" +# instance_class = var.instance_class +# monitoring_interval = var.monitoring_interval +# monitoring_role_arn = var.create_monitoring_role ? aws_iam_role.rds_enhanced_monitoring[0].arn : var.monitoring_role_arn +# performance_insights_enabled = var.performance_insights_enabled +# performance_insights_kms_key_id = var.performance_insights_kms_key_id +# performance_insights_retention_period = var.performance_insights_retention_period +# # preferred_backup_window - is set at the cluster level and will error if provided here +# preferred_maintenance_window = var.preferred_maintenance_window +# promotion_tier = null +# publicly_accessible = var.publicly_accessible +# tags = var.tags + +# timeouts { +# create = null +# update = null +# delete = null +# } +# } +resource "aws_rds_cluster_instance" "this" { + for_each = { for k, v in var.instances : k => v if !local.is_serverless } + + apply_immediately = try(each.value.apply_immediately, var.apply_immediately) + auto_minor_version_upgrade = try(each.value.auto_minor_version_upgrade, var.auto_minor_version_upgrade) + availability_zone = try(each.value.availability_zone, null) + ca_cert_identifier = var.ca_cert_identifier + cluster_identifier = aws_rds_cluster.this.id + copy_tags_to_snapshot = try(each.value.copy_tags_to_snapshot, var.copy_tags_to_snapshot) + db_parameter_group_name = try(each.value.db_parameter_group_name, var.db_parameter_group_name) + db_subnet_group_name = var.db_subnet_group_name + engine = var.engine + engine_version = var.engine_version + identifier = var.instances_use_identifier_prefix ? null : try(each.value.identifier, "${var.name}-${each.key}") + identifier_prefix = var.instances_use_identifier_prefix ? try(each.value.identifier_prefix, "${var.name}-${each.key}-") : null + instance_class = try(each.value.instance_class, var.instance_class) + monitoring_interval = try(each.value.monitoring_interval, var.monitoring_interval) + monitoring_role_arn = var.monitoring_role_arn + performance_insights_enabled = try(each.value.performance_insights_enabled, var.performance_insights_enabled) + performance_insights_kms_key_id = try(each.value.performance_insights_kms_key_id, var.performance_insights_kms_key_id) + performance_insights_retention_period = try(each.value.performance_insights_retention_period, var.performance_insights_retention_period) + # preferred_backup_window - is set at the cluster level and will error if provided here + preferred_maintenance_window = try(each.value.preferred_maintenance_window, var.preferred_maintenance_window) + promotion_tier = try(each.value.promotion_tier, null) + publicly_accessible = try(each.value.publicly_accessible, var.publicly_accessible) + tags = merge(var.tags, try(each.value.tags, {})) + + timeouts { + create = try(var.instance_timeouts.create, null) + update = try(var.instance_timeouts.update, null) + delete = try(var.instance_timeouts.delete, null) + } +} + +################################################################################ +# Cluster Endpoint(s) +################################################################################ + +resource "aws_rds_cluster_endpoint" "this" { + for_each = { for k, v in var.endpoints : k => v if !local.is_serverless } + + cluster_endpoint_identifier = each.value.identifier + cluster_identifier = aws_rds_cluster.this.id + custom_endpoint_type = each.value.type + excluded_members = try(each.value.excluded_members, null) + static_members = try(each.value.static_members, null) + tags = merge(var.tags, try(each.value.tags, {})) + + depends_on = [ + aws_rds_cluster_instance.this + ] +} + +################################################################################ +# Cluster IAM Roles +################################################################################ + +resource "aws_rds_cluster_role_association" "this" { + for_each = { for k, v in var.iam_roles : k => v} + + db_cluster_identifier = aws_rds_cluster.this.id + feature_name = each.value.feature_name + role_arn = each.value.role_arn +} + + +################################################################################ +# Autoscaling +################################################################################ + +resource "aws_appautoscaling_target" "this" { + count = var.autoscaling_enabled && !local.is_serverless ? 1 : 0 + + max_capacity = var.autoscaling_max_capacity + min_capacity = var.autoscaling_min_capacity + resource_id = "cluster:${aws_rds_cluster.this.cluster_identifier}" + scalable_dimension = "rds:cluster:ReadReplicaCount" + service_namespace = "rds" + + tags = var.tags +} + +resource "aws_appautoscaling_policy" "this" { + count = var.autoscaling_enabled && !local.is_serverless ? 1 : 0 + + name = var.autoscaling_policy_name + policy_type = "TargetTrackingScaling" + resource_id = "cluster:${aws_rds_cluster.this.cluster_identifier}" + scalable_dimension = "rds:cluster:ReadReplicaCount" + service_namespace = "rds" + + target_tracking_scaling_policy_configuration { + predefined_metric_specification { + predefined_metric_type = var.predefined_metric_type + } + + scale_in_cooldown = var.autoscaling_scale_in_cooldown + scale_out_cooldown = var.autoscaling_scale_out_cooldown + target_value = var.predefined_metric_type == "RDSReaderAverageCPUUtilization" ? var.autoscaling_target_cpu : var.autoscaling_target_connections + } + + depends_on = [ + aws_appautoscaling_target.this + ] +} + +# ################################################################################ +# # Security Group +# ################################################################################ + +# resource "aws_security_group" "this" { +# count = local.create && var.create_security_group ? 1 : 0 + +# name = var.security_group_use_name_prefix ? null : local.security_group_name +# name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null +# vpc_id = var.vpc_id +# description = coalesce(var.security_group_description, "Control traffic to/from RDS Aurora ${var.name}") + +# tags = merge(var.tags, var.security_group_tags, { Name = local.security_group_name }) + +# lifecycle { +# create_before_destroy = true +# } +# } + +# resource "aws_security_group_rule" "this" { +# for_each = { for k, v in var.security_group_rules : k => v if local.create && var.create_security_group } + +# # required +# type = try(each.value.type, "ingress") +# from_port = try(each.value.from_port, local.port) +# to_port = try(each.value.to_port, local.port) +# protocol = try(each.value.protocol, "tcp") +# security_group_id = aws_security_group.this[0].id + +# # optional +# cidr_blocks = try(each.value.cidr_blocks, null) +# description = try(each.value.description, null) +# ipv6_cidr_blocks = try(each.value.ipv6_cidr_blocks, null) +# prefix_list_ids = try(each.value.prefix_list_ids, null) +# source_security_group_id = try(each.value.source_security_group_id, null) +# } + +################################################################################ +# Cluster Activity Stream +################################################################################ + +resource "aws_rds_cluster_activity_stream" "this" { + count = var.create_db_cluster_activity_stream ? 1 : 0 + + resource_arn = aws_rds_cluster.this.arn + mode = var.db_cluster_activity_stream_mode + kms_key_id = var.db_cluster_activity_stream_kms_key_id + engine_native_audit_fields_included = var.engine_native_audit_fields_included + + depends_on = [aws_rds_cluster_instance.this] +} diff --git a/new_modules/rds-aurora/outputs.tf b/new_modules/rds-aurora/outputs.tf new file mode 100644 index 00000000..8fde54ed --- /dev/null +++ b/new_modules/rds-aurora/outputs.tf @@ -0,0 +1,186 @@ +################################################################################ +# DB Subnet Group +################################################################################ + +# output "db_subnet_group_name" { +# description = "The db subnet group name" +# value = local.db_subnet_group_name +# } + +################################################################################ +# Cluster +################################################################################ + +output "cluster_arn" { + description = "Amazon Resource Name (ARN) of cluster" + value = try(aws_rds_cluster.this.arn, null) +} + +output "cluster_id" { + description = "The RDS Cluster Identifier" + value = try(aws_rds_cluster.this.id, null) +} + +output "cluster_resource_id" { + description = "The RDS Cluster Resource ID" + value = try(aws_rds_cluster.this.cluster_resource_id, null) +} + +output "cluster_members" { + description = "List of RDS Instances that are a part of this cluster" + value = try(aws_rds_cluster.this.cluster_members, null) +} + +output "cluster_endpoint" { + description = "Writer endpoint for the cluster" + value = try(aws_rds_cluster.this.endpoint, null) +} + +output "cluster_reader_endpoint" { + description = "A read-only endpoint for the cluster, automatically load-balanced across replicas" + value = try(aws_rds_cluster.this.reader_endpoint, null) +} + +output "cluster_engine_version_actual" { + description = "The running version of the cluster database" + value = try(aws_rds_cluster.this.engine_version_actual, null) +} + +# database_name is not set on `aws_rds_cluster` resource if it was not specified, so can't be used in output +output "cluster_database_name" { + description = "Name for an automatically created database on cluster creation" + value = var.database_name +} + +output "cluster_port" { + description = "The database port" + value = try(aws_rds_cluster.this.port, null) +} + +output "cluster_master_password" { + description = "The database master password" + value = try(aws_rds_cluster.this.master_password, null) + sensitive = true +} + +output "cluster_master_username" { + description = "The database master username" + value = try(aws_rds_cluster.this.master_username, null) + sensitive = true +} + +output "cluster_master_user_secret" { + description = "The generated database master user secret when `manage_master_user_password` is set to `true`" + value = try(aws_rds_cluster.this.master_user_secret, null) +} + +output "cluster_master_user_secret_arn" { + description = "The ARN of the master user secret (Only available when manage_master_user_password is set to true)" + value = try(aws_rds_cluster.this.master_user_secret[0].secret_arn, null) +} + +output "cluster_hosted_zone_id" { + description = "The Route53 Hosted Zone ID of the endpoint" + value = try(aws_rds_cluster.this.hosted_zone_id, null) +} + +################################################################################ +# Cluster Instance(s) +################################################################################ + +output "cluster_instances" { + description = "A map of cluster instances and their attributes" + value = aws_rds_cluster_instance.this +} + +################################################################################ +# Cluster Endpoint(s) +################################################################################ + +output "additional_cluster_endpoints" { + description = "A map of additional cluster endpoints and their attributes" + value = aws_rds_cluster_endpoint.this +} + +################################################################################ +# Cluster IAM Roles +################################################################################ + +output "cluster_role_associations" { + description = "A map of IAM roles associated with the cluster and their attributes" + value = aws_rds_cluster_role_association.this +} + +# ################################################################################ +# # Enhanced Monitoring +# ################################################################################ + +# output "enhanced_monitoring_iam_role_name" { +# description = "The name of the enhanced monitoring role" +# value = try(aws_iam_role.rds_enhanced_monitoring[0].name, null) +# } + +# output "enhanced_monitoring_iam_role_arn" { +# description = "The Amazon Resource Name (ARN) specifying the enhanced monitoring role" +# value = try(aws_iam_role.rds_enhanced_monitoring[0].arn, null) +# } + +# output "enhanced_monitoring_iam_role_unique_id" { +# description = "Stable and unique string identifying the enhanced monitoring role" +# value = try(aws_iam_role.rds_enhanced_monitoring[0].unique_id, null) +# } + +################################################################################ +# Security Group +################################################################################ + +# output "security_group_id" { +# description = "The security group ID of the cluster" +# value = try(aws_security_group.this[0].id, null) +# } + +# ################################################################################ +# # Cluster Parameter Group +# ################################################################################ + +# output "db_cluster_parameter_group_arn" { +# description = "The ARN of the DB cluster parameter group created" +# value = try(aws_rds_cluster_parameter_group.this[0].arn, null) +# } + +# output "db_cluster_parameter_group_id" { +# description = "The ID of the DB cluster parameter group created" +# value = try(aws_rds_cluster_parameter_group.this[0].id, null) +# } + +# ################################################################################ +# # DB Parameter Group +# ################################################################################ + +# output "db_parameter_group_arn" { +# description = "The ARN of the DB parameter group created" +# value = try(aws_db_parameter_group.this[0].arn, null) +# } + +# output "db_parameter_group_id" { +# description = "The ID of the DB parameter group created" +# value = try(aws_db_parameter_group.this[0].id, null) +# } + +# ################################################################################ +# # CloudWatch Log Group +# ################################################################################ + +# output "db_cluster_cloudwatch_log_groups" { +# description = "Map of CloudWatch log groups created and their attributes" +# value = aws_cloudwatch_log_group.this +# } + +################################################################################ +# Cluster Activity Stream +################################################################################ + +output "db_cluster_activity_stream_kinesis_stream_name" { + description = "The name of the Amazon Kinesis data stream to be used for the database activity stream" + value = try(aws_rds_cluster_activity_stream.this[0].kinesis_stream_name, null) +} \ No newline at end of file diff --git a/new_modules/rds-aurora/variables.tf b/new_modules/rds-aurora/variables.tf new file mode 100644 index 00000000..82e93d94 --- /dev/null +++ b/new_modules/rds-aurora/variables.tf @@ -0,0 +1,712 @@ +# variable "create" { +# description = "Whether cluster should be created (affects nearly all resources)" +# type = bool +# default = true +# } + +variable "name" { # TODO: rename to identifier? + description = "Name used across resources created" + type = string + default = "" +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +# ################################################################################ +# # DB Subnet Group +# ################################################################################ + +# variable "create_db_subnet_group" { +# description = "Determines whether to create the database subnet group or use existing" +# type = bool +# default = false +# } + +variable "db_subnet_group_name" { + description = "The name of the subnet group name (existing or created)" + type = string + # default = "" +} + +# variable "subnets" { +# description = "List of subnet IDs used by database subnet group created" +# type = list(string) +# default = [] +# } + +################################################################################ +# Cluster +################################################################################ + +variable "is_primary_cluster" { + description = "Determines whether cluster is primary cluster with writer instance (set to `false` for global cluster and replica clusters)" + type = bool + default = true +} + +variable "cluster_use_name_prefix" { + description = "Whether to use `name` as a prefix for the cluster" + type = bool + default = false +} + +variable "allocated_storage" { + description = "The amount of storage in gibibytes (GiB) to allocate to each DB instance in the Multi-AZ DB cluster. (This setting is required to create a Multi-AZ DB cluster)" + type = number + default = null +} + +variable "allow_major_version_upgrade" { + description = "Enable to allow major engine version upgrades when changing engine versions. Defaults to `false`" + type = bool + default = false +} + +variable "apply_immediately" { + description = "Specifies whether any cluster modifications are applied immediately, or during the next maintenance window. Default is `false`" + type = bool + default = null +} + +variable "availability_zones" { + description = "List of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created. RDS automatically assigns 3 AZs if less than 3 AZs are configured, which will show as a difference requiring resource recreation next Terraform apply" + type = list(string) + default = null +} + +variable "backup_retention_period" { + description = "The days to retain backups for. Default `7`" + type = number + default = 7 +} + +variable "backtrack_window" { + description = "The target backtrack window, in seconds. Only available for `aurora` engine currently. To disable backtracking, set this value to 0. Must be between 0 and 259200 (72 hours)" + type = number + default = null +} + +variable "cluster_members" { + description = "List of RDS Instances that are a part of this cluster" + type = list(string) + default = null +} + +variable "copy_tags_to_snapshot" { + description = "Copy all Cluster `tags` to snapshots" + type = bool + default = null +} + +variable "database_name" { + description = "Name for an automatically created database on cluster creation" + type = string + default = null +} + +variable "db_cluster_instance_class" { + description = "The compute and memory capacity of each DB instance in the Multi-AZ DB cluster, for example db.m6g.xlarge. Not all DB instance classes are available in all AWS Regions, or for all database engines" + type = string + default = null +} + +variable "db_cluster_db_instance_parameter_group_name" { + description = "Instance parameter group to associate with all instances of the DB cluster. The `db_cluster_db_instance_parameter_group_name` is only valid in combination with `allow_major_version_upgrade`" + type = string + default = null +} + +variable "deletion_protection" { + description = "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`" + type = bool + default = null +} + +variable "enable_global_write_forwarding" { + description = "Whether cluster should forward writes to an associated global cluster. Applied to secondary clusters to enable them to forward writes to an `aws_rds_global_cluster`'s primary cluster" + type = bool + default = null +} + +variable "enabled_cloudwatch_logs_exports" { + description = "Set of log types to export to cloudwatch. If omitted, no logs will be exported. The following log types are supported: `audit`, `error`, `general`, `slowquery`, `postgresql`" + type = list(string) + default = [] +} + +variable "enable_http_endpoint" { + description = "Enable HTTP endpoint (data API). Only valid when engine_mode is set to `serverless`" + type = bool + default = null +} + +variable "engine" { + description = "The name of the database engine to be used for this DB cluster. Defaults to `aurora`. Valid Values: `aurora`, `aurora-mysql`, `aurora-postgresql`" + type = string + default = null +} + +variable "engine_mode" { + description = "The database engine mode. Valid values: `global`, `multimaster`, `parallelquery`, `provisioned`, `serverless`. Defaults to: `provisioned`" + type = string + default = "provisioned" +} + +variable "engine_version" { + description = "The database engine version. Updating this argument results in an outage" + type = string + default = null +} + +variable "final_snapshot_identifier" { + description = "The name of your final DB snapshot when this DB cluster is deleted. If omitted, no final snapshot will be made" + type = string + default = null +} + +variable "global_cluster_identifier" { + description = "The global cluster identifier specified on `aws_rds_global_cluster`" + type = string + default = null +} + +variable "iam_database_authentication_enabled" { + description = "Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled" + type = bool + default = null +} + +variable "iops" { + description = "The amount of Provisioned IOPS (input/output operations per second) to be initially allocated for each DB instance in the Multi-AZ DB cluster" + type = number + default = null +} + +variable "kms_key_id" { + description = "The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to `true`" + type = string + default = null +} + +variable "manage_master_user_password" { + description = "Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if `master_password` is provided" + type = bool + default = true +} + +variable "master_user_secret_kms_key_id" { + description = "The Amazon Web Services KMS key identifier is the key ARN, key ID, alias ARN, or alias name for the KMS key" + type = string + default = null +} + +variable "master_password" { + description = "Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file. Required unless `manage_master_user_password` is set to `true` or unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database" + type = string + default = null +} + +variable "master_username" { + description = "Username for the master DB user. Required unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database" + type = string + default = null +} + +variable "network_type" { + description = "The type of network stack to use (IPV4 or DUAL)" + type = string + default = null +} + +variable "port" { + description = "The port on which the DB accepts connections" + type = string + default = null +} + +variable "preferred_backup_window" { + description = "The daily time range during which automated backups are created if automated backups are enabled using the `backup_retention_period` parameter. Time in UTC" + type = string + default = "02:00-03:00" +} + +variable "preferred_maintenance_window" { + description = "The weekly time range during which system maintenance can occur, in (UTC)" + type = string + default = "sun:05:00-sun:06:00" +} + +variable "replication_source_identifier" { + description = "ARN of a source DB cluster or DB instance if this DB cluster is to be created as a Read Replica" + type = string + default = null +} + +variable "restore_to_point_in_time" { + description = "Map of nested attributes for cloning Aurora cluster" + type = map(string) + default = {} +} + +variable "s3_import" { + description = "Configuration map used to restore from a Percona Xtrabackup in S3 (only MySQL is supported)" + type = map(string) + default = {} +} + +variable "scaling_configuration" { + description = "Map of nested attributes with scaling properties. Only valid when `engine_mode` is set to `serverless`" + type = map(string) + default = {} +} + +variable "serverlessv2_scaling_configuration" { + description = "Map of nested attributes with serverless v2 scaling properties. Only valid when `engine_mode` is set to `provisioned`" + type = map(string) + default = {} +} + +variable "skip_final_snapshot" { + description = "Determines whether a final snapshot is created before the cluster is deleted. If true is specified, no snapshot is created" + type = bool + default = false +} + +variable "snapshot_identifier" { + description = "Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot" + type = string + default = null +} + +variable "source_region" { + description = "The source region for an encrypted replica DB cluster" + type = string + default = null +} + +variable "storage_encrypted" { + description = "Specifies whether the DB cluster is encrypted. The default is `true`" + type = bool + default = true +} + +variable "storage_type" { + description = "Determines the storage type for the DB cluster. Optional for Single-AZ, required for Multi-AZ DB clusters. Valid values for Single-AZ: `aurora`, `\"\"` (default, both refer to Aurora Standard), `aurora-iopt1` (Aurora I/O Optimized). Valid values for Multi-AZ: `io1` (default)." + type = string + default = null +} + +variable "cluster_tags" { + description = "A map of tags to add to only the cluster. Used for AWS Instance Scheduler tagging" + type = map(string) + default = {} +} + +variable "vpc_security_group_ids" { + description = "List of VPC security groups to associate to the cluster in addition to the security group created" + type = list(string) + default = [] +} + +variable "cluster_timeouts" { + description = "Create, update, and delete timeout configurations for the cluster" + type = map(string) + default = {} +} + +################################################################################ +# Cluster Instance(s) +################################################################################ + +variable "instances" { + description = "Map of cluster instances and any specific/overriding attributes to be created" + type = any + default = {} +} + +variable "cluster_db_instance_count" { + type = number + default = 0 +} + +variable "auto_minor_version_upgrade" { + description = "Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. Default `true`" + type = bool + default = null +} + +variable "ca_cert_identifier" { + description = "The identifier of the CA certificate for the DB instance" + type = string + default = null +} + +variable "db_parameter_group_name" { + description = "The name of the DB parameter group" + type = string + default = null +} + +variable "instances_use_identifier_prefix" { + description = "Determines whether cluster instance identifiers are used as prefixes" + type = bool + default = false +} + +variable "instance_class" { + description = "Instance type to use at master instance. Note: if `autoscaling_enabled` is `true`, this will be the same instance class used on instances created by autoscaling" + type = string + default = "" +} + +variable "monitoring_interval" { + description = "The interval, in seconds, between points when Enhanced Monitoring metrics are collected for instances. Set to `0` to disable. Default is `0`" + type = number + default = 0 +} + +variable "performance_insights_enabled" { + description = "Specifies whether Performance Insights is enabled or not" + type = bool + default = null +} + +variable "performance_insights_kms_key_id" { + description = "The ARN for the KMS key to encrypt Performance Insights data" + type = string + default = null +} + +variable "performance_insights_retention_period" { + description = "Amount of time in days to retain Performance Insights data. Either 7 (7 days) or 731 (2 years)" + type = number + default = null +} + +variable "publicly_accessible" { + description = "Determines whether instances are publicly accessible. Default `false`" + type = bool + default = null +} + +variable "instance_timeouts" { + description = "Create, update, and delete timeout configurations for the cluster instance(s)" + type = map(string) + default = {} +} + +################################################################################ +# Cluster Endpoint(s) +################################################################################ + +variable "endpoints" { + description = "Map of additional cluster endpoints and their attributes to be created" + type = any + default = {} +} + +################################################################################ +# Cluster IAM Roles +################################################################################ + +variable "iam_roles" { + description = "Map of IAM roles and supported feature names to associate with the cluster" + type = map(map(string)) + default = {} +} + +################################################################################ +# Enhanced Monitoring +################################################################################ + +# variable "create_monitoring_role" { +# description = "Determines whether to create the IAM role for RDS enhanced monitoring" +# type = bool +# default = true +# } + +variable "monitoring_role_arn" { + description = "IAM role used by RDS to send enhanced monitoring metrics to CloudWatch" + type = string + default = "" +} + +# variable "iam_role_name" { +# description = "Friendly name of the monitoring role" +# type = string +# default = null +# } + +# variable "iam_role_use_name_prefix" { +# description = "Determines whether to use `iam_role_name` as is or create a unique name beginning with the `iam_role_name` as the prefix" +# type = bool +# default = false +# } + +# variable "iam_role_description" { +# description = "Description of the monitoring role" +# type = string +# default = null +# } + +# variable "iam_role_path" { +# description = "Path for the monitoring role" +# type = string +# default = null +# } + +# variable "iam_role_managed_policy_arns" { +# description = "Set of exclusive IAM managed policy ARNs to attach to the monitoring role" +# type = list(string) +# default = null +# } + +# variable "iam_role_permissions_boundary" { +# description = "The ARN of the policy that is used to set the permissions boundary for the monitoring role" +# type = string +# default = null +# } + +# variable "iam_role_force_detach_policies" { +# description = "Whether to force detaching any policies the monitoring role has before destroying it" +# type = bool +# default = null +# } + +# variable "iam_role_max_session_duration" { +# description = "Maximum session duration (in seconds) that you want to set for the monitoring role" +# type = number +# default = null +# } + +################################################################################ +# Autoscaling +################################################################################ + +variable "autoscaling_enabled" { + description = "Determines whether autoscaling of the cluster read replicas is enabled" + type = bool + default = false +} + +variable "autoscaling_max_capacity" { + description = "Maximum number of read replicas permitted when autoscaling is enabled" + type = number + default = 2 +} + +variable "autoscaling_min_capacity" { + description = "Minimum number of read replicas permitted when autoscaling is enabled" + type = number + default = 0 +} + +variable "autoscaling_policy_name" { + description = "Autoscaling policy name" + type = string + default = "target-metric" +} + +variable "predefined_metric_type" { + description = "The metric type to scale on. Valid values are `RDSReaderAverageCPUUtilization` and `RDSReaderAverageDatabaseConnections`" + type = string + default = "RDSReaderAverageCPUUtilization" +} + +variable "autoscaling_scale_in_cooldown" { + description = "Cooldown in seconds before allowing further scaling operations after a scale in" + type = number + default = 300 +} + +variable "autoscaling_scale_out_cooldown" { + description = "Cooldown in seconds before allowing further scaling operations after a scale out" + type = number + default = 300 +} + +variable "autoscaling_target_cpu" { + description = "CPU threshold which will initiate autoscaling" + type = number + default = 70 +} + +variable "autoscaling_target_connections" { + description = "Average number of connections threshold which will initiate autoscaling. Default value is 70% of db.r4/r5/r6g.large's default max_connections" + type = number + default = 700 +} + +################################################################################ +# Security Group +################################################################################ + +variable "create_security_group" { + description = "Determines whether to create security group for RDS cluster" + type = bool + default = true +} + +variable "security_group_name" { + description = "The security group name. Default value is (`var.name`)" + type = string + default = "" +} + +variable "security_group_use_name_prefix" { + description = "Determines whether the security group name (`var.name`) is used as a prefix" + type = bool + default = true +} + +variable "security_group_description" { + description = "The description of the security group. If value is set to empty string it will contain cluster name in the description" + type = string + default = null +} + +# variable "vpc_id" { +# description = "ID of the VPC where to create security group" +# type = string +# default = "" +# } + +variable "security_group_rules" { + description = "Map of security group rules to add to the cluster security group created" + type = any + default = {} +} + +variable "security_group_tags" { + description = "Additional tags for the security group" + type = map(string) + default = {} +} + +# ################################################################################ +# # Cluster Parameter Group +# ################################################################################ + +# variable "create_db_cluster_parameter_group" { +# description = "Determines whether a cluster parameter should be created or use existing" +# type = bool +# default = false +# } + +variable "db_cluster_parameter_group_name" { + description = "The name of the DB cluster parameter group" + type = string + default = null +} + +# variable "db_cluster_parameter_group_use_name_prefix" { +# description = "Determines whether the DB cluster parameter group name is used as a prefix" +# type = bool +# default = false +# } + +# variable "db_cluster_parameter_group_description" { +# description = "The description of the DB cluster parameter group. Defaults to \"Managed by Terraform\"" +# type = string +# default = null +# } + +# variable "db_cluster_parameter_group_family" { +# description = "The family of the DB cluster parameter group" +# type = string +# default = "" +# } + +# variable "db_cluster_parameter_group_parameters" { +# description = "A list of DB cluster parameters to apply. Note that parameters may differ from a family to an other" +# type = list(map(string)) +# default = [] +# } + +################################################################################ +# DB Parameter Group +################################################################################ + +# variable "create_db_parameter_group" { +# description = "Determines whether a DB parameter should be created or use existing" +# type = bool +# default = false +# } + +# variable "db_parameter_group_use_name_prefix" { +# description = "Determines whether the DB parameter group name is used as a prefix" +# type = bool +# default = true +# } + +# variable "db_parameter_group_description" { +# description = "The description of the DB parameter group. Defaults to \"Managed by Terraform\"" +# type = string +# default = null +# } + +# variable "db_parameter_group_family" { +# description = "The family of the DB parameter group" +# type = string +# default = "" +# } + +# variable "db_parameter_group_parameters" { +# description = "A list of DB parameters to apply. Note that parameters may differ from a family to an other" +# type = list(map(string)) +# default = [] +# } + +# ################################################################################ +# # CloudWatch Log Group +# ################################################################################ + +# variable "create_cloudwatch_log_group" { +# description = "Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports`" +# type = bool +# default = false +# } + +# variable "cloudwatch_log_group_retention_in_days" { +# description = "The number of days to retain CloudWatch logs for the DB instance" +# type = number +# default = 7 +# } + +# variable "cloudwatch_log_group_kms_key_id" { +# description = "The ARN of the KMS Key to use when encrypting log data" +# type = string +# default = null +# } + +################################################################################ +# Cluster Activity Stream +################################################################################ + +variable "create_db_cluster_activity_stream" { + description = "Determines whether a cluster activity stream is created." + type = bool + default = false +} + +variable "db_cluster_activity_stream_mode" { + description = "Specifies the mode of the database activity stream. Database events such as a change or access generate an activity stream event. One of: sync, async" + type = string + default = null +} + +variable "db_cluster_activity_stream_kms_key_id" { + description = "The AWS KMS key identifier for encrypting messages in the database activity stream" + type = string + default = null +} + +variable "engine_native_audit_fields_included" { + description = "Specifies whether the database activity stream includes engine-native audit fields. This option only applies to an Oracle DB instance. By default, no engine-native audit fields are included" + type = bool + default = false +} diff --git a/new_modules/rds-aurora/versions.tf b/new_modules/rds-aurora/versions.tf new file mode 100644 index 00000000..47125bf8 --- /dev/null +++ b/new_modules/rds-aurora/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.67" + } + } +} diff --git a/new_modules/rds-proxy/README.md b/new_modules/rds-proxy/README.md new file mode 100644 index 00000000..4fcd4d5e --- /dev/null +++ b/new_modules/rds-proxy/README.md @@ -0,0 +1,165 @@ +# AWS RDS Proxy Terraform module + +Terraform module which creates an AWS RDS Proxy and its supporting resources. + +## Usage + +See [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) directory for working examples to reference: + +```hcl +module "rds_proxy" { + source = "terraform-aws-modules/rds-proxy/aws" + + name = "rds-proxy" + iam_role_name = "rds-proxy-role" + vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] + vpc_security_group_ids = ["sg-f1d03a88"] + + endpoints = { + read_write = { + name = "read-write-endpoint" + vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] + vpc_security_group_ids = ["sg-f1d03a88"] + }, + read_only = { + name = "read-only-endpoint" + vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] + vpc_security_group_ids = ["sg-f1d03a88"] + target_role = "READ_ONLY" + } + } + + auth = { + "superuser" = { + description = "Aurora PostgreSQL superuser password" + secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD" + } + } + + # Target Aurora cluster + engine_family = "POSTGRESQL" + target_db_cluster = true + db_cluster_identifier = "my-endpoint" + + tags = { + Terraform = "true" + Environment = "dev" + } +} +``` + +## Examples + +Examples codified under the [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module(s). If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you! + +- [IAM auth. w/ MySQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-cluster) +- [IAM auth. w/ MySQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-instance) +- [IAM auth. w/ PostgreSQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-cluster) +- [IAM auth. w/ PostgreSQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-instance) + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_db_proxy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy) | resource | +| [aws_db_proxy_default_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_default_target_group) | resource | +| [aws_db_proxy_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_endpoint) | resource | +| [aws_db_proxy_target.db_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | +| [aws_db_proxy_target.db_instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | +| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | +| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [auth](#input\_auth) | Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters | `any` | `{}` | no | +| [connection\_borrow\_timeout](#input\_connection\_borrow\_timeout) | The number of seconds for a proxy to wait for a connection to become available in the connection pool | `number` | `null` | no | +| [create](#input\_create) | Whether cluster should be created (affects nearly all resources) | `bool` | `true` | no | +| [create\_iam\_policy](#input\_create\_iam\_policy) | Determines whether an IAM policy is created | `bool` | `true` | no | +| [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created | `bool` | `true` | no | +| [db\_cluster\_identifier](#input\_db\_cluster\_identifier) | DB cluster identifier | `string` | `""` | no | +| [db\_instance\_identifier](#input\_db\_instance\_identifier) | DB instance identifier | `string` | `""` | no | +| [debug\_logging](#input\_debug\_logging) | Whether the proxy includes detailed information about SQL statements in its logs | `bool` | `false` | no | +| [endpoints](#input\_endpoints) | Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`) | `any` | `{}` | no | +| [engine\_family](#input\_engine\_family) | The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL` | `string` | `""` | no | +| [iam\_policy\_name](#input\_iam\_policy\_name) | The name of the role policy. If omitted, Terraform will assign a random, unique name | `string` | `""` | no | +| [iam\_role\_description](#input\_iam\_role\_description) | The description of the role | `string` | `""` | no | +| [iam\_role\_force\_detach\_policies](#input\_iam\_role\_force\_detach\_policies) | Specifies to force detaching any policies the role has before destroying it | `bool` | `true` | no | +| [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | The maximum session duration (in seconds) that you want to set for the specified role | `number` | `43200` | no | +| [iam\_role\_name](#input\_iam\_role\_name) | The name of the role. If omitted, Terraform will assign a random, unique name | `string` | `""` | no | +| [iam\_role\_path](#input\_iam\_role\_path) | The path to the role | `string` | `null` | no | +| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the policy that is used to set the permissions boundary for the role | `string` | `null` | no | +| [iam\_role\_tags](#input\_iam\_role\_tags) | A map of tags to apply to the IAM role | `map(string)` | `{}` | no | +| [idle\_client\_timeout](#input\_idle\_client\_timeout) | The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it | `number` | `1800` | no | +| [init\_query](#input\_init\_query) | One or more SQL statements for the proxy to run when opening each new database connection | `string` | `""` | no | +| [kms\_key\_arns](#input\_kms\_key\_arns) | List of KMS Key ARNs to allow access to decrypt SecretsManager secrets | `list(string)` | `[]` | no | +| [log\_group\_kms\_key\_id](#input\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | +| [log\_group\_retention\_in\_days](#input\_log\_group\_retention\_in\_days) | Specifies the number of days you want to retain log events in the log group | `number` | `30` | no | +| [log\_group\_tags](#input\_log\_group\_tags) | A map of tags to apply to the CloudWatch log group | `map(string)` | `{}` | no | +| [manage\_log\_group](#input\_manage\_log\_group) | Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist | `bool` | `true` | no | +| [max\_connections\_percent](#input\_max\_connections\_percent) | The maximum size of the connection pool for each target in a target group | `number` | `90` | no | +| [max\_idle\_connections\_percent](#input\_max\_idle\_connections\_percent) | Controls how actively the proxy closes idle database connections in the connection pool | `number` | `50` | no | +| [name](#input\_name) | The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens | `string` | `""` | no | +| [proxy\_tags](#input\_proxy\_tags) | A map of tags to apply to the RDS Proxy | `map(string)` | `{}` | no | +| [require\_tls](#input\_require\_tls) | A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy | `bool` | `true` | no | +| [role\_arn](#input\_role\_arn) | The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager | `string` | `""` | no | +| [session\_pinning\_filters](#input\_session\_pinning\_filters) | Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection | `list(string)` | `[]` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [target\_db\_cluster](#input\_target\_db\_cluster) | Determines whether DB cluster is targeted by proxy | `bool` | `false` | no | +| [target\_db\_instance](#input\_target\_db\_instance) | Determines whether DB instance is targeted by proxy | `bool` | `false` | no | +| [use\_policy\_name\_prefix](#input\_use\_policy\_name\_prefix) | Whether to use unique name beginning with the specified `iam_policy_name` | `bool` | `false` | no | +| [use\_role\_name\_prefix](#input\_use\_role\_name\_prefix) | Whether to use unique name beginning with the specified `iam_role_name` | `bool` | `false` | no | +| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | One or more VPC security group IDs to associate with the new proxy | `list(string)` | `[]` | no | +| [vpc\_subnet\_ids](#input\_vpc\_subnet\_ids) | One or more VPC subnet IDs to associate with the new proxy | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created | +| [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager. | +| [iam\_role\_name](#output\_iam\_role\_name) | IAM role name | +| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group | +| [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy | +| [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group | +| [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group | +| [proxy\_default\_target\_group\_name](#output\_proxy\_default\_target\_group\_name) | The name of the default target group | +| [proxy\_endpoint](#output\_proxy\_endpoint) | The endpoint that you can use to connect to the proxy | +| [proxy\_id](#output\_proxy\_id) | The ID for the proxy | +| [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | +| [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) | +| [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB Instance or Aurora DB Cluster | +| [proxy\_target\_rds\_resource\_id](#output\_proxy\_target\_rds\_resource\_id) | Identifier representing the DB Instance or DB Cluster target | +| [proxy\_target\_target\_arn](#output\_proxy\_target\_target\_arn) | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API | +| [proxy\_target\_tracked\_cluster\_id](#output\_proxy\_target\_tracked\_cluster\_id) | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster | +| [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` | + + +## License + +Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE). diff --git a/new_modules/rds-proxy/main.tf b/new_modules/rds-proxy/main.tf new file mode 100644 index 00000000..e8a8efc6 --- /dev/null +++ b/new_modules/rds-proxy/main.tf @@ -0,0 +1,188 @@ +locals { + role_arn = var.create && var.create_iam_role ? aws_iam_role.this[0].arn : var.role_arn + role_name = coalesce(var.iam_role_name, var.name) + policy_name = coalesce(var.iam_policy_name, var.name) +} + +data "aws_region" "current" {} +data "aws_partition" "current" {} + +################################################################################ +# RDS Proxy +################################################################################ + +resource "aws_db_proxy" "this" { + count = var.create ? 1 : 0 + + dynamic "auth" { + for_each = var.auth + + content { + auth_scheme = try(auth.value.auth_scheme, "SECRETS") + client_password_auth_type = try(auth.value.client_password_auth_type, null) + description = try(auth.value.description, null) + iam_auth = try(auth.value.iam_auth, null) + secret_arn = try(auth.value.secret_arn, null) + username = try(auth.value.username, null) + } + } + + debug_logging = var.debug_logging + engine_family = var.engine_family + idle_client_timeout = var.idle_client_timeout + name = var.name + require_tls = var.require_tls + role_arn = local.role_arn + vpc_security_group_ids = var.vpc_security_group_ids + vpc_subnet_ids = var.vpc_subnet_ids + + tags = merge(var.tags, var.proxy_tags) + + depends_on = [aws_cloudwatch_log_group.this] +} + +resource "aws_db_proxy_default_target_group" "this" { + count = var.create ? 1 : 0 + + db_proxy_name = aws_db_proxy.this[0].name + + connection_pool_config { + connection_borrow_timeout = var.connection_borrow_timeout + init_query = var.init_query + max_connections_percent = var.max_connections_percent + max_idle_connections_percent = var.max_idle_connections_percent + session_pinning_filters = var.session_pinning_filters + } +} + +resource "aws_db_proxy_target" "db_instance" { + count = var.create && var.target_db_instance ? 1 : 0 + + db_proxy_name = aws_db_proxy.this[0].name + target_group_name = aws_db_proxy_default_target_group.this[0].name + db_instance_identifier = var.db_instance_identifier +} + +resource "aws_db_proxy_target" "db_cluster" { + count = var.create && var.target_db_cluster ? 1 : 0 + + db_proxy_name = aws_db_proxy.this[0].name + target_group_name = aws_db_proxy_default_target_group.this[0].name + db_cluster_identifier = var.db_cluster_identifier +} + +resource "aws_db_proxy_endpoint" "this" { + for_each = { for k, v in var.endpoints : k => v if var.create } + + db_proxy_name = aws_db_proxy.this[0].name + db_proxy_endpoint_name = each.value.name + vpc_subnet_ids = each.value.vpc_subnet_ids + vpc_security_group_ids = lookup(each.value, "vpc_security_group_ids", null) + target_role = lookup(each.value, "target_role", null) + + tags = lookup(each.value, "tags", var.tags) +} + +################################################################################ +# CloudWatch Logs +################################################################################ + +resource "aws_cloudwatch_log_group" "this" { + count = var.create && var.manage_log_group ? 1 : 0 + + name = "/aws/rds/proxy/${var.name}" + retention_in_days = var.log_group_retention_in_days + kms_key_id = var.log_group_kms_key_id + + tags = merge(var.tags, var.log_group_tags) + skip_destroy = var.cloudwatch_log_group_skip_destroy_on_deletion +} + +################################################################################ +# IAM Role +################################################################################ + +data "aws_iam_policy_document" "assume_role" { + count = var.create && var.create_iam_role ? 1 : 0 + + statement { + sid = "RDSAssume" + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["rds.${data.aws_partition.current.dns_suffix}"] + } + } +} + +resource "aws_iam_role" "this" { + count = var.create && var.create_iam_role ? 1 : 0 + + name = var.use_role_name_prefix ? null : local.role_name + name_prefix = var.use_role_name_prefix ? "${local.role_name}-" : null + description = var.iam_role_description + path = var.iam_role_path + + assume_role_policy = data.aws_iam_policy_document.assume_role[0].json + force_detach_policies = var.iam_role_force_detach_policies + max_session_duration = var.iam_role_max_session_duration + permissions_boundary = var.iam_role_permissions_boundary + + tags = merge(var.tags, var.iam_role_tags) +} + +data "aws_iam_policy_document" "this" { + count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 + + statement { + sid = "DecryptSecrets" + effect = "Allow" + actions = ["kms:Decrypt"] + resources = coalescelist( + var.kms_key_arns, + ["arn:${data.aws_partition.current.partition}:kms:*:*:key/*"] + ) + + condition { + test = "StringEquals" + variable = "kms:ViaService" + values = [ + "secretsmanager.${data.aws_region.current.name}.${data.aws_partition.current.dns_suffix}" + ] + } + } + + statement { + sid = "ListSecrets" + effect = "Allow" + actions = [ + "secretsmanager:GetRandomPassword", + "secretsmanager:ListSecrets", + ] + resources = ["*"] + } + + statement { + sid = "GetSecrets" + effect = "Allow" + actions = [ + "secretsmanager:GetResourcePolicy", + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret", + "secretsmanager:ListSecretVersionIds", + ] + + resources = distinct([for auth in var.auth : auth.secret_arn]) + } +} + +resource "aws_iam_role_policy" "this" { + count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 + + name = var.use_policy_name_prefix ? null : local.policy_name + name_prefix = var.use_policy_name_prefix ? "${local.policy_name}-" : null + policy = data.aws_iam_policy_document.this[0].json + role = aws_iam_role.this[0].id +} diff --git a/new_modules/rds-proxy/outputs.tf b/new_modules/rds-proxy/outputs.tf new file mode 100644 index 00000000..355b2b43 --- /dev/null +++ b/new_modules/rds-proxy/outputs.tf @@ -0,0 +1,95 @@ +# RDS Proxy +output "proxy_id" { + description = "The ID for the proxy" + value = try(aws_db_proxy.this[0].id, null) +} + +output "proxy_arn" { + description = "The Amazon Resource Name (ARN) for the proxy" + value = try(aws_db_proxy.this[0].arn, null) +} + +output "proxy_endpoint" { + description = "The endpoint that you can use to connect to the proxy" + value = try(aws_db_proxy.this[0].endpoint, null) +} + +# Proxy Default Target Group +output "proxy_default_target_group_id" { + description = "The ID for the default target group" + value = try(aws_db_proxy_default_target_group.this[0].id, null) +} + +output "proxy_default_target_group_arn" { + description = "The Amazon Resource Name (ARN) for the default target group" + value = try(aws_db_proxy_default_target_group.this[0].arn, null) +} + +output "proxy_default_target_group_name" { + description = "The name of the default target group" + value = try(aws_db_proxy_default_target_group.this[0].name, null) +} + +# Proxy Target +output "proxy_target_endpoint" { + description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type" + value = try(aws_db_proxy_target.db_instance[0].endpoint, aws_db_proxy_target.db_cluster[0].endpoint, null) +} + +output "proxy_target_id" { + description = "Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/)" + value = try(aws_db_proxy_target.db_instance[0].id, aws_db_proxy_target.db_cluster[0].id, null) +} + +output "proxy_target_port" { + description = "Port for the target RDS DB Instance or Aurora DB Cluster" + value = try(aws_db_proxy_target.db_instance[0].port, aws_db_proxy_target.db_cluster[0].port, null) +} + +output "proxy_target_rds_resource_id" { + description = "Identifier representing the DB Instance or DB Cluster target" + value = try(aws_db_proxy_target.db_instance[0].rds_resource_id, aws_db_proxy_target.db_cluster[0].rds_resource_id, null) +} + +output "proxy_target_target_arn" { + description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API" + value = try(aws_db_proxy_target.db_instance[0].target_arn, aws_db_proxy_target.db_cluster[0].target_arn, null) +} + +output "proxy_target_tracked_cluster_id" { + description = "DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS_INSTANCE target that is part of a DB Cluster" + value = try(aws_db_proxy_target.db_cluster[0].tracked_cluster_id, null) +} + +output "proxy_target_type" { + description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`" + value = try(aws_db_proxy_target.db_instance[0].type, aws_db_proxy_target.db_cluster[0].type, null) +} + +# DB proxy endpoints +output "db_proxy_endpoints" { + description = "Array containing the full resource object and attributes for all DB proxy endpoints created" + value = aws_db_proxy_endpoint.this +} + +# CloudWatch logs +output "log_group_arn" { + description = "The Amazon Resource Name (ARN) of the CloudWatch log group" + value = try(aws_cloudwatch_log_group.this[0].arn, null) +} + +# IAM role +output "iam_role_arn" { + description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager." + value = try(aws_iam_role.this[0].arn, null) +} + +output "iam_role_name" { + description = "IAM role name" + value = try(aws_iam_role.this[0].name, null) +} + +output "iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = try(aws_iam_role.this[0].unique_id, null) +} diff --git a/new_modules/rds-proxy/variables.tf b/new_modules/rds-proxy/variables.tf new file mode 100644 index 00000000..dd4f24e2 --- /dev/null +++ b/new_modules/rds-proxy/variables.tf @@ -0,0 +1,255 @@ +variable "create" { + description = "Whether cluster should be created (affects nearly all resources)" + type = bool + default = true +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = {} +} + +################################################################################ +# RDS Proxy +################################################################################ + +variable "name" { + description = "The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens" + type = string + default = "" +} + +variable "auth" { + description = "Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters" + type = any + default = {} +} + +variable "debug_logging" { + description = "Whether the proxy includes detailed information about SQL statements in its logs" + type = bool + default = false +} + +variable "engine_family" { + description = "The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL`" + type = string + default = "" +} + +variable "idle_client_timeout" { + description = "The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it" + type = number + default = 1800 +} + +variable "require_tls" { + description = "A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy" + type = bool + default = true +} + +variable "role_arn" { + description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager" + type = string + default = "" +} + +variable "vpc_security_group_ids" { + description = "One or more VPC security group IDs to associate with the new proxy" + type = list(string) + default = [] +} + +variable "vpc_subnet_ids" { + description = "One or more VPC subnet IDs to associate with the new proxy" + type = list(string) + default = [] +} + +variable "proxy_tags" { + description = "A map of tags to apply to the RDS Proxy" + type = map(string) + default = {} +} + +# Proxy Default Target Group +variable "connection_borrow_timeout" { + description = "The number of seconds for a proxy to wait for a connection to become available in the connection pool" + type = number + default = null +} + +variable "init_query" { + description = "One or more SQL statements for the proxy to run when opening each new database connection" + type = string + default = "" +} + +variable "max_connections_percent" { + description = "The maximum size of the connection pool for each target in a target group" + type = number + default = 90 +} + +variable "max_idle_connections_percent" { + description = "Controls how actively the proxy closes idle database connections in the connection pool" + type = number + default = 50 +} + +variable "session_pinning_filters" { + description = "Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection" + type = list(string) + default = [] +} + +# Proxy Target +variable "target_db_instance" { + description = "Determines whether DB instance is targeted by proxy" + type = bool + default = false +} + +variable "db_instance_identifier" { + description = "DB instance identifier" + type = string + default = "" +} + +variable "target_db_cluster" { + description = "Determines whether DB cluster is targeted by proxy" + type = bool + default = false +} + +variable "db_cluster_identifier" { + description = "DB cluster identifier" + type = string + default = "" +} + +# Proxy endpoints +variable "endpoints" { + description = "Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`)" + type = any + default = {} +} + +################################################################################ +# CloudWatch Logs +################################################################################ + +variable "manage_log_group" { + description = "Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist" + type = bool + default = true +} + +variable "log_group_retention_in_days" { + description = "Specifies the number of days you want to retain log events in the log group" + type = number + default = 30 +} + +variable "log_group_kms_key_id" { + description = "The ARN of the KMS Key to use when encrypting log data" + type = string + default = null +} + +variable "log_group_tags" { + description = "A map of tags to apply to the CloudWatch log group" + type = map(string) + default = {} +} + +variable "cloudwatch_log_group_skip_destroy_on_deletion" { + description = "value to skip destroy ClouwWatch log group on deletion" + type = bool + default = false +} + +################################################################################ +# IAM Role +################################################################################ + +variable "create_iam_role" { + description = "Determines whether an IAM role is created" + type = bool + default = true +} + +variable "iam_role_name" { + description = "The name of the role. If omitted, Terraform will assign a random, unique name" + type = string + default = "" +} + +variable "use_role_name_prefix" { + description = "Whether to use unique name beginning with the specified `iam_role_name`" + type = bool + default = false +} + +variable "iam_role_description" { + description = "The description of the role" + type = string + default = "" +} + +variable "iam_role_path" { + description = "The path to the role" + type = string + default = null +} + +variable "iam_role_force_detach_policies" { + description = "Specifies to force detaching any policies the role has before destroying it" + type = bool + default = true +} + +variable "iam_role_max_session_duration" { + description = "The maximum session duration (in seconds) that you want to set for the specified role" + type = number + default = 43200 # 12 hours +} + +variable "iam_role_permissions_boundary" { + description = "The ARN of the policy that is used to set the permissions boundary for the role" + type = string + default = null +} + +variable "iam_role_tags" { + description = "A map of tags to apply to the IAM role" + type = map(string) + default = {} +} + +# IAM Policy +variable "create_iam_policy" { + description = "Determines whether an IAM policy is created" + type = bool + default = true +} + +variable "iam_policy_name" { + description = "The name of the role policy. If omitted, Terraform will assign a random, unique name" + type = string + default = "" +} + +variable "use_policy_name_prefix" { + description = "Whether to use unique name beginning with the specified `iam_policy_name`" + type = bool + default = false +} + +variable "kms_key_arns" { + description = "List of KMS Key ARNs to allow access to decrypt SecretsManager secrets" + type = list(string) + default = [] +} diff --git a/new_modules/rds-proxy/versions.tf b/new_modules/rds-proxy/versions.tf new file mode 100644 index 00000000..ddfcb0e0 --- /dev/null +++ b/new_modules/rds-proxy/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} diff --git a/variables.tf b/variables.tf index d1ddc1c1..8ecad139 100644 --- a/variables.tf +++ b/variables.tf @@ -100,7 +100,7 @@ variable "engine_version" { description = "The engine version to use" type = string # default = null - default = "14" + default = "14.9" } variable "skip_final_snapshot" { @@ -345,25 +345,26 @@ variable "db_subnet_group_tags" { } # DB subnet group -variable "create_db_subnet_group" { - description = "Whether to create a database subnet group" - type = bool - default = false +# variable "create_db_subnet_group" { +# description = "Whether to create a database subnet group" +# type = bool +# default = false -} +# } variable "db_subnet_group_name" { description = "Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC" type = string -# default = null # required # it can be null + default = null # required # it can be null ? } +# TODO: Remove variable "db_subnet_group_use_name_prefix" { description = "Determines whether to use `subnet_group_name` as is or create a unique name beginning with the `subnet_group_name` as the prefix" type = bool - default = true + default = false } - +# TODO: Remove variable "db_subnet_group_description" { description = "Description of the DB subnet group to create" type = string @@ -401,7 +402,13 @@ variable "parameter_group_description" { default = null } -variable "family" { +variable "parameter_group_family" { + description = "The family of the DB parameter group" + type = string + default = null # varies depending on engine and version and instance type +} + +variable "family" { # TODO: Remove description = "The family of the DB parameter group" type = string default = null # varies depending on engine and version and instance type From 587346662e1bed2aa1bbc4c26dc27fc7a602918c Mon Sep 17 00:00:00 2001 From: samidbb Date: Fri, 3 Nov 2023 08:24:09 +0100 Subject: [PATCH 05/12] wip --- new_modules/cluster_parameter_group/versions.tf | 5 ----- new_modules/db_cloudwatch_log_groups/versions.tf | 5 ----- 2 files changed, 10 deletions(-) diff --git a/new_modules/cluster_parameter_group/versions.tf b/new_modules/cluster_parameter_group/versions.tf index 8f85fe99..ddfcb0e0 100644 --- a/new_modules/cluster_parameter_group/versions.tf +++ b/new_modules/cluster_parameter_group/versions.tf @@ -6,10 +6,5 @@ terraform { source = "hashicorp/aws" version = ">= 5.0" } - - random = { - source = "hashicorp/random" - version = ">= 3.1" - } } } diff --git a/new_modules/db_cloudwatch_log_groups/versions.tf b/new_modules/db_cloudwatch_log_groups/versions.tf index 8f85fe99..ddfcb0e0 100644 --- a/new_modules/db_cloudwatch_log_groups/versions.tf +++ b/new_modules/db_cloudwatch_log_groups/versions.tf @@ -6,10 +6,5 @@ terraform { source = "hashicorp/aws" version = ">= 5.0" } - - random = { - source = "hashicorp/random" - version = ">= 3.1" - } } } From fc33d661ed8d7d5a10d35c08439169b016dc6e0b Mon Sep 17 00:00:00 2001 From: samidbb Date: Fri, 3 Nov 2023 08:25:50 +0100 Subject: [PATCH 06/12] folder rename. working components. working tests --- _sub/terraform-aws-rds-aurora/main.tf | 469 ------------ _sub/terraform-aws-rds-aurora/outputs.tf | 186 ----- _sub/terraform-aws-rds-aurora/variables.tf | 710 ------------------ _sub/terraform-aws-rds-proxy/main.tf | 188 ----- _sub/terraform-aws-rds/README.md | 370 --------- _sub/terraform-aws-rds/main.tf | 150 ---- .../modules/db_instance/main.tf | 200 ----- .../modules/db_instance/outputs.tf | 109 --- .../modules/db_instance/variables.tf | 431 ----------- .../main.tf | 9 - .../outputs.tf | 4 - .../variables.tf | 29 - .../modules/db_option_group/README.md | 47 -- .../modules/db_option_group/main.tf | 50 -- .../modules/db_option_group/outputs.tf | 9 - .../modules/db_option_group/variables.tf | 53 -- .../modules/db_parameter_group/main.tf | 35 - .../modules/db_parameter_group/outputs.tf | 9 - .../modules/db_subnet_group/main.tf | 22 - .../modules/db_subnet_group/outputs.tf | 9 - _sub/terraform-aws-rds/outputs.tf | 140 ---- _sub/terraform-aws-rds/variables.tf | 552 -------------- _sub/terraform-aws-rds/versions.tf | 10 - main.tf | 28 +- .../cloudwatch_log_groups}/main.tf | 0 .../cloudwatch_log_groups}/outputs.tf | 0 .../cloudwatch_log_groups}/vars.tf | 0 .../cloudwatch_log_groups}/versions.tf | 0 .../cluster_parameter_group/main.tf | 0 .../cluster_parameter_group/outputs.tf | 0 .../cluster_parameter_group/variables.tf | 0 .../cluster_parameter_group}/versions.tf | 0 .../enhanced_monitoring_role}/main.tf | 0 .../enhanced_monitoring_role}/outputs.tf | 0 .../enhanced_monitoring_role}/variables.tf | 0 .../instance_parameter_group}/README.md | 0 .../instance_parameter_group}/main.tf | 0 .../instance_parameter_group}/outputs.tf | 0 .../instance_parameter_group}/variables.tf | 0 .../instance_parameter_group}/versions.tf | 0 .../rds_aurora}/README.md | 0 .../rds-aurora => modules/rds_aurora}/main.tf | 0 .../rds_aurora}/outputs.tf | 0 .../rds_aurora}/variables.tf | 0 .../rds_aurora}/versions.tf | 0 .../rds_instance}/README.md | 0 .../rds_instance}/main.tf | 0 .../rds_instance}/outputs.tf | 0 .../rds_instance}/variables.tf | 0 .../rds_instance}/versions.tf | 0 .../rds_proxy}/README.md | 0 .../rds-proxy => modules/rds_proxy}/main.tf | 34 +- .../rds_proxy}/outputs.tf | 12 +- .../rds_proxy}/variables.tf | 6 - .../rds_proxy}/versions.tf | 0 .../rds_subnet_group}/README.md | 0 .../rds_subnet_group}/main.tf | 0 .../rds_subnet_group}/outputs.tf | 0 .../rds_subnet_group}/variables.tf | 0 .../rds_subnet_group}/versions.tf | 0 .../cluster_parameter_group/versions.tf | 10 - .../db_cloudwatch_log_groups/versions.tf | 10 - new_modules/db_instance/README.md | 134 ---- new_modules/db_instance/versions.tf | 15 - new_modules/db_parameter_group/README.md | 45 -- new_modules/db_parameter_group/variables.tf | 41 - new_modules/db_parameter_group/versions.tf | 10 - new_modules/db_subnet_group/README.md | 44 -- new_modules/db_subnet_group/variables.tf | 35 - new_modules/db_subnet_group/versions.tf | 10 - new_modules/rds-aurora/README.md | 422 ----------- new_modules/rds-aurora/versions.tf | 10 - new_modules/rds-proxy/README.md | 165 ---- new_modules/rds-proxy/outputs.tf | 95 --- new_modules/rds-proxy/variables.tf | 255 ------- new_modules/rds-proxy/versions.tf | 10 - tests/instance/main.tf | 127 ++++ tests/multi_az_cluster/main.tf | 125 +++ tests/serverless/main.tf | 125 +++ variables.tf | 9 +- 80 files changed, 420 insertions(+), 5148 deletions(-) delete mode 100644 _sub/terraform-aws-rds-aurora/main.tf delete mode 100644 _sub/terraform-aws-rds-aurora/outputs.tf delete mode 100644 _sub/terraform-aws-rds-aurora/variables.tf delete mode 100644 _sub/terraform-aws-rds-proxy/main.tf delete mode 100644 _sub/terraform-aws-rds/README.md delete mode 100644 _sub/terraform-aws-rds/main.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_instance/main.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_instance/outputs.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_instance/variables.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_instance_automated_backups_replication/main.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_instance_automated_backups_replication/outputs.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_instance_automated_backups_replication/variables.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_option_group/README.md delete mode 100644 _sub/terraform-aws-rds/modules/db_option_group/main.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_option_group/outputs.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_option_group/variables.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_parameter_group/main.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_parameter_group/outputs.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_subnet_group/main.tf delete mode 100644 _sub/terraform-aws-rds/modules/db_subnet_group/outputs.tf delete mode 100644 _sub/terraform-aws-rds/outputs.tf delete mode 100644 _sub/terraform-aws-rds/variables.tf delete mode 100644 _sub/terraform-aws-rds/versions.tf rename {new_modules/db_cloudwatch_log_groups => modules/cloudwatch_log_groups}/main.tf (100%) rename {new_modules/db_cloudwatch_log_groups => modules/cloudwatch_log_groups}/outputs.tf (100%) rename {new_modules/db_cloudwatch_log_groups => modules/cloudwatch_log_groups}/vars.tf (100%) rename {_sub/terraform-aws-rds-proxy => modules/cloudwatch_log_groups}/versions.tf (100%) rename {new_modules => modules}/cluster_parameter_group/main.tf (100%) rename {new_modules => modules}/cluster_parameter_group/outputs.tf (100%) rename {new_modules => modules}/cluster_parameter_group/variables.tf (100%) rename {_sub/terraform-aws-rds/modules/db_instance_automated_backups_replication => modules/cluster_parameter_group}/versions.tf (100%) rename {new_modules/db_enhanced_monitoring_role => modules/enhanced_monitoring_role}/main.tf (100%) rename {new_modules/db_enhanced_monitoring_role => modules/enhanced_monitoring_role}/outputs.tf (100%) rename {new_modules/db_enhanced_monitoring_role => modules/enhanced_monitoring_role}/variables.tf (100%) rename {_sub/terraform-aws-rds/modules/db_parameter_group => modules/instance_parameter_group}/README.md (100%) rename {new_modules/db_parameter_group => modules/instance_parameter_group}/main.tf (100%) rename {new_modules/db_parameter_group => modules/instance_parameter_group}/outputs.tf (100%) rename {_sub/terraform-aws-rds/modules/db_parameter_group => modules/instance_parameter_group}/variables.tf (100%) rename {_sub/terraform-aws-rds/modules/db_option_group => modules/instance_parameter_group}/versions.tf (100%) rename {_sub/terraform-aws-rds-aurora => modules/rds_aurora}/README.md (100%) rename {new_modules/rds-aurora => modules/rds_aurora}/main.tf (100%) rename {new_modules/rds-aurora => modules/rds_aurora}/outputs.tf (100%) rename {new_modules/rds-aurora => modules/rds_aurora}/variables.tf (100%) rename {_sub/terraform-aws-rds-aurora => modules/rds_aurora}/versions.tf (100%) rename {_sub/terraform-aws-rds/modules/db_instance => modules/rds_instance}/README.md (100%) rename {new_modules/db_instance => modules/rds_instance}/main.tf (100%) rename {new_modules/db_instance => modules/rds_instance}/outputs.tf (100%) rename {new_modules/db_instance => modules/rds_instance}/variables.tf (100%) rename {_sub/terraform-aws-rds/modules/db_instance => modules/rds_instance}/versions.tf (100%) rename {_sub/terraform-aws-rds-proxy => modules/rds_proxy}/README.md (100%) rename {new_modules/rds-proxy => modules/rds_proxy}/main.tf (85%) rename {_sub/terraform-aws-rds-proxy => modules/rds_proxy}/outputs.tf (89%) rename {_sub/terraform-aws-rds-proxy => modules/rds_proxy}/variables.tf (98%) rename {_sub/terraform-aws-rds/modules/db_parameter_group => modules/rds_proxy}/versions.tf (100%) rename {_sub/terraform-aws-rds/modules/db_subnet_group => modules/rds_subnet_group}/README.md (100%) rename {new_modules/db_subnet_group => modules/rds_subnet_group}/main.tf (100%) rename {new_modules/db_subnet_group => modules/rds_subnet_group}/outputs.tf (100%) rename {_sub/terraform-aws-rds/modules/db_subnet_group => modules/rds_subnet_group}/variables.tf (100%) rename {_sub/terraform-aws-rds/modules/db_subnet_group => modules/rds_subnet_group}/versions.tf (100%) delete mode 100644 new_modules/cluster_parameter_group/versions.tf delete mode 100644 new_modules/db_cloudwatch_log_groups/versions.tf delete mode 100644 new_modules/db_instance/README.md delete mode 100644 new_modules/db_instance/versions.tf delete mode 100644 new_modules/db_parameter_group/README.md delete mode 100644 new_modules/db_parameter_group/variables.tf delete mode 100644 new_modules/db_parameter_group/versions.tf delete mode 100644 new_modules/db_subnet_group/README.md delete mode 100644 new_modules/db_subnet_group/variables.tf delete mode 100644 new_modules/db_subnet_group/versions.tf delete mode 100644 new_modules/rds-aurora/README.md delete mode 100644 new_modules/rds-aurora/versions.tf delete mode 100644 new_modules/rds-proxy/README.md delete mode 100644 new_modules/rds-proxy/outputs.tf delete mode 100644 new_modules/rds-proxy/variables.tf delete mode 100644 new_modules/rds-proxy/versions.tf create mode 100644 tests/instance/main.tf create mode 100644 tests/multi_az_cluster/main.tf create mode 100644 tests/serverless/main.tf diff --git a/_sub/terraform-aws-rds-aurora/main.tf b/_sub/terraform-aws-rds-aurora/main.tf deleted file mode 100644 index 46e7ddcb..00000000 --- a/_sub/terraform-aws-rds-aurora/main.tf +++ /dev/null @@ -1,469 +0,0 @@ -data "aws_partition" "current" {} - -locals { - create = var.create - - port = coalesce(var.port, (var.engine == "aurora-postgresql" || var.engine == "postgres" ? 5432 : 3306)) - - internal_db_subnet_group_name = try(coalesce(var.db_subnet_group_name, var.name), "") - - ### - db_subnet_group_name = var.create_db_subnet_group ? try(aws_db_subnet_group.this[0].name, null) : local.internal_db_subnet_group_name - # db_subnet_group_name = var.db_subnet_group_name - ### - - security_group_name = try(coalesce(var.security_group_name, var.name), "") - - cluster_parameter_group_name = try(coalesce(var.db_cluster_parameter_group_name, var.name), null) - db_parameter_group_name = try(coalesce(var.db_parameter_group_name, var.name), null) - - backtrack_window = (var.engine == "aurora-mysql" || var.engine == "aurora") && var.engine_mode != "serverless" ? var.backtrack_window : 0 - - is_serverless = var.engine_mode == "serverless" -} - -################################################################################ -# DB Subnet Group -################################################################################ - -resource "aws_db_subnet_group" "this" { - count = local.create && var.create_db_subnet_group ? 1 : 0 - - name = local.internal_db_subnet_group_name - description = "For cluster ${var.name}" - subnet_ids = var.subnets - - tags = var.tags -} - -################################################################################ -# Cluster -################################################################################ - -resource "aws_rds_cluster" "this" { - count = local.create ? 1 : 0 - - allocated_storage = var.allocated_storage - allow_major_version_upgrade = var.allow_major_version_upgrade - apply_immediately = var.apply_immediately - availability_zones = var.availability_zones - backup_retention_period = var.backup_retention_period - backtrack_window = local.backtrack_window - cluster_identifier = var.cluster_use_name_prefix ? null : var.name - cluster_identifier_prefix = var.cluster_use_name_prefix ? "${var.name}-" : null - cluster_members = var.cluster_members - copy_tags_to_snapshot = var.copy_tags_to_snapshot - database_name = var.is_primary_cluster ? var.database_name : null - db_cluster_instance_class = var.db_cluster_instance_class - db_cluster_parameter_group_name = var.create_db_cluster_parameter_group ? aws_rds_cluster_parameter_group.this[0].id : var.db_cluster_parameter_group_name - db_instance_parameter_group_name = var.allow_major_version_upgrade ? var.db_cluster_db_instance_parameter_group_name : null - db_subnet_group_name = local.db_subnet_group_name - deletion_protection = var.deletion_protection - enable_global_write_forwarding = var.enable_global_write_forwarding - enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports - enable_http_endpoint = var.enable_http_endpoint - engine = var.engine - engine_mode = var.engine_mode - engine_version = var.engine_version - final_snapshot_identifier = var.final_snapshot_identifier - global_cluster_identifier = var.global_cluster_identifier - iam_database_authentication_enabled = var.iam_database_authentication_enabled - # iam_roles has been removed from this resource and instead will be used with aws_rds_cluster_role_association below to avoid conflicts per docs - iops = var.iops - kms_key_id = var.kms_key_id - manage_master_user_password = var.global_cluster_identifier == null && var.manage_master_user_password ? var.manage_master_user_password : null - master_user_secret_kms_key_id = var.global_cluster_identifier == null && var.manage_master_user_password ? var.master_user_secret_kms_key_id : null - master_password = var.is_primary_cluster && !var.manage_master_user_password ? var.master_password : null - master_username = var.is_primary_cluster ? var.master_username : null - network_type = var.network_type - port = local.port - preferred_backup_window = local.is_serverless ? null : var.preferred_backup_window - preferred_maintenance_window = local.is_serverless ? null : var.preferred_maintenance_window - replication_source_identifier = var.replication_source_identifier - - dynamic "restore_to_point_in_time" { - for_each = length(var.restore_to_point_in_time) > 0 ? [var.restore_to_point_in_time] : [] - - content { - restore_to_time = try(restore_to_point_in_time.value.restore_to_time, null) - restore_type = try(restore_to_point_in_time.value.restore_type, null) - source_cluster_identifier = restore_to_point_in_time.value.source_cluster_identifier - use_latest_restorable_time = try(restore_to_point_in_time.value.use_latest_restorable_time, null) - } - } - - dynamic "s3_import" { - for_each = length(var.s3_import) > 0 && !local.is_serverless ? [var.s3_import] : [] - - content { - bucket_name = s3_import.value.bucket_name - bucket_prefix = try(s3_import.value.bucket_prefix, null) - ingestion_role = s3_import.value.ingestion_role - source_engine = "mysql" - source_engine_version = s3_import.value.source_engine_version - } - } - - dynamic "scaling_configuration" { - for_each = length(var.scaling_configuration) > 0 && local.is_serverless ? [var.scaling_configuration] : [] - - content { - auto_pause = try(scaling_configuration.value.auto_pause, null) - max_capacity = try(scaling_configuration.value.max_capacity, null) - min_capacity = try(scaling_configuration.value.min_capacity, null) - seconds_until_auto_pause = try(scaling_configuration.value.seconds_until_auto_pause, null) - timeout_action = try(scaling_configuration.value.timeout_action, null) - } - } - - dynamic "serverlessv2_scaling_configuration" { - for_each = length(var.serverlessv2_scaling_configuration) > 0 && var.engine_mode == "provisioned" ? [var.serverlessv2_scaling_configuration] : [] - - content { - max_capacity = serverlessv2_scaling_configuration.value.max_capacity - min_capacity = serverlessv2_scaling_configuration.value.min_capacity - } - } - - skip_final_snapshot = var.skip_final_snapshot - snapshot_identifier = var.snapshot_identifier - source_region = var.source_region - storage_encrypted = var.storage_encrypted - storage_type = var.storage_type - tags = merge(var.tags, var.cluster_tags) - vpc_security_group_ids =var.vpc_security_group_ids # compact(concat([try(aws_security_group.this[0].id, "")], var.vpc_security_group_ids)) - - timeouts { - create = try(var.cluster_timeouts.create, null) - update = try(var.cluster_timeouts.update, null) - delete = try(var.cluster_timeouts.delete, null) - } - - lifecycle { - ignore_changes = [ - # See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster#replication_source_identifier - # Since this is used either in read-replica clusters or global clusters, this should be acceptable to specify - replication_source_identifier, - # See docs here https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_global_cluster#new-global-cluster-from-existing-db-cluster - global_cluster_identifier, - snapshot_identifier, - ] - } - - depends_on = [aws_cloudwatch_log_group.this] -} - -################################################################################ -# Cluster Instance(s) -################################################################################ - - -# TODO: remove the map and use count instead as in https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_instance#example-usage -# and here: https://dev.azure.com/dfds/Phoenix/_git/aws-modules-rds?path=/modules/db_cluster/main.tf&_a=contents&version=GBmaster -# resource "aws_rds_cluster_instance" "this" { -# count = local.create && !local.is_serverless ? var.cluster_db_instance_count : 0 - -# apply_immediately = var.apply_immediately -# auto_minor_version_upgrade = var.auto_minor_version_upgrade -# availability_zone = null # var.availability_zone -# ca_cert_identifier = var.ca_cert_identifier -# cluster_identifier = aws_rds_cluster.this[0].id -# copy_tags_to_snapshot = var.copy_tags_to_snapshot -# db_parameter_group_name = var.create_db_parameter_group ? aws_db_parameter_group.this[0].id : var.db_parameter_group_name -# db_subnet_group_name = local.db_subnet_group_name -# engine = var.engine -# engine_version = var.engine_version -# identifier = null #var.name -# identifier_prefix = "${var.name}-${count.index}-" -# instance_class = var.instance_class -# monitoring_interval = var.monitoring_interval -# monitoring_role_arn = var.create_monitoring_role ? aws_iam_role.rds_enhanced_monitoring[0].arn : var.monitoring_role_arn -# performance_insights_enabled = var.performance_insights_enabled -# performance_insights_kms_key_id = var.performance_insights_kms_key_id -# performance_insights_retention_period = var.performance_insights_retention_period -# # preferred_backup_window - is set at the cluster level and will error if provided here -# preferred_maintenance_window = var.preferred_maintenance_window -# promotion_tier = null -# publicly_accessible = var.publicly_accessible -# tags = var.tags - -# timeouts { -# create = null -# update = null -# delete = null -# } -# } -resource "aws_rds_cluster_instance" "this" { - for_each = { for k, v in var.instances : k => v if local.create && !local.is_serverless } - - apply_immediately = try(each.value.apply_immediately, var.apply_immediately) - auto_minor_version_upgrade = try(each.value.auto_minor_version_upgrade, var.auto_minor_version_upgrade) - availability_zone = try(each.value.availability_zone, null) - ca_cert_identifier = var.ca_cert_identifier - cluster_identifier = aws_rds_cluster.this[0].id - copy_tags_to_snapshot = try(each.value.copy_tags_to_snapshot, var.copy_tags_to_snapshot) - db_parameter_group_name = var.create_db_parameter_group ? aws_db_parameter_group.this[0].id : try(each.value.db_parameter_group_name, var.db_parameter_group_name) - db_subnet_group_name = local.db_subnet_group_name - engine = var.engine - engine_version = var.engine_version - identifier = var.instances_use_identifier_prefix ? null : try(each.value.identifier, "${var.name}-${each.key}") - identifier_prefix = var.instances_use_identifier_prefix ? try(each.value.identifier_prefix, "${var.name}-${each.key}-") : null - instance_class = try(each.value.instance_class, var.instance_class) - monitoring_interval = try(each.value.monitoring_interval, var.monitoring_interval) - monitoring_role_arn = var.create_monitoring_role ? try(aws_iam_role.rds_enhanced_monitoring[0].arn, null) : var.monitoring_role_arn - performance_insights_enabled = try(each.value.performance_insights_enabled, var.performance_insights_enabled) - performance_insights_kms_key_id = try(each.value.performance_insights_kms_key_id, var.performance_insights_kms_key_id) - performance_insights_retention_period = try(each.value.performance_insights_retention_period, var.performance_insights_retention_period) - # preferred_backup_window - is set at the cluster level and will error if provided here - preferred_maintenance_window = try(each.value.preferred_maintenance_window, var.preferred_maintenance_window) - promotion_tier = try(each.value.promotion_tier, null) - publicly_accessible = try(each.value.publicly_accessible, var.publicly_accessible) - tags = merge(var.tags, try(each.value.tags, {})) - - timeouts { - create = try(var.instance_timeouts.create, null) - update = try(var.instance_timeouts.update, null) - delete = try(var.instance_timeouts.delete, null) - } -} - -################################################################################ -# Cluster Endpoint(s) -################################################################################ - -resource "aws_rds_cluster_endpoint" "this" { - for_each = { for k, v in var.endpoints : k => v if local.create && !local.is_serverless } - - cluster_endpoint_identifier = each.value.identifier - cluster_identifier = aws_rds_cluster.this[0].id - custom_endpoint_type = each.value.type - excluded_members = try(each.value.excluded_members, null) - static_members = try(each.value.static_members, null) - tags = merge(var.tags, try(each.value.tags, {})) - - depends_on = [ - aws_rds_cluster_instance.this - ] -} - -################################################################################ -# Cluster IAM Roles -################################################################################ - -resource "aws_rds_cluster_role_association" "this" { - for_each = { for k, v in var.iam_roles : k => v if local.create } - - db_cluster_identifier = aws_rds_cluster.this[0].id - feature_name = each.value.feature_name - role_arn = each.value.role_arn -} - -################################################################################ -# Enhanced Monitoring -################################################################################ - -locals { - create_monitoring_role = local.create && var.create_monitoring_role && var.monitoring_interval > 0 -} - -data "aws_iam_policy_document" "monitoring_rds_assume_role" { - count = local.create_monitoring_role ? 1 : 0 - - statement { - actions = ["sts:AssumeRole"] - - principals { - type = "Service" - identifiers = ["monitoring.rds.${data.aws_partition.current.dns_suffix}"] - } - } -} - -resource "aws_iam_role" "rds_enhanced_monitoring" { - count = local.create_monitoring_role ? 1 : 0 - - name = var.iam_role_use_name_prefix ? null : var.iam_role_name - name_prefix = var.iam_role_use_name_prefix ? "${var.iam_role_name}-" : null - description = var.iam_role_description - path = var.iam_role_path - - assume_role_policy = data.aws_iam_policy_document.monitoring_rds_assume_role[0].json - managed_policy_arns = var.iam_role_managed_policy_arns - permissions_boundary = var.iam_role_permissions_boundary - force_detach_policies = var.iam_role_force_detach_policies - max_session_duration = var.iam_role_max_session_duration - - tags = var.tags -} - -resource "aws_iam_role_policy_attachment" "rds_enhanced_monitoring" { - count = local.create_monitoring_role ? 1 : 0 - - role = aws_iam_role.rds_enhanced_monitoring[0].name - policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" -} - -################################################################################ -# Autoscaling -################################################################################ - -resource "aws_appautoscaling_target" "this" { - count = local.create && var.autoscaling_enabled && !local.is_serverless ? 1 : 0 - - max_capacity = var.autoscaling_max_capacity - min_capacity = var.autoscaling_min_capacity - resource_id = "cluster:${aws_rds_cluster.this[0].cluster_identifier}" - scalable_dimension = "rds:cluster:ReadReplicaCount" - service_namespace = "rds" - - tags = var.tags -} - -resource "aws_appautoscaling_policy" "this" { - count = local.create && var.autoscaling_enabled && !local.is_serverless ? 1 : 0 - - name = var.autoscaling_policy_name - policy_type = "TargetTrackingScaling" - resource_id = "cluster:${aws_rds_cluster.this[0].cluster_identifier}" - scalable_dimension = "rds:cluster:ReadReplicaCount" - service_namespace = "rds" - - target_tracking_scaling_policy_configuration { - predefined_metric_specification { - predefined_metric_type = var.predefined_metric_type - } - - scale_in_cooldown = var.autoscaling_scale_in_cooldown - scale_out_cooldown = var.autoscaling_scale_out_cooldown - target_value = var.predefined_metric_type == "RDSReaderAverageCPUUtilization" ? var.autoscaling_target_cpu : var.autoscaling_target_connections - } - - depends_on = [ - aws_appautoscaling_target.this - ] -} - -# ################################################################################ -# # Security Group -# ################################################################################ - -# resource "aws_security_group" "this" { -# count = local.create && var.create_security_group ? 1 : 0 - -# name = var.security_group_use_name_prefix ? null : local.security_group_name -# name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null -# vpc_id = var.vpc_id -# description = coalesce(var.security_group_description, "Control traffic to/from RDS Aurora ${var.name}") - -# tags = merge(var.tags, var.security_group_tags, { Name = local.security_group_name }) - -# lifecycle { -# create_before_destroy = true -# } -# } - -# resource "aws_security_group_rule" "this" { -# for_each = { for k, v in var.security_group_rules : k => v if local.create && var.create_security_group } - -# # required -# type = try(each.value.type, "ingress") -# from_port = try(each.value.from_port, local.port) -# to_port = try(each.value.to_port, local.port) -# protocol = try(each.value.protocol, "tcp") -# security_group_id = aws_security_group.this[0].id - -# # optional -# cidr_blocks = try(each.value.cidr_blocks, null) -# description = try(each.value.description, null) -# ipv6_cidr_blocks = try(each.value.ipv6_cidr_blocks, null) -# prefix_list_ids = try(each.value.prefix_list_ids, null) -# source_security_group_id = try(each.value.source_security_group_id, null) -# } - -################################################################################ -# Cluster Parameter Group -################################################################################ - -resource "aws_rds_cluster_parameter_group" "this" { - count = local.create && var.create_db_cluster_parameter_group ? 1 : 0 - - name = var.db_cluster_parameter_group_use_name_prefix ? null : local.cluster_parameter_group_name - name_prefix = var.db_cluster_parameter_group_use_name_prefix ? "${local.cluster_parameter_group_name}-" : null - description = var.db_cluster_parameter_group_description - family = var.db_cluster_parameter_group_family - - dynamic "parameter" { - for_each = var.db_cluster_parameter_group_parameters - - content { - name = parameter.value.name - value = parameter.value.value - apply_method = try(parameter.value.apply_method, "immediate") - } - } - - lifecycle { - create_before_destroy = true - } - - tags = var.tags -} - -################################################################################ -# DB Parameter Group -################################################################################ - -resource "aws_db_parameter_group" "this" { - count = local.create && var.create_db_parameter_group ? 1 : 0 - - name = var.db_parameter_group_use_name_prefix ? null : local.db_parameter_group_name - name_prefix = var.db_parameter_group_use_name_prefix ? "${local.db_parameter_group_name}-" : null - description = var.db_parameter_group_description - family = var.db_parameter_group_family - - dynamic "parameter" { - for_each = var.db_parameter_group_parameters - - content { - name = parameter.value.name - value = parameter.value.value - apply_method = try(parameter.value.apply_method, "immediate") - } - } - - lifecycle { - create_before_destroy = true - } - - tags = var.tags -} - -################################################################################ -# CloudWatch Log Group -################################################################################ - -# Log groups will not be created if using a cluster identifier prefix -resource "aws_cloudwatch_log_group" "this" { - for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log if local.create && var.create_cloudwatch_log_group && !var.cluster_use_name_prefix]) - - name = "/aws/rds/cluster/${var.name}/${each.value}" - retention_in_days = var.cloudwatch_log_group_retention_in_days - kms_key_id = var.cloudwatch_log_group_kms_key_id - - tags = var.tags -} - -################################################################################ -# Cluster Activity Stream -################################################################################ - -resource "aws_rds_cluster_activity_stream" "this" { - count = local.create && var.create_db_cluster_activity_stream ? 1 : 0 - - resource_arn = aws_rds_cluster.this[0].arn - mode = var.db_cluster_activity_stream_mode - kms_key_id = var.db_cluster_activity_stream_kms_key_id - engine_native_audit_fields_included = var.engine_native_audit_fields_included - - depends_on = [aws_rds_cluster_instance.this] -} diff --git a/_sub/terraform-aws-rds-aurora/outputs.tf b/_sub/terraform-aws-rds-aurora/outputs.tf deleted file mode 100644 index 49bfe4ad..00000000 --- a/_sub/terraform-aws-rds-aurora/outputs.tf +++ /dev/null @@ -1,186 +0,0 @@ -################################################################################ -# DB Subnet Group -################################################################################ - -output "db_subnet_group_name" { - description = "The db subnet group name" - value = local.db_subnet_group_name -} - -################################################################################ -# Cluster -################################################################################ - -output "cluster_arn" { - description = "Amazon Resource Name (ARN) of cluster" - value = try(aws_rds_cluster.this[0].arn, null) -} - -output "cluster_id" { - description = "The RDS Cluster Identifier" - value = try(aws_rds_cluster.this[0].id, null) -} - -output "cluster_resource_id" { - description = "The RDS Cluster Resource ID" - value = try(aws_rds_cluster.this[0].cluster_resource_id, null) -} - -output "cluster_members" { - description = "List of RDS Instances that are a part of this cluster" - value = try(aws_rds_cluster.this[0].cluster_members, null) -} - -output "cluster_endpoint" { - description = "Writer endpoint for the cluster" - value = try(aws_rds_cluster.this[0].endpoint, null) -} - -output "cluster_reader_endpoint" { - description = "A read-only endpoint for the cluster, automatically load-balanced across replicas" - value = try(aws_rds_cluster.this[0].reader_endpoint, null) -} - -output "cluster_engine_version_actual" { - description = "The running version of the cluster database" - value = try(aws_rds_cluster.this[0].engine_version_actual, null) -} - -# database_name is not set on `aws_rds_cluster` resource if it was not specified, so can't be used in output -output "cluster_database_name" { - description = "Name for an automatically created database on cluster creation" - value = var.database_name -} - -output "cluster_port" { - description = "The database port" - value = try(aws_rds_cluster.this[0].port, null) -} - -output "cluster_master_password" { - description = "The database master password" - value = try(aws_rds_cluster.this[0].master_password, null) - sensitive = true -} - -output "cluster_master_username" { - description = "The database master username" - value = try(aws_rds_cluster.this[0].master_username, null) - sensitive = true -} - -output "cluster_master_user_secret" { - description = "The generated database master user secret when `manage_master_user_password` is set to `true`" - value = try(aws_rds_cluster.this[0].master_user_secret, null) -} - -output "cluster_master_user_secret_arn" { - description = "The ARN of the master user secret (Only available when manage_master_user_password is set to true)" - value = try(aws_rds_cluster.this[0].master_user_secret[0].secret_arn, null) -} - -output "cluster_hosted_zone_id" { - description = "The Route53 Hosted Zone ID of the endpoint" - value = try(aws_rds_cluster.this[0].hosted_zone_id, null) -} - -################################################################################ -# Cluster Instance(s) -################################################################################ - -output "cluster_instances" { - description = "A map of cluster instances and their attributes" - value = aws_rds_cluster_instance.this -} - -################################################################################ -# Cluster Endpoint(s) -################################################################################ - -output "additional_cluster_endpoints" { - description = "A map of additional cluster endpoints and their attributes" - value = aws_rds_cluster_endpoint.this -} - -################################################################################ -# Cluster IAM Roles -################################################################################ - -output "cluster_role_associations" { - description = "A map of IAM roles associated with the cluster and their attributes" - value = aws_rds_cluster_role_association.this -} - -################################################################################ -# Enhanced Monitoring -################################################################################ - -output "enhanced_monitoring_iam_role_name" { - description = "The name of the enhanced monitoring role" - value = try(aws_iam_role.rds_enhanced_monitoring[0].name, null) -} - -output "enhanced_monitoring_iam_role_arn" { - description = "The Amazon Resource Name (ARN) specifying the enhanced monitoring role" - value = try(aws_iam_role.rds_enhanced_monitoring[0].arn, null) -} - -output "enhanced_monitoring_iam_role_unique_id" { - description = "Stable and unique string identifying the enhanced monitoring role" - value = try(aws_iam_role.rds_enhanced_monitoring[0].unique_id, null) -} - -################################################################################ -# Security Group -################################################################################ - -# output "security_group_id" { -# description = "The security group ID of the cluster" -# value = try(aws_security_group.this[0].id, null) -# } - -################################################################################ -# Cluster Parameter Group -################################################################################ - -output "db_cluster_parameter_group_arn" { - description = "The ARN of the DB cluster parameter group created" - value = try(aws_rds_cluster_parameter_group.this[0].arn, null) -} - -output "db_cluster_parameter_group_id" { - description = "The ID of the DB cluster parameter group created" - value = try(aws_rds_cluster_parameter_group.this[0].id, null) -} - -################################################################################ -# DB Parameter Group -################################################################################ - -output "db_parameter_group_arn" { - description = "The ARN of the DB parameter group created" - value = try(aws_db_parameter_group.this[0].arn, null) -} - -output "db_parameter_group_id" { - description = "The ID of the DB parameter group created" - value = try(aws_db_parameter_group.this[0].id, null) -} - -################################################################################ -# CloudWatch Log Group -################################################################################ - -output "db_cluster_cloudwatch_log_groups" { - description = "Map of CloudWatch log groups created and their attributes" - value = aws_cloudwatch_log_group.this -} - -################################################################################ -# Cluster Activity Stream -################################################################################ - -output "db_cluster_activity_stream_kinesis_stream_name" { - description = "The name of the Amazon Kinesis data stream to be used for the database activity stream" - value = try(aws_rds_cluster_activity_stream.this[0].kinesis_stream_name, null) -} \ No newline at end of file diff --git a/_sub/terraform-aws-rds-aurora/variables.tf b/_sub/terraform-aws-rds-aurora/variables.tf deleted file mode 100644 index 4fe65bc3..00000000 --- a/_sub/terraform-aws-rds-aurora/variables.tf +++ /dev/null @@ -1,710 +0,0 @@ -variable "create" { - description = "Whether cluster should be created (affects nearly all resources)" - type = bool - default = true -} - -variable "name" { - description = "Name used across resources created" - type = string - default = "" -} - -variable "tags" { - description = "A map of tags to add to all resources" - type = map(string) - default = {} -} - -################################################################################ -# DB Subnet Group -################################################################################ - -variable "create_db_subnet_group" { - description = "Determines whether to create the database subnet group or use existing" - type = bool - default = false -} - -variable "db_subnet_group_name" { - description = "The name of the subnet group name (existing or created)" - type = string - default = "" -} - -variable "subnets" { - description = "List of subnet IDs used by database subnet group created" - type = list(string) - default = [] -} - -################################################################################ -# Cluster -################################################################################ - -variable "is_primary_cluster" { - description = "Determines whether cluster is primary cluster with writer instance (set to `false` for global cluster and replica clusters)" - type = bool - default = true -} - -variable "cluster_use_name_prefix" { - description = "Whether to use `name` as a prefix for the cluster" - type = bool - default = false -} - -variable "allocated_storage" { - description = "The amount of storage in gibibytes (GiB) to allocate to each DB instance in the Multi-AZ DB cluster. (This setting is required to create a Multi-AZ DB cluster)" - type = number - default = null -} - -variable "allow_major_version_upgrade" { - description = "Enable to allow major engine version upgrades when changing engine versions. Defaults to `false`" - type = bool - default = false -} - -variable "apply_immediately" { - description = "Specifies whether any cluster modifications are applied immediately, or during the next maintenance window. Default is `false`" - type = bool - default = null -} - -variable "availability_zones" { - description = "List of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created. RDS automatically assigns 3 AZs if less than 3 AZs are configured, which will show as a difference requiring resource recreation next Terraform apply" - type = list(string) - default = null -} - -variable "backup_retention_period" { - description = "The days to retain backups for. Default `7`" - type = number - default = 7 -} - -variable "backtrack_window" { - description = "The target backtrack window, in seconds. Only available for `aurora` engine currently. To disable backtracking, set this value to 0. Must be between 0 and 259200 (72 hours)" - type = number - default = null -} - -variable "cluster_members" { - description = "List of RDS Instances that are a part of this cluster" - type = list(string) - default = null -} - -variable "copy_tags_to_snapshot" { - description = "Copy all Cluster `tags` to snapshots" - type = bool - default = null -} - -variable "database_name" { - description = "Name for an automatically created database on cluster creation" - type = string - default = null -} - -variable "db_cluster_instance_class" { - description = "The compute and memory capacity of each DB instance in the Multi-AZ DB cluster, for example db.m6g.xlarge. Not all DB instance classes are available in all AWS Regions, or for all database engines" - type = string - default = null -} - -variable "db_cluster_db_instance_parameter_group_name" { - description = "Instance parameter group to associate with all instances of the DB cluster. The `db_cluster_db_instance_parameter_group_name` is only valid in combination with `allow_major_version_upgrade`" - type = string - default = null -} - -variable "deletion_protection" { - description = "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`" - type = bool - default = null -} - -variable "enable_global_write_forwarding" { - description = "Whether cluster should forward writes to an associated global cluster. Applied to secondary clusters to enable them to forward writes to an `aws_rds_global_cluster`'s primary cluster" - type = bool - default = null -} - -variable "enabled_cloudwatch_logs_exports" { - description = "Set of log types to export to cloudwatch. If omitted, no logs will be exported. The following log types are supported: `audit`, `error`, `general`, `slowquery`, `postgresql`" - type = list(string) - default = [] -} - -variable "enable_http_endpoint" { - description = "Enable HTTP endpoint (data API). Only valid when engine_mode is set to `serverless`" - type = bool - default = null -} - -variable "engine" { - description = "The name of the database engine to be used for this DB cluster. Defaults to `aurora`. Valid Values: `aurora`, `aurora-mysql`, `aurora-postgresql`" - type = string - default = null -} - -variable "engine_mode" { - description = "The database engine mode. Valid values: `global`, `multimaster`, `parallelquery`, `provisioned`, `serverless`. Defaults to: `provisioned`" - type = string - default = "provisioned" -} - -variable "engine_version" { - description = "The database engine version. Updating this argument results in an outage" - type = string - default = null -} - -variable "final_snapshot_identifier" { - description = "The name of your final DB snapshot when this DB cluster is deleted. If omitted, no final snapshot will be made" - type = string - default = null -} - -variable "global_cluster_identifier" { - description = "The global cluster identifier specified on `aws_rds_global_cluster`" - type = string - default = null -} - -variable "iam_database_authentication_enabled" { - description = "Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled" - type = bool - default = null -} - -variable "iops" { - description = "The amount of Provisioned IOPS (input/output operations per second) to be initially allocated for each DB instance in the Multi-AZ DB cluster" - type = number - default = null -} - -variable "kms_key_id" { - description = "The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to `true`" - type = string - default = null -} - -variable "manage_master_user_password" { - description = "Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if `master_password` is provided" - type = bool - default = true -} - -variable "master_user_secret_kms_key_id" { - description = "The Amazon Web Services KMS key identifier is the key ARN, key ID, alias ARN, or alias name for the KMS key" - type = string - default = null -} - -variable "master_password" { - description = "Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file. Required unless `manage_master_user_password` is set to `true` or unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database" - type = string - default = null -} - -variable "master_username" { - description = "Username for the master DB user. Required unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database" - type = string - default = null -} - -variable "network_type" { - description = "The type of network stack to use (IPV4 or DUAL)" - type = string - default = null -} - -variable "port" { - description = "The port on which the DB accepts connections" - type = string - default = null -} - -variable "preferred_backup_window" { - description = "The daily time range during which automated backups are created if automated backups are enabled using the `backup_retention_period` parameter. Time in UTC" - type = string - default = "02:00-03:00" -} - -variable "preferred_maintenance_window" { - description = "The weekly time range during which system maintenance can occur, in (UTC)" - type = string - default = "sun:05:00-sun:06:00" -} - -variable "replication_source_identifier" { - description = "ARN of a source DB cluster or DB instance if this DB cluster is to be created as a Read Replica" - type = string - default = null -} - -variable "restore_to_point_in_time" { - description = "Map of nested attributes for cloning Aurora cluster" - type = map(string) - default = {} -} - -variable "s3_import" { - description = "Configuration map used to restore from a Percona Xtrabackup in S3 (only MySQL is supported)" - type = map(string) - default = {} -} - -variable "scaling_configuration" { - description = "Map of nested attributes with scaling properties. Only valid when `engine_mode` is set to `serverless`" - type = map(string) - default = {} -} - -variable "serverlessv2_scaling_configuration" { - description = "Map of nested attributes with serverless v2 scaling properties. Only valid when `engine_mode` is set to `provisioned`" - type = map(string) - default = {} -} - -variable "skip_final_snapshot" { - description = "Determines whether a final snapshot is created before the cluster is deleted. If true is specified, no snapshot is created" - type = bool - default = false -} - -variable "snapshot_identifier" { - description = "Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot" - type = string - default = null -} - -variable "source_region" { - description = "The source region for an encrypted replica DB cluster" - type = string - default = null -} - -variable "storage_encrypted" { - description = "Specifies whether the DB cluster is encrypted. The default is `true`" - type = bool - default = true -} - -variable "storage_type" { - description = "Determines the storage type for the DB cluster. Optional for Single-AZ, required for Multi-AZ DB clusters. Valid values for Single-AZ: `aurora`, `\"\"` (default, both refer to Aurora Standard), `aurora-iopt1` (Aurora I/O Optimized). Valid values for Multi-AZ: `io1` (default)." - type = string - default = null -} - -variable "cluster_tags" { - description = "A map of tags to add to only the cluster. Used for AWS Instance Scheduler tagging" - type = map(string) - default = {} -} - -variable "vpc_security_group_ids" { - description = "List of VPC security groups to associate to the cluster in addition to the security group created" - type = list(string) - default = [] -} - -variable "cluster_timeouts" { - description = "Create, update, and delete timeout configurations for the cluster" - type = map(string) - default = {} -} - -################################################################################ -# Cluster Instance(s) -################################################################################ - -variable "instances" { - description = "Map of cluster instances and any specific/overriding attributes to be created" - type = any - default = {} -} -variable "cluster_db_instance_count" { -type = number -} - -variable "auto_minor_version_upgrade" { - description = "Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. Default `true`" - type = bool - default = null -} - -variable "ca_cert_identifier" { - description = "The identifier of the CA certificate for the DB instance" - type = string - default = null -} - -variable "db_parameter_group_name" { - description = "The name of the DB parameter group" - type = string - default = null -} - -variable "instances_use_identifier_prefix" { - description = "Determines whether cluster instance identifiers are used as prefixes" - type = bool - default = false -} - -variable "instance_class" { - description = "Instance type to use at master instance. Note: if `autoscaling_enabled` is `true`, this will be the same instance class used on instances created by autoscaling" - type = string - default = "" -} - -variable "monitoring_interval" { - description = "The interval, in seconds, between points when Enhanced Monitoring metrics are collected for instances. Set to `0` to disable. Default is `0`" - type = number - default = 0 -} - -variable "performance_insights_enabled" { - description = "Specifies whether Performance Insights is enabled or not" - type = bool - default = null -} - -variable "performance_insights_kms_key_id" { - description = "The ARN for the KMS key to encrypt Performance Insights data" - type = string - default = null -} - -variable "performance_insights_retention_period" { - description = "Amount of time in days to retain Performance Insights data. Either 7 (7 days) or 731 (2 years)" - type = number - default = null -} - -variable "publicly_accessible" { - description = "Determines whether instances are publicly accessible. Default `false`" - type = bool - default = null -} - -variable "instance_timeouts" { - description = "Create, update, and delete timeout configurations for the cluster instance(s)" - type = map(string) - default = {} -} - -################################################################################ -# Cluster Endpoint(s) -################################################################################ - -variable "endpoints" { - description = "Map of additional cluster endpoints and their attributes to be created" - type = any - default = {} -} - -################################################################################ -# Cluster IAM Roles -################################################################################ - -variable "iam_roles" { - description = "Map of IAM roles and supported feature names to associate with the cluster" - type = map(map(string)) - default = {} -} - -################################################################################ -# Enhanced Monitoring -################################################################################ - -variable "create_monitoring_role" { - description = "Determines whether to create the IAM role for RDS enhanced monitoring" - type = bool - default = true -} - -variable "monitoring_role_arn" { - description = "IAM role used by RDS to send enhanced monitoring metrics to CloudWatch" - type = string - default = "" -} - -variable "iam_role_name" { - description = "Friendly name of the monitoring role" - type = string - default = null -} - -variable "iam_role_use_name_prefix" { - description = "Determines whether to use `iam_role_name` as is or create a unique name beginning with the `iam_role_name` as the prefix" - type = bool - default = false -} - -variable "iam_role_description" { - description = "Description of the monitoring role" - type = string - default = null -} - -variable "iam_role_path" { - description = "Path for the monitoring role" - type = string - default = null -} - -variable "iam_role_managed_policy_arns" { - description = "Set of exclusive IAM managed policy ARNs to attach to the monitoring role" - type = list(string) - default = null -} - -variable "iam_role_permissions_boundary" { - description = "The ARN of the policy that is used to set the permissions boundary for the monitoring role" - type = string - default = null -} - -variable "iam_role_force_detach_policies" { - description = "Whether to force detaching any policies the monitoring role has before destroying it" - type = bool - default = null -} - -variable "iam_role_max_session_duration" { - description = "Maximum session duration (in seconds) that you want to set for the monitoring role" - type = number - default = null -} - -################################################################################ -# Autoscaling -################################################################################ - -variable "autoscaling_enabled" { - description = "Determines whether autoscaling of the cluster read replicas is enabled" - type = bool - default = false -} - -variable "autoscaling_max_capacity" { - description = "Maximum number of read replicas permitted when autoscaling is enabled" - type = number - default = 2 -} - -variable "autoscaling_min_capacity" { - description = "Minimum number of read replicas permitted when autoscaling is enabled" - type = number - default = 0 -} - -variable "autoscaling_policy_name" { - description = "Autoscaling policy name" - type = string - default = "target-metric" -} - -variable "predefined_metric_type" { - description = "The metric type to scale on. Valid values are `RDSReaderAverageCPUUtilization` and `RDSReaderAverageDatabaseConnections`" - type = string - default = "RDSReaderAverageCPUUtilization" -} - -variable "autoscaling_scale_in_cooldown" { - description = "Cooldown in seconds before allowing further scaling operations after a scale in" - type = number - default = 300 -} - -variable "autoscaling_scale_out_cooldown" { - description = "Cooldown in seconds before allowing further scaling operations after a scale out" - type = number - default = 300 -} - -variable "autoscaling_target_cpu" { - description = "CPU threshold which will initiate autoscaling" - type = number - default = 70 -} - -variable "autoscaling_target_connections" { - description = "Average number of connections threshold which will initiate autoscaling. Default value is 70% of db.r4/r5/r6g.large's default max_connections" - type = number - default = 700 -} - -################################################################################ -# Security Group -################################################################################ - -variable "create_security_group" { - description = "Determines whether to create security group for RDS cluster" - type = bool - default = true -} - -variable "security_group_name" { - description = "The security group name. Default value is (`var.name`)" - type = string - default = "" -} - -variable "security_group_use_name_prefix" { - description = "Determines whether the security group name (`var.name`) is used as a prefix" - type = bool - default = true -} - -variable "security_group_description" { - description = "The description of the security group. If value is set to empty string it will contain cluster name in the description" - type = string - default = null -} - -variable "vpc_id" { - description = "ID of the VPC where to create security group" - type = string - default = "" -} - -variable "security_group_rules" { - description = "Map of security group rules to add to the cluster security group created" - type = any - default = {} -} - -variable "security_group_tags" { - description = "Additional tags for the security group" - type = map(string) - default = {} -} - -################################################################################ -# Cluster Parameter Group -################################################################################ - -variable "create_db_cluster_parameter_group" { - description = "Determines whether a cluster parameter should be created or use existing" - type = bool - default = false -} - -variable "db_cluster_parameter_group_name" { - description = "The name of the DB cluster parameter group" - type = string - default = null -} - -variable "db_cluster_parameter_group_use_name_prefix" { - description = "Determines whether the DB cluster parameter group name is used as a prefix" - type = bool - default = true -} - -variable "db_cluster_parameter_group_description" { - description = "The description of the DB cluster parameter group. Defaults to \"Managed by Terraform\"" - type = string - default = null -} - -variable "db_cluster_parameter_group_family" { - description = "The family of the DB cluster parameter group" - type = string - default = "" -} - -variable "db_cluster_parameter_group_parameters" { - description = "A list of DB cluster parameters to apply. Note that parameters may differ from a family to an other" - type = list(map(string)) - default = [] -} - -################################################################################ -# DB Parameter Group -################################################################################ - -variable "create_db_parameter_group" { - description = "Determines whether a DB parameter should be created or use existing" - type = bool - default = false -} - -variable "db_parameter_group_use_name_prefix" { - description = "Determines whether the DB parameter group name is used as a prefix" - type = bool - default = true -} - -variable "db_parameter_group_description" { - description = "The description of the DB parameter group. Defaults to \"Managed by Terraform\"" - type = string - default = null -} - -variable "db_parameter_group_family" { - description = "The family of the DB parameter group" - type = string - default = "" -} - -variable "db_parameter_group_parameters" { - description = "A list of DB parameters to apply. Note that parameters may differ from a family to an other" - type = list(map(string)) - default = [] -} - -################################################################################ -# CloudWatch Log Group -################################################################################ - -variable "create_cloudwatch_log_group" { - description = "Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports`" - type = bool - default = false -} - -variable "cloudwatch_log_group_retention_in_days" { - description = "The number of days to retain CloudWatch logs for the DB instance" - type = number - default = 7 -} - -variable "cloudwatch_log_group_kms_key_id" { - description = "The ARN of the KMS Key to use when encrypting log data" - type = string - default = null -} - -################################################################################ -# Cluster Activity Stream -################################################################################ - -variable "create_db_cluster_activity_stream" { - description = "Determines whether a cluster activity stream is created." - type = bool - default = false -} - -variable "db_cluster_activity_stream_mode" { - description = "Specifies the mode of the database activity stream. Database events such as a change or access generate an activity stream event. One of: sync, async" - type = string - default = null -} - -variable "db_cluster_activity_stream_kms_key_id" { - description = "The AWS KMS key identifier for encrypting messages in the database activity stream" - type = string - default = null -} - -variable "engine_native_audit_fields_included" { - description = "Specifies whether the database activity stream includes engine-native audit fields. This option only applies to an Oracle DB instance. By default, no engine-native audit fields are included" - type = bool - default = false -} diff --git a/_sub/terraform-aws-rds-proxy/main.tf b/_sub/terraform-aws-rds-proxy/main.tf deleted file mode 100644 index e8a8efc6..00000000 --- a/_sub/terraform-aws-rds-proxy/main.tf +++ /dev/null @@ -1,188 +0,0 @@ -locals { - role_arn = var.create && var.create_iam_role ? aws_iam_role.this[0].arn : var.role_arn - role_name = coalesce(var.iam_role_name, var.name) - policy_name = coalesce(var.iam_policy_name, var.name) -} - -data "aws_region" "current" {} -data "aws_partition" "current" {} - -################################################################################ -# RDS Proxy -################################################################################ - -resource "aws_db_proxy" "this" { - count = var.create ? 1 : 0 - - dynamic "auth" { - for_each = var.auth - - content { - auth_scheme = try(auth.value.auth_scheme, "SECRETS") - client_password_auth_type = try(auth.value.client_password_auth_type, null) - description = try(auth.value.description, null) - iam_auth = try(auth.value.iam_auth, null) - secret_arn = try(auth.value.secret_arn, null) - username = try(auth.value.username, null) - } - } - - debug_logging = var.debug_logging - engine_family = var.engine_family - idle_client_timeout = var.idle_client_timeout - name = var.name - require_tls = var.require_tls - role_arn = local.role_arn - vpc_security_group_ids = var.vpc_security_group_ids - vpc_subnet_ids = var.vpc_subnet_ids - - tags = merge(var.tags, var.proxy_tags) - - depends_on = [aws_cloudwatch_log_group.this] -} - -resource "aws_db_proxy_default_target_group" "this" { - count = var.create ? 1 : 0 - - db_proxy_name = aws_db_proxy.this[0].name - - connection_pool_config { - connection_borrow_timeout = var.connection_borrow_timeout - init_query = var.init_query - max_connections_percent = var.max_connections_percent - max_idle_connections_percent = var.max_idle_connections_percent - session_pinning_filters = var.session_pinning_filters - } -} - -resource "aws_db_proxy_target" "db_instance" { - count = var.create && var.target_db_instance ? 1 : 0 - - db_proxy_name = aws_db_proxy.this[0].name - target_group_name = aws_db_proxy_default_target_group.this[0].name - db_instance_identifier = var.db_instance_identifier -} - -resource "aws_db_proxy_target" "db_cluster" { - count = var.create && var.target_db_cluster ? 1 : 0 - - db_proxy_name = aws_db_proxy.this[0].name - target_group_name = aws_db_proxy_default_target_group.this[0].name - db_cluster_identifier = var.db_cluster_identifier -} - -resource "aws_db_proxy_endpoint" "this" { - for_each = { for k, v in var.endpoints : k => v if var.create } - - db_proxy_name = aws_db_proxy.this[0].name - db_proxy_endpoint_name = each.value.name - vpc_subnet_ids = each.value.vpc_subnet_ids - vpc_security_group_ids = lookup(each.value, "vpc_security_group_ids", null) - target_role = lookup(each.value, "target_role", null) - - tags = lookup(each.value, "tags", var.tags) -} - -################################################################################ -# CloudWatch Logs -################################################################################ - -resource "aws_cloudwatch_log_group" "this" { - count = var.create && var.manage_log_group ? 1 : 0 - - name = "/aws/rds/proxy/${var.name}" - retention_in_days = var.log_group_retention_in_days - kms_key_id = var.log_group_kms_key_id - - tags = merge(var.tags, var.log_group_tags) - skip_destroy = var.cloudwatch_log_group_skip_destroy_on_deletion -} - -################################################################################ -# IAM Role -################################################################################ - -data "aws_iam_policy_document" "assume_role" { - count = var.create && var.create_iam_role ? 1 : 0 - - statement { - sid = "RDSAssume" - effect = "Allow" - actions = ["sts:AssumeRole"] - - principals { - type = "Service" - identifiers = ["rds.${data.aws_partition.current.dns_suffix}"] - } - } -} - -resource "aws_iam_role" "this" { - count = var.create && var.create_iam_role ? 1 : 0 - - name = var.use_role_name_prefix ? null : local.role_name - name_prefix = var.use_role_name_prefix ? "${local.role_name}-" : null - description = var.iam_role_description - path = var.iam_role_path - - assume_role_policy = data.aws_iam_policy_document.assume_role[0].json - force_detach_policies = var.iam_role_force_detach_policies - max_session_duration = var.iam_role_max_session_duration - permissions_boundary = var.iam_role_permissions_boundary - - tags = merge(var.tags, var.iam_role_tags) -} - -data "aws_iam_policy_document" "this" { - count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 - - statement { - sid = "DecryptSecrets" - effect = "Allow" - actions = ["kms:Decrypt"] - resources = coalescelist( - var.kms_key_arns, - ["arn:${data.aws_partition.current.partition}:kms:*:*:key/*"] - ) - - condition { - test = "StringEquals" - variable = "kms:ViaService" - values = [ - "secretsmanager.${data.aws_region.current.name}.${data.aws_partition.current.dns_suffix}" - ] - } - } - - statement { - sid = "ListSecrets" - effect = "Allow" - actions = [ - "secretsmanager:GetRandomPassword", - "secretsmanager:ListSecrets", - ] - resources = ["*"] - } - - statement { - sid = "GetSecrets" - effect = "Allow" - actions = [ - "secretsmanager:GetResourcePolicy", - "secretsmanager:GetSecretValue", - "secretsmanager:DescribeSecret", - "secretsmanager:ListSecretVersionIds", - ] - - resources = distinct([for auth in var.auth : auth.secret_arn]) - } -} - -resource "aws_iam_role_policy" "this" { - count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 - - name = var.use_policy_name_prefix ? null : local.policy_name - name_prefix = var.use_policy_name_prefix ? "${local.policy_name}-" : null - policy = data.aws_iam_policy_document.this[0].json - role = aws_iam_role.this[0].id -} diff --git a/_sub/terraform-aws-rds/README.md b/_sub/terraform-aws-rds/README.md deleted file mode 100644 index 81ac06dc..00000000 --- a/_sub/terraform-aws-rds/README.md +++ /dev/null @@ -1,370 +0,0 @@ -# AWS RDS Terraform module - -Terraform module which creates RDS resources on AWS. - -[![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) - -Root module calls these modules which can also be used separately to create independent resources: - -- [db_instance](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/modules/db_instance) - creates RDS DB instance -- [db_subnet_group](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/modules/db_subnet_group) - creates RDS DB subnet group -- [db_parameter_group](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/modules/db_parameter_group) - creates RDS DB parameter group -- [db_option_group](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/modules/db_option_group) - creates RDS DB option group - -## Usage - -```hcl -module "db" { - source = "terraform-aws-modules/rds/aws" - - identifier = "demodb" - - engine = "mysql" - engine_version = "5.7" - instance_class = "db.t3a.large" - allocated_storage = 5 - - db_name = "demodb" - username = "user" - port = "3306" - - iam_database_authentication_enabled = true - - vpc_security_group_ids = ["sg-12345678"] - - maintenance_window = "Mon:00:00-Mon:03:00" - backup_window = "03:00-06:00" - - # Enhanced Monitoring - see example for details on how to create the role - # by yourself, in case you don't want to create it automatically - monitoring_interval = "30" - monitoring_role_name = "MyRDSMonitoringRole" - create_monitoring_role = true - - tags = { - Owner = "user" - Environment = "dev" - } - - # DB subnet group - create_db_subnet_group = true - subnet_ids = ["subnet-12345678", "subnet-87654321"] - - # DB parameter group - family = "mysql5.7" - - # DB option group - major_engine_version = "5.7" - - # Database Deletion Protection - deletion_protection = true - - parameters = [ - { - name = "character_set_client" - value = "utf8mb4" - }, - { - name = "character_set_server" - value = "utf8mb4" - } - ] - - options = [ - { - option_name = "MARIADB_AUDIT_PLUGIN" - - option_settings = [ - { - name = "SERVER_AUDIT_EVENTS" - value = "CONNECT" - }, - { - name = "SERVER_AUDIT_FILE_ROTATIONS" - value = "37" - }, - ] - }, - ] -} -``` - -## Conditional creation - -The following values are provided to toggle on/off creation of the associated resources as desired: - -```hcl -module "db" { - source = "terraform-aws-modules/rds/aws" - - # Disable creation of RDS instance(s) - create_db_instance = false - - # Disable creation of option group - provide an option group or default AWS default - create_db_option_group = false - - # Disable creation of parameter group - provide a parameter group or default to AWS default - create_db_parameter_group = false - - # Enable creation of subnet group (disabled by default) - create_db_subnet_group = true - - # Enable creation of monitoring IAM role - create_monitoring_role = true - - # ... omitted -} -``` - -## Option Groups - -[Reference](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithOptionGroups.html) - -Users have the ability to: - -- Create an option group with the name provided: - -```hcl - option_group_name = "prod-instance-mysql-8.0" - option_group_use_name_prefix = false -``` - -- Create an option group using a unique prefix beginning with the name provided: - -```hcl - option_group_name = "prod-instance-mysql-8.0" -``` - -- Pass the name of an option group to use that has been created outside of the module: - -```hcl - create_db_option_group = false - option_group_name = "prod-instance-mysql-8.0" # must already exist in AWS -``` - -- Skip creating an option group for PostgreSQL entirely as that is not supported - -```hcl - engine = "postgres" - option_group_name = "prod-instance-postgresql-11.0" # this will be ignored, no option group created -``` - -- Use a default option group provided by AWS - -```hcl - create_db_option_group = false -``` - -## Parameter Groups - -[Reference](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.html) - -Users have the ability to: - -- Create a parameter group with the name provided: - -```hcl - parameter_group_name = "prod-instance-mysql-8.0" - parameter_group_use_name_prefix = false -``` - -- Create a parameter group using a unique prefix beginning with the name provided: - -```hcl - parameter_group_name = "prod-instance-mysql-8.0" -``` - -- Pass the name of a parameter group to use that has been created outside of the module: - -```hcl - create_db_parameter_group = false - parameter_group_name = "prod-instance-mysql-8.0" # must already exist in AWS -``` - -- Use a default parameter group provided by AWS - -```hcl - create_db_parameter_group = false -``` - -## Examples - -- [Complete RDS example for MSSQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-mssql) -- [Complete RDS example for MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-mysql) -- [Complete RDS example for Oracle](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-oracle) -- [Complete RDS example for PostgreSQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/complete-postgres) -- [Enhanced monitoring example](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/enhanced-monitoring) -- [Replica RDS example for MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/replica-mysql) -- [Replica RDS example for PostgreSQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/replica-postgres) -- [S3 import example for MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/examples/s3-import-mysql) - -## Notes - -1. This module does not create RDS security group. Use [terraform-aws-security-group](https://github.com/terraform-aws-modules/terraform-aws-security-group) module for this. -2. For an RDS instance with `storage_type` using `gp3`, be aware that `iops` and `storage_throughput` cannot be specified if the `allocated_storage` value is below a per-`engine` threshold. See the [RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html#gp3-storage) for details. - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.0 | - -## Providers - -No providers. - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [db\_instance](#module\_db\_instance) | ./modules/db_instance | n/a | -| [db\_option\_group](#module\_db\_option\_group) | ./modules/db_option_group | n/a | -| [db\_parameter\_group](#module\_db\_parameter\_group) | ./modules/db_parameter_group | n/a | -| [db\_subnet\_group](#module\_db\_subnet\_group) | ./modules/db_subnet_group | n/a | - -## Resources - -No resources. - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [allocated\_storage](#input\_allocated\_storage) | The allocated storage in gigabytes | `number` | `null` | no | -| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Indicates that major version upgrades are allowed. Changing this parameter does not result in an outage and the change is asynchronously applied as soon as possible | `bool` | `false` | no | -| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any database modifications are applied immediately, or during the next maintenance window | `bool` | `false` | no | -| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window | `bool` | `true` | no | -| [availability\_zone](#input\_availability\_zone) | The Availability Zone of the RDS instance | `string` | `null` | no | -| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `null` | no | -| [backup\_window](#input\_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` | `null` | no | -| [blue\_green\_update](#input\_blue\_green\_update) | Enables low-downtime updates using RDS Blue/Green deployments. | `map(string)` | `{}` | no | -| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | `string` | `null` | no | -| [character\_set\_name](#input\_character\_set\_name) | 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 and Collations and Character Sets for Microsoft SQL Server for more information. This can only be set on creation | `string` | `null` | no | -| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | -| [cloudwatch\_log\_group\_retention\_in\_days](#input\_cloudwatch\_log\_group\_retention\_in\_days) | The number of days to retain CloudWatch logs for the DB instance | `number` | `7` | no | -| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | On delete, copy all Instance tags to the final snapshot | `bool` | `false` | no | -| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports` | `bool` | `false` | no | -| [create\_db\_instance](#input\_create\_db\_instance) | Whether to create a database instance | `bool` | `true` | no | -| [create\_db\_option\_group](#input\_create\_db\_option\_group) | Create a database option group | `bool` | `true` | no | -| [create\_db\_parameter\_group](#input\_create\_db\_parameter\_group) | Whether to create a database parameter group | `bool` | `true` | no | -| [create\_db\_subnet\_group](#input\_create\_db\_subnet\_group) | Whether to create a database subnet group | `bool` | `false` | no | -| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Create IAM role with a defined name that permits RDS to send enhanced monitoring metrics to CloudWatch Logs | `bool` | `false` | no | -| [custom\_iam\_instance\_profile](#input\_custom\_iam\_instance\_profile) | RDS custom iam instance profile | `string` | `null` | no | -| [db\_instance\_tags](#input\_db\_instance\_tags) | Additional tags for the DB instance | `map(string)` | `{}` | no | -| [db\_name](#input\_db\_name) | The DB name to create. If omitted, no database is created initially | `string` | `null` | no | -| [db\_option\_group\_tags](#input\_db\_option\_group\_tags) | Additional tags for the DB option group | `map(string)` | `{}` | no | -| [db\_parameter\_group\_tags](#input\_db\_parameter\_group\_tags) | Additional tags for the DB parameter group | `map(string)` | `{}` | no | -| [db\_subnet\_group\_description](#input\_db\_subnet\_group\_description) | Description of the DB subnet group to create | `string` | `null` | no | -| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC | `string` | `null` | no | -| [db\_subnet\_group\_tags](#input\_db\_subnet\_group\_tags) | Additional tags for the DB subnet group | `map(string)` | `{}` | no | -| [db\_subnet\_group\_use\_name\_prefix](#input\_db\_subnet\_group\_use\_name\_prefix) | Determines whether to use `subnet_group_name` as is or create a unique name beginning with the `subnet_group_name` as the prefix | `bool` | `true` | no | -| [delete\_automated\_backups](#input\_delete\_automated\_backups) | Specifies whether to remove automated backups immediately after the DB instance is deleted | `bool` | `true` | no | -| [deletion\_protection](#input\_deletion\_protection) | The database can't be deleted when this value is set to true | `bool` | `false` | no | -| [domain](#input\_domain) | The ID of the Directory Service Active Directory domain to create the instance in | `string` | `null` | no | -| [domain\_iam\_role\_name](#input\_domain\_iam\_role\_name) | (Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service | `string` | `null` | no | -| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on engine): alert, audit, error, general, listener, slowquery, trace, postgresql (PostgreSQL), upgrade (PostgreSQL) | `list(string)` | `[]` | no | -| [engine](#input\_engine) | The database engine to use | `string` | `null` | no | -| [engine\_version](#input\_engine\_version) | The engine version to use | `string` | `null` | no | -| [family](#input\_family) | The family of the DB parameter group | `string` | `null` | no | -| [final\_snapshot\_identifier\_prefix](#input\_final\_snapshot\_identifier\_prefix) | The name which is prefixed to the final snapshot on cluster destroy | `string` | `"final"` | no | -| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or not the mappings of AWS Identity and Access Management (IAM) accounts to database accounts are enabled | `bool` | `false` | no | -| [identifier](#input\_identifier) | The name of the RDS instance | `string` | n/a | yes | -| [instance\_class](#input\_instance\_class) | The instance type of the RDS instance | `string` | `null` | no | -| [instance\_use\_identifier\_prefix](#input\_instance\_use\_identifier\_prefix) | Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix | `bool` | `false` | no | -| [iops](#input\_iops) | The amount of provisioned IOPS. Setting this implies a storage\_type of 'io1' or `gp3`. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | -| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage\_encrypted is set to true and kms\_key\_id is not specified the default KMS key created in your account will be used. Be sure to use the full ARN, not a key alias. | `string` | `null` | no | -| [license\_model](#input\_license\_model) | License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1 | `string` | `null` | no | -| [maintenance\_window](#input\_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 | -| [major\_engine\_version](#input\_major\_engine\_version) | Specifies the major version of the engine that this option group should be associated with | `string` | `null` | no | -| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager | `bool` | `true` | no | -| [master\_user\_secret\_kms\_key\_id](#input\_master\_user\_secret\_kms\_key\_id) | The key ARN, key ID, alias ARN or alias name for the KMS key to encrypt the master user password secret in Secrets Manager.
If not specified, the default KMS key for your Amazon Web Services account is used. | `string` | `null` | no | -| [max\_allocated\_storage](#input\_max\_allocated\_storage) | Specifies the value for Storage Autoscaling | `number` | `0` | no | -| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. The default is 0. Valid Values: 0, 1, 5, 10, 15, 30, 60 | `number` | `0` | no | -| [monitoring\_role\_arn](#input\_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` | `null` | no | -| [monitoring\_role\_description](#input\_monitoring\_role\_description) | Description of the monitoring IAM role | `string` | `null` | no | -| [monitoring\_role\_name](#input\_monitoring\_role\_name) | Name of the IAM role which will be created when create\_monitoring\_role is enabled | `string` | `"rds-monitoring-role"` | no | -| [monitoring\_role\_permissions\_boundary](#input\_monitoring\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the monitoring IAM role | `string` | `null` | no | -| [monitoring\_role\_use\_name\_prefix](#input\_monitoring\_role\_use\_name\_prefix) | Determines whether to use `monitoring_role_name` as is or create a unique identifier beginning with `monitoring_role_name` as the specified prefix | `bool` | `false` | no | -| [multi\_az](#input\_multi\_az) | Specifies if the RDS instance is multi-AZ | `bool` | `false` | no | -| [nchar\_character\_set\_name](#input\_nchar\_character\_set\_name) | The national character set is used in the NCHAR, NVARCHAR2, and NCLOB data types for Oracle instances. This can't be changed. | `string` | `null` | no | -| [network\_type](#input\_network\_type) | The type of network stack to use | `string` | `null` | no | -| [option\_group\_description](#input\_option\_group\_description) | The description of the option group | `string` | `null` | no | -| [option\_group\_name](#input\_option\_group\_name) | Name of the option group | `string` | `null` | no | -| [option\_group\_timeouts](#input\_option\_group\_timeouts) | Define maximum timeout for deletion of `aws_db_option_group` resource | `map(string)` | `{}` | no | -| [option\_group\_use\_name\_prefix](#input\_option\_group\_use\_name\_prefix) | Determines whether to use `option_group_name` as is or create a unique name beginning with the `option_group_name` as the prefix | `bool` | `true` | no | -| [options](#input\_options) | A list of Options to apply | `any` | `[]` | no | -| [parameter\_group\_description](#input\_parameter\_group\_description) | Description of the DB parameter group to create | `string` | `null` | no | -| [parameter\_group\_name](#input\_parameter\_group\_name) | Name of the DB parameter group to associate or create | `string` | `null` | no | -| [parameter\_group\_use\_name\_prefix](#input\_parameter\_group\_use\_name\_prefix) | Determines whether to use `parameter_group_name` as is or create a unique name beginning with the `parameter_group_name` as the prefix | `bool` | `true` | no | -| [parameters](#input\_parameters) | A list of DB parameters (map) to apply | `list(map(string))` | `[]` | no | -| [password](#input\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file.
The password provided will not be used if `manage_master_user_password` is set to true. | `string` | `null` | no | -| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Specifies whether Performance Insights are enabled | `bool` | `false` | no | -| [performance\_insights\_kms\_key\_id](#input\_performance\_insights\_kms\_key\_id) | The ARN for the KMS key to encrypt Performance Insights data | `string` | `null` | no | -| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | The amount of time in days to retain Performance Insights data. Valid values are `7`, `731` (2 years) or a multiple of `31` | `number` | `7` | no | -| [port](#input\_port) | The port on which the DB accepts connections | `string` | `null` | no | -| [publicly\_accessible](#input\_publicly\_accessible) | Bool to control if instance is publicly accessible | `bool` | `false` | no | -| [putin\_khuylo](#input\_putin\_khuylo) | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | `bool` | `true` | no | -| [replica\_mode](#input\_replica\_mode) | Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified | `string` | `null` | no | -| [replicate\_source\_db](#input\_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 | -| [restore\_to\_point\_in\_time](#input\_restore\_to\_point\_in\_time) | Restore to a point in time (MySQL is NOT supported) | `map(string)` | `null` | no | -| [s3\_import](#input\_s3\_import) | Restore from a Percona Xtrabackup in S3 (only MySQL is supported) | `map(string)` | `null` | no | -| [skip\_final\_snapshot](#input\_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 | `bool` | `false` | no | -| [snapshot\_identifier](#input\_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, e.g: rds:production-2015-06-26-06-05 | `string` | `null` | no | -| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB instance is encrypted | `bool` | `true` | no | -| [storage\_throughput](#input\_storage\_throughput) | Storage throughput value for the DB instance. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | -| [storage\_type](#input\_storage\_type) | One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter | `string` | `null` | no | -| [subnet\_ids](#input\_subnet\_ids) | A list of VPC subnet IDs | `list(string)` | `[]` | no | -| [tags](#input\_tags) | A mapping of tags to assign to all resources | `map(string)` | `{}` | no | -| [timeouts](#input\_timeouts) | Updated Terraform resource management timeouts. Applies to `aws_db_instance` in particular to permit resource management times | `map(string)` | `{}` | no | -| [timezone](#input\_timezone) | 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 | `string` | `null` | no | -| [username](#input\_username) | Username for the master DB user | `string` | `null` | no | -| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of VPC security groups to associate | `list(string)` | `[]` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [db\_instance\_address](#output\_db\_instance\_address) | The address of the RDS instance | -| [db\_instance\_arn](#output\_db\_instance\_arn) | The ARN of the RDS instance | -| [db\_instance\_availability\_zone](#output\_db\_instance\_availability\_zone) | The availability zone of the RDS instance | -| [db\_instance\_ca\_cert\_identifier](#output\_db\_instance\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | -| [db\_instance\_cloudwatch\_log\_groups](#output\_db\_instance\_cloudwatch\_log\_groups) | Map of CloudWatch log groups created and their attributes | -| [db\_instance\_domain](#output\_db\_instance\_domain) | The ID of the Directory Service Active Directory domain the instance is joined to | -| [db\_instance\_domain\_iam\_role\_name](#output\_db\_instance\_domain\_iam\_role\_name) | The name of the IAM role to be used when making API calls to the Directory Service | -| [db\_instance\_endpoint](#output\_db\_instance\_endpoint) | The connection endpoint | -| [db\_instance\_engine](#output\_db\_instance\_engine) | The database engine | -| [db\_instance\_engine\_version\_actual](#output\_db\_instance\_engine\_version\_actual) | The running version of the database | -| [db\_instance\_hosted\_zone\_id](#output\_db\_instance\_hosted\_zone\_id) | The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record) | -| [db\_instance\_identifier](#output\_db\_instance\_identifier) | The RDS instance identifier | -| [db\_instance\_master\_user\_secret\_arn](#output\_db\_instance\_master\_user\_secret\_arn) | The ARN of the master user secret (Only available when manage\_master\_user\_password is set to true) | -| [db\_instance\_name](#output\_db\_instance\_name) | The database name | -| [db\_instance\_port](#output\_db\_instance\_port) | The database port | -| [db\_instance\_resource\_id](#output\_db\_instance\_resource\_id) | The RDS Resource ID of this instance | -| [db\_instance\_status](#output\_db\_instance\_status) | The RDS instance status | -| [db\_instance\_username](#output\_db\_instance\_username) | The master username for the database | -| [db\_listener\_endpoint](#output\_db\_listener\_endpoint) | Specifies the listener connection endpoint for SQL Server Always On | -| [db\_option\_group\_arn](#output\_db\_option\_group\_arn) | The ARN of the db option group | -| [db\_option\_group\_id](#output\_db\_option\_group\_id) | The db option group id | -| [db\_parameter\_group\_arn](#output\_db\_parameter\_group\_arn) | The ARN of the db parameter group | -| [db\_parameter\_group\_id](#output\_db\_parameter\_group\_id) | The db parameter group id | -| [db\_subnet\_group\_arn](#output\_db\_subnet\_group\_arn) | The ARN of the db subnet group | -| [db\_subnet\_group\_id](#output\_db\_subnet\_group\_id) | The db subnet group name | -| [enhanced\_monitoring\_iam\_role\_arn](#output\_enhanced\_monitoring\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the monitoring role | -| [enhanced\_monitoring\_iam\_role\_name](#output\_enhanced\_monitoring\_iam\_role\_name) | The name of the monitoring role | - - -## Authors - -Module is maintained by [Anton Babenko](https://github.com/antonbabenko) with help from [these awesome contributors](https://github.com/terraform-aws-modules/terraform-aws-rds/graphs/contributors). - -## License - -Apache 2 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds/tree/master/LICENSE) for full details. - -## Additional information for users from Russia and Belarus - -* Russia has [illegally annexed Crimea in 2014](https://en.wikipedia.org/wiki/Annexation_of_Crimea_by_the_Russian_Federation) and [brought the war in Donbas](https://en.wikipedia.org/wiki/War_in_Donbas) followed by [full-scale invasion of Ukraine in 2022](https://en.wikipedia.org/wiki/2022_Russian_invasion_of_Ukraine). -* Russia has brought sorrow and devastations to millions of Ukrainians, killed hundreds of innocent people, damaged thousands of buildings, and forced several million people to flee. -* [Putin khuylo!](https://en.wikipedia.org/wiki/Putin_khuylo!) diff --git a/_sub/terraform-aws-rds/main.tf b/_sub/terraform-aws-rds/main.tf deleted file mode 100644 index 19261931..00000000 --- a/_sub/terraform-aws-rds/main.tf +++ /dev/null @@ -1,150 +0,0 @@ -locals { - create_db_subnet_group = var.create_db_subnet_group - create_db_parameter_group = var.create_db_parameter_group - create_db_instance = var.create_db_instance - - ### - db_subnet_group_name = var.create_db_subnet_group ? module.db_subnet_group.db_subnet_group_id : var.db_subnet_group_name - # db_subnet_group_name = var.db_subnet_group_name # for now - ### - - parameter_group_name_id = var.create_db_parameter_group ? module.db_parameter_group.db_parameter_group_id : var.parameter_group_name - - create_db_option_group = var.create_db_option_group && var.engine != "postgres" - option_group = local.create_db_option_group ? module.db_option_group.db_option_group_id : var.option_group_name -} - -module "db_subnet_group" { - source = "./modules/db_subnet_group" - - create = local.create_db_subnet_group - - name = coalesce(var.db_subnet_group_name, var.identifier) - use_name_prefix = var.db_subnet_group_use_name_prefix - description = var.db_subnet_group_description - subnet_ids = var.subnet_ids - - tags = merge(var.tags, var.db_subnet_group_tags) -} - -module "db_parameter_group" { - source = "./modules/db_parameter_group" - - create = local.create_db_parameter_group - - name = coalesce(var.parameter_group_name, var.identifier) - use_name_prefix = var.parameter_group_use_name_prefix - description = var.parameter_group_description - family = var.family - - parameters = var.parameters - - tags = merge(var.tags, var.db_parameter_group_tags) -} - -module "db_option_group" { - source = "./modules/db_option_group" - - create = local.create_db_option_group - - name = coalesce(var.option_group_name, var.identifier) - use_name_prefix = var.option_group_use_name_prefix - option_group_description = var.option_group_description - engine_name = var.engine - major_engine_version = var.major_engine_version - - options = var.options - - timeouts = var.option_group_timeouts - - tags = merge(var.tags, var.db_option_group_tags) -} - -module "db_instance" { - source = "./modules/db_instance" - - create = local.create_db_instance - identifier = var.identifier - use_identifier_prefix = var.instance_use_identifier_prefix - - 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 - - db_name = var.db_name - username = var.username - password = var.manage_master_user_password ? null : var.password - port = var.port - domain = var.domain - domain_iam_role_name = var.domain_iam_role_name - iam_database_authentication_enabled = var.iam_database_authentication_enabled - custom_iam_instance_profile = var.custom_iam_instance_profile - manage_master_user_password = var.manage_master_user_password - master_user_secret_kms_key_id = var.master_user_secret_kms_key_id - - vpc_security_group_ids = var.vpc_security_group_ids - db_subnet_group_name = local.db_subnet_group_name - parameter_group_name = local.parameter_group_name_id - option_group_name = var.engine != "postgres" ? local.option_group : null - network_type = var.network_type - - availability_zone = var.availability_zone - multi_az = var.multi_az - iops = var.iops - storage_throughput = var.storage_throughput - publicly_accessible = var.publicly_accessible - ca_cert_identifier = var.ca_cert_identifier - - 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 - blue_green_update = var.blue_green_update - - snapshot_identifier = var.snapshot_identifier - copy_tags_to_snapshot = var.copy_tags_to_snapshot - skip_final_snapshot = var.skip_final_snapshot - final_snapshot_identifier_prefix = var.final_snapshot_identifier_prefix - - performance_insights_enabled = var.performance_insights_enabled - performance_insights_retention_period = var.performance_insights_retention_period - performance_insights_kms_key_id = var.performance_insights_enabled ? var.performance_insights_kms_key_id : null - - replicate_source_db = var.replicate_source_db - replica_mode = var.replica_mode - backup_retention_period = var.backup_retention_period - backup_window = var.backup_window - max_allocated_storage = var.max_allocated_storage - monitoring_interval = var.monitoring_interval - monitoring_role_arn = var.monitoring_role_arn - monitoring_role_name = var.monitoring_role_name - monitoring_role_use_name_prefix = var.monitoring_role_use_name_prefix - monitoring_role_description = var.monitoring_role_description - create_monitoring_role = var.create_monitoring_role - monitoring_role_permissions_boundary = var.monitoring_role_permissions_boundary - - character_set_name = var.character_set_name - nchar_character_set_name = var.nchar_character_set_name - timezone = var.timezone - - enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports - create_cloudwatch_log_group = var.create_cloudwatch_log_group - cloudwatch_log_group_retention_in_days = var.cloudwatch_log_group_retention_in_days - cloudwatch_log_group_kms_key_id = var.cloudwatch_log_group_kms_key_id - cloudwatch_log_group_skip_destroy_on_deletion = var.cloudwatch_log_group_skip_destroy_on_deletion - - timeouts = var.timeouts - - deletion_protection = var.deletion_protection - delete_automated_backups = var.delete_automated_backups - - restore_to_point_in_time = var.restore_to_point_in_time - s3_import = var.s3_import - - tags = merge(var.tags, var.db_instance_tags) -} diff --git a/_sub/terraform-aws-rds/modules/db_instance/main.tf b/_sub/terraform-aws-rds/modules/db_instance/main.tf deleted file mode 100644 index 3e013e35..00000000 --- a/_sub/terraform-aws-rds/modules/db_instance/main.tf +++ /dev/null @@ -1,200 +0,0 @@ -locals { - monitoring_role_arn = var.create_monitoring_role ? aws_iam_role.enhanced_monitoring[0].arn : var.monitoring_role_arn - - final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.final_snapshot_identifier_prefix}-${var.identifier}-${try(random_id.snapshot_identifier[0].hex, "")}" - - identifier = var.use_identifier_prefix ? null : var.identifier - identifier_prefix = var.use_identifier_prefix ? "${var.identifier}-" : null - - monitoring_role_name = var.monitoring_role_use_name_prefix ? null : var.monitoring_role_name - monitoring_role_name_prefix = var.monitoring_role_use_name_prefix ? "${var.monitoring_role_name}-" : null - - # Replicas will use source metadata - is_replica = var.replicate_source_db != null -} - -# Ref. https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces -data "aws_partition" "current" {} - -resource "random_id" "snapshot_identifier" { - count = var.create && !var.skip_final_snapshot ? 1 : 0 - - keepers = { - id = var.identifier - } - - byte_length = 4 -} - -resource "aws_db_instance" "this" { - count = var.create ? 1 : 0 - - identifier = local.identifier - identifier_prefix = local.identifier_prefix - - engine = local.is_replica ? null : var.engine - engine_version = var.engine_version - instance_class = var.instance_class - allocated_storage = local.is_replica ? null : 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 - - db_name = var.db_name - username = !local.is_replica ? var.username : null - password = !local.is_replica && var.manage_master_user_password ? null : var.password - port = var.port - domain = var.domain - domain_iam_role_name = var.domain_iam_role_name - iam_database_authentication_enabled = var.iam_database_authentication_enabled - custom_iam_instance_profile = var.custom_iam_instance_profile - manage_master_user_password = !local.is_replica && var.manage_master_user_password ? var.manage_master_user_password : null - master_user_secret_kms_key_id = !local.is_replica && var.manage_master_user_password ? var.master_user_secret_kms_key_id : null - - 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 - option_group_name = var.option_group_name - network_type = var.network_type - - availability_zone = var.availability_zone - multi_az = var.multi_az - iops = var.iops - storage_throughput = var.storage_throughput - publicly_accessible = var.publicly_accessible - ca_cert_identifier = var.ca_cert_identifier - - 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 - - # https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html - dynamic "blue_green_update" { - for_each = length(var.blue_green_update) > 0 ? [var.blue_green_update] : [] - - content { - enabled = try(blue_green_update.value.enabled, null) - } - } - - snapshot_identifier = var.snapshot_identifier - copy_tags_to_snapshot = var.copy_tags_to_snapshot - skip_final_snapshot = var.skip_final_snapshot - final_snapshot_identifier = local.final_snapshot_identifier - - performance_insights_enabled = var.performance_insights_enabled - performance_insights_retention_period = var.performance_insights_enabled ? var.performance_insights_retention_period : null - performance_insights_kms_key_id = var.performance_insights_enabled ? var.performance_insights_kms_key_id : null - - replicate_source_db = var.replicate_source_db - replica_mode = var.replica_mode - backup_retention_period = length(var.blue_green_update) > 0 ? coalesce(var.backup_retention_period, 1) : var.backup_retention_period - backup_window = var.backup_window - max_allocated_storage = var.max_allocated_storage - monitoring_interval = var.monitoring_interval - monitoring_role_arn = var.monitoring_interval > 0 ? local.monitoring_role_arn : null - - character_set_name = var.character_set_name - nchar_character_set_name = var.nchar_character_set_name - timezone = var.timezone - enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports - - deletion_protection = var.deletion_protection - delete_automated_backups = var.delete_automated_backups - - dynamic "restore_to_point_in_time" { - for_each = var.restore_to_point_in_time != null ? [var.restore_to_point_in_time] : [] - - content { - restore_time = lookup(restore_to_point_in_time.value, "restore_time", null) - source_db_instance_automated_backups_arn = lookup(restore_to_point_in_time.value, "source_db_instance_automated_backups_arn", null) - source_db_instance_identifier = lookup(restore_to_point_in_time.value, "source_db_instance_identifier", null) - source_dbi_resource_id = lookup(restore_to_point_in_time.value, "source_dbi_resource_id", null) - use_latest_restorable_time = lookup(restore_to_point_in_time.value, "use_latest_restorable_time", null) - } - } - - dynamic "s3_import" { - for_each = var.s3_import != null ? [var.s3_import] : [] - - content { - source_engine = "mysql" - source_engine_version = s3_import.value.source_engine_version - bucket_name = s3_import.value.bucket_name - bucket_prefix = lookup(s3_import.value, "bucket_prefix", null) - ingestion_role = s3_import.value.ingestion_role - } - } - - tags = var.tags - - depends_on = [aws_cloudwatch_log_group.this] - - timeouts { - create = lookup(var.timeouts, "create", null) - delete = lookup(var.timeouts, "delete", null) - update = lookup(var.timeouts, "update", null) - } - - # Note: do not add `latest_restorable_time` to `ignore_changes` - # https://github.com/terraform-aws-modules/terraform-aws-rds/issues/478 -} - -################################################################################ -# CloudWatch Log Group -################################################################################ - -# Log groups will not be created if using an identifier prefix ?? -resource "aws_cloudwatch_log_group" "this" { - # for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log if var.create && var.create_cloudwatch_log_group && !var.use_identifier_prefix]) - for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log if var.create && var.create_cloudwatch_log_group]) - - name = "/aws/rds/instance/${var.identifier}/${each.value}" # it is not possible to use the identifier_prefix here since it is not known at plan time and we can't have cyclic reference to the db instance resource - retention_in_days = var.cloudwatch_log_group_retention_in_days - kms_key_id = var.cloudwatch_log_group_kms_key_id - skip_destroy = var.cloudwatch_log_group_skip_destroy_on_deletion - tags = var.tags -} - -################################################################################ -# Enhanced monitoring -################################################################################ - -data "aws_iam_policy_document" "enhanced_monitoring" { - statement { - actions = [ - "sts:AssumeRole", - ] - - principals { - type = "Service" - identifiers = ["monitoring.rds.amazonaws.com"] - } - } -} - -resource "aws_iam_role" "enhanced_monitoring" { - count = var.create_monitoring_role ? 1 : 0 - - name = local.monitoring_role_name - name_prefix = local.monitoring_role_name_prefix - assume_role_policy = data.aws_iam_policy_document.enhanced_monitoring.json - description = var.monitoring_role_description - permissions_boundary = var.monitoring_role_permissions_boundary - path = var.monitoring_iam_role_path - tags = merge( - { - "Name" = format("%s", var.monitoring_role_name) - }, - var.tags, - ) -} - -resource "aws_iam_role_policy_attachment" "enhanced_monitoring" { - count = var.create_monitoring_role ? 1 : 0 - - role = aws_iam_role.enhanced_monitoring[0].name - policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" -} diff --git a/_sub/terraform-aws-rds/modules/db_instance/outputs.tf b/_sub/terraform-aws-rds/modules/db_instance/outputs.tf deleted file mode 100644 index de06eb57..00000000 --- a/_sub/terraform-aws-rds/modules/db_instance/outputs.tf +++ /dev/null @@ -1,109 +0,0 @@ -output "enhanced_monitoring_iam_role_name" { - description = "The name of the monitoring role" - value = try(aws_iam_role.enhanced_monitoring[0].name, null) -} - -output "enhanced_monitoring_iam_role_arn" { - description = "The Amazon Resource Name (ARN) specifying the monitoring role" - value = try(aws_iam_role.enhanced_monitoring[0].arn, null) -} - -output "db_instance_address" { - description = "The address of the RDS instance" - value = try(aws_db_instance.this[0].address, null) -} - -output "db_instance_arn" { - description = "The ARN of the RDS instance" - value = try(aws_db_instance.this[0].arn, null) -} - -output "db_instance_availability_zone" { - description = "The availability zone of the RDS instance" - value = try(aws_db_instance.this[0].availability_zone, null) -} - -output "db_instance_endpoint" { - description = "The connection endpoint" - value = try(aws_db_instance.this[0].endpoint, null) -} - -output "db_listener_endpoint" { - description = "Specifies the listener connection endpoint for SQL Server Always On" - value = try(aws_db_instance.this[0].listener_endpoint, null) -} - -output "db_instance_engine" { - description = "The database engine" - value = try(aws_db_instance.this[0].engine, null) -} - -output "db_instance_engine_version_actual" { - description = "The running version of the database" - value = try(aws_db_instance.this[0].engine_version_actual, null) -} - -output "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 = try(aws_db_instance.this[0].hosted_zone_id, null) -} - -output "db_instance_identifier" { - description = "The RDS instance identifier" - value = try(aws_db_instance.this[0].identifier, null) -} - -output "db_instance_resource_id" { - description = "The RDS Resource ID of this instance" - value = try(aws_db_instance.this[0].resource_id, null) -} - -output "db_instance_status" { - description = "The RDS instance status" - value = try(aws_db_instance.this[0].status, null) -} - -output "db_instance_name" { - description = "The database name" - value = try(aws_db_instance.this[0].db_name, null) -} - -output "db_instance_username" { - description = "The master username for the database" - value = try(aws_db_instance.this[0].username, null) - sensitive = true -} - -output "db_instance_port" { - description = "The database port" - value = try(aws_db_instance.this[0].port, null) -} - -output "db_instance_ca_cert_identifier" { - description = "Specifies the identifier of the CA certificate for the DB instance" - value = try(aws_db_instance.this[0].ca_cert_identifier, null) -} - -output "db_instance_domain" { - description = "The ID of the Directory Service Active Directory domain the instance is joined to" - value = try(aws_db_instance.this[0].domain, null) -} - -output "db_instance_domain_iam_role_name" { - description = "The name of the IAM role to be used when making API calls to the Directory Service" - value = try(aws_db_instance.this[0].domain_iam_role_name, null) -} - -output "db_instance_master_user_secret_arn" { - description = "The ARN of the master user secret (Only available when manage_master_user_password is set to true)" - value = try(aws_db_instance.this[0].master_user_secret[0].secret_arn, null) -} - -################################################################################ -# CloudWatch Log Group -################################################################################ - -output "db_instance_cloudwatch_log_groups" { - description = "Map of CloudWatch log groups created and their attributes" - value = aws_cloudwatch_log_group.this -} diff --git a/_sub/terraform-aws-rds/modules/db_instance/variables.tf b/_sub/terraform-aws-rds/modules/db_instance/variables.tf deleted file mode 100644 index 06d75222..00000000 --- a/_sub/terraform-aws-rds/modules/db_instance/variables.tf +++ /dev/null @@ -1,431 +0,0 @@ -variable "create" { - description = "Whether to create this resource or not?" - type = bool - default = true -} - -variable "identifier" { - description = "The name of the RDS instance" - type = string -} -variable "custom_iam_instance_profile" { - description = "RDS custom iam instance profile" - type = string - default = null -} - -variable "use_identifier_prefix" { - description = "Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix" - type = bool - default = false -} - -variable "allocated_storage" { - description = "The allocated storage in gigabytes" - type = number - default = null -} - -variable "storage_type" { - description = "One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter" - type = string - default = null -} - -variable "storage_throughput" { - description = "Storage throughput value for the DB instance. This setting applies only to the `gp3` storage type. See `notes` for limitations regarding this variable for `gp3`" - type = number - default = null -} - -variable "storage_encrypted" { - description = "Specifies whether the DB instance is encrypted" - type = bool - default = true -} - -variable "kms_key_id" { - description = "The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage_encrypted is set to true and kms_key_id is not specified the default KMS key created in your account will be used" - type = string - default = null -} - -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." - type = string - default = null -} - -variable "license_model" { - description = "License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1" - type = string - default = null -} - -variable "replica_mode" { - description = "Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified" - type = string - default = null -} - -variable "iam_database_authentication_enabled" { - description = "Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled" - type = bool - default = false -} - -variable "domain" { - description = "The ID of the Directory Service Active Directory domain to create the instance in" - type = string - default = null -} - -variable "domain_iam_role_name" { - description = "(Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service" - type = string - default = null -} - -variable "engine" { - description = "The database engine to use" - type = string - default = null -} - -variable "engine_version" { - description = "The engine version to use" - type = string - default = null -} - -variable "instance_class" { - description = "The instance type of the RDS instance" - type = string - default = null -} - -variable "db_name" { - description = "The DB name to create. If omitted, no database is created initially" - type = string - default = null -} - -variable "username" { - description = "Username for the master DB user" - type = string - default = null -} - -variable "password" { - description = "Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file" - type = string - default = null -} - -variable "manage_master_user_password" { - description = "Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if password is provided" - type = bool - default = false -} - -variable "master_user_secret_kms_key_id" { - description = < -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.0 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | >= 5.0 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [aws_db_option_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_option_group) | resource | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | -| [engine\_name](#input\_engine\_name) | Specifies the name of the engine that this option group should be associated with | `string` | `null` | no | -| [major\_engine\_version](#input\_major\_engine\_version) | Specifies the major version of the engine that this option group should be associated with | `string` | `null` | no | -| [name](#input\_name) | The name of the option group | `string` | `""` | no | -| [option\_group\_description](#input\_option\_group\_description) | The description of the option group | `string` | `null` | no | -| [options](#input\_options) | A list of Options to apply | `any` | `[]` | no | -| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | -| [timeouts](#input\_timeouts) | Define maximum timeout for deletion of `aws_db_option_group` resource | `map(string)` | `{}` | no | -| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix | `bool` | `true` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [db\_option\_group\_arn](#output\_db\_option\_group\_arn) | The ARN of the db option group | -| [db\_option\_group\_id](#output\_db\_option\_group\_id) | The db option group id | - diff --git a/_sub/terraform-aws-rds/modules/db_option_group/main.tf b/_sub/terraform-aws-rds/modules/db_option_group/main.tf deleted file mode 100644 index 6ae35840..00000000 --- a/_sub/terraform-aws-rds/modules/db_option_group/main.tf +++ /dev/null @@ -1,50 +0,0 @@ -locals { - name = var.use_name_prefix ? null : var.name - name_prefix = var.use_name_prefix ? "${var.name}-" : null - - description = coalesce(var.option_group_description, format("%s option group", var.name)) -} - -resource "aws_db_option_group" "this" { - count = var.create ? 1 : 0 - - name = local.name - name_prefix = local.name_prefix - option_group_description = local.description - engine_name = var.engine_name - major_engine_version = var.major_engine_version - - dynamic "option" { - for_each = var.options - content { - option_name = option.value.option_name - port = lookup(option.value, "port", null) - version = lookup(option.value, "version", null) - db_security_group_memberships = lookup(option.value, "db_security_group_memberships", null) - vpc_security_group_memberships = lookup(option.value, "vpc_security_group_memberships", null) - - dynamic "option_settings" { - for_each = lookup(option.value, "option_settings", []) - content { - name = lookup(option_settings.value, "name", null) - value = lookup(option_settings.value, "value", null) - } - } - } - } - - tags = merge( - var.tags, - { - "Name" = var.name - }, - ) - - timeouts { - delete = lookup(var.timeouts, "delete", null) - } - - lifecycle { - create_before_destroy = true - } -} diff --git a/_sub/terraform-aws-rds/modules/db_option_group/outputs.tf b/_sub/terraform-aws-rds/modules/db_option_group/outputs.tf deleted file mode 100644 index 377e169a..00000000 --- a/_sub/terraform-aws-rds/modules/db_option_group/outputs.tf +++ /dev/null @@ -1,9 +0,0 @@ -output "db_option_group_id" { - description = "The db option group id" - value = try(aws_db_option_group.this[0].id, null) -} - -output "db_option_group_arn" { - description = "The ARN of the db option group" - value = try(aws_db_option_group.this[0].arn, null) -} diff --git a/_sub/terraform-aws-rds/modules/db_option_group/variables.tf b/_sub/terraform-aws-rds/modules/db_option_group/variables.tf deleted file mode 100644 index de4be194..00000000 --- a/_sub/terraform-aws-rds/modules/db_option_group/variables.tf +++ /dev/null @@ -1,53 +0,0 @@ -variable "create" { - description = "Whether to create this resource or not?" - type = bool - default = true -} - -variable "name" { - description = "The name of the option group" - type = string - default = "" -} - -variable "use_name_prefix" { - description = "Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix" - type = bool - default = true -} - -variable "option_group_description" { - description = "The description of the option group" - type = string - default = null -} - -variable "engine_name" { - description = "Specifies the name of the engine that this option group should be associated with" - type = string - default = null -} - -variable "major_engine_version" { - description = "Specifies the major version of the engine that this option group should be associated with" - type = string - default = null -} - -variable "options" { - description = "A list of Options to apply" - type = any - default = [] -} - -variable "timeouts" { - description = "Define maximum timeout for deletion of `aws_db_option_group` resource" - type = map(string) - default = {} -} - -variable "tags" { - description = "A mapping of tags to assign to the resource" - type = map(string) - default = {} -} diff --git a/_sub/terraform-aws-rds/modules/db_parameter_group/main.tf b/_sub/terraform-aws-rds/modules/db_parameter_group/main.tf deleted file mode 100644 index 94acbe5e..00000000 --- a/_sub/terraform-aws-rds/modules/db_parameter_group/main.tf +++ /dev/null @@ -1,35 +0,0 @@ -locals { - name = var.use_name_prefix ? null : var.name - name_prefix = var.use_name_prefix ? "${var.name}-" : null - - description = coalesce(var.description, format("%s parameter group", var.name)) -} - -resource "aws_db_parameter_group" "this" { - count = var.create ? 1 : 0 - - name = local.name - name_prefix = local.name_prefix - description = local.description - family = var.family - - dynamic "parameter" { - for_each = var.parameters - content { - name = parameter.value.name - value = parameter.value.value - apply_method = lookup(parameter.value, "apply_method", null) - } - } - - tags = merge( - var.tags, - { - "Name" = var.name - }, - ) - - lifecycle { - create_before_destroy = true - } -} diff --git a/_sub/terraform-aws-rds/modules/db_parameter_group/outputs.tf b/_sub/terraform-aws-rds/modules/db_parameter_group/outputs.tf deleted file mode 100644 index 0ea46412..00000000 --- a/_sub/terraform-aws-rds/modules/db_parameter_group/outputs.tf +++ /dev/null @@ -1,9 +0,0 @@ -output "db_parameter_group_id" { - description = "The db parameter group id" - value = try(aws_db_parameter_group.this[0].id, null) -} - -output "db_parameter_group_arn" { - description = "The ARN of the db parameter group" - value = try(aws_db_parameter_group.this[0].arn, null) -} diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/main.tf b/_sub/terraform-aws-rds/modules/db_subnet_group/main.tf deleted file mode 100644 index 6eecd88a..00000000 --- a/_sub/terraform-aws-rds/modules/db_subnet_group/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -locals { - name = var.use_name_prefix ? null : var.name - name_prefix = var.use_name_prefix ? "${var.name}-" : null - - description = coalesce(var.description, format("%s subnet group", var.name)) -} - -resource "aws_db_subnet_group" "this" { - count = var.create ? 1 : 0 - - name = local.name - name_prefix = local.name_prefix - description = local.description - subnet_ids = var.subnet_ids - - tags = merge( - var.tags, - { - "Name" = var.name - }, - ) -} diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/outputs.tf b/_sub/terraform-aws-rds/modules/db_subnet_group/outputs.tf deleted file mode 100644 index dd92fe8b..00000000 --- a/_sub/terraform-aws-rds/modules/db_subnet_group/outputs.tf +++ /dev/null @@ -1,9 +0,0 @@ -output "db_subnet_group_id" { - description = "The db subnet group name" - value = try(aws_db_subnet_group.this[0].id, null) -} - -output "db_subnet_group_arn" { - description = "The ARN of the db subnet group" - value = try(aws_db_subnet_group.this[0].arn, null) -} diff --git a/_sub/terraform-aws-rds/outputs.tf b/_sub/terraform-aws-rds/outputs.tf deleted file mode 100644 index f9c771ec..00000000 --- a/_sub/terraform-aws-rds/outputs.tf +++ /dev/null @@ -1,140 +0,0 @@ -output "enhanced_monitoring_iam_role_name" { - description = "The name of the monitoring role" - value = module.db_instance.enhanced_monitoring_iam_role_name -} - -output "enhanced_monitoring_iam_role_arn" { - description = "The Amazon Resource Name (ARN) specifying the monitoring role" - value = module.db_instance.enhanced_monitoring_iam_role_arn -} - -output "db_instance_address" { - description = "The address of the RDS instance" - value = module.db_instance.db_instance_address -} - -output "db_instance_arn" { - description = "The ARN of the RDS instance" - value = module.db_instance.db_instance_arn -} - -output "db_instance_availability_zone" { - description = "The availability zone of the RDS instance" - value = module.db_instance.db_instance_availability_zone -} - -output "db_instance_endpoint" { - description = "The connection endpoint" - value = module.db_instance.db_instance_endpoint -} - -output "db_listener_endpoint" { - description = "Specifies the listener connection endpoint for SQL Server Always On" - value = module.db_instance.db_listener_endpoint -} - -output "db_instance_engine" { - description = "The database engine" - value = module.db_instance.db_instance_engine -} - -output "db_instance_engine_version_actual" { - description = "The running version of the database" - value = module.db_instance.db_instance_engine_version_actual -} - -output "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_instance.db_instance_hosted_zone_id -} - -output "db_instance_identifier" { - description = "The RDS instance identifier" - value = module.db_instance.db_instance_identifier -} - -output "db_instance_resource_id" { - description = "The RDS Resource ID of this instance" - value = module.db_instance.db_instance_resource_id -} - -output "db_instance_status" { - description = "The RDS instance status" - value = module.db_instance.db_instance_status -} - -output "db_instance_name" { - description = "The database name" - value = module.db_instance.db_instance_name -} - -output "db_instance_username" { - description = "The master username for the database" - value = module.db_instance.db_instance_username - sensitive = true -} - -output "db_instance_domain" { - description = "The ID of the Directory Service Active Directory domain the instance is joined to" - value = module.db_instance.db_instance_domain -} - -output "db_instance_domain_iam_role_name" { - description = "The name of the IAM role to be used when making API calls to the Directory Service" - value = module.db_instance.db_instance_domain_iam_role_name -} - -output "db_instance_port" { - description = "The database port" - value = module.db_instance.db_instance_port -} - -output "db_instance_ca_cert_identifier" { - description = "Specifies the identifier of the CA certificate for the DB instance" - value = module.db_instance.db_instance_ca_cert_identifier -} - -output "db_instance_master_user_secret_arn" { - description = "The ARN of the master user secret (Only available when manage_master_user_password is set to true)" - value = module.db_instance.db_instance_master_user_secret_arn -} - -output "db_subnet_group_id" { - description = "The db subnet group name" - value = module.db_subnet_group.db_subnet_group_id -} - -output "db_subnet_group_arn" { - description = "The ARN of the db subnet group" - value = module.db_subnet_group.db_subnet_group_arn -} - -output "db_parameter_group_id" { - description = "The db parameter group id" - value = module.db_parameter_group.db_parameter_group_id -} - -output "db_parameter_group_arn" { - description = "The ARN of the db parameter group" - value = module.db_parameter_group.db_parameter_group_arn -} - -# DB option group -output "db_option_group_id" { - description = "The db option group id" - value = module.db_option_group.db_option_group_id -} - -output "db_option_group_arn" { - description = "The ARN of the db option group" - value = module.db_option_group.db_option_group_arn -} - -################################################################################ -# CloudWatch Log Group -################################################################################ - -output "db_instance_cloudwatch_log_groups" { - description = "Map of CloudWatch log groups created and their attributes" - value = module.db_instance.db_instance_cloudwatch_log_groups -} diff --git a/_sub/terraform-aws-rds/variables.tf b/_sub/terraform-aws-rds/variables.tf deleted file mode 100644 index bbbcdb8c..00000000 --- a/_sub/terraform-aws-rds/variables.tf +++ /dev/null @@ -1,552 +0,0 @@ -variable "identifier" { - description = "The name of the RDS instance" - type = string -} - -variable "instance_use_identifier_prefix" { - description = "Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix" - type = bool - default = false -} - -variable "custom_iam_instance_profile" { - description = "RDS custom iam instance profile" - type = string - default = null -} - -variable "allocated_storage" { - description = "The allocated storage in gigabytes" - type = number - default = null -} - -variable "storage_type" { - description = "One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter" - type = string - default = null -} - -variable "storage_throughput" { - description = "Storage throughput value for the DB instance. See `notes` for limitations regarding this variable for `gp3`" - type = number - default = null -} - -variable "storage_encrypted" { - description = "Specifies whether the DB instance is encrypted" - type = bool - default = true -} - -variable "kms_key_id" { - description = "The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage_encrypted is set to true and kms_key_id is not specified the default KMS key created in your account will be used. Be sure to use the full ARN, not a key alias." - type = string - default = null -} - -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" - type = string - default = null -} - -variable "license_model" { - description = "License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1" - type = string - default = null -} - -variable "replica_mode" { - description = "Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified" - type = string - default = null -} - -variable "iam_database_authentication_enabled" { - description = "Specifies whether or not the mappings of AWS Identity and Access Management (IAM) accounts to database accounts are enabled" - type = bool - default = false -} - -variable "domain" { - description = "The ID of the Directory Service Active Directory domain to create the instance in" - type = string - default = null -} - -variable "domain_iam_role_name" { - description = "(Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service" - type = string - default = null -} - -variable "engine" { - description = "The database engine to use" - type = string - default = null -} - -variable "engine_version" { - description = "The engine version to use" - type = string - default = null -} - -variable "skip_final_snapshot" { - description = "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" - type = bool - default = false -} - -variable "snapshot_identifier" { - description = "Specifies whether or not to create this database from a snapshot. This correlates to the snapshot ID you'd find in the RDS console, e.g: rds:production-2015-06-26-06-05" - type = string - default = null -} - -variable "copy_tags_to_snapshot" { - description = "On delete, copy all Instance tags to the final snapshot" - type = bool - default = false -} - -variable "final_snapshot_identifier_prefix" { - description = "The name which is prefixed to the final snapshot on cluster destroy" - type = string - default = "final" -} - -variable "instance_class" { - description = "The instance type of the RDS instance" - type = string - default = null -} - -variable "db_name" { - description = "The DB name to create. If omitted, no database is created initially" - type = string - default = null -} - -variable "username" { - description = "Username for the master DB user" - type = string - default = null -} - -variable "password" { - description = < v if var.create } + for_each = { for k, v in var.endpoints : k => v } - db_proxy_name = aws_db_proxy.this[0].name + db_proxy_name = aws_db_proxy.this.name db_proxy_endpoint_name = each.value.name vpc_subnet_ids = each.value.vpc_subnet_ids vpc_security_group_ids = lookup(each.value, "vpc_security_group_ids", null) @@ -88,7 +84,7 @@ resource "aws_db_proxy_endpoint" "this" { ################################################################################ resource "aws_cloudwatch_log_group" "this" { - count = var.create && var.manage_log_group ? 1 : 0 + count = var.manage_log_group ? 1 : 0 name = "/aws/rds/proxy/${var.name}" retention_in_days = var.log_group_retention_in_days @@ -103,7 +99,7 @@ resource "aws_cloudwatch_log_group" "this" { ################################################################################ data "aws_iam_policy_document" "assume_role" { - count = var.create && var.create_iam_role ? 1 : 0 + count = var.create_iam_role ? 1 : 0 statement { sid = "RDSAssume" @@ -118,7 +114,7 @@ data "aws_iam_policy_document" "assume_role" { } resource "aws_iam_role" "this" { - count = var.create && var.create_iam_role ? 1 : 0 + count = var.create_iam_role ? 1 : 0 name = var.use_role_name_prefix ? null : local.role_name name_prefix = var.use_role_name_prefix ? "${local.role_name}-" : null @@ -134,7 +130,7 @@ resource "aws_iam_role" "this" { } data "aws_iam_policy_document" "this" { - count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 + count = var.create_iam_role && var.create_iam_policy ? 1 : 0 statement { sid = "DecryptSecrets" @@ -179,7 +175,7 @@ data "aws_iam_policy_document" "this" { } resource "aws_iam_role_policy" "this" { - count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 + count = var.create_iam_role && var.create_iam_policy ? 1 : 0 name = var.use_policy_name_prefix ? null : local.policy_name name_prefix = var.use_policy_name_prefix ? "${local.policy_name}-" : null diff --git a/_sub/terraform-aws-rds-proxy/outputs.tf b/modules/rds_proxy/outputs.tf similarity index 89% rename from _sub/terraform-aws-rds-proxy/outputs.tf rename to modules/rds_proxy/outputs.tf index 355b2b43..dd7c1185 100644 --- a/_sub/terraform-aws-rds-proxy/outputs.tf +++ b/modules/rds_proxy/outputs.tf @@ -1,33 +1,33 @@ # RDS Proxy output "proxy_id" { description = "The ID for the proxy" - value = try(aws_db_proxy.this[0].id, null) + value = try(aws_db_proxy.this.id, null) } output "proxy_arn" { description = "The Amazon Resource Name (ARN) for the proxy" - value = try(aws_db_proxy.this[0].arn, null) + value = try(aws_db_proxy.this.arn, null) } output "proxy_endpoint" { description = "The endpoint that you can use to connect to the proxy" - value = try(aws_db_proxy.this[0].endpoint, null) + value = try(aws_db_proxy.this.endpoint, null) } # Proxy Default Target Group output "proxy_default_target_group_id" { description = "The ID for the default target group" - value = try(aws_db_proxy_default_target_group.this[0].id, null) + value = try(aws_db_proxy_default_target_group.this.id, null) } output "proxy_default_target_group_arn" { description = "The Amazon Resource Name (ARN) for the default target group" - value = try(aws_db_proxy_default_target_group.this[0].arn, null) + value = try(aws_db_proxy_default_target_group.this.arn, null) } output "proxy_default_target_group_name" { description = "The name of the default target group" - value = try(aws_db_proxy_default_target_group.this[0].name, null) + value = try(aws_db_proxy_default_target_group.this.name, null) } # Proxy Target diff --git a/_sub/terraform-aws-rds-proxy/variables.tf b/modules/rds_proxy/variables.tf similarity index 98% rename from _sub/terraform-aws-rds-proxy/variables.tf rename to modules/rds_proxy/variables.tf index dd4f24e2..b42d5a4c 100644 --- a/_sub/terraform-aws-rds-proxy/variables.tf +++ b/modules/rds_proxy/variables.tf @@ -1,9 +1,3 @@ -variable "create" { - description = "Whether cluster should be created (affects nearly all resources)" - type = bool - default = true -} - variable "tags" { description = "A map of tags to add to all resources" type = map(string) diff --git a/_sub/terraform-aws-rds/modules/db_parameter_group/versions.tf b/modules/rds_proxy/versions.tf similarity index 100% rename from _sub/terraform-aws-rds/modules/db_parameter_group/versions.tf rename to modules/rds_proxy/versions.tf diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/README.md b/modules/rds_subnet_group/README.md similarity index 100% rename from _sub/terraform-aws-rds/modules/db_subnet_group/README.md rename to modules/rds_subnet_group/README.md diff --git a/new_modules/db_subnet_group/main.tf b/modules/rds_subnet_group/main.tf similarity index 100% rename from new_modules/db_subnet_group/main.tf rename to modules/rds_subnet_group/main.tf diff --git a/new_modules/db_subnet_group/outputs.tf b/modules/rds_subnet_group/outputs.tf similarity index 100% rename from new_modules/db_subnet_group/outputs.tf rename to modules/rds_subnet_group/outputs.tf diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/variables.tf b/modules/rds_subnet_group/variables.tf similarity index 100% rename from _sub/terraform-aws-rds/modules/db_subnet_group/variables.tf rename to modules/rds_subnet_group/variables.tf diff --git a/_sub/terraform-aws-rds/modules/db_subnet_group/versions.tf b/modules/rds_subnet_group/versions.tf similarity index 100% rename from _sub/terraform-aws-rds/modules/db_subnet_group/versions.tf rename to modules/rds_subnet_group/versions.tf diff --git a/new_modules/cluster_parameter_group/versions.tf b/new_modules/cluster_parameter_group/versions.tf deleted file mode 100644 index ddfcb0e0..00000000 --- a/new_modules/cluster_parameter_group/versions.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 5.0" - } - } -} diff --git a/new_modules/db_cloudwatch_log_groups/versions.tf b/new_modules/db_cloudwatch_log_groups/versions.tf deleted file mode 100644 index ddfcb0e0..00000000 --- a/new_modules/db_cloudwatch_log_groups/versions.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 5.0" - } - } -} diff --git a/new_modules/db_instance/README.md b/new_modules/db_instance/README.md deleted file mode 100644 index 05091470..00000000 --- a/new_modules/db_instance/README.md +++ /dev/null @@ -1,134 +0,0 @@ -# aws_db_instance - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.0 | -| [random](#requirement\_random) | >= 3.1 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | >= 5.0 | -| [random](#provider\_random) | >= 3.1 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | -| [aws_db_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance) | resource | -| [aws_iam_role.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy_attachment.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [random_id.snapshot_identifier](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | -| [aws_iam_policy_document.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [allocated\_storage](#input\_allocated\_storage) | The allocated storage in gigabytes | `number` | `null` | no | -| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Indicates that major version upgrades are allowed. Changing this parameter does not result in an outage and the change is asynchronously applied as soon as possible | `bool` | `false` | no | -| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any database modifications are applied immediately, or during the next maintenance window | `bool` | `false` | no | -| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window | `bool` | `true` | no | -| [availability\_zone](#input\_availability\_zone) | The Availability Zone of the RDS instance | `string` | `null` | no | -| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for | `number` | `null` | no | -| [backup\_window](#input\_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` | `null` | no | -| [blue\_green\_update](#input\_blue\_green\_update) | Enables low-downtime updates using RDS Blue/Green deployments. | `map(string)` | `{}` | no | -| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | `string` | `null` | no | -| [character\_set\_name](#input\_character\_set\_name) | 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 and Collations and Character Sets for Microsoft SQL Server for more information. This can only be set on creation. | `string` | `null` | no | -| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | -| [cloudwatch\_log\_group\_retention\_in\_days](#input\_cloudwatch\_log\_group\_retention\_in\_days) | The number of days to retain CloudWatch logs for the DB instance | `number` | `7` | no | -| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | On delete, copy all Instance tags to the final snapshot | `bool` | `false` | no | -| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | -| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports` | `bool` | `false` | no | -| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Create IAM role with a defined name that permits RDS to send enhanced monitoring metrics to CloudWatch Logs. | `bool` | `false` | no | -| [custom\_iam\_instance\_profile](#input\_custom\_iam\_instance\_profile) | RDS custom iam instance profile | `string` | `null` | no | -| [db\_name](#input\_db\_name) | The DB name to create. If omitted, no database is created initially | `string` | `null` | no | -| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC | `string` | `null` | no | -| [delete\_automated\_backups](#input\_delete\_automated\_backups) | Specifies whether to remove automated backups immediately after the DB instance is deleted | `bool` | `true` | no | -| [deletion\_protection](#input\_deletion\_protection) | The database can't be deleted when this value is set to true. | `bool` | `false` | no | -| [domain](#input\_domain) | The ID of the Directory Service Active Directory domain to create the instance in | `string` | `null` | no | -| [domain\_iam\_role\_name](#input\_domain\_iam\_role\_name) | (Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service | `string` | `null` | no | -| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on engine): alert, audit, error, general, listener, slowquery, trace, postgresql (PostgreSQL), upgrade (PostgreSQL). | `list(string)` | `[]` | no | -| [engine](#input\_engine) | The database engine to use | `string` | `null` | no | -| [engine\_version](#input\_engine\_version) | The engine version to use | `string` | `null` | no | -| [final\_snapshot\_identifier\_prefix](#input\_final\_snapshot\_identifier\_prefix) | The name which is prefixed to the final snapshot on cluster destroy | `string` | `"final"` | no | -| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled | `bool` | `false` | no | -| [identifier](#input\_identifier) | The name of the RDS instance | `string` | n/a | yes | -| [instance\_class](#input\_instance\_class) | The instance type of the RDS instance | `string` | `null` | no | -| [iops](#input\_iops) | The amount of provisioned IOPS. Setting this implies a storage\_type of 'io1' or `gp3`. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | -| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage\_encrypted is set to true and kms\_key\_id is not specified the default KMS key created in your account will be used | `string` | `null` | no | -| [license\_model](#input\_license\_model) | License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1 | `string` | `null` | no | -| [maintenance\_window](#input\_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 | -| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if password is provided | `bool` | `false` | no | -| [master\_user\_secret\_kms\_key\_id](#input\_master\_user\_secret\_kms\_key\_id) | The key ARN, key ID, alias ARN or alias name for the KMS key to encrypt the master user password secret in Secrets Manager.
If not specified, the default KMS key for your Amazon Web Services account is used. | `string` | `null` | no | -| [max\_allocated\_storage](#input\_max\_allocated\_storage) | Specifies the value for Storage Autoscaling | `number` | `0` | no | -| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. To disable collecting Enhanced Monitoring metrics, specify 0. The default is 0. Valid Values: 0, 1, 5, 10, 15, 30, 60. | `number` | `0` | no | -| [monitoring\_role\_arn](#input\_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` | `null` | no | -| [monitoring\_role\_description](#input\_monitoring\_role\_description) | Description of the monitoring IAM role | `string` | `null` | no | -| [monitoring\_role\_name](#input\_monitoring\_role\_name) | Name of the IAM role which will be created when create\_monitoring\_role is enabled. | `string` | `"rds-monitoring-role"` | no | -| [monitoring\_role\_permissions\_boundary](#input\_monitoring\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the monitoring IAM role | `string` | `null` | no | -| [monitoring\_role\_use\_name\_prefix](#input\_monitoring\_role\_use\_name\_prefix) | Determines whether to use `monitoring_role_name` as is or create a unique identifier beginning with `monitoring_role_name` as the specified prefix | `bool` | `false` | no | -| [multi\_az](#input\_multi\_az) | Specifies if the RDS instance is multi-AZ | `bool` | `false` | no | -| [nchar\_character\_set\_name](#input\_nchar\_character\_set\_name) | The national character set is used in the NCHAR, NVARCHAR2, and NCLOB data types for Oracle instances. This can't be changed. | `string` | `null` | no | -| [network\_type](#input\_network\_type) | The type of network stack | `string` | `null` | no | -| [option\_group\_name](#input\_option\_group\_name) | Name of the DB option group to associate. | `string` | `null` | no | -| [parameter\_group\_name](#input\_parameter\_group\_name) | Name of the DB parameter group to associate | `string` | `null` | no | -| [password](#input\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file | `string` | `null` | no | -| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Specifies whether Performance Insights are enabled | `bool` | `false` | no | -| [performance\_insights\_kms\_key\_id](#input\_performance\_insights\_kms\_key\_id) | The ARN for the KMS key to encrypt Performance Insights data. | `string` | `null` | no | -| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | The amount of time in days to retain Performance Insights data. Either 7 (7 days) or 731 (2 years). | `number` | `7` | no | -| [port](#input\_port) | The port on which the DB accepts connections | `string` | `null` | no | -| [publicly\_accessible](#input\_publicly\_accessible) | Bool to control if instance is publicly accessible | `bool` | `false` | no | -| [replica\_mode](#input\_replica\_mode) | Specifies whether the replica is in either mounted or open-read-only mode. This attribute is only supported by Oracle instances. Oracle replicas operate in open-read-only mode unless otherwise specified | `string` | `null` | no | -| [replicate\_source\_db](#input\_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 | -| [restore\_to\_point\_in\_time](#input\_restore\_to\_point\_in\_time) | Restore to a point in time (MySQL is NOT supported) | `map(string)` | `null` | no | -| [s3\_import](#input\_s3\_import) | Restore from a Percona Xtrabackup in S3 (only MySQL is supported) | `map(string)` | `null` | no | -| [skip\_final\_snapshot](#input\_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 | `bool` | `false` | no | -| [snapshot\_identifier](#input\_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, e.g: rds:production-2015-06-26-06-05. | `string` | `null` | no | -| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB instance is encrypted | `bool` | `true` | no | -| [storage\_throughput](#input\_storage\_throughput) | Storage throughput value for the DB instance. This setting applies only to the `gp3` storage type. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | -| [storage\_type](#input\_storage\_type) | One of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (new generation of general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'gp2' if not. If you specify 'io1' or 'gp3' , you must also include a value for the 'iops' parameter | `string` | `null` | no | -| [tags](#input\_tags) | A mapping of tags to assign to all resources | `map(string)` | `{}` | no | -| [timeouts](#input\_timeouts) | Updated Terraform resource management timeouts. Applies to `aws_db_instance` in particular to permit resource management times | `map(string)` | `{}` | no | -| [timezone](#input\_timezone) | 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. | `string` | `null` | no | -| [use\_identifier\_prefix](#input\_use\_identifier\_prefix) | Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix | `bool` | `false` | no | -| [username](#input\_username) | Username for the master DB user | `string` | `null` | no | -| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of VPC security groups to associate | `list(string)` | `[]` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [db\_instance\_address](#output\_db\_instance\_address) | The address of the RDS instance | -| [db\_instance\_arn](#output\_db\_instance\_arn) | The ARN of the RDS instance | -| [db\_instance\_availability\_zone](#output\_db\_instance\_availability\_zone) | The availability zone of the RDS instance | -| [db\_instance\_ca\_cert\_identifier](#output\_db\_instance\_ca\_cert\_identifier) | Specifies the identifier of the CA certificate for the DB instance | -| [db\_instance\_cloudwatch\_log\_groups](#output\_db\_instance\_cloudwatch\_log\_groups) | Map of CloudWatch log groups created and their attributes | -| [db\_instance\_domain](#output\_db\_instance\_domain) | The ID of the Directory Service Active Directory domain the instance is joined to | -| [db\_instance\_domain\_iam\_role\_name](#output\_db\_instance\_domain\_iam\_role\_name) | The name of the IAM role to be used when making API calls to the Directory Service | -| [db\_instance\_endpoint](#output\_db\_instance\_endpoint) | The connection endpoint | -| [db\_instance\_engine](#output\_db\_instance\_engine) | The database engine | -| [db\_instance\_engine\_version\_actual](#output\_db\_instance\_engine\_version\_actual) | The running version of the database | -| [db\_instance\_hosted\_zone\_id](#output\_db\_instance\_hosted\_zone\_id) | The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record) | -| [db\_instance\_identifier](#output\_db\_instance\_identifier) | The RDS instance identifier | -| [db\_instance\_master\_user\_secret\_arn](#output\_db\_instance\_master\_user\_secret\_arn) | The ARN of the master user secret (Only available when manage\_master\_user\_password is set to true) | -| [db\_instance\_name](#output\_db\_instance\_name) | The database name | -| [db\_instance\_port](#output\_db\_instance\_port) | The database port | -| [db\_instance\_resource\_id](#output\_db\_instance\_resource\_id) | The RDS Resource ID of this instance | -| [db\_instance\_status](#output\_db\_instance\_status) | The RDS instance status | -| [db\_instance\_username](#output\_db\_instance\_username) | The master username for the database | -| [db\_listener\_endpoint](#output\_db\_listener\_endpoint) | Specifies the listener connection endpoint for SQL Server Always On | -| [enhanced\_monitoring\_iam\_role\_arn](#output\_enhanced\_monitoring\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the monitoring role | -| [enhanced\_monitoring\_iam\_role\_name](#output\_enhanced\_monitoring\_iam\_role\_name) | The name of the monitoring role | - diff --git a/new_modules/db_instance/versions.tf b/new_modules/db_instance/versions.tf deleted file mode 100644 index 8f85fe99..00000000 --- a/new_modules/db_instance/versions.tf +++ /dev/null @@ -1,15 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 5.0" - } - - random = { - source = "hashicorp/random" - version = ">= 3.1" - } - } -} diff --git a/new_modules/db_parameter_group/README.md b/new_modules/db_parameter_group/README.md deleted file mode 100644 index 56e16577..00000000 --- a/new_modules/db_parameter_group/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# aws_db_parameter_group - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.0 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | >= 5.0 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [aws_db_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | -| [description](#input\_description) | The description of the DB parameter group | `string` | `null` | no | -| [family](#input\_family) | The family of the DB parameter group | `string` | `null` | no | -| [name](#input\_name) | The name of the DB parameter group | `string` | `""` | no | -| [parameters](#input\_parameters) | A list of DB parameter maps to apply | `list(map(string))` | `[]` | no | -| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | -| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix | `bool` | `true` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [db\_parameter\_group\_arn](#output\_db\_parameter\_group\_arn) | The ARN of the db parameter group | -| [db\_parameter\_group\_id](#output\_db\_parameter\_group\_id) | The db parameter group id | - diff --git a/new_modules/db_parameter_group/variables.tf b/new_modules/db_parameter_group/variables.tf deleted file mode 100644 index b7b7af9f..00000000 --- a/new_modules/db_parameter_group/variables.tf +++ /dev/null @@ -1,41 +0,0 @@ -variable "create" { - description = "Whether to create this resource or not?" - type = bool - default = true -} - -variable "name" { - description = "The name of the DB parameter group" - type = string - default = "" -} - -variable "use_name_prefix" { - description = "Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix" - type = bool - default = true -} - -variable "description" { - description = "The description of the DB parameter group" - type = string - default = null -} - -variable "family" { - description = "The family of the DB parameter group" - type = string - default = null -} - -variable "parameters" { - description = "A list of DB parameter maps to apply" - type = list(map(string)) - default = [] -} - -variable "tags" { - description = "A mapping of tags to assign to the resource" - type = map(string) - default = {} -} diff --git a/new_modules/db_parameter_group/versions.tf b/new_modules/db_parameter_group/versions.tf deleted file mode 100644 index ddfcb0e0..00000000 --- a/new_modules/db_parameter_group/versions.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 5.0" - } - } -} diff --git a/new_modules/db_subnet_group/README.md b/new_modules/db_subnet_group/README.md deleted file mode 100644 index 68a1d5ff..00000000 --- a/new_modules/db_subnet_group/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# aws_db_subnet_group - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.0 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | >= 5.0 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [aws_db_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_subnet_group) | resource | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [create](#input\_create) | Whether to create this resource or not? | `bool` | `true` | no | -| [description](#input\_description) | The description of the DB subnet group | `string` | `null` | no | -| [name](#input\_name) | The name of the DB subnet group | `string` | `""` | no | -| [subnet\_ids](#input\_subnet\_ids) | A list of VPC subnet IDs | `list(string)` | `[]` | no | -| [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | -| [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix | `bool` | `true` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [db\_subnet\_group\_arn](#output\_db\_subnet\_group\_arn) | The ARN of the db subnet group | -| [db\_subnet\_group\_id](#output\_db\_subnet\_group\_id) | The db subnet group name | - diff --git a/new_modules/db_subnet_group/variables.tf b/new_modules/db_subnet_group/variables.tf deleted file mode 100644 index 48185ab4..00000000 --- a/new_modules/db_subnet_group/variables.tf +++ /dev/null @@ -1,35 +0,0 @@ -variable "create" { - description = "Whether to create this resource or not?" - type = bool - default = true -} - -variable "name" { - description = "The name of the DB subnet group" - type = string - default = "" -} - -variable "use_name_prefix" { - description = "Determines whether to use `name` as is or create a unique name beginning with `name` as the specified prefix" - type = bool - default = true -} - -variable "description" { - description = "The description of the DB subnet group" - type = string - default = null -} - -variable "subnet_ids" { - description = "A list of VPC subnet IDs" - type = list(string) - default = [] -} - -variable "tags" { - description = "A mapping of tags to assign to the resource" - type = map(string) - default = {} -} diff --git a/new_modules/db_subnet_group/versions.tf b/new_modules/db_subnet_group/versions.tf deleted file mode 100644 index ddfcb0e0..00000000 --- a/new_modules/db_subnet_group/versions.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 5.0" - } - } -} diff --git a/new_modules/rds-aurora/README.md b/new_modules/rds-aurora/README.md deleted file mode 100644 index 26451203..00000000 --- a/new_modules/rds-aurora/README.md +++ /dev/null @@ -1,422 +0,0 @@ -# AWS RDS Aurora Terraform module - -Terraform module which creates AWS RDS Aurora resources. - -[![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) - -## Available Features - -- Autoscaling of read-replicas -- Global cluster -- Enhanced monitoring -- Serverless cluster (v1 and v2) -- Import from S3 -- Fine grained control of individual cluster instances -- Custom endpoints -- RDS multi-AZ support (not Aurora) - -## Usage - -```hcl -module "cluster" { - source = "terraform-aws-modules/rds-aurora/aws" - - name = "test-aurora-db-postgres96" - engine = "aurora-postgresql" - engine_version = "14.5" - instance_class = "db.r6g.large" - instances = { - one = {} - 2 = { - instance_class = "db.r6g.2xlarge" - } - } - - vpc_id = "vpc-12345678" - db_subnet_group_name = "db-subnet-group" - security_group_rules = { - ex1_ingress = { - cidr_blocks = ["10.20.0.0/20"] - } - ex1_ingress = { - source_security_group_id = "sg-12345678" - } - } - - storage_encrypted = true - apply_immediately = true - monitoring_interval = 10 - - enabled_cloudwatch_logs_exports = ["postgresql"] - - tags = { - Environment = "dev" - Terraform = "true" - } -} -``` - -### Cluster Instance Configuration - -There are a couple different configuration methods that can be used to create instances within the cluster: - -ℹ️ Only the pertinent attributes are shown for brevity - -1. Create homogenous cluster of any number of instances - - - Resources created: - - Writer: 1 - - Reader(s): 2 - -```hcl - instance_class = "db.r6g.large" - instances = { - one = {} - two = {} - three = {} - } -``` - -2. Create homogenous cluster of instances w/ autoscaling enabled. This is redundant and we'll show why in the next example. - - - Resources created: - - Writer: 1 - - Reader(s): - - At least 4 readers (2 created directly, 2 created by appautoscaling) - - At most 7 reader instances (2 created directly, 5 created by appautoscaling) - -ℹ️ Autoscaling uses the instance class specified by `instance_class`. - -```hcl - instance_class = "db.r6g.large" - instances = { - one = {} - two = {} - three = {} - } - - autoscaling_enabled = true - autoscaling_min_capacity = 2 - autoscaling_max_capacity = 5 -``` - -3. Create homogeneous cluster scaled via autoscaling. At least one instance (writer) is required - - - Resources created: - - Writer: 1 - - Reader(s): - - At least 1 reader - - At most 5 readers - -```hcl - instance_class = "db.r6g.large" - instances = { - one = {} - } - - autoscaling_enabled = true - autoscaling_min_capacity = 1 - autoscaling_max_capacity = 5 -``` - -4. Create heterogenous cluster to support mixed-use workloads - - It is common in this configuration to independently control the instance `promotion_tier` paired with `endpoints` to create custom endpoints directed at select instances or instance groups. - - - Resources created: - - Writer: 1 - - Readers: 2 - -```hcl - instance_class = "db.r5.large" - instances = { - one = { - instance_class = "db.r5.2xlarge" - publicly_accessible = true - } - two = { - identifier = "static-member-1" - instance_class = "db.r5.2xlarge" - } - three = { - identifier = "excluded-member-1" - instance_class = "db.r5.large" - promotion_tier = 15 - } - } -``` - -5. Create heterogenous cluster to support mixed-use workloads w/ autoscaling enabled - - - Resources created: - - Writer: 1 - - Reader(s): - - At least 3 readers (2 created directly, 1 created through appautoscaling) - - At most 7 readers (2 created directly, 5 created through appautoscaling) - -ℹ️ Autoscaling uses the instance class specified by `instance_class`. - -```hcl - instance_class = "db.r5.large" - instances = { - one = { - instance_class = "db.r5.2xlarge" - publicly_accessible = true - } - two = { - identifier = "static-member-1" - instance_class = "db.r5.2xlarge" - } - three = { - identifier = "excluded-member-1" - instance_class = "db.r5.large" - promotion_tier = 15 - } - } - - autoscaling_enabled = true - autoscaling_min_capacity = 1 - autoscaling_max_capacity = 5 -``` - -## Conditional Creation - -The following values are provided to toggle on/off creation of the associated resources as desired: - -```hcl -# This RDS cluster will not be created -module "cluster" { - source = "terraform-aws-modules/rds-aurora/aws" - - # Disable creation of cluster and all resources - create = false - - # Disable creation of subnet group - provide a subnet group - create_db_subnet_group = false - - # Disable creation of security group - provide a security group - create_security_group = false - - # Disable creation of monitoring IAM role - provide a role ARN - create_monitoring_role = false - - # ... omitted -} -``` - -## Examples - -- [Autoscaling](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/autoscaling): A PostgreSQL cluster with enhanced monitoring and autoscaling enabled -- [Global Cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/global-cluster): A PostgreSQL global cluster with clusters provisioned in two different region -- [Multi-AZ](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/multi-az): A multi-AZ RDS cluster (not using Aurora engine) -- [MySQL](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/mysql): A simple MySQL cluster -- [PostgreSQL](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/postgresql): A simple PostgreSQL cluster -- [S3 Import](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/s3-import): A MySQL cluster created from a Percona Xtrabackup stored in S3 -- [Serverless](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/examples/serverless): Serverless V1 and V2 (PostgreSQL and MySQL) - -## Documentation - -Terraform documentation is generated automatically using [pre-commit hooks](http://www.pre-commit.com/). Follow installation instructions [here](https://pre-commit.com/#install). - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 4.67 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | >= 4.67 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [aws_appautoscaling_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_policy) | resource | -| [aws_appautoscaling_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_target) | resource | -| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | -| [aws_db_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource | -| [aws_db_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_subnet_group) | resource | -| [aws_iam_role.rds_enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy_attachment.rds_enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_rds_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster) | resource | -| [aws_rds_cluster_activity_stream.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_activity_stream) | resource | -| [aws_rds_cluster_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_endpoint) | resource | -| [aws_rds_cluster_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_instance) | resource | -| [aws_rds_cluster_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_parameter_group) | resource | -| [aws_rds_cluster_role_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_role_association) | resource | -| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | -| [aws_security_group_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_iam_policy_document.monitoring_rds_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [allocated\_storage](#input\_allocated\_storage) | The amount of storage in gibibytes (GiB) to allocate to each DB instance in the Multi-AZ DB cluster. (This setting is required to create a Multi-AZ DB cluster) | `number` | `null` | no | -| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Enable to allow major engine version upgrades when changing engine versions. Defaults to `false` | `bool` | `false` | no | -| [apply\_immediately](#input\_apply\_immediately) | Specifies whether any cluster modifications are applied immediately, or during the next maintenance window. Default is `false` | `bool` | `null` | no | -| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. Default `true` | `bool` | `null` | no | -| [autoscaling\_enabled](#input\_autoscaling\_enabled) | Determines whether autoscaling of the cluster read replicas is enabled | `bool` | `false` | no | -| [autoscaling\_max\_capacity](#input\_autoscaling\_max\_capacity) | Maximum number of read replicas permitted when autoscaling is enabled | `number` | `2` | no | -| [autoscaling\_min\_capacity](#input\_autoscaling\_min\_capacity) | Minimum number of read replicas permitted when autoscaling is enabled | `number` | `0` | no | -| [autoscaling\_policy\_name](#input\_autoscaling\_policy\_name) | Autoscaling policy name | `string` | `"target-metric"` | no | -| [autoscaling\_scale\_in\_cooldown](#input\_autoscaling\_scale\_in\_cooldown) | Cooldown in seconds before allowing further scaling operations after a scale in | `number` | `300` | no | -| [autoscaling\_scale\_out\_cooldown](#input\_autoscaling\_scale\_out\_cooldown) | Cooldown in seconds before allowing further scaling operations after a scale out | `number` | `300` | no | -| [autoscaling\_target\_connections](#input\_autoscaling\_target\_connections) | Average number of connections threshold which will initiate autoscaling. Default value is 70% of db.r4/r5/r6g.large's default max\_connections | `number` | `700` | no | -| [autoscaling\_target\_cpu](#input\_autoscaling\_target\_cpu) | CPU threshold which will initiate autoscaling | `number` | `70` | no | -| [availability\_zones](#input\_availability\_zones) | List of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created. RDS automatically assigns 3 AZs if less than 3 AZs are configured, which will show as a difference requiring resource recreation next Terraform apply | `list(string)` | `null` | no | -| [backtrack\_window](#input\_backtrack\_window) | The target backtrack window, in seconds. Only available for `aurora` engine currently. To disable backtracking, set this value to 0. Must be between 0 and 259200 (72 hours) | `number` | `null` | no | -| [backup\_retention\_period](#input\_backup\_retention\_period) | The days to retain backups for. Default `7` | `number` | `7` | no | -| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | The identifier of the CA certificate for the DB instance | `string` | `null` | no | -| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | -| [cloudwatch\_log\_group\_retention\_in\_days](#input\_cloudwatch\_log\_group\_retention\_in\_days) | The number of days to retain CloudWatch logs for the DB instance | `number` | `7` | no | -| [cluster\_members](#input\_cluster\_members) | List of RDS Instances that are a part of this cluster | `list(string)` | `null` | no | -| [cluster\_tags](#input\_cluster\_tags) | A map of tags to add to only the cluster. Used for AWS Instance Scheduler tagging | `map(string)` | `{}` | no | -| [cluster\_timeouts](#input\_cluster\_timeouts) | Create, update, and delete timeout configurations for the cluster | `map(string)` | `{}` | no | -| [cluster\_use\_name\_prefix](#input\_cluster\_use\_name\_prefix) | Whether to use `name` as a prefix for the cluster | `bool` | `false` | no | -| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | Copy all Cluster `tags` to snapshots | `bool` | `null` | no | -| [create](#input\_create) | Whether cluster should be created (affects nearly all resources) | `bool` | `true` | no | -| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports` | `bool` | `false` | no | -| [create\_db\_cluster\_activity\_stream](#input\_create\_db\_cluster\_activity\_stream) | Determines whether a cluster activity stream is created. | `bool` | `false` | no | -| [create\_db\_cluster\_parameter\_group](#input\_create\_db\_cluster\_parameter\_group) | Determines whether a cluster parameter should be created or use existing | `bool` | `false` | no | -| [create\_db\_parameter\_group](#input\_create\_db\_parameter\_group) | Determines whether a DB parameter should be created or use existing | `bool` | `false` | no | -| [create\_db\_subnet\_group](#input\_create\_db\_subnet\_group) | Determines whether to create the database subnet group or use existing | `bool` | `false` | no | -| [create\_monitoring\_role](#input\_create\_monitoring\_role) | Determines whether to create the IAM role for RDS enhanced monitoring | `bool` | `true` | no | -| [create\_security\_group](#input\_create\_security\_group) | Determines whether to create security group for RDS cluster | `bool` | `true` | no | -| [database\_name](#input\_database\_name) | Name for an automatically created database on cluster creation | `string` | `null` | no | -| [db\_cluster\_activity\_stream\_kms\_key\_id](#input\_db\_cluster\_activity\_stream\_kms\_key\_id) | The AWS KMS key identifier for encrypting messages in the database activity stream | `string` | `null` | no | -| [db\_cluster\_activity\_stream\_mode](#input\_db\_cluster\_activity\_stream\_mode) | Specifies the mode of the database activity stream. Database events such as a change or access generate an activity stream event. One of: sync, async | `string` | `null` | no | -| [db\_cluster\_db\_instance\_parameter\_group\_name](#input\_db\_cluster\_db\_instance\_parameter\_group\_name) | Instance parameter group to associate with all instances of the DB cluster. The `db_cluster_db_instance_parameter_group_name` is only valid in combination with `allow_major_version_upgrade` | `string` | `null` | no | -| [db\_cluster\_instance\_class](#input\_db\_cluster\_instance\_class) | The compute and memory capacity of each DB instance in the Multi-AZ DB cluster, for example db.m6g.xlarge. Not all DB instance classes are available in all AWS Regions, or for all database engines | `string` | `null` | no | -| [db\_cluster\_parameter\_group\_description](#input\_db\_cluster\_parameter\_group\_description) | The description of the DB cluster parameter group. Defaults to "Managed by Terraform" | `string` | `null` | no | -| [db\_cluster\_parameter\_group\_family](#input\_db\_cluster\_parameter\_group\_family) | The family of the DB cluster parameter group | `string` | `""` | no | -| [db\_cluster\_parameter\_group\_name](#input\_db\_cluster\_parameter\_group\_name) | The name of the DB cluster parameter group | `string` | `null` | no | -| [db\_cluster\_parameter\_group\_parameters](#input\_db\_cluster\_parameter\_group\_parameters) | A list of DB cluster parameters to apply. Note that parameters may differ from a family to an other | `list(map(string))` | `[]` | no | -| [db\_cluster\_parameter\_group\_use\_name\_prefix](#input\_db\_cluster\_parameter\_group\_use\_name\_prefix) | Determines whether the DB cluster parameter group name is used as a prefix | `bool` | `true` | no | -| [db\_parameter\_group\_description](#input\_db\_parameter\_group\_description) | The description of the DB parameter group. Defaults to "Managed by Terraform" | `string` | `null` | no | -| [db\_parameter\_group\_family](#input\_db\_parameter\_group\_family) | The family of the DB parameter group | `string` | `""` | no | -| [db\_parameter\_group\_name](#input\_db\_parameter\_group\_name) | The name of the DB parameter group | `string` | `null` | no | -| [db\_parameter\_group\_parameters](#input\_db\_parameter\_group\_parameters) | A list of DB parameters to apply. Note that parameters may differ from a family to an other | `list(map(string))` | `[]` | no | -| [db\_parameter\_group\_use\_name\_prefix](#input\_db\_parameter\_group\_use\_name\_prefix) | Determines whether the DB parameter group name is used as a prefix | `bool` | `true` | no | -| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | The name of the subnet group name (existing or created) | `string` | `""` | no | -| [deletion\_protection](#input\_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` | `null` | no | -| [enable\_global\_write\_forwarding](#input\_enable\_global\_write\_forwarding) | Whether cluster should forward writes to an associated global cluster. Applied to secondary clusters to enable them to forward writes to an `aws_rds_global_cluster`'s primary cluster | `bool` | `null` | no | -| [enable\_http\_endpoint](#input\_enable\_http\_endpoint) | Enable HTTP endpoint (data API). Only valid when engine\_mode is set to `serverless` | `bool` | `null` | no | -| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | Set of log types to export to cloudwatch. If omitted, no logs will be exported. The following log types are supported: `audit`, `error`, `general`, `slowquery`, `postgresql` | `list(string)` | `[]` | no | -| [endpoints](#input\_endpoints) | Map of additional cluster endpoints and their attributes to be created | `any` | `{}` | no | -| [engine](#input\_engine) | The name of the database engine to be used for this DB cluster. Defaults to `aurora`. Valid Values: `aurora`, `aurora-mysql`, `aurora-postgresql` | `string` | `null` | no | -| [engine\_mode](#input\_engine\_mode) | The database engine mode. Valid values: `global`, `multimaster`, `parallelquery`, `provisioned`, `serverless`. Defaults to: `provisioned` | `string` | `"provisioned"` | no | -| [engine\_native\_audit\_fields\_included](#input\_engine\_native\_audit\_fields\_included) | Specifies whether the database activity stream includes engine-native audit fields. This option only applies to an Oracle DB instance. By default, no engine-native audit fields are included | `bool` | `false` | no | -| [engine\_version](#input\_engine\_version) | The database engine version. Updating this argument results in an outage | `string` | `null` | no | -| [final\_snapshot\_identifier](#input\_final\_snapshot\_identifier) | The name of your final DB snapshot when this DB cluster is deleted. If omitted, no final snapshot will be made | `string` | `null` | no | -| [global\_cluster\_identifier](#input\_global\_cluster\_identifier) | The global cluster identifier specified on `aws_rds_global_cluster` | `string` | `null` | no | -| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled | `bool` | `null` | no | -| [iam\_role\_description](#input\_iam\_role\_description) | Description of the monitoring role | `string` | `null` | no | -| [iam\_role\_force\_detach\_policies](#input\_iam\_role\_force\_detach\_policies) | Whether to force detaching any policies the monitoring role has before destroying it | `bool` | `null` | no | -| [iam\_role\_managed\_policy\_arns](#input\_iam\_role\_managed\_policy\_arns) | Set of exclusive IAM managed policy ARNs to attach to the monitoring role | `list(string)` | `null` | no | -| [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | Maximum session duration (in seconds) that you want to set for the monitoring role | `number` | `null` | no | -| [iam\_role\_name](#input\_iam\_role\_name) | Friendly name of the monitoring role | `string` | `null` | no | -| [iam\_role\_path](#input\_iam\_role\_path) | Path for the monitoring role | `string` | `null` | no | -| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the policy that is used to set the permissions boundary for the monitoring role | `string` | `null` | no | -| [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether to use `iam_role_name` as is or create a unique name beginning with the `iam_role_name` as the prefix | `bool` | `false` | no | -| [iam\_roles](#input\_iam\_roles) | Map of IAM roles and supported feature names to associate with the cluster | `map(map(string))` | `{}` | no | -| [instance\_class](#input\_instance\_class) | Instance type to use at master instance. Note: if `autoscaling_enabled` is `true`, this will be the same instance class used on instances created by autoscaling | `string` | `""` | no | -| [instance\_timeouts](#input\_instance\_timeouts) | Create, update, and delete timeout configurations for the cluster instance(s) | `map(string)` | `{}` | no | -| [instances](#input\_instances) | Map of cluster instances and any specific/overriding attributes to be created | `any` | `{}` | no | -| [instances\_use\_identifier\_prefix](#input\_instances\_use\_identifier\_prefix) | Determines whether cluster instance identifiers are used as prefixes | `bool` | `false` | no | -| [iops](#input\_iops) | The amount of Provisioned IOPS (input/output operations per second) to be initially allocated for each DB instance in the Multi-AZ DB cluster | `number` | `null` | no | -| [is\_primary\_cluster](#input\_is\_primary\_cluster) | Determines whether cluster is primary cluster with writer instance (set to `false` for global cluster and replica clusters) | `bool` | `true` | no | -| [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. When specifying `kms_key_id`, `storage_encrypted` needs to be set to `true` | `string` | `null` | no | -| [manage\_master\_user\_password](#input\_manage\_master\_user\_password) | Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if `master_password` is provided | `bool` | `true` | no | -| [master\_password](#input\_master\_password) | Password for the master DB user. Note that this may show up in logs, and it will be stored in the state file. Required unless `manage_master_user_password` is set to `true` or unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database | `string` | `null` | no | -| [master\_user\_secret\_kms\_key\_id](#input\_master\_user\_secret\_kms\_key\_id) | The Amazon Web Services KMS key identifier is the key ARN, key ID, alias ARN, or alias name for the KMS key | `string` | `null` | no | -| [master\_username](#input\_master\_username) | Username for the master DB user. Required unless `snapshot_identifier` or `replication_source_identifier` is provided or unless a `global_cluster_identifier` is provided when the cluster is the secondary cluster of a global database | `string` | `null` | no | -| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected for instances. Set to `0` to disable. Default is `0` | `number` | `0` | no | -| [monitoring\_role\_arn](#input\_monitoring\_role\_arn) | IAM role used by RDS to send enhanced monitoring metrics to CloudWatch | `string` | `""` | no | -| [name](#input\_name) | Name used across resources created | `string` | `""` | no | -| [network\_type](#input\_network\_type) | The type of network stack to use (IPV4 or DUAL) | `string` | `null` | no | -| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Specifies whether Performance Insights is enabled or not | `bool` | `null` | no | -| [performance\_insights\_kms\_key\_id](#input\_performance\_insights\_kms\_key\_id) | The ARN for the KMS key to encrypt Performance Insights data | `string` | `null` | no | -| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | Amount of time in days to retain Performance Insights data. Either 7 (7 days) or 731 (2 years) | `number` | `null` | no | -| [port](#input\_port) | The port on which the DB accepts connections | `string` | `null` | no | -| [predefined\_metric\_type](#input\_predefined\_metric\_type) | The metric type to scale on. Valid values are `RDSReaderAverageCPUUtilization` and `RDSReaderAverageDatabaseConnections` | `string` | `"RDSReaderAverageCPUUtilization"` | no | -| [preferred\_backup\_window](#input\_preferred\_backup\_window) | The daily time range during which automated backups are created if automated backups are enabled using the `backup_retention_period` parameter. Time in UTC | `string` | `"02:00-03:00"` | no | -| [preferred\_maintenance\_window](#input\_preferred\_maintenance\_window) | The weekly time range during which system maintenance can occur, in (UTC) | `string` | `"sun:05:00-sun:06:00"` | no | -| [publicly\_accessible](#input\_publicly\_accessible) | Determines whether instances are publicly accessible. Default `false` | `bool` | `null` | no | -| [putin\_khuylo](#input\_putin\_khuylo) | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | `bool` | `true` | no | -| [replication\_source\_identifier](#input\_replication\_source\_identifier) | ARN of a source DB cluster or DB instance if this DB cluster is to be created as a Read Replica | `string` | `null` | no | -| [restore\_to\_point\_in\_time](#input\_restore\_to\_point\_in\_time) | Map of nested attributes for cloning Aurora cluster | `map(string)` | `{}` | no | -| [s3\_import](#input\_s3\_import) | Configuration map used to restore from a Percona Xtrabackup in S3 (only MySQL is supported) | `map(string)` | `{}` | no | -| [scaling\_configuration](#input\_scaling\_configuration) | Map of nested attributes with scaling properties. Only valid when `engine_mode` is set to `serverless` | `map(string)` | `{}` | no | -| [security\_group\_description](#input\_security\_group\_description) | The description of the security group. If value is set to empty string it will contain cluster name in the description | `string` | `null` | no | -| [security\_group\_name](#input\_security\_group\_name) | The security group name. Default value is (`var.name`) | `string` | `""` | no | -| [security\_group\_rules](#input\_security\_group\_rules) | Map of security group rules to add to the cluster security group created | `any` | `{}` | no | -| [security\_group\_tags](#input\_security\_group\_tags) | Additional tags for the security group | `map(string)` | `{}` | no | -| [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`var.name`) is used as a prefix | `bool` | `true` | no | -| [serverlessv2\_scaling\_configuration](#input\_serverlessv2\_scaling\_configuration) | Map of nested attributes with serverless v2 scaling properties. Only valid when `engine_mode` is set to `provisioned` | `map(string)` | `{}` | no | -| [skip\_final\_snapshot](#input\_skip\_final\_snapshot) | Determines whether a final snapshot is created before the cluster is deleted. If true is specified, no snapshot is created | `bool` | `false` | no | -| [snapshot\_identifier](#input\_snapshot\_identifier) | Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot | `string` | `null` | no | -| [source\_region](#input\_source\_region) | The source region for an encrypted replica DB cluster | `string` | `null` | no | -| [storage\_encrypted](#input\_storage\_encrypted) | Specifies whether the DB cluster is encrypted. The default is `true` | `bool` | `true` | no | -| [storage\_type](#input\_storage\_type) | Determines the storage type for the DB cluster. Optional for Single-AZ, required for Multi-AZ DB clusters. Valid values for Single-AZ: `aurora`, `""` (default, both refer to Aurora Standard), `aurora-iopt1` (Aurora I/O Optimized). Valid values for Multi-AZ: `io1` (default). | `string` | `null` | no | -| [subnets](#input\_subnets) | List of subnet IDs used by database subnet group created | `list(string)` | `[]` | no | -| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | -| [vpc\_id](#input\_vpc\_id) | ID of the VPC where to create security group | `string` | `""` | no | -| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | List of VPC security groups to associate to the cluster in addition to the security group created | `list(string)` | `[]` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [additional\_cluster\_endpoints](#output\_additional\_cluster\_endpoints) | A map of additional cluster endpoints and their attributes | -| [cluster\_arn](#output\_cluster\_arn) | Amazon Resource Name (ARN) of cluster | -| [cluster\_database\_name](#output\_cluster\_database\_name) | Name for an automatically created database on cluster creation | -| [cluster\_endpoint](#output\_cluster\_endpoint) | Writer endpoint for the cluster | -| [cluster\_engine\_version\_actual](#output\_cluster\_engine\_version\_actual) | The running version of the cluster database | -| [cluster\_hosted\_zone\_id](#output\_cluster\_hosted\_zone\_id) | The Route53 Hosted Zone ID of the endpoint | -| [cluster\_id](#output\_cluster\_id) | The RDS Cluster Identifier | -| [cluster\_instances](#output\_cluster\_instances) | A map of cluster instances and their attributes | -| [cluster\_master\_password](#output\_cluster\_master\_password) | The database master password | -| [cluster\_master\_user\_secret](#output\_cluster\_master\_user\_secret) | The generated database master user secret when `manage_master_user_password` is set to `true` | -| [cluster\_master\_username](#output\_cluster\_master\_username) | The database master username | -| [cluster\_members](#output\_cluster\_members) | List of RDS Instances that are a part of this cluster | -| [cluster\_port](#output\_cluster\_port) | The database port | -| [cluster\_reader\_endpoint](#output\_cluster\_reader\_endpoint) | A read-only endpoint for the cluster, automatically load-balanced across replicas | -| [cluster\_resource\_id](#output\_cluster\_resource\_id) | The RDS Cluster Resource ID | -| [cluster\_role\_associations](#output\_cluster\_role\_associations) | A map of IAM roles associated with the cluster and their attributes | -| [db\_cluster\_activity\_stream\_kinesis\_stream\_name](#output\_db\_cluster\_activity\_stream\_kinesis\_stream\_name) | The name of the Amazon Kinesis data stream to be used for the database activity stream | -| [db\_cluster\_cloudwatch\_log\_groups](#output\_db\_cluster\_cloudwatch\_log\_groups) | Map of CloudWatch log groups created and their attributes | -| [db\_cluster\_parameter\_group\_arn](#output\_db\_cluster\_parameter\_group\_arn) | The ARN of the DB cluster parameter group created | -| [db\_cluster\_parameter\_group\_id](#output\_db\_cluster\_parameter\_group\_id) | The ID of the DB cluster parameter group created | -| [db\_parameter\_group\_arn](#output\_db\_parameter\_group\_arn) | The ARN of the DB parameter group created | -| [db\_parameter\_group\_id](#output\_db\_parameter\_group\_id) | The ID of the DB parameter group created | -| [db\_subnet\_group\_name](#output\_db\_subnet\_group\_name) | The db subnet group name | -| [enhanced\_monitoring\_iam\_role\_arn](#output\_enhanced\_monitoring\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the enhanced monitoring role | -| [enhanced\_monitoring\_iam\_role\_name](#output\_enhanced\_monitoring\_iam\_role\_name) | The name of the enhanced monitoring role | -| [enhanced\_monitoring\_iam\_role\_unique\_id](#output\_enhanced\_monitoring\_iam\_role\_unique\_id) | Stable and unique string identifying the enhanced monitoring role | -| [security\_group\_id](#output\_security\_group\_id) | The security group ID of the cluster | - - -## Authors - -Module is maintained by [Anton Babenko](https://github.com/antonbabenko) with help from [these awesome contributors](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/graphs/contributors). - -## License - -Apache 2 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-aurora/tree/master/LICENSE) for full details. - -## Additional information for users from Russia and Belarus - -* Russia has [illegally annexed Crimea in 2014](https://en.wikipedia.org/wiki/Annexation_of_Crimea_by_the_Russian_Federation) and [brought the war in Donbas](https://en.wikipedia.org/wiki/War_in_Donbas) followed by [full-scale invasion of Ukraine in 2022](https://en.wikipedia.org/wiki/2022_Russian_invasion_of_Ukraine). -* Russia has brought sorrow and devastations to millions of Ukrainians, killed hundreds of innocent people, damaged thousands of buildings, and forced several million people to flee. -* [Putin khuylo!](https://en.wikipedia.org/wiki/Putin_khuylo!) diff --git a/new_modules/rds-aurora/versions.tf b/new_modules/rds-aurora/versions.tf deleted file mode 100644 index 47125bf8..00000000 --- a/new_modules/rds-aurora/versions.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.67" - } - } -} diff --git a/new_modules/rds-proxy/README.md b/new_modules/rds-proxy/README.md deleted file mode 100644 index 4fcd4d5e..00000000 --- a/new_modules/rds-proxy/README.md +++ /dev/null @@ -1,165 +0,0 @@ -# AWS RDS Proxy Terraform module - -Terraform module which creates an AWS RDS Proxy and its supporting resources. - -## Usage - -See [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) directory for working examples to reference: - -```hcl -module "rds_proxy" { - source = "terraform-aws-modules/rds-proxy/aws" - - name = "rds-proxy" - iam_role_name = "rds-proxy-role" - vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] - vpc_security_group_ids = ["sg-f1d03a88"] - - endpoints = { - read_write = { - name = "read-write-endpoint" - vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] - vpc_security_group_ids = ["sg-f1d03a88"] - }, - read_only = { - name = "read-only-endpoint" - vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] - vpc_security_group_ids = ["sg-f1d03a88"] - target_role = "READ_ONLY" - } - } - - auth = { - "superuser" = { - description = "Aurora PostgreSQL superuser password" - secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD" - } - } - - # Target Aurora cluster - engine_family = "POSTGRESQL" - target_db_cluster = true - db_cluster_identifier = "my-endpoint" - - tags = { - Terraform = "true" - Environment = "dev" - } -} -``` - -## Examples - -Examples codified under the [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module(s). If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you! - -- [IAM auth. w/ MySQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-cluster) -- [IAM auth. w/ MySQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-instance) -- [IAM auth. w/ PostgreSQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-cluster) -- [IAM auth. w/ PostgreSQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-instance) - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.0 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | >= 5.0 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | -| [aws_db_proxy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy) | resource | -| [aws_db_proxy_default_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_default_target_group) | resource | -| [aws_db_proxy_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_endpoint) | resource | -| [aws_db_proxy_target.db_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | -| [aws_db_proxy_target.db_instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | -| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | -| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | -| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [auth](#input\_auth) | Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters | `any` | `{}` | no | -| [connection\_borrow\_timeout](#input\_connection\_borrow\_timeout) | The number of seconds for a proxy to wait for a connection to become available in the connection pool | `number` | `null` | no | -| [create](#input\_create) | Whether cluster should be created (affects nearly all resources) | `bool` | `true` | no | -| [create\_iam\_policy](#input\_create\_iam\_policy) | Determines whether an IAM policy is created | `bool` | `true` | no | -| [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created | `bool` | `true` | no | -| [db\_cluster\_identifier](#input\_db\_cluster\_identifier) | DB cluster identifier | `string` | `""` | no | -| [db\_instance\_identifier](#input\_db\_instance\_identifier) | DB instance identifier | `string` | `""` | no | -| [debug\_logging](#input\_debug\_logging) | Whether the proxy includes detailed information about SQL statements in its logs | `bool` | `false` | no | -| [endpoints](#input\_endpoints) | Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`) | `any` | `{}` | no | -| [engine\_family](#input\_engine\_family) | The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL` | `string` | `""` | no | -| [iam\_policy\_name](#input\_iam\_policy\_name) | The name of the role policy. If omitted, Terraform will assign a random, unique name | `string` | `""` | no | -| [iam\_role\_description](#input\_iam\_role\_description) | The description of the role | `string` | `""` | no | -| [iam\_role\_force\_detach\_policies](#input\_iam\_role\_force\_detach\_policies) | Specifies to force detaching any policies the role has before destroying it | `bool` | `true` | no | -| [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | The maximum session duration (in seconds) that you want to set for the specified role | `number` | `43200` | no | -| [iam\_role\_name](#input\_iam\_role\_name) | The name of the role. If omitted, Terraform will assign a random, unique name | `string` | `""` | no | -| [iam\_role\_path](#input\_iam\_role\_path) | The path to the role | `string` | `null` | no | -| [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the policy that is used to set the permissions boundary for the role | `string` | `null` | no | -| [iam\_role\_tags](#input\_iam\_role\_tags) | A map of tags to apply to the IAM role | `map(string)` | `{}` | no | -| [idle\_client\_timeout](#input\_idle\_client\_timeout) | The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it | `number` | `1800` | no | -| [init\_query](#input\_init\_query) | One or more SQL statements for the proxy to run when opening each new database connection | `string` | `""` | no | -| [kms\_key\_arns](#input\_kms\_key\_arns) | List of KMS Key ARNs to allow access to decrypt SecretsManager secrets | `list(string)` | `[]` | no | -| [log\_group\_kms\_key\_id](#input\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | -| [log\_group\_retention\_in\_days](#input\_log\_group\_retention\_in\_days) | Specifies the number of days you want to retain log events in the log group | `number` | `30` | no | -| [log\_group\_tags](#input\_log\_group\_tags) | A map of tags to apply to the CloudWatch log group | `map(string)` | `{}` | no | -| [manage\_log\_group](#input\_manage\_log\_group) | Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist | `bool` | `true` | no | -| [max\_connections\_percent](#input\_max\_connections\_percent) | The maximum size of the connection pool for each target in a target group | `number` | `90` | no | -| [max\_idle\_connections\_percent](#input\_max\_idle\_connections\_percent) | Controls how actively the proxy closes idle database connections in the connection pool | `number` | `50` | no | -| [name](#input\_name) | The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens | `string` | `""` | no | -| [proxy\_tags](#input\_proxy\_tags) | A map of tags to apply to the RDS Proxy | `map(string)` | `{}` | no | -| [require\_tls](#input\_require\_tls) | A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy | `bool` | `true` | no | -| [role\_arn](#input\_role\_arn) | The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager | `string` | `""` | no | -| [session\_pinning\_filters](#input\_session\_pinning\_filters) | Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection | `list(string)` | `[]` | no | -| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | -| [target\_db\_cluster](#input\_target\_db\_cluster) | Determines whether DB cluster is targeted by proxy | `bool` | `false` | no | -| [target\_db\_instance](#input\_target\_db\_instance) | Determines whether DB instance is targeted by proxy | `bool` | `false` | no | -| [use\_policy\_name\_prefix](#input\_use\_policy\_name\_prefix) | Whether to use unique name beginning with the specified `iam_policy_name` | `bool` | `false` | no | -| [use\_role\_name\_prefix](#input\_use\_role\_name\_prefix) | Whether to use unique name beginning with the specified `iam_role_name` | `bool` | `false` | no | -| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | One or more VPC security group IDs to associate with the new proxy | `list(string)` | `[]` | no | -| [vpc\_subnet\_ids](#input\_vpc\_subnet\_ids) | One or more VPC subnet IDs to associate with the new proxy | `list(string)` | `[]` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created | -| [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager. | -| [iam\_role\_name](#output\_iam\_role\_name) | IAM role name | -| [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | -| [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group | -| [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy | -| [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group | -| [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group | -| [proxy\_default\_target\_group\_name](#output\_proxy\_default\_target\_group\_name) | The name of the default target group | -| [proxy\_endpoint](#output\_proxy\_endpoint) | The endpoint that you can use to connect to the proxy | -| [proxy\_id](#output\_proxy\_id) | The ID for the proxy | -| [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | -| [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) | -| [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB Instance or Aurora DB Cluster | -| [proxy\_target\_rds\_resource\_id](#output\_proxy\_target\_rds\_resource\_id) | Identifier representing the DB Instance or DB Cluster target | -| [proxy\_target\_target\_arn](#output\_proxy\_target\_target\_arn) | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API | -| [proxy\_target\_tracked\_cluster\_id](#output\_proxy\_target\_tracked\_cluster\_id) | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster | -| [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` | - - -## License - -Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE). diff --git a/new_modules/rds-proxy/outputs.tf b/new_modules/rds-proxy/outputs.tf deleted file mode 100644 index 355b2b43..00000000 --- a/new_modules/rds-proxy/outputs.tf +++ /dev/null @@ -1,95 +0,0 @@ -# RDS Proxy -output "proxy_id" { - description = "The ID for the proxy" - value = try(aws_db_proxy.this[0].id, null) -} - -output "proxy_arn" { - description = "The Amazon Resource Name (ARN) for the proxy" - value = try(aws_db_proxy.this[0].arn, null) -} - -output "proxy_endpoint" { - description = "The endpoint that you can use to connect to the proxy" - value = try(aws_db_proxy.this[0].endpoint, null) -} - -# Proxy Default Target Group -output "proxy_default_target_group_id" { - description = "The ID for the default target group" - value = try(aws_db_proxy_default_target_group.this[0].id, null) -} - -output "proxy_default_target_group_arn" { - description = "The Amazon Resource Name (ARN) for the default target group" - value = try(aws_db_proxy_default_target_group.this[0].arn, null) -} - -output "proxy_default_target_group_name" { - description = "The name of the default target group" - value = try(aws_db_proxy_default_target_group.this[0].name, null) -} - -# Proxy Target -output "proxy_target_endpoint" { - description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type" - value = try(aws_db_proxy_target.db_instance[0].endpoint, aws_db_proxy_target.db_cluster[0].endpoint, null) -} - -output "proxy_target_id" { - description = "Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/)" - value = try(aws_db_proxy_target.db_instance[0].id, aws_db_proxy_target.db_cluster[0].id, null) -} - -output "proxy_target_port" { - description = "Port for the target RDS DB Instance or Aurora DB Cluster" - value = try(aws_db_proxy_target.db_instance[0].port, aws_db_proxy_target.db_cluster[0].port, null) -} - -output "proxy_target_rds_resource_id" { - description = "Identifier representing the DB Instance or DB Cluster target" - value = try(aws_db_proxy_target.db_instance[0].rds_resource_id, aws_db_proxy_target.db_cluster[0].rds_resource_id, null) -} - -output "proxy_target_target_arn" { - description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API" - value = try(aws_db_proxy_target.db_instance[0].target_arn, aws_db_proxy_target.db_cluster[0].target_arn, null) -} - -output "proxy_target_tracked_cluster_id" { - description = "DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS_INSTANCE target that is part of a DB Cluster" - value = try(aws_db_proxy_target.db_cluster[0].tracked_cluster_id, null) -} - -output "proxy_target_type" { - description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`" - value = try(aws_db_proxy_target.db_instance[0].type, aws_db_proxy_target.db_cluster[0].type, null) -} - -# DB proxy endpoints -output "db_proxy_endpoints" { - description = "Array containing the full resource object and attributes for all DB proxy endpoints created" - value = aws_db_proxy_endpoint.this -} - -# CloudWatch logs -output "log_group_arn" { - description = "The Amazon Resource Name (ARN) of the CloudWatch log group" - value = try(aws_cloudwatch_log_group.this[0].arn, null) -} - -# IAM role -output "iam_role_arn" { - description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager." - value = try(aws_iam_role.this[0].arn, null) -} - -output "iam_role_name" { - description = "IAM role name" - value = try(aws_iam_role.this[0].name, null) -} - -output "iam_role_unique_id" { - description = "Stable and unique string identifying the IAM role" - value = try(aws_iam_role.this[0].unique_id, null) -} diff --git a/new_modules/rds-proxy/variables.tf b/new_modules/rds-proxy/variables.tf deleted file mode 100644 index dd4f24e2..00000000 --- a/new_modules/rds-proxy/variables.tf +++ /dev/null @@ -1,255 +0,0 @@ -variable "create" { - description = "Whether cluster should be created (affects nearly all resources)" - type = bool - default = true -} - -variable "tags" { - description = "A map of tags to add to all resources" - type = map(string) - default = {} -} - -################################################################################ -# RDS Proxy -################################################################################ - -variable "name" { - description = "The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens" - type = string - default = "" -} - -variable "auth" { - description = "Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters" - type = any - default = {} -} - -variable "debug_logging" { - description = "Whether the proxy includes detailed information about SQL statements in its logs" - type = bool - default = false -} - -variable "engine_family" { - description = "The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL`" - type = string - default = "" -} - -variable "idle_client_timeout" { - description = "The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it" - type = number - default = 1800 -} - -variable "require_tls" { - description = "A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy" - type = bool - default = true -} - -variable "role_arn" { - description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager" - type = string - default = "" -} - -variable "vpc_security_group_ids" { - description = "One or more VPC security group IDs to associate with the new proxy" - type = list(string) - default = [] -} - -variable "vpc_subnet_ids" { - description = "One or more VPC subnet IDs to associate with the new proxy" - type = list(string) - default = [] -} - -variable "proxy_tags" { - description = "A map of tags to apply to the RDS Proxy" - type = map(string) - default = {} -} - -# Proxy Default Target Group -variable "connection_borrow_timeout" { - description = "The number of seconds for a proxy to wait for a connection to become available in the connection pool" - type = number - default = null -} - -variable "init_query" { - description = "One or more SQL statements for the proxy to run when opening each new database connection" - type = string - default = "" -} - -variable "max_connections_percent" { - description = "The maximum size of the connection pool for each target in a target group" - type = number - default = 90 -} - -variable "max_idle_connections_percent" { - description = "Controls how actively the proxy closes idle database connections in the connection pool" - type = number - default = 50 -} - -variable "session_pinning_filters" { - description = "Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection" - type = list(string) - default = [] -} - -# Proxy Target -variable "target_db_instance" { - description = "Determines whether DB instance is targeted by proxy" - type = bool - default = false -} - -variable "db_instance_identifier" { - description = "DB instance identifier" - type = string - default = "" -} - -variable "target_db_cluster" { - description = "Determines whether DB cluster is targeted by proxy" - type = bool - default = false -} - -variable "db_cluster_identifier" { - description = "DB cluster identifier" - type = string - default = "" -} - -# Proxy endpoints -variable "endpoints" { - description = "Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`)" - type = any - default = {} -} - -################################################################################ -# CloudWatch Logs -################################################################################ - -variable "manage_log_group" { - description = "Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist" - type = bool - default = true -} - -variable "log_group_retention_in_days" { - description = "Specifies the number of days you want to retain log events in the log group" - type = number - default = 30 -} - -variable "log_group_kms_key_id" { - description = "The ARN of the KMS Key to use when encrypting log data" - type = string - default = null -} - -variable "log_group_tags" { - description = "A map of tags to apply to the CloudWatch log group" - type = map(string) - default = {} -} - -variable "cloudwatch_log_group_skip_destroy_on_deletion" { - description = "value to skip destroy ClouwWatch log group on deletion" - type = bool - default = false -} - -################################################################################ -# IAM Role -################################################################################ - -variable "create_iam_role" { - description = "Determines whether an IAM role is created" - type = bool - default = true -} - -variable "iam_role_name" { - description = "The name of the role. If omitted, Terraform will assign a random, unique name" - type = string - default = "" -} - -variable "use_role_name_prefix" { - description = "Whether to use unique name beginning with the specified `iam_role_name`" - type = bool - default = false -} - -variable "iam_role_description" { - description = "The description of the role" - type = string - default = "" -} - -variable "iam_role_path" { - description = "The path to the role" - type = string - default = null -} - -variable "iam_role_force_detach_policies" { - description = "Specifies to force detaching any policies the role has before destroying it" - type = bool - default = true -} - -variable "iam_role_max_session_duration" { - description = "The maximum session duration (in seconds) that you want to set for the specified role" - type = number - default = 43200 # 12 hours -} - -variable "iam_role_permissions_boundary" { - description = "The ARN of the policy that is used to set the permissions boundary for the role" - type = string - default = null -} - -variable "iam_role_tags" { - description = "A map of tags to apply to the IAM role" - type = map(string) - default = {} -} - -# IAM Policy -variable "create_iam_policy" { - description = "Determines whether an IAM policy is created" - type = bool - default = true -} - -variable "iam_policy_name" { - description = "The name of the role policy. If omitted, Terraform will assign a random, unique name" - type = string - default = "" -} - -variable "use_policy_name_prefix" { - description = "Whether to use unique name beginning with the specified `iam_policy_name`" - type = bool - default = false -} - -variable "kms_key_arns" { - description = "List of KMS Key ARNs to allow access to decrypt SecretsManager secrets" - type = list(string) - default = [] -} diff --git a/new_modules/rds-proxy/versions.tf b/new_modules/rds-proxy/versions.tf deleted file mode 100644 index ddfcb0e0..00000000 --- a/new_modules/rds-proxy/versions.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 5.0" - } - } -} diff --git a/tests/instance/main.tf b/tests/instance/main.tf new file mode 100644 index 00000000..5acd28c1 --- /dev/null +++ b/tests/instance/main.tf @@ -0,0 +1,127 @@ +provider "aws" { + region = local.region +} + +data "aws_caller_identity" "current" {} +data "aws_availability_zones" "available" {} + +locals { + name = "postgresql-instance" + region = "eu-central-1" + + vpc_cidr = "10.20.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + tags = { + Name = local.name + Example = local.name + Repository = "https://github.com/terraform-aws-modules/terraform-aws-rds" + } +} + + +module "rds_instance_test" { + source = "../../" + identifier = local.name + + + instance_class = "db.t3.micro" + multi_az = true + username = "instance_user" + vpc_security_group_ids = [module.security_group.security_group_id] + ca_cert_identifier = "rds-ca-ecc384-g1" + apply_immediately = true + tags = local.tags + + + publicly_accessible = true + + + subnet_ids = concat(module.vpc.public_subnets) + allocated_storage = 100 + + enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"] + + rds_proxy_security_group_ids = [aws_security_group.rds_proxy_sg.id] + + include_proxy = true + proxy_debug_logging = true + + monitoring_interval = 60 + +} + + +################################################################################ +# Supporting Resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 5.0" + + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] + # database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] + + # create_database_subnet_group = true + + tags = local.tags +} + +module "security_group" { # update with another rule for public access + source = "terraform-aws-modules/security-group/aws" + version = "~> 5.0" + + name = local.name + description = "Complete PostgreSQL example security group" + vpc_id = module.vpc.vpc_id + + # ingress + ingress_with_cidr_blocks = [ + { + from_port = 5432 + to_port = 5432 + protocol = "tcp" + description = "PostgreSQL access from within VPC" + cidr_blocks = module.vpc.vpc_cidr_block + }, + { + rule = "postgresql-tcp" + cidr_blocks = "0.0.0.0/0" + description = "PostgreSQL access from internet" + }, + ] + + tags = local.tags +} + + +resource "aws_security_group" "rds_proxy_sg" { # TODO: add conditional to only create when proxy is enabled + + name = "rds-proxy-${local.name}" + description = "A security group for ${local.name} database proxy" + vpc_id = module.vpc.vpc_id + + tags = local.tags + + # Proxy requires self referencing inbound rule + ingress { + from_port = 5432 + to_port = 5432 + protocol = "tcp" + self = true + } + + # Allow outbound all traffic + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} diff --git a/tests/multi_az_cluster/main.tf b/tests/multi_az_cluster/main.tf new file mode 100644 index 00000000..7ca005c3 --- /dev/null +++ b/tests/multi_az_cluster/main.tf @@ -0,0 +1,125 @@ +provider "aws" { + region = local.region +} + +data "aws_caller_identity" "current" {} +data "aws_availability_zones" "available" {} + +locals { + name = "postgresql-multi-az-cluster" + region = "eu-central-1" + + vpc_cidr = "10.20.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + tags = { + Name = local.name + Example = local.name + Repository = "https://github.com/terraform-aws-modules/terraform-aws-rds" + } +} + + +module "rds_cluster_test" { + source = "../../" + identifier = local.name + + is_db_cluster = true + cluster_db_instance_count = 0 + instance_class = "db.m5d.large" + username = "cluster_user" + vpc_security_group_ids = [module.security_group.security_group_id] + ca_cert_identifier = "rds-ca-ecc384-g1" + apply_immediately = true + tags = local.tags + + + publicly_accessible = true + + subnet_ids = concat(module.vpc.public_subnets) + allocated_storage = 100 + + enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"] + + rds_proxy_security_group_ids = [aws_security_group.rds_proxy_sg.id] + + include_proxy = false + + monitoring_interval = 60 +} + + + +################################################################################ +# Supporting Resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 5.0" + + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] + # database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] + + # create_database_subnet_group = true + + tags = local.tags +} + +module "security_group" { # update with another rule for public access + source = "terraform-aws-modules/security-group/aws" + version = "~> 5.0" + + name = local.name + description = "Complete PostgreSQL example security group" + vpc_id = module.vpc.vpc_id + + # ingress + ingress_with_cidr_blocks = [ + { + from_port = 5432 + to_port = 5432 + protocol = "tcp" + description = "PostgreSQL access from within VPC" + cidr_blocks = module.vpc.vpc_cidr_block + }, + { + rule = "postgresql-tcp" + cidr_blocks = "0.0.0.0/0" + description = "PostgreSQL access from internet" + }, + ] + + tags = local.tags +} + + +resource "aws_security_group" "rds_proxy_sg" { # TODO: add conditional to only create when proxy is enabled + + name = "rds-proxy-${local.name}" + description = "A security group for ${local.name} database proxy" + vpc_id = module.vpc.vpc_id + + tags = local.tags + + # Proxy requires self referencing inbound rule + ingress { + from_port = 5432 + to_port = 5432 + protocol = "tcp" + self = true + } + + # Allow outbound all traffic + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} diff --git a/tests/serverless/main.tf b/tests/serverless/main.tf new file mode 100644 index 00000000..6e95b290 --- /dev/null +++ b/tests/serverless/main.tf @@ -0,0 +1,125 @@ +provider "aws" { + region = local.region +} + +data "aws_caller_identity" "current" {} +data "aws_availability_zones" "available" {} + +locals { + name = "postgresql-serverless" + region = "eu-central-1" + + vpc_cidr = "10.20.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + tags = { + Name = local.name + Example = local.name + Repository = "https://github.com/terraform-aws-modules/terraform-aws-rds" + } +} + + +module "rds_cluster_test" { + source = "../../" + identifier = local.name + +# is_db_cluster = true + is_serverless = true + cluster_db_instance_count = 0 + username = "cluster_user" + vpc_security_group_ids = [module.security_group.security_group_id] + ca_cert_identifier = "rds-ca-ecc384-g1" + apply_immediately = true + tags = local.tags + + + publicly_accessible = true + + subnet_ids = concat(module.vpc.public_subnets) + allocated_storage = 100 + + enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"] + + rds_proxy_security_group_ids = [aws_security_group.rds_proxy_sg.id] + + include_proxy = false + + monitoring_interval = 60 +} + + + +################################################################################ +# Supporting Resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 5.0" + + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] + # database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] + + # create_database_subnet_group = true + + tags = local.tags +} + +module "security_group" { # update with another rule for public access + source = "terraform-aws-modules/security-group/aws" + version = "~> 5.0" + + name = local.name + description = "Complete PostgreSQL example security group" + vpc_id = module.vpc.vpc_id + + # ingress + ingress_with_cidr_blocks = [ + { + from_port = 5432 + to_port = 5432 + protocol = "tcp" + description = "PostgreSQL access from within VPC" + cidr_blocks = module.vpc.vpc_cidr_block + }, + { + rule = "postgresql-tcp" + cidr_blocks = "0.0.0.0/0" + description = "PostgreSQL access from internet" + }, + ] + + tags = local.tags +} + + +resource "aws_security_group" "rds_proxy_sg" { # TODO: add conditional to only create when proxy is enabled + + name = "rds-proxy-${local.name}" + description = "A security group for ${local.name} database proxy" + vpc_id = module.vpc.vpc_id + + tags = local.tags + + # Proxy requires self referencing inbound rule + ingress { + from_port = 5432 + to_port = 5432 + protocol = "tcp" + self = true + } + + # Allow outbound all traffic + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} diff --git a/variables.tf b/variables.tf index 8ecad139..d3b6258d 100644 --- a/variables.tf +++ b/variables.tf @@ -680,7 +680,8 @@ variable "cluster_instances" { } variable "cluster_db_instance_count" { -type = number + type = number + default = 0 } variable "cluster_instances_use_identifier_prefix" { @@ -838,4 +839,10 @@ variable "vpc_id" { # TODO: include? variable "rds_proxy_security_group_ids" { # TODO: remove type = list(string) default = [] +} + + +variable "is_serverless" { # tempprary variable for testing + type = bool + default = false } \ No newline at end of file From 78af72a43776d54501509bf947a341d954dc1283 Mon Sep 17 00:00:00 2001 From: samidbb Date: Fri, 3 Nov 2023 08:33:14 +0100 Subject: [PATCH 07/12] minor cleanup --- modules/cloudwatch_log_groups/outputs.tf | 4 -- modules/rds_aurora/outputs.tf | 74 ---------------------- modules/rds_aurora/variables.tf | 80 ------------------------ modules/rds_instance/variables.tf | 72 +-------------------- 4 files changed, 1 insertion(+), 229 deletions(-) diff --git a/modules/cloudwatch_log_groups/outputs.tf b/modules/cloudwatch_log_groups/outputs.tf index c131f108..34021011 100644 --- a/modules/cloudwatch_log_groups/outputs.tf +++ b/modules/cloudwatch_log_groups/outputs.tf @@ -1,7 +1,3 @@ -################################################################################ -# CloudWatch Log Group -################################################################################ - output "db_instance_cloudwatch_log_groups" { description = "Map of CloudWatch log groups created and their attributes" value = aws_cloudwatch_log_group.this diff --git a/modules/rds_aurora/outputs.tf b/modules/rds_aurora/outputs.tf index 8fde54ed..7e4717e6 100644 --- a/modules/rds_aurora/outputs.tf +++ b/modules/rds_aurora/outputs.tf @@ -1,12 +1,3 @@ -################################################################################ -# DB Subnet Group -################################################################################ - -# output "db_subnet_group_name" { -# description = "The db subnet group name" -# value = local.db_subnet_group_name -# } - ################################################################################ # Cluster ################################################################################ @@ -111,71 +102,6 @@ output "cluster_role_associations" { value = aws_rds_cluster_role_association.this } -# ################################################################################ -# # Enhanced Monitoring -# ################################################################################ - -# output "enhanced_monitoring_iam_role_name" { -# description = "The name of the enhanced monitoring role" -# value = try(aws_iam_role.rds_enhanced_monitoring[0].name, null) -# } - -# output "enhanced_monitoring_iam_role_arn" { -# description = "The Amazon Resource Name (ARN) specifying the enhanced monitoring role" -# value = try(aws_iam_role.rds_enhanced_monitoring[0].arn, null) -# } - -# output "enhanced_monitoring_iam_role_unique_id" { -# description = "Stable and unique string identifying the enhanced monitoring role" -# value = try(aws_iam_role.rds_enhanced_monitoring[0].unique_id, null) -# } - -################################################################################ -# Security Group -################################################################################ - -# output "security_group_id" { -# description = "The security group ID of the cluster" -# value = try(aws_security_group.this[0].id, null) -# } - -# ################################################################################ -# # Cluster Parameter Group -# ################################################################################ - -# output "db_cluster_parameter_group_arn" { -# description = "The ARN of the DB cluster parameter group created" -# value = try(aws_rds_cluster_parameter_group.this[0].arn, null) -# } - -# output "db_cluster_parameter_group_id" { -# description = "The ID of the DB cluster parameter group created" -# value = try(aws_rds_cluster_parameter_group.this[0].id, null) -# } - -# ################################################################################ -# # DB Parameter Group -# ################################################################################ - -# output "db_parameter_group_arn" { -# description = "The ARN of the DB parameter group created" -# value = try(aws_db_parameter_group.this[0].arn, null) -# } - -# output "db_parameter_group_id" { -# description = "The ID of the DB parameter group created" -# value = try(aws_db_parameter_group.this[0].id, null) -# } - -# ################################################################################ -# # CloudWatch Log Group -# ################################################################################ - -# output "db_cluster_cloudwatch_log_groups" { -# description = "Map of CloudWatch log groups created and their attributes" -# value = aws_cloudwatch_log_group.this -# } - ################################################################################ # Cluster Activity Stream ################################################################################ diff --git a/modules/rds_aurora/variables.tf b/modules/rds_aurora/variables.tf index 82e93d94..7610f916 100644 --- a/modules/rds_aurora/variables.tf +++ b/modules/rds_aurora/variables.tf @@ -603,86 +603,6 @@ variable "db_cluster_parameter_group_name" { default = null } -# variable "db_cluster_parameter_group_use_name_prefix" { -# description = "Determines whether the DB cluster parameter group name is used as a prefix" -# type = bool -# default = false -# } - -# variable "db_cluster_parameter_group_description" { -# description = "The description of the DB cluster parameter group. Defaults to \"Managed by Terraform\"" -# type = string -# default = null -# } - -# variable "db_cluster_parameter_group_family" { -# description = "The family of the DB cluster parameter group" -# type = string -# default = "" -# } - -# variable "db_cluster_parameter_group_parameters" { -# description = "A list of DB cluster parameters to apply. Note that parameters may differ from a family to an other" -# type = list(map(string)) -# default = [] -# } - -################################################################################ -# DB Parameter Group -################################################################################ - -# variable "create_db_parameter_group" { -# description = "Determines whether a DB parameter should be created or use existing" -# type = bool -# default = false -# } - -# variable "db_parameter_group_use_name_prefix" { -# description = "Determines whether the DB parameter group name is used as a prefix" -# type = bool -# default = true -# } - -# variable "db_parameter_group_description" { -# description = "The description of the DB parameter group. Defaults to \"Managed by Terraform\"" -# type = string -# default = null -# } - -# variable "db_parameter_group_family" { -# description = "The family of the DB parameter group" -# type = string -# default = "" -# } - -# variable "db_parameter_group_parameters" { -# description = "A list of DB parameters to apply. Note that parameters may differ from a family to an other" -# type = list(map(string)) -# default = [] -# } - -# ################################################################################ -# # CloudWatch Log Group -# ################################################################################ - -# variable "create_cloudwatch_log_group" { -# description = "Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports`" -# type = bool -# default = false -# } - -# variable "cloudwatch_log_group_retention_in_days" { -# description = "The number of days to retain CloudWatch logs for the DB instance" -# type = number -# default = 7 -# } - -# variable "cloudwatch_log_group_kms_key_id" { -# description = "The ARN of the KMS Key to use when encrypting log data" -# type = string -# default = null -# } - ################################################################################ # Cluster Activity Stream ################################################################################ diff --git a/modules/rds_instance/variables.tf b/modules/rds_instance/variables.tf index dc82695d..313fe709 100644 --- a/modules/rds_instance/variables.tf +++ b/modules/rds_instance/variables.tf @@ -1,9 +1,3 @@ -# variable "create" { -# description = "Whether to create this resource or not?" -# type = bool -# default = true -# } - variable "identifier" { description = "The name of the RDS instance" type = string @@ -221,42 +215,6 @@ variable "monitoring_role_arn" { default = null } -# variable "monitoring_role_name" { -# description = "Name of the IAM role which will be created when create_monitoring_role is enabled." -# type = string -# default = "rds-monitoring-role" -# } - -# variable "monitoring_role_use_name_prefix" { -# description = "Determines whether to use `monitoring_role_name` as is or create a unique identifier beginning with `monitoring_role_name` as the specified prefix" -# type = bool -# default = false -# } - -# variable "monitoring_role_description" { -# description = "Description of the monitoring IAM role" -# type = string -# default = null -# } - -# variable "monitoring_role_permissions_boundary" { -# description = "ARN of the policy that is used to set the permissions boundary for the monitoring IAM role" -# type = string -# default = null -# } - -# variable "monitoring_iam_role_path" { -# description = "Path for the monitoring role" -# type = string -# default = null -# } - -# variable "create_monitoring_role" { -# description = "Create IAM role with a defined name that permits RDS to send enhanced monitoring metrics to CloudWatch Logs." -# type = bool -# default = false -# } - variable "allow_major_version_upgrade" { description = "Indicates that major version upgrades are allowed. Changing this parameter does not result in an outage and the change is asynchronously applied as soon as possible" type = bool @@ -400,32 +358,4 @@ variable "network_type" { description = "The type of network stack" type = string default = null -} - -# ################################################################################ -# # CloudWatch Log Group -# ################################################################################ - -# variable "create_cloudwatch_log_group" { -# description = "Determines whether a CloudWatch log group is created for each `enabled_cloudwatch_logs_exports`" -# type = bool -# default = false -# } - -# variable "cloudwatch_log_group_retention_in_days" { -# description = "The number of days to retain CloudWatch logs for the DB instance" -# type = number -# default = 7 -# } - -# variable "cloudwatch_log_group_kms_key_id" { -# description = "The ARN of the KMS Key to use when encrypting log data" -# type = string -# default = null -# } - -# variable "cloudwatch_log_group_skip_destroy_on_deletion" { -# description = "value to skip destroy ClouwWatch log group on deletion" -# type = bool -# default = false -# } \ No newline at end of file +} \ No newline at end of file From fbe1111dd8c916270685e08afd262da05c4591cd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 3 Nov 2023 07:35:07 +0000 Subject: [PATCH 08/12] terraform-docs: automated action --- README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6e98c699..0cebe63e 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,15 @@ Terraform module for AWS RDS instances | Name | Source | Version | |------|--------|---------| -| [cluster](#module\_cluster) | ./_sub/terraform-aws-rds-aurora | n/a | -| [db](#module\_db) | ./_sub/terraform-aws-rds | n/a | -| [db\_proxy](#module\_db\_proxy) | ./_sub/terraform-aws-rds-proxy | n/a | +| [cluster\_parameters](#module\_cluster\_parameters) | ./modules/cluster_parameter_group | n/a | +| [cw\_log\_group](#module\_cw\_log\_group) | ./modules/cloudwatch_log_groups | n/a | +| [db\_cluster\_serverless](#module\_db\_cluster\_serverless) | ./modules/rds_aurora | n/a | +| [db\_instance](#module\_db\_instance) | ./modules/rds_instance | n/a | +| [db\_multi\_az\_cluster](#module\_db\_multi\_az\_cluster) | ./modules/rds_aurora | n/a | +| [db\_parameter\_group](#module\_db\_parameter\_group) | ./modules/instance_parameter_group | n/a | +| [db\_proxy](#module\_db\_proxy) | ./modules/rds_proxy | n/a | +| [db\_subnet\_group](#module\_db\_subnet\_group) | ./modules/rds_subnet_group | n/a | +| [enhanced\_monitoring\_iam\_role](#module\_enhanced\_monitoring\_iam\_role) | ./modules/enhanced_monitoring_role | n/a | ## Resources @@ -58,7 +64,7 @@ Terraform module for AWS RDS instances | [cluster\_autoscaling\_target\_cpu](#input\_cluster\_autoscaling\_target\_cpu) | CPU threshold which will initiate autoscaling | `number` | `70` | no | | [cluster\_availability\_zones](#input\_cluster\_availability\_zones) | List of EC2 Availability Zones for the DB cluster storage where DB cluster instances can be created. RDS automatically assigns 3 AZs if less than 3 AZs are configured, which will show as a difference requiring resource recreation next Terraform apply | `list(string)` | `null` | no | | [cluster\_backtrack\_window](#input\_cluster\_backtrack\_window) | The target backtrack window, in seconds. Only available for `aurora` engine currently. To disable backtracking, set this value to 0. Must be between 0 and 259200 (72 hours) | `number` | `null` | no | -| [cluster\_db\_instance\_count](#input\_cluster\_db\_instance\_count) | n/a | `number` | n/a | yes | +| [cluster\_db\_instance\_count](#input\_cluster\_db\_instance\_count) | n/a | `number` | `0` | no | | [cluster\_enable\_global\_write\_forwarding](#input\_cluster\_enable\_global\_write\_forwarding) | Whether cluster should forward writes to an associated global cluster. Applied to secondary clusters to enable them to forward writes to an `aws_rds_global_cluster`'s primary cluster | `bool` | `null` | no | | [cluster\_enable\_http\_endpoint](#input\_cluster\_enable\_http\_endpoint) | Enable HTTP endpoint (data API). Only valid when engine\_mode is set to `serverless` | `bool` | `null` | no | | [cluster\_endpoints](#input\_cluster\_endpoints) | Map of additional cluster endpoints and their attributes to be created | `any` | `{}` | no | @@ -84,7 +90,6 @@ Terraform module for AWS RDS instances | [create\_db\_instance](#input\_create\_db\_instance) | Whether to create a database instance | `bool` | `true` | no | | [create\_db\_option\_group](#input\_create\_db\_option\_group) | Create a database option group | `bool` | `true` | no | | [create\_db\_parameter\_group](#input\_create\_db\_parameter\_group) | Whether to create a database parameter group | `bool` | `true` | no | -| [create\_db\_subnet\_group](#input\_create\_db\_subnet\_group) | Whether to create a database subnet group | `bool` | `false` | no | | [create\_monitoring\_role](#input\_create\_monitoring\_role) | Create IAM role with a defined name that permits RDS to send enhanced monitoring metrics to CloudWatch Logs | `bool` | `false` | no | | [custom\_iam\_instance\_profile](#input\_custom\_iam\_instance\_profile) | RDS custom iam instance profile | `string` | `null` | no | | [db\_instance\_tags](#input\_db\_instance\_tags) | Additional tags for the DB instance | `map(string)` | `{}` | no | @@ -92,16 +97,16 @@ Terraform module for AWS RDS instances | [db\_option\_group\_tags](#input\_db\_option\_group\_tags) | Additional tags for the DB option group | `map(string)` | `{}` | no | | [db\_parameter\_group\_tags](#input\_db\_parameter\_group\_tags) | Additional tags for the DB parameter group | `map(string)` | `{}` | no | | [db\_subnet\_group\_description](#input\_db\_subnet\_group\_description) | Description of the DB subnet group to create | `string` | `null` | no | -| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC | `string` | n/a | yes | +| [db\_subnet\_group\_name](#input\_db\_subnet\_group\_name) | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. If unspecified, will be created in the default VPC | `string` | `null` | no | | [db\_subnet\_group\_tags](#input\_db\_subnet\_group\_tags) | Additional tags for the DB subnet group | `map(string)` | `{}` | no | -| [db\_subnet\_group\_use\_name\_prefix](#input\_db\_subnet\_group\_use\_name\_prefix) | Determines whether to use `subnet_group_name` as is or create a unique name beginning with the `subnet_group_name` as the prefix | `bool` | `true` | no | +| [db\_subnet\_group\_use\_name\_prefix](#input\_db\_subnet\_group\_use\_name\_prefix) | Determines whether to use `subnet_group_name` as is or create a unique name beginning with the `subnet_group_name` as the prefix | `bool` | `false` | no | | [delete\_automated\_backups](#input\_delete\_automated\_backups) | Specifies whether to remove automated backups immediately after the DB instance is deleted | `bool` | `true` | no | | [deletion\_protection](#input\_deletion\_protection) | The database can't be deleted when this value is set to true | `bool` | `false` | no | | [domain](#input\_domain) | The ID of the Directory Service Active Directory domain to create the instance in | `string` | `null` | no | | [domain\_iam\_role\_name](#input\_domain\_iam\_role\_name) | (Required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service | `string` | `null` | no | | [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on engine): alert, audit, error, general, listener, slowquery, trace, postgresql (PostgreSQL), upgrade (PostgreSQL) | `list(string)` | `[]` | no | | [engine](#input\_engine) | The database engine to use | `string` | `"postgres"` | no | -| [engine\_version](#input\_engine\_version) | The engine version to use | `string` | `"14"` | no | +| [engine\_version](#input\_engine\_version) | The engine version to use | `string` | `"14.9"` | no | | [family](#input\_family) | The family of the DB parameter group | `string` | `null` | no | | [final\_snapshot\_identifier\_prefix](#input\_final\_snapshot\_identifier\_prefix) | The name which is prefixed to the final snapshot on cluster destroy | `string` | `"final"` | no | | [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Specifies whether or not the mappings of AWS Identity and Access Management (IAM) accounts to database accounts are enabled | `bool` | `false` | no | @@ -112,6 +117,7 @@ Terraform module for AWS RDS instances | [instance\_use\_identifier\_prefix](#input\_instance\_use\_identifier\_prefix) | Determines whether to use `identifier` as is or create a unique identifier beginning with `identifier` as the specified prefix | `bool` | `false` | no | | [iops](#input\_iops) | The amount of provisioned IOPS. Setting this implies a storage\_type of 'io1' or `gp3`. See `notes` for limitations regarding this variable for `gp3` | `number` | `null` | no | | [is\_db\_cluster](#input\_is\_db\_cluster) | n/a | `bool` | `false` | no | +| [is\_serverless](#input\_is\_serverless) | n/a | `bool` | `false` | no | | [kms\_key\_id](#input\_kms\_key\_id) | The ARN for the KMS encryption key. If creating an encrypted replica, set this to the destination KMS ARN. If storage\_encrypted is set to true and kms\_key\_id is not specified the default KMS key created in your account will be used. Be sure to use the full ARN, not a key alias. | `string` | `null` | no | | [license\_model](#input\_license\_model) | License model information for this DB instance. Optional, but required for some DB engines, i.e. Oracle SE1 | `string` | `null` | no | | [maintenance\_window](#input\_maintenance\_window) | The window to perform maintenance in. Syntax: 'ddd:hh24:mi-ddd:hh24:mi'. Eg: 'Mon:00:00-Mon:03:00' | `string` | `"Sat:21:00-Sun:01:00"` | no | @@ -135,6 +141,7 @@ Terraform module for AWS RDS instances | [option\_group\_use\_name\_prefix](#input\_option\_group\_use\_name\_prefix) | Determines whether to use `option_group_name` as is or create a unique name beginning with the `option_group_name` as the prefix | `bool` | `true` | no | | [options](#input\_options) | A list of Options to apply | `any` | `[]` | no | | [parameter\_group\_description](#input\_parameter\_group\_description) | Description of the DB parameter group to create | `string` | `null` | no | +| [parameter\_group\_family](#input\_parameter\_group\_family) | The family of the DB parameter group | `string` | `null` | no | | [parameter\_group\_name](#input\_parameter\_group\_name) | Name of the DB parameter group to associate or create | `string` | `null` | no | | [parameter\_group\_use\_name\_prefix](#input\_parameter\_group\_use\_name\_prefix) | Determines whether to use `parameter_group_name` as is or create a unique name beginning with the `parameter_group_name` as the prefix | `bool` | `true` | no | | [parameters](#input\_parameters) | A list of DB parameters (map) to apply | `list(map(string))` | `[]` | no | From a6510e7471836635117afff3b01f09af179b58a4 Mon Sep 17 00:00:00 2001 From: samidbb Date: Fri, 3 Nov 2023 08:41:47 +0100 Subject: [PATCH 09/12] more cleanup --- modules/rds_aurora/variables.tf | 88 --------------------------------- 1 file changed, 88 deletions(-) diff --git a/modules/rds_aurora/variables.tf b/modules/rds_aurora/variables.tf index 7610f916..19974d50 100644 --- a/modules/rds_aurora/variables.tf +++ b/modules/rds_aurora/variables.tf @@ -1,9 +1,3 @@ -# variable "create" { -# description = "Whether cluster should be created (affects nearly all resources)" -# type = bool -# default = true -# } - variable "name" { # TODO: rename to identifier? description = "Name used across resources created" type = string @@ -20,24 +14,12 @@ variable "tags" { # # DB Subnet Group # ################################################################################ -# variable "create_db_subnet_group" { -# description = "Determines whether to create the database subnet group or use existing" -# type = bool -# default = false -# } - variable "db_subnet_group_name" { description = "The name of the subnet group name (existing or created)" type = string # default = "" } -# variable "subnets" { -# description = "List of subnet IDs used by database subnet group created" -# type = list(string) -# default = [] -# } - ################################################################################ # Cluster ################################################################################ @@ -423,66 +405,12 @@ variable "iam_roles" { # Enhanced Monitoring ################################################################################ -# variable "create_monitoring_role" { -# description = "Determines whether to create the IAM role for RDS enhanced monitoring" -# type = bool -# default = true -# } - variable "monitoring_role_arn" { description = "IAM role used by RDS to send enhanced monitoring metrics to CloudWatch" type = string default = "" } -# variable "iam_role_name" { -# description = "Friendly name of the monitoring role" -# type = string -# default = null -# } - -# variable "iam_role_use_name_prefix" { -# description = "Determines whether to use `iam_role_name` as is or create a unique name beginning with the `iam_role_name` as the prefix" -# type = bool -# default = false -# } - -# variable "iam_role_description" { -# description = "Description of the monitoring role" -# type = string -# default = null -# } - -# variable "iam_role_path" { -# description = "Path for the monitoring role" -# type = string -# default = null -# } - -# variable "iam_role_managed_policy_arns" { -# description = "Set of exclusive IAM managed policy ARNs to attach to the monitoring role" -# type = list(string) -# default = null -# } - -# variable "iam_role_permissions_boundary" { -# description = "The ARN of the policy that is used to set the permissions boundary for the monitoring role" -# type = string -# default = null -# } - -# variable "iam_role_force_detach_policies" { -# description = "Whether to force detaching any policies the monitoring role has before destroying it" -# type = bool -# default = null -# } - -# variable "iam_role_max_session_duration" { -# description = "Maximum session duration (in seconds) that you want to set for the monitoring role" -# type = number -# default = null -# } - ################################################################################ # Autoscaling ################################################################################ @@ -569,12 +497,6 @@ variable "security_group_description" { default = null } -# variable "vpc_id" { -# description = "ID of the VPC where to create security group" -# type = string -# default = "" -# } - variable "security_group_rules" { description = "Map of security group rules to add to the cluster security group created" type = any @@ -587,16 +509,6 @@ variable "security_group_tags" { default = {} } -# ################################################################################ -# # Cluster Parameter Group -# ################################################################################ - -# variable "create_db_cluster_parameter_group" { -# description = "Determines whether a cluster parameter should be created or use existing" -# type = bool -# default = false -# } - variable "db_cluster_parameter_group_name" { description = "The name of the DB cluster parameter group" type = string From 4f17268d469d59e9fed18792cd3b911b036a8983 Mon Sep 17 00:00:00 2001 From: samidbb Date: Mon, 13 Nov 2023 10:58:43 +0100 Subject: [PATCH 10/12] disabled sarif uploads for now --- .github/workflows/secret-detection.yml | 15 ++++++++------- .github/workflows/tfsec.yml | 13 +++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/workflows/secret-detection.yml b/.github/workflows/secret-detection.yml index 97a1c090..73937dc6 100644 --- a/.github/workflows/secret-detection.yml +++ b/.github/workflows/secret-detection.yml @@ -24,13 +24,14 @@ jobs: chmod +x gitleaks - name: Scan with gitleaks run: ./gitleaks detect --exit-code 0 --redact --report-format sarif --report-path gitleaks-results.sarif - - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v2 - with: - # Path to SARIF file relative to the root of the repository - sarif_file: gitleaks-results.sarif - category: GitLeaks Secret Scanning + + # Disabled this until repo is switched to be public + # - name: Upload SARIF file + # uses: github/codeql-action/upload-sarif@v2 + # with: + # # Path to SARIF file relative to the root of the repository + # sarif_file: gitleaks-results.sarif + # category: GitLeaks Secret Scanning - name: Clean up results file run: rm -f gitleaks-results.sarif diff --git a/.github/workflows/tfsec.yml b/.github/workflows/tfsec.yml index e3574e4d..7abc7aba 100644 --- a/.github/workflows/tfsec.yml +++ b/.github/workflows/tfsec.yml @@ -19,9 +19,10 @@ jobs: with: sarif_file: tfsec.sarif - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v2 - with: - # Path to SARIF file relative to the root of the repository - sarif_file: tfsec.sarif - category: Tfsec IAC Scanning + # Disabled this until repo is switched to be public + # - name: Upload SARIF file + # uses: github/codeql-action/upload-sarif@v2 + # with: + # # Path to SARIF file relative to the root of the repository + # sarif_file: tfsec.sarif + # category: Tfsec IAC Scanning From e7701248a5f1cf269ded430c6a423cbad90110e8 Mon Sep 17 00:00:00 2001 From: samidbb Date: Mon, 13 Nov 2023 11:43:22 +0100 Subject: [PATCH 11/12] tfsec repo is not recognized --- .github/workflows/tfsec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tfsec.yml b/.github/workflows/tfsec.yml index 7abc7aba..fbbe455f 100644 --- a/.github/workflows/tfsec.yml +++ b/.github/workflows/tfsec.yml @@ -15,7 +15,7 @@ jobs: uses: actions/checkout@master - name: tfsec - uses: tfsec/tfsec-sarif-action@master + uses: aquasecurity/tfsec-sarif-action@master with: sarif_file: tfsec.sarif From 3adbd1d1cb8fb90ea9fe0e526d6b6975c5264197 Mon Sep 17 00:00:00 2001 From: samidbb Date: Mon, 13 Nov 2023 12:53:33 +0100 Subject: [PATCH 12/12] repo housekeeping workflow added --- .github/workflows/housekeeping.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/housekeeping.yml diff --git a/.github/workflows/housekeeping.yml b/.github/workflows/housekeeping.yml new file mode 100644 index 00000000..a11b7317 --- /dev/null +++ b/.github/workflows/housekeeping.yml @@ -0,0 +1,14 @@ +name: Housekeeping + +on: + schedule: + - cron: "0 6 * * 1" + +jobs: + shared: + uses: dfds/shared-workflows/.github/workflows/automation-housekeeping.yml@master + secrets: inherit + with: + delete_head_branch: true + squash_merge: true + branch_protection: true \ No newline at end of file