diff --git a/.snyk b/.snyk new file mode 100644 index 0000000..7bcce15 --- /dev/null +++ b/.snyk @@ -0,0 +1,16 @@ +# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. +version: v1.25.0 +# ignores vulnerabilities until expiry date; change duration by modifying expiry date +ignore: + SNYK-CC-AWS-710: + - aurora-cluster.tf > resource > aws_rds_cluster[this] > iam_database_authentication_enabled: + reason: IAM authentication is set by variable + expires: 2027-04-01T00:00:00.000Z + created: 2022-11-14T18:20:39.256Z + SNYK-CC-AWS-414: + - main.tf > resource > aws_db_instance[this] > iam_database_authentication_enabled: + reason: IAM authentication is set by variable + expires: 2027-04-01T00:00:00.000Z + created: 2022-11-14T18:20:39.256Z + +patch: {} diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index f3a780a..c56a9f6 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -2,84 +2,64 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/aws" { - version = "5.59.0" - constraints = ">= 2.0.0, >= 3.0.0, >= 4.0.0, >= 4.9.0, >= 4.23.0, >= 5.0.0, < 6.0.0" + version = "5.73.0" + constraints = ">= 4.0.0, ~> 5.0, < 6.0.0" hashes = [ - "h1:RTI7BbGzkYrknXFSa/Fmh6oNLP0FqgjNb+xyFNJeyKo=", - "zh:077f41a15057d01d833d7438322adf9b507d17ac0c8e1287430a305b6e609775", - "zh:130b112c85b67413bc65e95e5927188d8e41b45abd75350690b93d95771a587c", - "zh:16e97f1af67a5d4c6bf4f2df824a6a332b446be4516dd85a2e097317c959a174", - "zh:1cd7b0946eaf0fb11090710e9c774d22d90de0ca4516485253be96e332ebaf73", - "zh:2591d8a269014fb59111793cb8a175aafa12e370cd856fe2522577efbb72e5be", - "zh:3db5387ecc7da4e6a55a34877ea426ae87d10238bdbdf284a52e16b4be83302c", - "zh:78169400a85912d7f05fe99d4f3ba9a56871411442bdc133083dd657b18fae4e", + "h1:hyOg38/ifG8Jf/b4GC6ydR8ClyRRdsAF3SmMHL6qbes=", + "zh:0d24edc51ab6600f56d759831658a9d7a8f69b53900546b75038fc8e3f312406", + "zh:1f8b8414f710a8c5a8777cb1ef1cad1cb4293bc035deb804734a8ec698b0850d", + "zh:2cf76b03564051ee86ef5fbdaea1949e3af549f8836e56371fe94335cf795e1c", + "zh:2ffe05c62b4ae6292dda66cd3a3cbe3e290a1a04369f3e6f74812e885cf3f2f0", + "zh:3564069d9bc918e5bded252d65b6a8758d08b309e1ac54bf7c8e5947a94cdadc", + "zh:4eb5395d52cfcb3c78e86c4ca3759bf9736e0e8dfa6955b0e1a59d9a7f41d805", + "zh:6cd14cbabbcf8b1c15fa73f9ebba4d4df41215ef92bf8d14a3780a7cb571e5c4", + "zh:6f7dc212dee1be2edb4620d352d9b0ea759744b5be08b84012a7621efa262052", + "zh:7468a490d6df04a401f49422c86b46ef91eba00878cc9a5ec3ee4a12fe9447d0", "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:ad93fedbf1d2694faab6d793c6697ff5732449cdebacaa49acf6452c0c8e2ea0", - "zh:b8a2884858dde9d204dc6855903e3078a1c402485ae85b41c28e667f99a2a777", - "zh:bd3d4bd51172d08c0df277673a25fb3f0818ef47ef9f491b0c41e880b1dedce3", - "zh:d8e132bcafee2e69e21173fac409e4b99d8c81d60a7d25c58c379c67067dbf36", - "zh:eee5113ff29a42c5a75c83e9853e99a9b5c0ed066e36d6fe251083b19d38c7eb", - "zh:f0d8bcdb01d0fa0c9ed2ca8c198d4f11aabfd9d42fa239286b65ddcc6f606dfd", - "zh:f8ae46d14ec54c275e20f71d052f1b6af0cf948819b0667016045a6244edf292", + "zh:b440ff1be9fc62235b2dcb522dd922cefe751065ba4a601415130462e79fb68e", + "zh:d53dfd7311d8f130f0ce3184ed50461c34086d3490913a0d80d63574dac104a6", + "zh:de9a130dd684aed5b89edc7ce44aef37fa38eca06549035cf387cde9d3937432", + "zh:e0922d81fbed02062a74ea126d3cc6830fa0c8eac92108825d1120a262980831", + "zh:fdd6cdabcf5e9bedb3a419ac18bd12b5b02d8371ba0fb2a6123420937354c8e1", ] } provider "registry.terraform.io/hashicorp/null" { - version = "3.2.2" - constraints = ">= 2.0.0, >= 3.1.1" + version = "3.2.3" + constraints = ">= 3.1.0" hashes = [ - "h1:IMVAUHKoydFrlPrl9OzasDnw/8ntZFerCC9iXw1rXQY=", - "zh:3248aae6a2198f3ec8394218d05bd5e42be59f43a3a7c0b71c66ec0df08b69e7", - "zh:32b1aaa1c3013d33c245493f4a65465eab9436b454d250102729321a44c8ab9a", - "zh:38eff7e470acb48f66380a73a5c7cdd76cc9b9c9ba9a7249c7991488abe22fe3", - "zh:4c2f1faee67af104f5f9e711c4574ff4d298afaa8a420680b0cb55d7bbc65606", - "zh:544b33b757c0b954dbb87db83a5ad921edd61f02f1dc86c6186a5ea86465b546", - "zh:696cf785090e1e8cf1587499516b0494f47413b43cb99877ad97f5d0de3dc539", - "zh:6e301f34757b5d265ae44467d95306d61bef5e41930be1365f5a8dcf80f59452", + "h1:I0Um8UkrMUb81Fxq/dxbr3HLP2cecTH2WMJiwKSrwQY=", + "zh:22d062e5278d872fe7aed834f5577ba0a5afe34a3bdac2b81f828d8d3e6706d2", + "zh:23dead00493ad863729495dc212fd6c29b8293e707b055ce5ba21ee453ce552d", + "zh:28299accf21763ca1ca144d8f660688d7c2ad0b105b7202554ca60b02a3856d3", + "zh:55c9e8a9ac25a7652df8c51a8a9a422bd67d784061b1de2dc9fe6c3cb4e77f2f", + "zh:756586535d11698a216291c06b9ed8a5cc6a4ec43eee1ee09ecd5c6a9e297ac1", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:913a929070c819e59e94bb37a2a253c228f83921136ff4a7aa1a178c7cce5422", - "zh:aa9015926cd152425dbf86d1abdbc74bfe0e1ba3d26b3db35051d7b9ca9f72ae", - "zh:bb04798b016e1e1d49bcc76d62c53b56c88c63d6f2dfe38821afef17c416a0e1", - "zh:c23084e1b23577de22603cff752e59128d83cfecc2e6819edadd8cf7a10af11e", + "zh:9d5eea62fdb587eeb96a8c4d782459f4e6b73baeece4d04b4a40e44faaee9301", + "zh:a6355f596a3fb8fc85c2fb054ab14e722991533f87f928e7169a486462c74670", + "zh:b5a65a789cff4ada58a5baffc76cb9767dc26ec6b45c00d2ec8b1b027f6db4ed", + "zh:db5ab669cf11d0e9f81dc380a6fdfcac437aea3d69109c7aef1a5426639d2d65", + "zh:de655d251c470197bcbb5ac45d289595295acb8f829f6c781d4a75c8c8b7c7dd", + "zh:f5c68199f2e6076bce92a12230434782bf768103a427e9bb9abee99b116af7b5", ] } provider "registry.terraform.io/hashicorp/random" { - version = "3.6.2" + version = "3.6.3" constraints = ">= 3.4.0" hashes = [ - "h1:VavG5unYCa3SYISMKF9pzc3718M0bhPlcbUZZGl7wuo=", - "zh:0ef01a4f81147b32c1bea3429974d4d104bbc4be2ba3cfa667031a8183ef88ec", - "zh:1bcd2d8161e89e39886119965ef0f37fcce2da9c1aca34263dd3002ba05fcb53", - "zh:37c75d15e9514556a5f4ed02e1548aaa95c0ecd6ff9af1119ac905144c70c114", - "zh:4210550a767226976bc7e57d988b9ce48f4411fa8a60cd74a6b246baf7589dad", - "zh:562007382520cd4baa7320f35e1370ffe84e46ed4e2071fdc7e4b1a9b1f8ae9b", - "zh:5efb9da90f665e43f22c2e13e0ce48e86cae2d960aaf1abf721b497f32025916", - "zh:6f71257a6b1218d02a573fc9bff0657410404fb2ef23bc66ae8cd968f98d5ff6", + "h1:zG9uFP8l9u+yGZZvi5Te7PV62j50azpgwPunq2vTm1E=", + "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", + "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", + "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe", + "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1", + "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36", + "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:9647e18f221380a85f2f0ab387c68fdafd58af6193a932417299cdcae4710150", - "zh:bb6297ce412c3c2fa9fec726114e5e0508dd2638cad6a0cb433194930c97a544", - "zh:f83e925ed73ff8a5ef6e3608ad9225baa5376446349572c2449c0c0b3cf184b7", - "zh:fbef0781cb64de76b1df1ca11078aecba7800d82fd4a956302734999cfd9a4af", - ] -} - -provider "registry.terraform.io/hashicorp/time" { - version = "0.12.0" - constraints = ">= 0.7.0" - hashes = [ - "h1:Os2Ok7txtlUJHh6Hg7o+74Ql85SnRb/fGmah22yXpLw=", - "zh:019a4c09af254ef80b72cf0d843dfe72d99483e227138cf5b514a1b9977ab4c3", - "zh:0ae310ec740ebc6f275529507d60bb747d0bf39e72fc5a2fa90d74486006132c", - "zh:13d6aec117f05237fbf8c7d91d6ebb19797b00aa87e7a812642d3ea4738a394e", - "zh:2e87abbc261f9317d0c2ef26e01d5fabf77679da7d2cac6f47df7d198f720989", - "zh:4a6d471176ce0264455aa7d5457b8702f78400010c201c1719708958a1b7b647", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:8978d5474a6da30bc0ad21c17db188d6918cacf3df3f6506b72ef3a268d53e2e", - "zh:b109efe138dfcb45dc04a9cc6809d185ab8b0ebc12040847c2dac430fda5af68", - "zh:b58e039b9106ac0a8de3c07f53b5279d7f0215fb35f2d23df642dfce0875382f", - "zh:ba2cbb2e515922d13efe3a46647be84f5426fcfcaa0f1520b3efeab8db847ed3", - "zh:c6c1ef1f26f25bca3abb5e07fa33dca37ed39cc26d0ff877964f2ffe5edd618c", - "zh:f8e171f923b7d2e789abd034072465dec3e6133c3a7644b7a7a965a74d52224e", + "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30", + "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615", + "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad", + "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556", + "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0", ] } diff --git a/README.md b/README.md index 5a301a4..96ec053 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## Overview -The SourceFuse AWS Reference Architecture (ARC) Terraform module offers a comprehensive solution for efficiently managing Aurora and RDS (Relational Database Service) instances within the Amazon Web Services (AWS) environment. This Terraform module is designed to streamline the provisioning, configuration, and management of these database instances, leveraging best practices. +The SourceFuse AWS Reference Architecture (ARC) Terraform module offers a comprehensive solution for efficiently managing Aurora, RDS cluster, RDS proxy and RDS (Relational Database Service) instances within the Amazon Web Services (AWS) environment. This Terraform module is designed to streamline the provisioning, configuration, and management of these database instances, leveraging best practices. For more information about this repository and its usage, please see [Terraform AWS ARC DB Usage Guide](https://github.com/sourcefuse/terraform-aws-arc-db/blob/main/docs/module-usage-guide/README.md). @@ -31,172 +31,120 @@ To see a full example, check out the [main.tf](https://github.com/sourcefuse/ter | Name | Version | |------|---------| -| [aws](#provider\_aws) | 5.59.0 | -| [random](#provider\_random) | 3.6.2 | +| [aws](#provider\_aws) | 5.73.0 | +| [random](#provider\_random) | 3.6.3 | ## Modules | Name | Source | Version | |------|--------|---------| -| [aurora\_cluster](#module\_aurora\_cluster) | git::https://github.com/cloudposse/terraform-aws-rds-cluster.git | 1.11.0 | -| [db\_management](#module\_db\_management) | git::https://github.com/cloudposse/terraform-aws-s3-bucket | 4.5.0 | -| [rds\_instance](#module\_rds\_instance) | git::https://github.com/cloudposse/terraform-aws-rds | 1.1.2 | -| [this](#module\_this) | cloudposse/label/null | 0.25.0 | +| [proxy\_security\_group](#module\_proxy\_security\_group) | ./modules/security-group | n/a | +| [security\_group](#module\_security\_group) | ./modules/security-group | n/a | ## Resources | Name | Type | |------|------| -| [aws_db_instance_role_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance_role_association) | resource | +| [aws_db_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance) | resource | | [aws_db_option_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_option_group) | resource | -| [aws_iam_policy.option_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_db_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_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_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | +| [aws_db_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_subnet_group) | resource | +| [aws_iam_policy.logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.read_secrets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_role.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role.option_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role.proxy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.attach_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_role_policy_attachment.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_iam_role_policy_attachment.option_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_kms_alias.aurora_cluster_kms_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | -| [aws_kms_alias.rds_db_kms_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | -| [aws_kms_key.aurora_cluster_kms_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | -| [aws_kms_key.rds_db_kms_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | -| [aws_security_group_rule.additional_ingress_rules_aurora](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.additional_ingress_rules_rds](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_ssm_parameter.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | -| [random_password.aurora_db_admin_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | -| [random_password.rds_db_admin_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | 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.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | +| [aws_iam_role_policy_attachment.proxy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_kms_alias.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | +| [aws_kms_key.secret](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_kms_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_rds_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster) | resource | +| [aws_rds_cluster_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_instance) | resource | +| [aws_secretsmanager_secret.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource | +| [aws_secretsmanager_secret_version.db_secret_version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource | +| [aws_ssm_parameter.database_creds](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | +| [random_password.master](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy) | data source | +| [aws_kms_alias.rds](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | 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 | |------|-------------|------|---------|:--------:| -| [account\_id](#input\_account\_id) | Account ID where the resources will be deployed to. This is required if `enable_custom_option_group` is set to `true`. | `string` | `""` | no | -| [additional\_ingress\_rules\_aurora](#input\_additional\_ingress\_rules\_aurora) | Additional ingress rules for Aurora |
list(object({
name = string
description = string
type = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
| `[]` | no | -| [additional\_ingress\_rules\_rds](#input\_additional\_ingress\_rules\_rds) | Additional ingress rules for RDS |
list(object({
name = string
description = string
type = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
| `[]` | no | -| [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no | -| [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no | -| [aurora\_allow\_major\_version\_upgrade](#input\_aurora\_allow\_major\_version\_upgrade) | Enable to allow major engine version upgrades when changing engine versions. Defaults to false. | `bool` | `false` | no | -| [aurora\_allowed\_cidr\_blocks](#input\_aurora\_allowed\_cidr\_blocks) | List of CIDR blocks allowed to access the cluster | `list(string)` | `[]` | no | -| [aurora\_auto\_minor\_version\_upgrade](#input\_aurora\_auto\_minor\_version\_upgrade) | Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window | `bool` | `true` | no | -| [aurora\_backup\_retention\_period](#input\_aurora\_backup\_retention\_period) | Number of days to retain backups for | `number` | `5` | no | -| [aurora\_backup\_window](#input\_aurora\_backup\_window) | Daily time range during which the backups happen | `string` | `"07:00-09:00"` | no | -| [aurora\_ca\_cert\_identifier](#input\_aurora\_ca\_cert\_identifier) | The identifier of the CA certificate for the Aurora DB instance | `string` | `null` | no | -| [aurora\_cluster\_enabled](#input\_aurora\_cluster\_enabled) | Enable creation of an Aurora Cluster | `bool` | `false` | no | -| [aurora\_cluster\_family](#input\_aurora\_cluster\_family) | The family of the DB cluster parameter group | `string` | `"aurora-postgresql14"` | no | -| [aurora\_cluster\_name](#input\_aurora\_cluster\_name) | Database name (default is not to create a database) | `string` | `""` | no | -| [aurora\_cluster\_name\_override](#input\_aurora\_cluster\_name\_override) | If `true`, this will set a the Aurora Cluster name to what is defined in var.aurora\_cluster\_name.
If `false`, this will prepend ${var.namespace}-${var.environment} to ${var.aurora\_cluster\_name}" | `bool` | `false` | no | -| [aurora\_cluster\_size](#input\_aurora\_cluster\_size) | Number of DB instances to create in the cluster | `number` | `0` | no | -| [aurora\_db\_admin\_password](#input\_aurora\_db\_admin\_password) | Password of the DB admin | `string` | `""` | no | -| [aurora\_db\_admin\_username](#input\_aurora\_db\_admin\_username) | Name of the default DB admin user role | `string` | `""` | no | -| [aurora\_db\_name](#input\_aurora\_db\_name) | Database name. | `string` | `"auroradb"` | no | -| [aurora\_db\_port](#input\_aurora\_db\_port) | Port for the Aurora DB instance to use. | `number` | `5432` | no | -| [aurora\_enabled\_cloudwatch\_logs\_exports](#input\_aurora\_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 | -| [aurora\_engine](#input\_aurora\_engine) | The name of the database engine to be used for this DB cluster. Valid values: `aurora`, `aurora-mysql`, `aurora-postgresql` | `string` | `"aurora-postgresql"` | no | -| [aurora\_engine\_mode](#input\_aurora\_engine\_mode) | The database engine mode. Valid values: `parallelquery`, `provisioned`, `serverless` | `string` | `"provisioned"` | no | -| [aurora\_engine\_version](#input\_aurora\_engine\_version) | The version of the database engine tocl use. See `aws rds describe-db-engine-versions` | `string` | `"14.5"` | no | -| [aurora\_instance\_type](#input\_aurora\_instance\_type) | Instance type to use | `string` | `"db.serverless"` | no | -| [aurora\_iops](#input\_aurora\_iops) | The amount of provisioned IOPS. Setting this implies a storage\_type of 'io1'. This setting is required to create a Multi-AZ DB cluster. Check TF docs for values based on db engine | `number` | `null` | no | -| [aurora\_scaling\_configuration](#input\_aurora\_scaling\_configuration) | List of nested attributes with scaling properties. Only valid when engine\_mode is set to serverless |
list(object({
auto_pause = bool
max_capacity = number
min_capacity = number
seconds_until_auto_pause = number
timeout_action = string
}))
| `[]` | no | -| [aurora\_security\_groups](#input\_aurora\_security\_groups) | List of security group IDs to be allowed to connect to the DB instance | `list(string)` | `[]` | no | -| [aurora\_serverlessv2\_scaling\_configuration](#input\_aurora\_serverlessv2\_scaling\_configuration) | serverlessv2 scaling properties |
object({
min_capacity = number
max_capacity = number
})
| `null` | no | -| [aurora\_storage\_type](#input\_aurora\_storage\_type) | One of 'standard' (magnetic), 'gp2' / 'gp3' (general purpose SSD), or 'io1' (provisioned IOPS SSD) or aurora-iopt1 | `string` | `null` | no | -| [aurora\_subnets](#input\_aurora\_subnets) | Subnets for the cluster to run in. | `list(string)` | `[]` | no | -| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | -| [deletion\_protection](#input\_deletion\_protection) | Protect the instance from being deleted | `bool` | `false` | no | -| [deletion\_window\_in\_days](#input\_deletion\_window\_in\_days) | n/a | `number` | `10` | no | -| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | -| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | -| [enable\_http\_endpoint](#input\_enable\_http\_endpoint) | Enable HTTP endpoint (data API). Only valid when engine\_mode is set to serverless | `bool` | `false` | no | -| [enable\_key\_rotation](#input\_enable\_key\_rotation) | n/a | `bool` | `true` | no | -| [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | -| [enhanced\_monitoring\_arn](#input\_enhanced\_monitoring\_arn) | ARN to the enhanced monitoring policy | `string` | `"arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole"` | no | -| [enhanced\_monitoring\_name](#input\_enhanced\_monitoring\_name) | Name to assign the enhanced monitoring resources. | `string` | n/a | yes | +| [allocated\_storage](#input\_allocated\_storage) | (optional) Storage for RDS instance | `string` | `20` | no | +| [allow\_major\_version\_upgrade](#input\_allow\_major\_version\_upgrade) | Whether major version upgrades are allowed during maintenance windows. | `bool` | `false` | no | +| [apply\_immediately](#input\_apply\_immediately) | Whether to apply changes immediately or during the next maintenance window. | `bool` | `false` | no | +| [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Whether minor engine upgrades are applied automatically during the maintenance window. | `bool` | `true` | no | +| [backup\_retention\_period](#input\_backup\_retention\_period) | The number of days to retain backups for the DB cluster. | `number` | `7` | no | +| [ca\_cert\_identifier](#input\_ca\_cert\_identifier) | The identifier of the CA certificate for the DB instance. If not specified, the RDS default CA is used. | `string` | `null` | no | +| [ca\_certificate\_identifier](#input\_ca\_certificate\_identifier) | (optional) The CA certificate identifier to use for the DB cluster's server certificate. | `string` | `null` | no | +| [copy\_tags\_to\_snapshot](#input\_copy\_tags\_to\_snapshot) | Whether to copy all tags to snapshots. | `bool` | `true` | no | +| [database\_name](#input\_database\_name) | The name of the database to create when the cluster is created. | `string` | `null` | no | +| [db\_cluster\_parameter\_group\_name](#input\_db\_cluster\_parameter\_group\_name) | (optional) A cluster parameter group to associate with the cluster. | `string` | `null` | no | +| [db\_instance\_parameter\_group\_name](#input\_db\_instance\_parameter\_group\_name) | (optional) Instance parameter group to associate with all instances of the DB cluster. The db\_instance\_parameter\_group\_name parameter is only valid in combination with the allow\_major\_version\_upgrade parameter. | `string` | `null` | no | +| [db\_server\_class](#input\_db\_server\_class) | Instance class for RDS instance | `string` | `"db.t3.medium"` | no | +| [db\_subnet\_group\_data](#input\_db\_subnet\_group\_data) | (optional) DB Subnet Group details |
object({
name = string
create = optional(bool, false)
description = optional(string, null)
subnet_ids = optional(list(string), [])
})
| n/a | yes | +| [delete\_automated\_backups](#input\_delete\_automated\_backups) | (optional) Specifies whether to remove automated backups immediately after the DB cluster is deleted. Default is true. | `string` | `true` | no | +| [deletion\_protection](#input\_deletion\_protection) | Whether to enable deletion protection for the DB cluster. | `bool` | `false` | no | +| [enable\_multi\_az](#input\_enable\_multi\_az) | Whether to enable Multi-AZ deployment for the RDS instance. | `bool` | `false` | no | +| [enabled\_cloudwatch\_logs\_exports](#input\_enabled\_cloudwatch\_logs\_exports) | List of log types to export to CloudWatch Logs. Valid values: audit, error, general, slowquery. | `list(string)` | `[]` | no | +| [engine](#input\_engine) | The database engine to use for the RDS cluster (e.g., aurora, aurora-mysql, aurora-postgresql). | `string` | n/a | yes | +| [engine\_lifecycle\_support](#input\_engine\_lifecycle\_support) | (optional) The life cycle type for this DB instance. This setting is valid for cluster types Aurora DB clusters and Multi-AZ DB clusters. Valid values are open-source-rds-extended-support, open-source-rds-extended-support-disabled. Default value is open-source-rds-extended-support | `string` | `"open-source-rds-extended-support"` | no | +| [engine\_mode](#input\_engine\_mode) | (optional) Database engine mode. Valid values: global (only valid for Aurora MySQL 1.21 and earlier), parallelquery, provisioned, serverless. Defaults to: provisioned
Note :- For Serverless V2 , engine\_mode should be "provisioned" but for simplecity "serverless" is expected
Refer : https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster#rds-serverless-v2-cluster | `string` | `"provisioned"` | no | +| [engine\_type](#input\_engine\_type) | (optional) Engine type, valid values are 'rds' or 'cluster' | `string` | n/a | yes | +| [engine\_version](#input\_engine\_version) | The version of the database engine to use. | `string` | n/a | yes | | [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | n/a | yes | -| [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 | -| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | -| [kms\_key\_arn](#input\_kms\_key\_arn) | The ARN for the KMS encryption key. When specifying `kms_key_arn`, `storage_encrypted` needs to be set to `true` | `string` | `""` | no | -| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | -| [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | -| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | -| [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | -| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no | -| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | n/a | yes | -| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | Whether to enable Performance Insights | `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. When specifying `performance_insights_kms_key_id`, `performance_insights_enabled` needs to be set to true | `string` | `""` | 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 | -| [rds\_enable\_custom\_option\_group](#input\_rds\_enable\_custom\_option\_group) | Enable the custom Option Group for restoring backups via S3 | `bool` | `false` | no | -| [rds\_enabled\_cloudwatch\_logs\_exports](#input\_rds\_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 | -| [rds\_instance\_allocated\_storage](#input\_rds\_instance\_allocated\_storage) | The allocated storage in GBs. Required unless a snapshot\_identifier or replicate\_source\_db is provided. | `number` | `20` | no | -| [rds\_instance\_allow\_major\_version\_upgrade](#input\_rds\_instance\_allow\_major\_version\_upgrade) | Allow major version upgrade | `bool` | `false` | no | -| [rds\_instance\_allowed\_cidr\_blocks](#input\_rds\_instance\_allowed\_cidr\_blocks) | The whitelisted CIDRs which to allow ingress traffic to the DB instance | `list(string)` | `[]` | no | -| [rds\_instance\_apply\_immediately](#input\_rds\_instance\_apply\_immediately) | Specifies whether any database modifications are applied immediately, or during the next maintenance window | `bool` | `true` | no | -| [rds\_instance\_auto\_minor\_version\_upgrade](#input\_rds\_instance\_auto\_minor\_version\_upgrade) | Allow automated minor version upgrade (e.g. from Postgres 9.5.3 to Postgres 9.5.4) | `bool` | `true` | no | -| [rds\_instance\_backup\_retention\_period](#input\_rds\_instance\_backup\_retention\_period) | Backup retention period in days. Must be > 0 to enable backups | `number` | `0` | no | -| [rds\_instance\_backup\_window](#input\_rds\_instance\_backup\_window) | When AWS can perform DB snapshots, can't overlap with maintenance window | `string` | `"22:00-03:00"` | no | -| [rds\_instance\_ca\_cert\_identifier](#input\_rds\_instance\_ca\_cert\_identifier) | The identifier of the CA certificate for the DB instance | `string` | `null` | no | -| [rds\_instance\_copy\_tags\_to\_snapshot](#input\_rds\_instance\_copy\_tags\_to\_snapshot) | Copy tags from DB to a snapshot | `bool` | `true` | no | -| [rds\_instance\_database\_name](#input\_rds\_instance\_database\_name) | The name of the database to create when the DB instance is created | `string` | `null` | no | -| [rds\_instance\_database\_password](#input\_rds\_instance\_database\_password) | Password for the primary DB user. Required unless a snapshot\_identifier or replicate\_source\_db is provided. | `string` | `""` | no | -| [rds\_instance\_database\_port](#input\_rds\_instance\_database\_port) | Database port (\_e.g.\_ 3306 for MySQL). Used in the DB Security Group to allow access to the DB instance from the provided security\_group\_ids | `number` | `5432` | no | -| [rds\_instance\_database\_user](#input\_rds\_instance\_database\_user) | The name of the database to create when the DB instance is created | `string` | `"admin"` | no | -| [rds\_instance\_db\_options](#input\_rds\_instance\_db\_options) | A list of DB options to apply with an option group. Depends on DB engine |
list(object({
db_security_group_memberships = list(string)
option_name = string
port = number
version = string
vpc_security_group_memberships = list(string)

option_settings = list(object({
name = string
value = string
}))
}))
| `[]` | no | -| [rds\_instance\_db\_parameter](#input\_rds\_instance\_db\_parameter) | A list of DB parameters to apply. Note that parameters may differ from a DB family to another |
list(object({
apply_method = string
name = string
value = string
}))
| `[]` | no | -| [rds\_instance\_db\_parameter\_group](#input\_rds\_instance\_db\_parameter\_group) | The DB parameter group family name. The value depends on DB engine used. See [DBParameterGroupFamily](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBParameterGroup.html#API_CreateDBParameterGroup_RequestParameters) for instructions on how to retrieve applicable value | `string` | `"postgres16"` | no | -| [rds\_instance\_db\_parameter\_group\_name](#input\_rds\_instance\_db\_parameter\_group\_name) | Name of the DB parameter group to associate. | `string` | `""` | no | -| [rds\_instance\_dns\_zone\_id](#input\_rds\_instance\_dns\_zone\_id) | The ID of the DNS Zone in Route53 where a new DNS record will be created for the DB host name | `string` | `""` | no | -| [rds\_instance\_enabled](#input\_rds\_instance\_enabled) | Enable creation of an RDS instance | `bool` | `false` | no | -| [rds\_instance\_engine](#input\_rds\_instance\_engine) | Database engine type. Required unless a snapshot\_identifier or replicate\_source\_db is provided. For supported values, see the Engine parameter in API action CreateDBInstance. | `string` | `"sqlserver-*"` | no | -| [rds\_instance\_engine\_version](#input\_rds\_instance\_engine\_version) | Database engine version, depends on engine type. Required unless a snapshot\_identifier or replicate\_source\_db is provided. | `string` | `"16.2"` | no | -| [rds\_instance\_host\_name](#input\_rds\_instance\_host\_name) | The DB host name created in Route53 | `string` | `"db"` | no | -| [rds\_instance\_instance\_class](#input\_rds\_instance\_instance\_class) | Class of RDS instance | `string` | `"db.t3.medium"` | no | -| [rds\_instance\_iops](#input\_rds\_instance\_iops) | RDS instance IOPS | `number` | `0` | no | -| [rds\_instance\_license\_model](#input\_rds\_instance\_license\_model) | License model for this DB. Optional, but required for some DB Engines. Valid values: license-included \| bring-your-own-license \| general-public-license | `string` | `""` | no | -| [rds\_instance\_maintenance\_window](#input\_rds\_instance\_maintenance\_window) | The window to perform maintenance in. Syntax: 'ddd:hh24:mi-ddd:hh24:mi' UTC | `string` | `"Mon:03:00-Mon:04:00"` | no | -| [rds\_instance\_major\_engine\_version](#input\_rds\_instance\_major\_engine\_version) | major\_engine\_version Database MAJOR engine version, depends on engine type | `string` | `"16"` | no | -| [rds\_instance\_multi\_az](#input\_rds\_instance\_multi\_az) | Set to true if multi AZ deployment must be supported | `bool` | `false` | no | -| [rds\_instance\_name](#input\_rds\_instance\_name) | RDS Instance name | `string` | `""` | no | -| [rds\_instance\_name\_override](#input\_rds\_instance\_name\_override) | If `true`, this will set a the RDS Instance name to what is defined in var.rds\_instance\_name.
If `false`, this will prepend ${var.namespace}-${var.environment} to ${var.rds\_instance\_name}" | `bool` | `false` | no | -| [rds\_instance\_option\_group\_name](#input\_rds\_instance\_option\_group\_name) | Name of the DB option group to associate | `string` | `""` | no | -| [rds\_instance\_publicly\_accessible](#input\_rds\_instance\_publicly\_accessible) | Determines if database can be publicly available (NOT recommended) | `bool` | `false` | no | -| [rds\_instance\_security\_group\_ids](#input\_rds\_instance\_security\_group\_ids) | The IDs of the security groups from which to allow ingress traffic to the DB instance | `list(string)` | `[]` | no | -| [rds\_instance\_skip\_final\_snapshot](#input\_rds\_instance\_skip\_final\_snapshot) | If true (default), no snapshot will be made before deleting DB | `bool` | `true` | no | -| [rds\_instance\_snapshot\_identifier](#input\_rds\_instance\_snapshot\_identifier) | Snapshot identifier e.g: rds:production-2019-06-26-06-05. If specified, the module create cluster from the snapshot | `string` | `null` | no | -| [rds\_instance\_storage\_encrypted](#input\_rds\_instance\_storage\_encrypted) | Specifies whether the DB instance is encrypted. The default is false if not specified | `bool` | `true` | no | -| [rds\_instance\_storage\_type](#input\_rds\_instance\_storage\_type) | One of 'standard' (magnetic), 'gp2' / 'gp3' (general purpose SSD), or 'io1' (provisioned IOPS SSD) | `string` | `"gp3"` | no | -| [rds\_instance\_subnet\_ids](#input\_rds\_instance\_subnet\_ids) | List of subnet IDs for the DB. DB instance will be created in the VPC associated with the DB subnet group provisioned using the subnet IDs. Specify one of subnet\_ids, db\_subnet\_group\_name or availability\_zone | `list(string)` | `[]` | no | -| [rds\_kms\_key\_arn\_override](#input\_rds\_kms\_key\_arn\_override) | Override the default created KMS key to encrypt storage | `string` | `""` | no | -| [rds\_kms\_key\_id\_override](#input\_rds\_kms\_key\_id\_override) | Override the default created KMS key ID to encrypt storage | `string` | `""` | no | -| [rds\_monitoring\_interval](#input\_rds\_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. Valid Values are 0, 1, 5, 10, 15, 30, 60 | `number` | `0` | no | -| [rds\_random\_admin\_password\_length](#input\_rds\_random\_admin\_password\_length) | Length of the generated random password. | `number` | `64` | no | -| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | -| [region](#input\_region) | Region which the resource is deployed to | `string` | `"us-east-1"` | no | -| [s3\_kms\_alias\_override](#input\_s3\_kms\_alias\_override) | Override the KMS key alias for the S3 bucket. Default is set to AWS Managed KMS alias. | `string` | `""` | no | -| [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | -| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | -| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `""` | no | -| [timeouts](#input\_timeouts) | A list of DB timeouts to apply to the running code while creating, updating, or deleting the DB instance. |
object({
create = string
update = string
delete = string
})
|
{
"create": "40m",
"delete": "60m",
"update": "80m"
}
| no | -| [vpc\_id](#input\_vpc\_id) | vpc\_id for the VPC to run the cluster. | `string` | n/a | yes | -| [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | Additional security group IDs to apply to the cluster, in addition to the provisioned default security group with ingress traffic from existing CIDR blocks and existing security groups | `list(string)` | `[]` | no | +| [final\_snapshot\_identifier](#input\_final\_snapshot\_identifier) | (optional) Name of your final DB snapshot when this DB cluster is deleted. If omitted, no final snapshot will be made. | `string` | `null` | no | +| [iam\_database\_authentication\_enabled](#input\_iam\_database\_authentication\_enabled) | Enable IAM database authentication for the RDS cluster. | `bool` | `false` | no | +| [iops](#input\_iops) | The amount of provisioned IOPS. Required if using io1 storage type. | `number` | `0` | no | +| [kms\_data](#input\_kms\_data) | Configuration for KMS key settings for RDS encryption and performance insights:
- create: (Optional) If true, a new KMS key is created.
- kms\_key\_id: (Optional) The ID of an existing KMS key for RDS encryption. If null it used AWS managed keys
- performance\_insights\_kms\_key\_id: (Optional) Key ID for Performance Insights. If null it used AWS managed keys
- description: (Optional) description for the KMS key.
- policy: (Optional) Specific policy for the KMS key.
- deletion\_window\_in\_days: (Optional) Number of days before deletion, default is 7.
- enable\_key\_rotation: (Optional) Enables key rotation for security; defaults to true. |
object({
create = optional(bool, true)
kms_key_id = optional(string, null)
performance_insights_kms_key_id = optional(string, null)
name = optional(string, null)
description = optional(string, null)
policy = optional(string, null)
deletion_window_in_days = optional(number, 7)
enable_key_rotation = optional(bool, true)
})
|
{
"create": false
}
| no | +| [license\_model](#input\_license\_model) | The license model for the DB instance (e.g., license-included, bring-your-own-license, general-public-license). | `string` | n/a | yes | +| [manage\_user\_password](#input\_manage\_user\_password) | (optional) Set to true to allow RDS to manage the master user password in Secrets Manager. Cannot be set if master\_password is provided."
null - is equal to 'false', don't set it to false , known bug : https://github.com/hashicorp/terraform-provider-aws/issues/31179 | `bool` | `null` | no | +| [monitoring\_interval](#input\_monitoring\_interval) | The interval, in seconds, between points when Enhanced Monitoring metrics are collected. Valid values are 0, 1, 5, 10, 15, 30, 60. | `number` | `0` | no | +| [monitoring\_role\_arn](#input\_monitoring\_role\_arn) | The ARN for the IAM role that allows RDS to send Enhanced Monitoring metrics to CloudWatch Logs. | `string` | `null` | no | +| [name](#input\_name) | The identifier for the RDS instance or cluster. | `string` | n/a | yes | +| [namespace](#input\_namespace) | Namespace for the resources. | `string` | n/a | yes | +| [network\_type](#input\_network\_type) | (optional) Network type of the cluster. Valid values: IPV4, DUAL. | `string` | `"IPV4"` | no | +| [option\_group\_config](#input\_option\_group\_config) | Configuration for RDS option group, with attributes to create or specify a group name, engine details, and database options including settings, ports, and versions. |
object({
create = optional(bool, false)
name = optional(string, null)
engine_name = optional(string)
major_engine_version = optional(string)
description = optional(string, "Managed by Terraform")
options = map(object({
option_name = string
port = number
version = string
option_settings = map(object({
name = string
value = string
}))
}))
})
|
{
"name": null,
"options": {}
}
| no | +| [parameter\_group\_config](#input\_parameter\_group\_config) | Configuration for RDS parameter group, with options to create or specify a group name, family, and a map of database parameters including settings and apply methods. |
object({
create = optional(bool, false)
name = optional(string, null)
family = optional(string)
description = optional(string, "Managed by Terraform")
parameters = map(object({
name = string
value = string
apply_method = optional(string, "immediate") # Options: "immediate" or "pending-reboot"
}))
})
|
{
"name": null,
"parameters": {}
}
| no | +| [password](#input\_password) | The password for the database. | `string` | `null` | no | +| [performance\_insights\_enabled](#input\_performance\_insights\_enabled) | (optional) Valid only for Non-Aurora Multi-AZ DB Clusters. Enables Performance Insights for the RDS Cluster | `bool` | `false` | no | +| [performance\_insights\_retention\_period](#input\_performance\_insights\_retention\_period) | The retention period (in days) for Performance Insights data. Valid values are 7, 731, or any value between 8 and 730. | `number` | `7` | no | +| [port](#input\_port) | Port on which the DB accepts connections | `number` | n/a | yes | +| [preferred\_backup\_window](#input\_preferred\_backup\_window) | The daily time range during which backups are taken. | `string` | `"07:00-09:00"` | no | +| [preferred\_maintenance\_window](#input\_preferred\_maintenance\_window) | The weekly time range during which maintenance can occur. | `string` | `"sun:06:00-sun:07:00"` | no | +| [proxy\_config](#input\_proxy\_config) | Configuration object for setting up an AWS RDS Proxy. It includes options for creating the proxy, connection pooling, authentication, and other proxy-specific settings.

- **create** (optional): A boolean that determines whether to create the RDS Proxy resource. Defaults to false.
- **name** (optional): The name of the RDS Proxy. If not specified, Terraform will create a default name.
- **engine\_family**: The database engine family for the proxy (e.g., "MYSQL", "POSTGRESQL").
- **vpc\_subnet\_ids**: List of VPC subnet IDs in which the proxy will be deployed.
- **security\_group\_data**: List of security groups to associate with the RDS Proxy.
- **require\_tls** (optional): Boolean flag to enforce the use of TLS for client connections to the proxy. Defaults to false.
- **debug\_logging** (optional): Boolean flag to enable debug logging for the proxy. Defaults to false.
- **idle\_client\_timeout\_secs** (optional): Number of seconds before the proxy closes idle client connections. The minimum is 60 seconds (1 minute), and the maximum is 28,800 seconds (8 hours). Defaults to 1,800 seconds (30 minutes).
- **role\_arn** (optional): The ARN of the IAM role used by the proxy for accessing database credentials in AWS Secrets Manager. If null, Terraform will create a new IAM role.

Authentication settings:
- **auth.auth\_scheme**: The authentication scheme to use (e.g., "SECRETS").
- **auth.description** (optional): A description of the authentication method. Defaults to null.
- **auth.iam\_auth** (optional): Specifies whether to use IAM authentication for the proxy. Defaults to "DISABLED".
- **auth.secret\_arn**: The ARN of the AWS Secrets Manager secret that contains the database credentials.
- **auth.client\_password\_auth\_type**: Specifies the password authentication type for the database.

Connection pool configuration:
- **connection\_pool\_config.connection\_borrow\_timeout** (optional): The amount of time (in seconds) a client connection can be held open before being returned to the pool. Defaults to 5 seconds.
- **connection\_pool\_config.init\_query** (optional): An optional initialization query executed when a connection is first established. Defaults to null.
- **connection\_pool\_config.max\_connections\_percent** (optional): The maximum percentage of available database connections that the proxy can use. Defaults to 100%.
- **connection\_pool\_config.max\_idle\_connections\_percent** (optional): The maximum percentage of idle database connections that the proxy can keep open. Defaults to 50%.
- **connection\_pool\_config.session\_pinning\_filters** (optional): List of filters for controlling session pinning behavior. Defaults to an empty list. |
object({
create = optional(bool, false)
name = optional(string, null)
engine_family = string
vpc_subnet_ids = list(string)
require_tls = optional(bool, false)
debug_logging = optional(bool, false)
idle_client_timeout_secs = optional(number, 30 * 60) // in seconds The minimum is 1 minute and the maximum is 8 hours.
role_arn = optional(string, null) // null value will create new role
auth = object({
auth_scheme = string
description = optional(string, null)
iam_auth = optional(string, "DISABLED")
client_password_auth_type = string
})
additional_auth_list = optional(list(object({
auth_scheme = string
secret_arn = optional(string, null)
description = optional(string, null)
iam_auth = optional(string, "DISABLED")
client_password_auth_type = string
})), [])
connection_pool_config = object({
connection_borrow_timeout = optional(number, 5)
init_query = optional(string, null)
max_connections_percent = optional(number, 100)
max_idle_connections_percent = optional(number, 50)
session_pinning_filters = optional(list(string), [])
})
security_group_data = optional(object({
security_group_ids_to_attach = optional(list(string), [])
create = optional(bool, true)
description = optional(string, null)
ingress_rules = optional(list(object({
description = optional(string, null)
cidr_block = optional(string, null)
source_security_group_id = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
self = optional(bool, false)
})), [])
egress_rules = optional(list(object({
description = optional(string, null)
cidr_block = optional(string, null)
destination_security_group_id = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
})), [])
}))
})
|
{
"auth": null,
"connection_pool_config": null,
"create": false,
"engine_family": "POSTGRESQL",
"security_group_data": {
"create": false
},
"vpc_subnet_ids": []
}
| no | +| [publicly\_accessible](#input\_publicly\_accessible) | Whether the RDS instance should be publicly accessible. | `bool` | `false` | no | +| [rds\_cluster\_instances](#input\_rds\_cluster\_instances) | "(optional) A list of objects defining configurations for RDS Cluster instances. Each object represents a single RDS instance configuration within the cluster, including options for instance class, monitoring, performance insights, maintenance windows, and other instance-specific settings."
name: Optional. Name of the instance (default: null).
instance\_class: The instance class for the RDS instance (e.g., db.r5.large).
availability\_zone: Optional. Specifies the availability zone for the instance (default: null).
publicly\_accessible: Optional. Whether the instance is publicly accessible (default: false).
db\_parameter\_group\_name: Optional. The name of the DB parameter group to associate with the instance (default: null).
apply\_immediately: Optional. Apply modifications immediately or during the next maintenance window (default: false).
ca\_cert\_identifier: Optional. Identifier for the CA certificate for the instance (default: null).
promotion\_tier: Optional. Promotion tier for the instance within the cluster (default: 0).
copy\_tags\_to\_snapshot: Optional. Copy tags to snapshots (default: true). |
list(object({
name = optional(string, null)
instance_class = string
availability_zone = optional(string, null)
publicly_accessible = optional(bool, false)
db_parameter_group_name = optional(string, null)
promotion_tier = optional(number, 0)
copy_tags_to_snapshot = optional(bool, true)
}))
| `[]` | no | +| [security\_group\_data](#input\_security\_group\_data) | (optional) Security Group data |
object({
security_group_ids_to_attach = optional(list(string), [])
create = optional(bool, true)
description = optional(string, null)
ingress_rules = optional(list(object({
description = optional(string, null)
cidr_block = optional(string, null)
source_security_group_id = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
})), [])
egress_rules = optional(list(object({
description = optional(string, null)
cidr_block = optional(string, null)
destination_security_group_id = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
})), [])
})
|
{
"create": false
}
| no | +| [serverlessv2\_scaling\_config](#input\_serverlessv2\_scaling\_config) | Configuration for Serverless V2 scaling:
- max\_capacity: (Required) The maximum ACU capacity for scaling (e.g., 256.0).
- min\_capacity: (Required) The minimum ACU capacity for scaling (e.g., 0.5). |
object({
max_capacity = number
min_capacity = number
})
|
{
"max_capacity": 1,
"min_capacity": 0.5
}
| no | +| [skip\_final\_snapshot](#input\_skip\_final\_snapshot) | (optional) Determines whether a final DB snapshot is created before the DB cluster is deleted. If true is specified, no DB snapshot is created. If false is specified, a DB snapshot is created before the DB cluster is deleted, using the value from final\_snapshot\_identifier. Default is false. | `string` | `true` | no | +| [storage\_encrypted](#input\_storage\_encrypted) | Whether to enable storage encryption. | `bool` | `true` | no | +| [storage\_type](#input\_storage\_type) | (optional) Required for Multi-AZ DB cluster) (Forces new for Multi-AZ DB clusters) Specifies the storage type to be associated with the DB cluster. For Aurora DB clusters, storage\_type modifications can be done in-place. For Multi-AZ DB Clusters, the iops argument must also be set. Valid values are: "", aurora-iopt1 (Aurora DB Clusters); io1, io2 (Multi-AZ DB Clusters). Default: "" (Aurora DB Clusters); io1 (Multi-AZ DB Clusters). | `string` | `""` | no | +| [tags](#input\_tags) | A map of tags to assign to the DB Cluster. | `map(string)` | `{}` | no | +| [username](#input\_username) | The username for the database. | `string` | n/a | yes | +| [vpc\_id](#input\_vpc\_id) | VPC Id for creating security group | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| -| [aurora\_arn](#output\_aurora\_arn) | Amazon Resource Name (ARN) of cluster | -| [aurora\_cluster\_identifier](#output\_aurora\_cluster\_identifier) | Cluster Identifier | -| [aurora\_endpoint](#output\_aurora\_endpoint) | The DNS address of the RDS instance | -| [aurora\_master\_host](#output\_aurora\_master\_host) | DB Master hostname | -| [aurora\_master\_username](#output\_aurora\_master\_username) | Username for the master DB user | -| [aurora\_name](#output\_aurora\_name) | Database name | -| [aurora\_reader\_endpoint](#output\_aurora\_reader\_endpoint) | A read-only endpoint for the Aurora cluster, automatically load-balanced across replicas | -| [aurora\_replicas\_host](#output\_aurora\_replicas\_host) | Replicas hostname | -| [rds\_instance\_arn](#output\_rds\_instance\_arn) | The RDS Instance AWS ARN. | -| [rds\_instance\_endpoint](#output\_rds\_instance\_endpoint) | The DNS address to the RDS Instance. | -| [rds\_instance\_hostname](#output\_rds\_instance\_hostname) | Hostname of the RDS Instance. | -| [rds\_instance\_id](#output\_rds\_instance\_id) | The RDS Instance AWS ID. | -| [rds\_instance\_kms\_arn](#output\_rds\_instance\_kms\_arn) | RDS KMS Key ARN | -| [rds\_instance\_kms\_id](#output\_rds\_instance\_kms\_id) | Output RDS KMS Key ID if the var.rds\_kms\_key\_arn\_override is "" | -| [rds\_instance\_resource\_id](#output\_rds\_instance\_resource\_id) | The RDS Instance AWS resource ID. | +| [arn](#output\_arn) | Instance or Cluster ARN | +| [database](#output\_database) | database name | +| [endpoint](#output\_endpoint) | Instance or Cluster Endpoint | +| [id](#output\_id) | Instance or Cluster ID | +| [identifier](#output\_identifier) | Instance or Cluster Identifier | +| [kms\_key\_id](#output\_kms\_key\_id) | Instance or Cluster KM Key ID | +| [monitoring\_role\_arn](#output\_monitoring\_role\_arn) | Instance or Cluster Monitoring role arn | +| [performance\_insights\_kms\_key\_id](#output\_performance\_insights\_kms\_key\_id) | Instance or Cluster Performance insight KM Key ID | +| [port](#output\_port) | Dtabase server port | +| [username](#output\_username) | Username for the Database | ## Development diff --git a/aurora-cluster.tf b/aurora-cluster.tf new file mode 100644 index 0000000..7f598f8 --- /dev/null +++ b/aurora-cluster.tf @@ -0,0 +1,101 @@ +resource "random_password" "master" { + count = var.password == null && var.manage_user_password == null ? 1 : 0 + + length = 41 + special = true + override_special = "!#*^" + + lifecycle { + ignore_changes = [ + length, + lower, + min_lower, + min_numeric, + min_special, + min_upper, + override_special, + special, + upper + ] + } +} + +resource "aws_rds_cluster" "this" { + count = var.engine_type == "cluster" ? 1 : 0 + + cluster_identifier = var.name + engine = var.engine + engine_version = var.engine_version + engine_mode = var.engine_mode == "serverless" ? "provisioned" : var.engine_mode + port = var.port + master_username = var.username + master_password = var.password == null && var.manage_user_password == null ? random_password.master[0].result : var.password + manage_master_user_password = var.manage_user_password + database_name = var.database_name + db_cluster_instance_class = strcontains(var.engine, "aurora") ? null : var.db_server_class + vpc_security_group_ids = local.security_group_ids_to_attach + db_subnet_group_name = var.db_subnet_group_data.name + db_cluster_parameter_group_name = var.db_cluster_parameter_group_name + db_instance_parameter_group_name = var.db_instance_parameter_group_name + allocated_storage = strcontains(var.engine, "aurora") ? null : var.allocated_storage + backup_retention_period = var.backup_retention_period + preferred_backup_window = var.preferred_backup_window + preferred_maintenance_window = var.preferred_maintenance_window + storage_encrypted = var.storage_encrypted + iam_database_authentication_enabled = var.iam_database_authentication_enabled + storage_type = var.storage_type + ca_certificate_identifier = var.ca_certificate_identifier + kms_key_id = var.kms_data.create ? aws_kms_alias.this[0].target_key_arn : (var.kms_data.kms_key_id == null ? data.aws_kms_alias.rds.target_key_arn : var.kms_data.kms_key_id) + performance_insights_enabled = var.performance_insights_enabled + performance_insights_kms_key_id = var.kms_data.create ? aws_kms_alias.this[0].target_key_arn : (var.kms_data.performance_insights_kms_key_id == null ? data.aws_kms_alias.rds.target_key_arn : var.kms_data.performance_insights_kms_key_id) + deletion_protection = var.deletion_protection + delete_automated_backups = var.delete_automated_backups + skip_final_snapshot = var.skip_final_snapshot + final_snapshot_identifier = var.final_snapshot_identifier + copy_tags_to_snapshot = var.copy_tags_to_snapshot + engine_lifecycle_support = var.engine_lifecycle_support + network_type = var.network_type + + + dynamic "serverlessv2_scaling_configuration" { + for_each = var.engine_mode == "serverless" ? [var.serverlessv2_scaling_config] : [] // Note :- For Serverless V2 , engine_mode should be "provisioned" but for simplecity "serverless" is expected + // Refer : serverless + + content { + max_capacity = serverlessv2_scaling_configuration.value.max_capacity + min_capacity = serverlessv2_scaling_configuration.value.max_capacity + } + + } + + tags = var.tags + depends_on = [aws_db_subnet_group.this, module.security_group] +} + +resource "aws_rds_cluster_instance" "this" { + for_each = { for idx, instance in var.rds_cluster_instances : idx => instance } + + cluster_identifier = aws_rds_cluster.this[0].id + identifier = each.value.name != null ? each.value.name : "${aws_rds_cluster.this[0].id}-${each.key + 1}" + instance_class = each.value.instance_class + + engine = aws_rds_cluster.this[0].engine + engine_version = aws_rds_cluster.this[0].engine_version + db_subnet_group_name = aws_rds_cluster.this[0].db_subnet_group_name + availability_zone = each.value.availability_zone + publicly_accessible = each.value.publicly_accessible + db_parameter_group_name = each.value.db_parameter_group_name + apply_immediately = var.apply_immediately + preferred_maintenance_window = var.preferred_maintenance_window + auto_minor_version_upgrade = var.auto_minor_version_upgrade + ca_cert_identifier = var.ca_cert_identifier + monitoring_interval = var.monitoring_interval + monitoring_role_arn = var.monitoring_interval > 0 ? (var.monitoring_role_arn == null ? aws_iam_role.enhanced_monitoring[0].arn : var.monitoring_role_arn) : null + performance_insights_enabled = var.performance_insights_enabled + performance_insights_kms_key_id = var.kms_data.create ? aws_kms_alias.this[0].target_key_arn : (var.kms_data.performance_insights_kms_key_id == null ? data.aws_kms_alias.rds.target_key_arn : var.kms_data.performance_insights_kms_key_id) + performance_insights_retention_period = var.performance_insights_retention_period + promotion_tier = each.value.promotion_tier + copy_tags_to_snapshot = each.value.copy_tags_to_snapshot + + tags = var.tags +} diff --git a/common.tf b/common.tf new file mode 100644 index 0000000..d0db22f --- /dev/null +++ b/common.tf @@ -0,0 +1,177 @@ + + +resource "aws_db_subnet_group" "this" { + count = var.db_subnet_group_data.create ? 1 : 0 + + name = var.db_subnet_group_data.name + description = var.db_subnet_group_data.description + subnet_ids = var.db_subnet_group_data.subnet_ids + + tags = var.tags +} + +resource "aws_db_option_group" "this" { + count = var.option_group_config.create ? 1 : 0 + + name = var.option_group_config.name + engine_name = var.option_group_config.engine_name + major_engine_version = var.option_group_config.major_engine_version + option_group_description = var.option_group_config.description + + dynamic "option" { + for_each = var.option_group_config.options + content { + option_name = option.value.option_name + port = option.value.port + version = option.value.version + + dynamic "option_settings" { + for_each = option.value.option_settings + content { + name = option_settings.value.name + value = option_settings.value.value + } + } + } + } + + tags = var.tags +} + +resource "aws_db_parameter_group" "this" { + count = var.parameter_group_config.create ? 1 : 0 + + name = var.parameter_group_config.name + family = var.parameter_group_config.family + description = var.parameter_group_config.description + + dynamic "parameter" { + for_each = var.parameter_group_config.parameters + content { + name = parameter.value.name + value = parameter.value.value + apply_method = parameter.value.apply_method + } + } + + tags = var.tags +} + +################################################################################ +## KMS +################################################################################ + +resource "aws_kms_key" "this" { + count = var.kms_data.create ? 1 : 0 + + description = var.kms_data.description == null ? "RDS KMS key" : var.kms_data.description + deletion_window_in_days = var.kms_data.deletion_window_in_days + enable_key_rotation = var.kms_data.enable_key_rotation + + tags = merge(var.tags, { + Name = var.kms_data.name == null ? "${local.prefix}-${var.name}-kms-key" : var.kms_data.name + }) +} + +resource "aws_kms_alias" "this" { + count = var.kms_data.create ? 1 : 0 + + name = var.kms_data.name == null ? "alias/${local.prefix}-${var.name}-kms-key" : "alias/${var.kms_data.name}" + target_key_id = aws_kms_key.this[0].id +} + +################################################################################ +## IAM - create IAM role for monitoring +################################################################################ +resource "aws_iam_role" "enhanced_monitoring" { + count = var.monitoring_interval > 0 && var.monitoring_role_arn == null ? 1 : 0 + name = "${local.prefix}-${var.name}-enhanced-monitoring-role" + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Sid = "" + Principal = { + Service = "monitoring.rds.amazonaws.com" + } + }, + ] + }) + + tags = var.tags +} + +resource "aws_iam_policy" "logs" { + count = var.monitoring_interval > 0 && var.monitoring_role_arn == null ? 1 : 0 + + name = "${local.prefix}-${var.name}-policy" + description = "Policy for RDS Enhanced Monitoring" + + policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Effect = "Allow", + Action = [ + "logs:CreateLogStream", + "logs:PutLogEvents", + "logs:CreateLogGroup", + ], + Resource = [ + "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:/aws/rds/instance/*:log-stream:*", + "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:/aws/rds/cluster/*:log-stream:*" + ] + } + ] + }) +} + +resource "aws_iam_role_policy_attachment" "attach_policy" { + count = var.monitoring_interval > 0 && var.monitoring_role_arn == null ? 1 : 0 + + role = aws_iam_role.enhanced_monitoring[0].name + policy_arn = aws_iam_policy.logs[0].arn +} + +data "aws_iam_policy" "enhanced_monitoring" { + count = var.monitoring_interval > 0 && var.monitoring_role_arn == null ? 1 : 0 + arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" +} + +resource "aws_iam_role_policy_attachment" "enhanced_monitoring" { + count = var.monitoring_interval > 0 && var.monitoring_role_arn == null ? 1 : 0 + + role = aws_iam_role.enhanced_monitoring[0].name + policy_arn = data.aws_iam_policy.enhanced_monitoring[0].arn +} + + +resource "aws_ssm_parameter" "database_creds" { + name = "/${var.namespace}/${var.environment}/${var.engine_type}/${var.name}/database-credentials" + description = "Database credentials" + type = "SecureString" + value = jsonencode({ + "username" : local.username + "password" : local.password + "database" : local.database + "endpoint" : local.endpoint + "port" : local.port + }) + + tags = var.tags +} + +module "security_group" { + source = "./modules/security-group" + + count = var.security_group_data.create ? 1 : 0 + + name = "${var.name}-security-group" + description = var.security_group_data.description == null ? "Allow inbound traffic and outbound traffic" : var.security_group_data.description + vpc_id = var.vpc_id + egress_rules = var.security_group_data.egress_rules + ingress_rules = local.db_ingress_rules + tags = var.tags +} diff --git a/context.tf b/context.tf deleted file mode 100644 index 841d622..0000000 --- a/context.tf +++ /dev/null @@ -1,277 +0,0 @@ -# -# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label -# All other instances of this file should be a copy of that one -# -# -# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf -# and then place it in your Terraform module to automatically get -# Cloud Posse's standard configuration inputs suitable for passing -# to Cloud Posse modules. -# -# curl -sL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf -o context.tf -# -# Modules should access the whole context as `module.this.context` -# to get the input variables with nulls for defaults, -# for example `context = module.this.context`, -# and access individual variables as `module.this.`, -# with final values filled in. -# -# For example, when using defaults, `module.this.context.delimiter` -# will be null, and `module.this.delimiter` will be `-` (hyphen). -# - -module "this" { - source = "cloudposse/label/null" - version = "0.25.0" # requires Terraform >= 0.13.0 - - enabled = var.enabled - namespace = var.namespace - tenant = var.tenant - environment = var.environment - stage = var.stage - name = var.name - delimiter = var.delimiter - attributes = var.attributes - tags = var.tags - additional_tag_map = var.additional_tag_map - label_order = var.label_order - regex_replace_chars = var.regex_replace_chars - id_length_limit = var.id_length_limit - label_key_case = var.label_key_case - label_value_case = var.label_value_case - descriptor_formats = var.descriptor_formats - labels_as_tags = var.labels_as_tags - - context = var.context -} - -# Copy contents of cloudposse/terraform-null-label/variables.tf here - -variable "context" { - type = any - default = { - enabled = true - namespace = null - tenant = null - environment = null - stage = null - name = null - delimiter = null - attributes = [] - tags = {} - additional_tag_map = {} - regex_replace_chars = null - label_order = [] - id_length_limit = null - label_key_case = null - label_value_case = null - descriptor_formats = {} - # Note: we have to use [] instead of null for unset lists due to - # https://github.com/hashicorp/terraform/issues/28137 - # which was not fixed until Terraform 1.0.0, - # but we want the default to be all the labels in `label_order` - # and we want users to be able to prevent all tag generation - # by setting `labels_as_tags` to `[]`, so we need - # a different sentinel to indicate "default" - labels_as_tags = ["unset"] - } - description = <<-EOT - Single object for setting entire context at once. - See description of individual variables for details. - Leave string and numeric variables as `null` to use default value. - Individual variable settings (non-null) override settings in context object, - except for attributes, tags, and additional_tag_map, which are merged. - EOT - - validation { - condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`." - } - - validation { - condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"]) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "enabled" { - type = bool - default = null - description = "Set to false to prevent the module from creating any resources" -} - -variable "namespace" { - type = string - description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" -} - -variable "tenant" { - type = string - default = "" - description = "ID element _(Rarely used, not included by default)_. A customer identifier, indicating who this instance of a resource is for" -} - -variable "environment" { - type = string - description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" -} - -variable "stage" { - type = string - default = null - description = "ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release'" -} - -variable "name" { - type = string - default = null - description = <<-EOT - ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'. - This is the only ID element not also included as a `tag`. - The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. - EOT -} - -variable "delimiter" { - type = string - default = null - description = <<-EOT - Delimiter to be used between ID elements. - Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. - EOT -} - -variable "attributes" { - type = list(string) - default = [] - description = <<-EOT - ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`, - in the order they appear in the list. New attributes are appended to the - end of the list. The elements of the list are joined by the `delimiter` - and treated as a single ID element. - EOT -} - -variable "labels_as_tags" { - type = set(string) - default = ["default"] - description = <<-EOT - Set of labels (ID elements) to include as tags in the `tags` output. - Default is to include all labels. - Tags with empty values will not be included in the `tags` output. - Set to `[]` to suppress all generated tags. - **Notes:** - The value of the `name` tag, if included, will be the `id`, not the `name`. - Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be - changed in later chained modules. Attempts to change it will be silently ignored. - EOT -} - -variable "tags" { - type = map(string) - default = {} - description = <<-EOT - Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`). - Neither the tag keys nor the tag values will be modified by this module. - EOT -} - -variable "additional_tag_map" { - type = map(string) - default = {} - description = <<-EOT - Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`. - This is for some rare cases where resources want additional configuration of tags - and therefore take a list of maps with tag key, value, and additional configuration. - EOT -} - -variable "label_order" { - type = list(string) - default = null - description = <<-EOT - The order in which the labels (ID elements) appear in the `id`. - Defaults to ["namespace", "environment", "stage", "name", "attributes"]. - You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. - EOT -} - -variable "regex_replace_chars" { - type = string - default = null - description = <<-EOT - Terraform regular expression (regex) string. - Characters matching the regex will be removed from the ID elements. - If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. - EOT -} - -variable "id_length_limit" { - type = number - default = null - description = <<-EOT - Limit `id` to this many characters (minimum 6). - Set to `0` for unlimited length. - Set to `null` for keep the existing setting, which defaults to `0`. - Does not affect `id_full`. - EOT - validation { - condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0 - error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length." - } -} - -variable "label_key_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of the `tags` keys (label names) for tags generated by this module. - Does not affect keys of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper`. - Default value: `title`. - EOT - - validation { - condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case) - error_message = "Allowed values: `lower`, `title`, `upper`." - } -} - -variable "label_value_case" { - type = string - default = null - description = <<-EOT - Controls the letter case of ID elements (labels) as included in `id`, - set as tag values, and output by this module individually. - Does not affect values of tags passed in via the `tags` input. - Possible values: `lower`, `title`, `upper` and `none` (no transformation). - Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs. - Default value: `lower`. - EOT - - validation { - condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case) - error_message = "Allowed values: `lower`, `title`, `upper`, `none`." - } -} - -variable "descriptor_formats" { - type = any - default = {} - description = <<-EOT - Describe additional descriptors to be output in the `descriptors` output map. - Map of maps. Keys are names of descriptors. Values are maps of the form - `{ - format = string - labels = list(string) - }` - (Type is `any` so the map values can later be enhanced to provide additional options.) - `format` is a Terraform format string to be passed to the `format()` function. - `labels` is a list of labels, in order, to pass to `format()` function. - Label values will be normalized before being passed to `format()` so they will be - identical to how they appear in `id`. - Default is `{}` (`descriptors` output will be empty). - EOT -} - -#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/data.tf b/data.tf new file mode 100644 index 0000000..a189edd --- /dev/null +++ b/data.tf @@ -0,0 +1,7 @@ +data "aws_kms_alias" "rds" { + name = "alias/aws/rds" +} + +data "aws_caller_identity" "current" {} + +data "aws_region" "current" {} diff --git a/docs/example/README.md b/docs/example/README.md deleted file mode 100644 index 49701be..0000000 --- a/docs/example/README.md +++ /dev/null @@ -1,83 +0,0 @@ - -## Requirements - -| Name | Version | -|------|---------| -| [null](#requirement\_null) | 3.1.0 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | 3.59.0 | -| [random](#provider\_random) | 3.1.0 | - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [rds\_cluster\_aurora\_postgres](#module\_rds\_cluster\_aurora\_postgres) | git::https://github.com/cloudposse/terraform-aws-rds-cluster.git | 0.46.2 | -| [this](#module\_this) | cloudposse/label/null | 0.25.0 | - -## Resources - -| Name | Type | -|------|------| -| [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 | -| [aws_kms_alias.aurora_cluster_kms_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | -| [aws_kms_key.aurora_cluster_kms_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | -| [aws_ssm_parameter.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | -| [random_password.db_admin_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | -| [aws_iam_policy_document.enhanced_monitoring](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | 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 | -| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | List of CIDR blocks allowed to access the cluster | `list(string)` | `[]` | no | -| [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | 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 | -| [cluster\_family](#input\_cluster\_family) | The family of the DB cluster parameter group | `string` | `"aurora-postgresql10"` | no | -| [cluster\_size](#input\_cluster\_size) | Number of DB instances to create in the cluster | `number` | `0` | no | -| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | -| [db\_admin\_username](#input\_db\_admin\_username) | Name of the default DB admin user role | `string` | n/a | yes | -| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | -| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | -| [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | -| [engine](#input\_engine) | The name of the database engine to be used for this DB cluster. Valid values: `aurora`, `aurora-mysql`, `aurora-postgresql` | `string` | `"aurora-postgresql"` | no | -| [engine\_mode](#input\_engine\_mode) | The database engine mode. Valid values: `parallelquery`, `provisioned`, `serverless` | `string` | `"serverless"` | no | -| [engine\_version](#input\_engine\_version) | The version of the database engine to use. See `aws rds describe-db-engine-versions` | `string` | `"aurora-postgresql13.3"` | no | -| [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | n/a | yes | -| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | -| [instance\_type](#input\_instance\_type) | Instance type to use | `string` | `"db.t3.medium"` | no | -| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | -| [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | -| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | -| [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | -| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no | -| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | n/a | yes | -| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | -| [region](#input\_region) | AWS region | `string` | n/a | yes | -| [security\_groups](#input\_security\_groups) | List of security groups to be allowed to connect to the DB instance | `list(string)` | `[]` | no | -| [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | -| [subnets](#input\_subnets) | Subnets for the cluster to run in. | `list(string)` | n/a | yes | -| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | -| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `""` | no | -| [vpc\_id](#input\_vpc\_id) | vpc\_id for the VPC to run the cluster. | `string` | n/a | yes | - -## Outputs - -| Name | Description | -|------|-------------| -| [arn](#output\_arn) | Amazon Resource Name (ARN) of cluster | -| [cluster\_identifier](#output\_cluster\_identifier) | Cluster Identifier | -| [endpoint](#output\_endpoint) | The DNS address of the RDS instance | -| [master\_host](#output\_master\_host) | DB Master hostname | -| [master\_username](#output\_master\_username) | Username for the master DB user | -| [name](#output\_name) | Database name | -| [reader\_endpoint](#output\_reader\_endpoint) | A read-only endpoint for the Aurora cluster, automatically load-balanced across replicas | -| [replicas\_host](#output\_replicas\_host) | Replicas hostname | - diff --git a/docs/module-usage-guide/README.md b/docs/module-usage-guide/README.md index e84dd37..6b607eb 100644 --- a/docs/module-usage-guide/README.md +++ b/docs/module-usage-guide/README.md @@ -27,7 +27,7 @@ To use the module in your Terraform configuration, include the following source ```hcl module "aurora" { source = "sourcefuse/arc-db/aws" - version = "3.0.0" + version = "4.0.0" # insert the required variables here } ``` @@ -37,7 +37,7 @@ module "aurora" { Integrate the module with your existing Terraform mono repo configuration, follow the steps below: 1. Create a new folder in `terraform/` named `db`. -2. Create the required files, see the [examples](https://github.com/sourcefuse/terraform-aws-arc-db/tree/main/examples/simple) to base off of. +2. Create the required files, see the [examples](https://github.com/sourcefuse/terraform-aws-arc-db/tree/main/examples/rds) to base off of. 3. Configure with your backend - Create the environment backend configuration file: `config..hcl` - **region**: Where the backend resides @@ -64,15 +64,33 @@ For a list of outputs, see the README [Outputs](https://github.com/sourcefuse/te ### Basic Usage -For basic usage, see the [example](https://github.com/sourcefuse/terraform-aws-arc-db/tree/main/example) folder. +For basic usage, see the [example](https://github.com/sourcefuse/terraform-aws-arc-db/tree/main/examples/rds) folder. This example will create: -module "aurora": This module is creating an Aurora database cluster.The module is configuring the Aurora cluster with various settings, such as the instance type, the number of instances in the cluster, the subnets and security groups it's associated with, and more. +- RDS Instance Example +This example demonstrates deploying a single RDS instance using the module, configuring an Amazon RDS database with basic settings like instance class, storage, and connectivity. It showcases options for database engine, encryption, and CloudWatch monitoring for a standalone RDS database. Ideal for simple, production-ready RDS setups. -module "rds_sql_server": This module is creating an Amazon RDS instance for SQL Server.This module is configuring the RDS instance with various settings, such as the database engine and version, the instance class, the allocated storage, the security groups it's associated with, and more. +### RDS Proxy -Both of these modules are using data sources (data.aws_vpc.vpc, data.aws_subnets.private, data.aws_security_groups.db_sg, etc.) to fetch information about the existing AWS infrastructure, such as the VPC, subnets, and security groups, and use that information to configure the databases. +For RDS Proxy, see the [example](https://github.com/sourcefuse/terraform-aws-arc-db/tree/main/examples/rds-proxy) folder. + +- RDS Proxy Example +This example configures an RDS Proxy for an RDS database, helping manage connection pooling for improved database performance and security. By integrating with RDS Proxy, it reduces connection management overhead and scales automatically with demand, useful for applications with variable database traffic and sensitive to scaling requirements. + +### Aurora Cluster + +For Aurora Cluster, see the [example](https://github.com/sourcefuse/terraform-aws-arc-db/tree/main/examples/aurora) folder. + +- Aurora Cluster Example +This example provisions an Amazon Aurora cluster, utilizing the module to set up a high-availability, high-performance database solution. The configuration includes multiple instances within a cluster, providing a resilient and cost-effective solution suitable for demanding applications. + +### Aurora Cluster Serverless + +For Aurora Cluster Serverless, see the [example](https://github.com/sourcefuse/terraform-aws-arc-db/tree/main/examples/aurora-serverless) folder. + +- Aurora Serverless Cluster Example +This example deploys an Aurora Serverless cluster autoscaling, making it ideal for applications with unpredictable or intermittent database usage. The module configures serverless capacity, connectivity, and database settings, automatically adjusting to workload needs without manual intervention. ### Tips and Recommendations diff --git a/example/.terraform.lock.hcl b/example/.terraform.lock.hcl deleted file mode 100644 index 62e6e72..0000000 --- a/example/.terraform.lock.hcl +++ /dev/null @@ -1,89 +0,0 @@ -# This file is maintained automatically by "terraform init". -# Manual edits may be lost in future updates. - -provider "registry.terraform.io/hashicorp/aws" { - version = "5.46.0" - constraints = ">= 2.0.0, >= 3.0.0, >= 4.0.0, >= 4.9.0, >= 4.23.0, >= 5.0.0, < 6.0.0" - hashes = [ - "h1:bGEG0vS4seLpWWXVPnOqjhD1s6hkZB7etQIwOSSd00U=", - "h1:d0Mf33mbbQujZ/JaYkqmH5gZGvP+iEIWf9yBSiOwimE=", - "zh:05ae6180a7f23071435f6e5e59c19af0b6c5da42ee600c6c1568c8660214d548", - "zh:0d878d1565d5e57ce6b34ec5f04b28662044a50c999ec5770c374aa1f1020de2", - "zh:25ef1467af2514d8011c44759307445f7057836ff87dfe4503c3e1c9776d5c1a", - "zh:26c006df6200f0063b827aab05bec94f9f3f77848e82ed72e48a51d1170d1961", - "zh:37cdf4292649a10f12858622826925e18ad4eca354c31f61d02c66895eb91274", - "zh:4315b0433c2fc512666c74e989e2d95240934ef370bea1c690d36cb02d30c4ce", - "zh:75df0b3f631b78aeff1832cc77d99b527c2a5e79d40f7aac40bdc4a66124dac2", - "zh:90693d936c9a556d2bf945de4920ff82052002eb73139bd7164fafd02920f0ef", - "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:c9177ad09804c60fd2ed25950570407b6bdcdf0fcc309e1673b584f06a827fae", - "zh:ca8e8db24a4d62d92afd8d3d383b81a08693acac191a2e0a110fb46deeff56a3", - "zh:d5fa3a36e13957d63bfe9bbd6df0426a2422214403aac9f20b60c36f8d9ebec6", - "zh:e4ede44a112296c9cc77b15e439e41ee15c0e8b3a0dec94ae34df5ebba840e8b", - "zh:f2d4de8d8cde69caffede1544ebea74e69fcc4552e1b79ae053519a05c060706", - "zh:fc19e9266b1841d4a3aeefa8a5b5ad6988baed6540f85a373b6c2d0dc1ca5830", - ] -} - -provider "registry.terraform.io/hashicorp/null" { - version = "3.2.2" - constraints = ">= 2.0.0, >= 3.1.1" - hashes = [ - "h1:IMVAUHKoydFrlPrl9OzasDnw/8ntZFerCC9iXw1rXQY=", - "h1:m467k2tZ9cdFFgHW7LPBK2GLPH43LC6wc3ppxr8yvoE=", - "zh:3248aae6a2198f3ec8394218d05bd5e42be59f43a3a7c0b71c66ec0df08b69e7", - "zh:32b1aaa1c3013d33c245493f4a65465eab9436b454d250102729321a44c8ab9a", - "zh:38eff7e470acb48f66380a73a5c7cdd76cc9b9c9ba9a7249c7991488abe22fe3", - "zh:4c2f1faee67af104f5f9e711c4574ff4d298afaa8a420680b0cb55d7bbc65606", - "zh:544b33b757c0b954dbb87db83a5ad921edd61f02f1dc86c6186a5ea86465b546", - "zh:696cf785090e1e8cf1587499516b0494f47413b43cb99877ad97f5d0de3dc539", - "zh:6e301f34757b5d265ae44467d95306d61bef5e41930be1365f5a8dcf80f59452", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:913a929070c819e59e94bb37a2a253c228f83921136ff4a7aa1a178c7cce5422", - "zh:aa9015926cd152425dbf86d1abdbc74bfe0e1ba3d26b3db35051d7b9ca9f72ae", - "zh:bb04798b016e1e1d49bcc76d62c53b56c88c63d6f2dfe38821afef17c416a0e1", - "zh:c23084e1b23577de22603cff752e59128d83cfecc2e6819edadd8cf7a10af11e", - ] -} - -provider "registry.terraform.io/hashicorp/random" { - version = "3.6.1" - constraints = ">= 3.4.0" - hashes = [ - "h1:Xx3UvdKXObNTjfd4yYHDcFalYZujg7NBY/VpZISiTb4=", - "h1:a+Goawwh6Qtg4/bRWzfDtIdrEFfPlnVy0y4LdUQY3nI=", - "zh:2a0ec154e39911f19c8214acd6241e469157489fc56b6c739f45fbed5896a176", - "zh:57f4e553224a5e849c99131f5e5294be3a7adcabe2d867d8a4fef8d0976e0e52", - "zh:58f09948c608e601bd9d0a9e47dcb78e2b2c13b4bda4d8f097d09152ea9e91c5", - "zh:5c2a297146ed6fb3fe934c800e78380f700f49ff24dbb5fb5463134948e3a65f", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:7ce41e26f0603e31cdac849085fc99e5cd5b3b73414c6c6d955c0ceb249b593f", - "zh:8c9e8d30c4ef08ee8bcc4294dbf3c2115cd7d9049c6ba21422bd3471d92faf8a", - "zh:93e91be717a7ffbd6410120eb925ebb8658cc8f563de35a8b53804d33c51c8b0", - "zh:982542e921970d727ce10ed64795bf36c4dec77a5db0741d4665230d12250a0d", - "zh:b9d1873f14d6033e216510ef541c891f44d249464f13cc07d3f782d09c7d18de", - "zh:cfe27faa0bc9556391c8803ade135a5856c34a3fe85b9ae3bdd515013c0c87c1", - "zh:e4aabf3184bbb556b89e4b195eab1514c86a2914dd01c23ad9813ec17e863a8a", - ] -} - -provider "registry.terraform.io/hashicorp/time" { - version = "0.11.1" - constraints = ">= 0.7.0" - hashes = [ - "h1:bf7JCfBV8KHOJ0iicZ705maRJTeme0Br4QdBYnu1gMw=", - "h1:pQGSL9mdgw4qsLndFYsEF93mbsIxyxNoAyIbBqhS3Xo=", - "zh:19a393db736ec4fd024d098d55aefaef07056c37a448ece3b55b3f5f4c2c7e4a", - "zh:227fa1e221de2907f37be78d40c06ca6a6f7b243a1ec33ade014dfaf6d92cd9c", - "zh:29970fecbf4a3ca23bacbb05d6b90cdd33dd379f90059fe39e08289951502d9f", - "zh:65024596f22f10e7dcb5e0e4a75277f275b529daa0bc0daf34ca7901c678ab88", - "zh:694d080cb5e3bf5ef08c7409208d061c135a4f5f4cdc93ea8607860995264b2e", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:b29d15d13e1b3412e6a4e1627d378dbd102659132f7488f64017dd6b6d5216d3", - "zh:bb79f4cae9f8c17c73998edc54aa16c2130a03227f7f4e71fc6ac87e230575ec", - "zh:ceccf80e95929d97f62dcf1bb3c7c7553d5757b2d9e7d222518722fc934f7ad5", - "zh:f40e638336527490e294d9c938ae55919069e6987e85a80506784ba90348792a", - "zh:f99ef33b1629a3b2278201142a3011a8489e66d92da832a5b99e442204de18fb", - "zh:fded14754ea46fdecc62a52cd970126420d4cd190e598cb61190b4724a727edb", - ] -} diff --git a/example/README.md b/example/README.md deleted file mode 100644 index 72ce14e..0000000 --- a/example/README.md +++ /dev/null @@ -1,47 +0,0 @@ - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | ~> 1.3, < 2.0.0 | -| [aws](#requirement\_aws) | >= 4.0, < 6.0 | - -## Providers - -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | 5.46.0 | - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [aurora](#module\_aurora) | ../ | n/a | -| [rds\_postgresql](#module\_rds\_postgresql) | ../ | n/a | -| [rds\_sql\_server](#module\_rds\_sql\_server) | ../ | n/a | - -## Resources - -| Name | Type | -|------|------| -| [aws_caller_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | -| [aws_kms_alias.aurora_cluster_kms_arn](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | -| [aws_security_groups.db_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_groups) | data source | -| [aws_subnets.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | -| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [additional\_ingress\_rules\_aurora](#input\_additional\_ingress\_rules\_aurora) | Additional ingress rules for Aurora |
list(object({
name = string
description = string
type = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
| `[]` | no | -| [additional\_ingress\_rules\_rds](#input\_additional\_ingress\_rules\_rds) | Additional ingress rules for RDS |
list(object({
name = string
description = string
type = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
| `[]` | no | -| [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `"poc"` | no | -| [kms\_alias\_name](#input\_kms\_alias\_name) | Name of the KMS alias | `string` | `"alias/arc-poc-aurora-cluster-kms-key"` | no | -| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `"arc"` | no | -| [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no | - -## Outputs - -No outputs. - diff --git a/example/main.tf b/example/main.tf deleted file mode 100644 index 7671db7..0000000 --- a/example/main.tf +++ /dev/null @@ -1,125 +0,0 @@ -################################################################################ -## defaults -################################################################################ -terraform { - required_version = "~> 1.3, < 2.0.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 4.0, < 6.0" - } - } -} - -provider "aws" { - region = var.region -} - -################################################################################ -## lookups -################################################################################ -data "aws_caller_identity" "this" {} - -################################################################################ -## db -################################################################################ -## aurora cluster -module "aurora" { - source = "../" - - environment = var.environment - namespace = var.namespace - region = var.region - vpc_id = data.aws_vpc.vpc.id - - aurora_cluster_enabled = true - aurora_cluster_name = "aurora-example" - enhanced_monitoring_name = "aurora-example-enhanced-monitoring" - aurora_db_admin_username = "example_db_admin" - aurora_db_name = "example" - aurora_allow_major_version_upgrade = true - aurora_auto_minor_version_upgrade = true - aurora_cluster_size = 1 - aurora_instance_type = "db.t3.medium" - aurora_subnets = data.aws_subnets.private.ids - aurora_security_groups = data.aws_security_groups.db_sg.ids - aurora_allowed_cidr_blocks = [data.aws_vpc.vpc.cidr_block] - performance_insights_enabled = true - performance_insights_retention_period = 7 - performance_insights_kms_key_id = data.aws_kms_alias.aurora_cluster_kms_arn.target_key_arn - kms_key_arn = data.aws_kms_alias.aurora_cluster_kms_arn.target_key_arn - iam_database_authentication_enabled = true - additional_ingress_rules_aurora = var.additional_ingress_rules_aurora -} - -## sql server rds instance -module "rds_sql_server" { - source = "../" - - environment = var.environment - namespace = var.namespace - region = var.region - vpc_id = data.aws_vpc.vpc.id - - account_id = data.aws_caller_identity.this.id - rds_instance_enabled = true - rds_instance_name = "sql-server-example" - enhanced_monitoring_name = "sql-server-example-enhanced-monitoring" - rds_instance_dns_zone_id = "" - rds_instance_host_name = "" - rds_instance_database_name = null // sql server database name must be null - rds_instance_database_user = "example_db_admin" - rds_instance_database_port = 1433 - rds_instance_engine = "sqlserver-ex" // express edition. - rds_instance_engine_version = "16.00.4105.2.v1" - rds_instance_major_engine_version = "16.00" - rds_instance_db_parameter_group = "sqlserver-ex-16.0" - rds_instance_db_parameter = [] - rds_instance_db_options = [] - rds_enable_custom_option_group = true - rds_instance_ca_cert_identifier = "rds-ca-2019" - rds_instance_publicly_accessible = false - rds_instance_multi_az = false - rds_instance_storage_type = "gp3" - rds_instance_instance_class = "db.t3.small" - rds_instance_allocated_storage = 400 - rds_instance_storage_encrypted = false // sql server express doesn't support encryption at rest - rds_instance_snapshot_identifier = null - rds_instance_auto_minor_version_upgrade = true - rds_instance_allow_major_version_upgrade = true - rds_instance_apply_immediately = true - rds_instance_maintenance_window = "Mon:00:00-Mon:02:00" - rds_instance_skip_final_snapshot = true - rds_instance_copy_tags_to_snapshot = true - rds_instance_backup_retention_period = 3 - rds_instance_backup_window = "22:00-23:59" - rds_instance_security_group_ids = data.aws_security_groups.db_sg.ids - rds_instance_allowed_cidr_blocks = [data.aws_vpc.vpc.cidr_block] - rds_instance_subnet_ids = data.aws_subnets.private.ids - additional_ingress_rules_rds = var.additional_ingress_rules_rds -} - -## postgresql rds instance -module "rds_postgresql" { - source = "../" - - environment = var.environment - namespace = var.namespace - region = var.region - vpc_id = data.aws_vpc.vpc.id - - account_id = data.aws_caller_identity.this.id - rds_instance_enabled = true - rds_instance_name = "postgresql-example" - performance_insights_enabled = true - enhanced_monitoring_name = "postgresql-example-enhanced-monitoring" - enhanced_monitoring_arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" - rds_instance_database_name = "arc" - rds_instance_database_user = "example_db_admin" - - rds_instance_security_group_ids = data.aws_security_groups.db_sg.ids - rds_instance_allowed_cidr_blocks = [data.aws_vpc.vpc.cidr_block] - rds_instance_subnet_ids = data.aws_subnets.private.ids - additional_ingress_rules_rds = var.additional_ingress_rules_rds -} diff --git a/example/variables.tf b/example/variables.tf deleted file mode 100644 index a76895f..0000000 --- a/example/variables.tf +++ /dev/null @@ -1,54 +0,0 @@ -################################################################################ -## shared -################################################################################ -variable "region" { - type = string - default = "us-east-1" - description = "AWS region" -} - -variable "environment" { - type = string - default = "poc" - description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" -} - -variable "namespace" { - type = string - default = "arc" - description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" -} - -variable "kms_alias_name" { - type = string - description = "Name of the KMS alias" - default = "alias/arc-poc-aurora-cluster-kms-key" -} - -variable "additional_ingress_rules_aurora" { - description = "Additional ingress rules for Aurora" - type = list(object({ - name = string - description = string - type = string - from_port = number - to_port = number - protocol = string - cidr_blocks = list(string) - })) - default = [] -} - -variable "additional_ingress_rules_rds" { - description = "Additional ingress rules for RDS" - type = list(object({ - name = string - description = string - type = string - from_port = number - to_port = number - protocol = string - cidr_blocks = list(string) - })) - default = [] -} diff --git a/example/.terraform-version b/examples/aurora-serverless/.terraform-version similarity index 100% rename from example/.terraform-version rename to examples/aurora-serverless/.terraform-version diff --git a/examples/aurora-serverless/.terraform.lock.hcl b/examples/aurora-serverless/.terraform.lock.hcl new file mode 100644 index 0000000..30c9869 --- /dev/null +++ b/examples/aurora-serverless/.terraform.lock.hcl @@ -0,0 +1,65 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.74.0" + constraints = ">= 4.0.0, ~> 5.0, < 6.0.0" + hashes = [ + "h1:0Iq3x8RSdWedvATBO1RZbCQqRCHPNsdhkYVrRs9crEE=", + "zh:1e2d65add4d63af5b396ae33d55c48303eca6c86bd1be0f6fae13267a9b47bc4", + "zh:20ddec3dac3d06a188f12e58b6428854949b1295e937c5d4dca4866dc1c937af", + "zh:35b72de4e6a3e3d69efc07184fb413406262fe447b2d82d57eaf8c787a068a06", + "zh:44eada24a50cd869aadc4b29f9e791fdf262d7f426921e9ac2893bbb86013176", + "zh:455e666e3a9a2312b3b9f434b87a404b6515d64a8853751e20566a6548f9df9e", + "zh:58b3ae74abfca7b9b61f42f0c8b10d97f9b01aff18bd1d4ab091129c9d203707", + "zh:840a8a32d5923f9e7422f9c80d165c3f89bb6ea370b8283095081e39050a8ea8", + "zh:87cb6dbbdbc1b73bdde4b8b5d6d780914a3e8f1df0385da4ea7323dc1a68468f", + "zh:8b8953e39b0e6e6156c5570d1ca653450bfa0d9b280e2475f01ee5c51a6554db", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9bd750262e2fb0187a8420a561e55b0a1da738f690f53f5c7df170cb1f380459", + "zh:9d2474c1432dfa5e1db197e2dd6cd61a6a15452e0bc7acd09ca86b3cdb228871", + "zh:b763ecaf471c7737a5c6e4cf257b5318e922a6610fd83b36ed8eb68582a8642e", + "zh:c1344cd8fe03ff7433a19b14b14a1898c2ca5ba22a468fb8e1687f0a7f564d52", + "zh:dc0e0abf3be7402d0d022ced82816884356115ed27646df9c7222609e96840e6", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.3" + constraints = ">= 3.1.0" + hashes = [ + "h1:I0Um8UkrMUb81Fxq/dxbr3HLP2cecTH2WMJiwKSrwQY=", + "zh:22d062e5278d872fe7aed834f5577ba0a5afe34a3bdac2b81f828d8d3e6706d2", + "zh:23dead00493ad863729495dc212fd6c29b8293e707b055ce5ba21ee453ce552d", + "zh:28299accf21763ca1ca144d8f660688d7c2ad0b105b7202554ca60b02a3856d3", + "zh:55c9e8a9ac25a7652df8c51a8a9a422bd67d784061b1de2dc9fe6c3cb4e77f2f", + "zh:756586535d11698a216291c06b9ed8a5cc6a4ec43eee1ee09ecd5c6a9e297ac1", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:9d5eea62fdb587eeb96a8c4d782459f4e6b73baeece4d04b4a40e44faaee9301", + "zh:a6355f596a3fb8fc85c2fb054ab14e722991533f87f928e7169a486462c74670", + "zh:b5a65a789cff4ada58a5baffc76cb9767dc26ec6b45c00d2ec8b1b027f6db4ed", + "zh:db5ab669cf11d0e9f81dc380a6fdfcac437aea3d69109c7aef1a5426639d2d65", + "zh:de655d251c470197bcbb5ac45d289595295acb8f829f6c781d4a75c8c8b7c7dd", + "zh:f5c68199f2e6076bce92a12230434782bf768103a427e9bb9abee99b116af7b5", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.6.3" + constraints = ">= 3.4.0" + hashes = [ + "h1:zG9uFP8l9u+yGZZvi5Te7PV62j50azpgwPunq2vTm1E=", + "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", + "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", + "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe", + "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1", + "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36", + "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30", + "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615", + "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad", + "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556", + "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0", + ] +} diff --git a/examples/aurora-serverless/README.md b/examples/aurora-serverless/README.md new file mode 100644 index 0000000..67f97d8 --- /dev/null +++ b/examples/aurora-serverless/README.md @@ -0,0 +1,50 @@ + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~> 1.3, < 2.0.0 | +| [aws](#requirement\_aws) | >= 4.0, < 6.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.74.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [aurora](#module\_aurora) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_subnets.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | +| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `"poc"` | no | +| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `"arc"` | no | +| [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | Instance or Cluster ARN | +| [database](#output\_database) | Database name | +| [endpoint](#output\_endpoint) | Instance or Cluster Endpoint | +| [id](#output\_id) | Instance or Cluster ID | +| [identifier](#output\_identifier) | Instance or Cluster Identifier | +| [kms\_key\_id](#output\_kms\_key\_id) | Instance or Cluster KMS Key ID | +| [monitoring\_role\_arn](#output\_monitoring\_role\_arn) | Instance or Cluster Monitoring Role ARN | +| [performance\_insights\_kms\_key\_id](#output\_performance\_insights\_kms\_key\_id) | Instance or Cluster Performance Insights KMS Key ID | +| [port](#output\_port) | Database server port | +| [username](#output\_username) | Username for the Database | + diff --git a/example/data.tf b/examples/aurora-serverless/data.tf similarity index 51% rename from example/data.tf rename to examples/aurora-serverless/data.tf index 7e5ae7c..4fca06e 100644 --- a/example/data.tf +++ b/examples/aurora-serverless/data.tf @@ -11,28 +11,14 @@ data "aws_vpc" "vpc" { ## network data "aws_subnets" "private" { + filter { + name = "vpc-id" + values = [data.aws_vpc.vpc.id] + } filter { name = "tag:Name" values = [ - "${var.namespace}-${var.environment}-private-subnet-private-${var.region}a", - "${var.namespace}-${var.environment}-private-subnet-private-${var.region}b" + "*private*" ] } } - -## security -data "aws_security_groups" "db_sg" { - filter { - name = "group-name" - values = ["example-${var.environment}-db-sg"] - } - - filter { - name = "vpc-id" - values = [data.aws_vpc.vpc.id] - } -} - -data "aws_kms_alias" "aurora_cluster_kms_arn" { - name = var.kms_alias_name -} diff --git a/examples/aurora-serverless/main.tf b/examples/aurora-serverless/main.tf new file mode 100644 index 0000000..b6f17db --- /dev/null +++ b/examples/aurora-serverless/main.tf @@ -0,0 +1,93 @@ +################################################################################ +## defaults +################################################################################ +terraform { + required_version = "~> 1.3, < 2.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0, < 6.0" + } + } +} + +provider "aws" { + region = var.region +} + +locals { + rds_security_group_data = { + create = true + description = "Security Group for RDS Cluster" + + ingress_rules = [ + { + description = "Allow traffic from local network" + cidr_block = data.aws_vpc.vpc.cidr_block + from_port = 5432 + ip_protocol = "tcp" + to_port = 5432 + } + ] + + egress_rules = [ + { + description = "Allow all outbound traffic" + cidr_block = "0.0.0.0/0" + from_port = -1 + ip_protocol = "-1" + to_port = -1 + } + ] + } + +} + +module "aurora" { + source = "../../" + + environment = var.environment + namespace = var.namespace + vpc_id = data.aws_vpc.vpc.id + + name = "${var.namespace}-${var.environment}-aurora-serverless" + engine_type = "cluster" + port = 5432 + username = "postgres" + engine = "aurora-postgresql" + engine_version = "16.2" + engine_mode = "serverless" + + license_model = "postgresql-license" + rds_cluster_instances = [ + { + instance_class = "db.serverless" + db_parameter_group_name = "default.aurora-postgresql16" + apply_immediately = true + promotion_tier = 1 + } + ] + + serverlessv2_scaling_config = { + max_capacity = 1.0 + min_capacity = 0.5 + } + + db_subnet_group_data = { + name = "${var.namespace}-${var.environment}-subnet-group" + create = true + description = "Subnet group for rds instance" + subnet_ids = data.aws_subnets.private.ids + } + + performance_insights_enabled = true + + kms_data = { + create = true + description = "KMS for Performance insight and storage" + deletion_window_in_days = 7 + enable_key_rotation = true + } + security_group_data = local.rds_security_group_data +} diff --git a/examples/aurora-serverless/output.tf b/examples/aurora-serverless/output.tf new file mode 100644 index 0000000..3e50a17 --- /dev/null +++ b/examples/aurora-serverless/output.tf @@ -0,0 +1,49 @@ +output "id" { + value = module.aurora.id + description = "Instance or Cluster ID" +} + +output "identifier" { + value = module.aurora.identifier + description = "Instance or Cluster Identifier" +} + +output "arn" { + value = module.aurora.arn + description = "Instance or Cluster ARN" +} + +output "username" { + value = module.aurora.username + description = "Username for the Database" +} + +output "database" { + value = module.aurora.database + description = "Database name" +} + +output "port" { + value = module.aurora.port + description = "Database server port" +} + +output "endpoint" { + value = module.aurora.endpoint + description = "Instance or Cluster Endpoint" +} + +output "kms_key_id" { + value = module.aurora.kms_key_id + description = "Instance or Cluster KMS Key ID" +} + +output "performance_insights_kms_key_id" { + value = module.aurora.performance_insights_kms_key_id + description = "Instance or Cluster Performance Insights KMS Key ID" +} + +output "monitoring_role_arn" { + value = module.aurora.monitoring_role_arn + description = "Instance or Cluster Monitoring Role ARN" +} diff --git a/examples/aurora-serverless/variables.tf b/examples/aurora-serverless/variables.tf new file mode 100644 index 0000000..8e65782 --- /dev/null +++ b/examples/aurora-serverless/variables.tf @@ -0,0 +1,20 @@ +################################################################################ +## shared +################################################################################ +variable "region" { + type = string + default = "us-east-1" + description = "AWS region" +} + +variable "environment" { + type = string + default = "poc" + description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" +} + +variable "namespace" { + type = string + default = "arc" + description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" +} diff --git a/examples/aurora/.terraform-version b/examples/aurora/.terraform-version new file mode 100644 index 0000000..7324740 --- /dev/null +++ b/examples/aurora/.terraform-version @@ -0,0 +1 @@ +latest:^1.7 diff --git a/examples/aurora/.terraform.lock.hcl b/examples/aurora/.terraform.lock.hcl new file mode 100644 index 0000000..30c9869 --- /dev/null +++ b/examples/aurora/.terraform.lock.hcl @@ -0,0 +1,65 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.74.0" + constraints = ">= 4.0.0, ~> 5.0, < 6.0.0" + hashes = [ + "h1:0Iq3x8RSdWedvATBO1RZbCQqRCHPNsdhkYVrRs9crEE=", + "zh:1e2d65add4d63af5b396ae33d55c48303eca6c86bd1be0f6fae13267a9b47bc4", + "zh:20ddec3dac3d06a188f12e58b6428854949b1295e937c5d4dca4866dc1c937af", + "zh:35b72de4e6a3e3d69efc07184fb413406262fe447b2d82d57eaf8c787a068a06", + "zh:44eada24a50cd869aadc4b29f9e791fdf262d7f426921e9ac2893bbb86013176", + "zh:455e666e3a9a2312b3b9f434b87a404b6515d64a8853751e20566a6548f9df9e", + "zh:58b3ae74abfca7b9b61f42f0c8b10d97f9b01aff18bd1d4ab091129c9d203707", + "zh:840a8a32d5923f9e7422f9c80d165c3f89bb6ea370b8283095081e39050a8ea8", + "zh:87cb6dbbdbc1b73bdde4b8b5d6d780914a3e8f1df0385da4ea7323dc1a68468f", + "zh:8b8953e39b0e6e6156c5570d1ca653450bfa0d9b280e2475f01ee5c51a6554db", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9bd750262e2fb0187a8420a561e55b0a1da738f690f53f5c7df170cb1f380459", + "zh:9d2474c1432dfa5e1db197e2dd6cd61a6a15452e0bc7acd09ca86b3cdb228871", + "zh:b763ecaf471c7737a5c6e4cf257b5318e922a6610fd83b36ed8eb68582a8642e", + "zh:c1344cd8fe03ff7433a19b14b14a1898c2ca5ba22a468fb8e1687f0a7f564d52", + "zh:dc0e0abf3be7402d0d022ced82816884356115ed27646df9c7222609e96840e6", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.3" + constraints = ">= 3.1.0" + hashes = [ + "h1:I0Um8UkrMUb81Fxq/dxbr3HLP2cecTH2WMJiwKSrwQY=", + "zh:22d062e5278d872fe7aed834f5577ba0a5afe34a3bdac2b81f828d8d3e6706d2", + "zh:23dead00493ad863729495dc212fd6c29b8293e707b055ce5ba21ee453ce552d", + "zh:28299accf21763ca1ca144d8f660688d7c2ad0b105b7202554ca60b02a3856d3", + "zh:55c9e8a9ac25a7652df8c51a8a9a422bd67d784061b1de2dc9fe6c3cb4e77f2f", + "zh:756586535d11698a216291c06b9ed8a5cc6a4ec43eee1ee09ecd5c6a9e297ac1", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:9d5eea62fdb587eeb96a8c4d782459f4e6b73baeece4d04b4a40e44faaee9301", + "zh:a6355f596a3fb8fc85c2fb054ab14e722991533f87f928e7169a486462c74670", + "zh:b5a65a789cff4ada58a5baffc76cb9767dc26ec6b45c00d2ec8b1b027f6db4ed", + "zh:db5ab669cf11d0e9f81dc380a6fdfcac437aea3d69109c7aef1a5426639d2d65", + "zh:de655d251c470197bcbb5ac45d289595295acb8f829f6c781d4a75c8c8b7c7dd", + "zh:f5c68199f2e6076bce92a12230434782bf768103a427e9bb9abee99b116af7b5", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.6.3" + constraints = ">= 3.4.0" + hashes = [ + "h1:zG9uFP8l9u+yGZZvi5Te7PV62j50azpgwPunq2vTm1E=", + "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", + "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", + "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe", + "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1", + "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36", + "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30", + "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615", + "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad", + "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556", + "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0", + ] +} diff --git a/examples/aurora/README.md b/examples/aurora/README.md new file mode 100644 index 0000000..67f97d8 --- /dev/null +++ b/examples/aurora/README.md @@ -0,0 +1,50 @@ + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~> 1.3, < 2.0.0 | +| [aws](#requirement\_aws) | >= 4.0, < 6.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.74.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [aurora](#module\_aurora) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_subnets.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | +| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `"poc"` | no | +| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `"arc"` | no | +| [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | Instance or Cluster ARN | +| [database](#output\_database) | Database name | +| [endpoint](#output\_endpoint) | Instance or Cluster Endpoint | +| [id](#output\_id) | Instance or Cluster ID | +| [identifier](#output\_identifier) | Instance or Cluster Identifier | +| [kms\_key\_id](#output\_kms\_key\_id) | Instance or Cluster KMS Key ID | +| [monitoring\_role\_arn](#output\_monitoring\_role\_arn) | Instance or Cluster Monitoring Role ARN | +| [performance\_insights\_kms\_key\_id](#output\_performance\_insights\_kms\_key\_id) | Instance or Cluster Performance Insights KMS Key ID | +| [port](#output\_port) | Database server port | +| [username](#output\_username) | Username for the Database | + diff --git a/examples/aurora/data.tf b/examples/aurora/data.tf new file mode 100644 index 0000000..4fca06e --- /dev/null +++ b/examples/aurora/data.tf @@ -0,0 +1,24 @@ +################################################ +## imports +################################################ +## vpc +data "aws_vpc" "vpc" { + filter { + name = "tag:Name" + values = ["${var.namespace}-${var.environment}-vpc"] + } +} + +## network +data "aws_subnets" "private" { + filter { + name = "vpc-id" + values = [data.aws_vpc.vpc.id] + } + filter { + name = "tag:Name" + values = [ + "*private*" + ] + } +} diff --git a/examples/aurora/main.tf b/examples/aurora/main.tf new file mode 100644 index 0000000..d8cabfc --- /dev/null +++ b/examples/aurora/main.tf @@ -0,0 +1,58 @@ +################################################################################ +## defaults +################################################################################ +terraform { + required_version = "~> 1.3, < 2.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0, < 6.0" + } + } +} + +provider "aws" { + region = var.region +} + +module "aurora" { + source = "../../" + + environment = var.environment + namespace = var.namespace + vpc_id = data.aws_vpc.vpc.id + + name = "${var.namespace}-${var.environment}-test" + engine_type = "cluster" + port = 5432 + username = "postgres" + engine = "aurora-postgresql" + engine_version = "16.2" + + license_model = "postgresql-license" + rds_cluster_instances = [ + { + instance_class = "db.t3.medium" + db_parameter_group_name = "default.aurora-postgresql16" + apply_immediately = true + promotion_tier = 1 + } + ] + + db_subnet_group_data = { + name = "${var.namespace}-${var.environment}-subnet-group" + create = true + description = "Subnet group for rds instance" + subnet_ids = data.aws_subnets.private.ids + } + + performance_insights_enabled = true + + kms_data = { + create = true + description = "KMS for Performance insight and storage" + deletion_window_in_days = 7 + enable_key_rotation = true + } +} diff --git a/examples/aurora/output.tf b/examples/aurora/output.tf new file mode 100644 index 0000000..3e50a17 --- /dev/null +++ b/examples/aurora/output.tf @@ -0,0 +1,49 @@ +output "id" { + value = module.aurora.id + description = "Instance or Cluster ID" +} + +output "identifier" { + value = module.aurora.identifier + description = "Instance or Cluster Identifier" +} + +output "arn" { + value = module.aurora.arn + description = "Instance or Cluster ARN" +} + +output "username" { + value = module.aurora.username + description = "Username for the Database" +} + +output "database" { + value = module.aurora.database + description = "Database name" +} + +output "port" { + value = module.aurora.port + description = "Database server port" +} + +output "endpoint" { + value = module.aurora.endpoint + description = "Instance or Cluster Endpoint" +} + +output "kms_key_id" { + value = module.aurora.kms_key_id + description = "Instance or Cluster KMS Key ID" +} + +output "performance_insights_kms_key_id" { + value = module.aurora.performance_insights_kms_key_id + description = "Instance or Cluster Performance Insights KMS Key ID" +} + +output "monitoring_role_arn" { + value = module.aurora.monitoring_role_arn + description = "Instance or Cluster Monitoring Role ARN" +} diff --git a/examples/aurora/variables.tf b/examples/aurora/variables.tf new file mode 100644 index 0000000..8e65782 --- /dev/null +++ b/examples/aurora/variables.tf @@ -0,0 +1,20 @@ +################################################################################ +## shared +################################################################################ +variable "region" { + type = string + default = "us-east-1" + description = "AWS region" +} + +variable "environment" { + type = string + default = "poc" + description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" +} + +variable "namespace" { + type = string + default = "arc" + description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" +} diff --git a/examples/rds-proxy/.terraform-version b/examples/rds-proxy/.terraform-version new file mode 100644 index 0000000..7324740 --- /dev/null +++ b/examples/rds-proxy/.terraform-version @@ -0,0 +1 @@ +latest:^1.7 diff --git a/examples/rds-proxy/.terraform.lock.hcl b/examples/rds-proxy/.terraform.lock.hcl new file mode 100644 index 0000000..30c9869 --- /dev/null +++ b/examples/rds-proxy/.terraform.lock.hcl @@ -0,0 +1,65 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.74.0" + constraints = ">= 4.0.0, ~> 5.0, < 6.0.0" + hashes = [ + "h1:0Iq3x8RSdWedvATBO1RZbCQqRCHPNsdhkYVrRs9crEE=", + "zh:1e2d65add4d63af5b396ae33d55c48303eca6c86bd1be0f6fae13267a9b47bc4", + "zh:20ddec3dac3d06a188f12e58b6428854949b1295e937c5d4dca4866dc1c937af", + "zh:35b72de4e6a3e3d69efc07184fb413406262fe447b2d82d57eaf8c787a068a06", + "zh:44eada24a50cd869aadc4b29f9e791fdf262d7f426921e9ac2893bbb86013176", + "zh:455e666e3a9a2312b3b9f434b87a404b6515d64a8853751e20566a6548f9df9e", + "zh:58b3ae74abfca7b9b61f42f0c8b10d97f9b01aff18bd1d4ab091129c9d203707", + "zh:840a8a32d5923f9e7422f9c80d165c3f89bb6ea370b8283095081e39050a8ea8", + "zh:87cb6dbbdbc1b73bdde4b8b5d6d780914a3e8f1df0385da4ea7323dc1a68468f", + "zh:8b8953e39b0e6e6156c5570d1ca653450bfa0d9b280e2475f01ee5c51a6554db", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9bd750262e2fb0187a8420a561e55b0a1da738f690f53f5c7df170cb1f380459", + "zh:9d2474c1432dfa5e1db197e2dd6cd61a6a15452e0bc7acd09ca86b3cdb228871", + "zh:b763ecaf471c7737a5c6e4cf257b5318e922a6610fd83b36ed8eb68582a8642e", + "zh:c1344cd8fe03ff7433a19b14b14a1898c2ca5ba22a468fb8e1687f0a7f564d52", + "zh:dc0e0abf3be7402d0d022ced82816884356115ed27646df9c7222609e96840e6", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.3" + constraints = ">= 3.1.0" + hashes = [ + "h1:I0Um8UkrMUb81Fxq/dxbr3HLP2cecTH2WMJiwKSrwQY=", + "zh:22d062e5278d872fe7aed834f5577ba0a5afe34a3bdac2b81f828d8d3e6706d2", + "zh:23dead00493ad863729495dc212fd6c29b8293e707b055ce5ba21ee453ce552d", + "zh:28299accf21763ca1ca144d8f660688d7c2ad0b105b7202554ca60b02a3856d3", + "zh:55c9e8a9ac25a7652df8c51a8a9a422bd67d784061b1de2dc9fe6c3cb4e77f2f", + "zh:756586535d11698a216291c06b9ed8a5cc6a4ec43eee1ee09ecd5c6a9e297ac1", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:9d5eea62fdb587eeb96a8c4d782459f4e6b73baeece4d04b4a40e44faaee9301", + "zh:a6355f596a3fb8fc85c2fb054ab14e722991533f87f928e7169a486462c74670", + "zh:b5a65a789cff4ada58a5baffc76cb9767dc26ec6b45c00d2ec8b1b027f6db4ed", + "zh:db5ab669cf11d0e9f81dc380a6fdfcac437aea3d69109c7aef1a5426639d2d65", + "zh:de655d251c470197bcbb5ac45d289595295acb8f829f6c781d4a75c8c8b7c7dd", + "zh:f5c68199f2e6076bce92a12230434782bf768103a427e9bb9abee99b116af7b5", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.6.3" + constraints = ">= 3.4.0" + hashes = [ + "h1:zG9uFP8l9u+yGZZvi5Te7PV62j50azpgwPunq2vTm1E=", + "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", + "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", + "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe", + "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1", + "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36", + "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30", + "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615", + "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad", + "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556", + "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0", + ] +} diff --git a/examples/rds-proxy/README.md b/examples/rds-proxy/README.md new file mode 100644 index 0000000..6cf2958 --- /dev/null +++ b/examples/rds-proxy/README.md @@ -0,0 +1,50 @@ + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~> 1.3, < 2.0.0 | +| [aws](#requirement\_aws) | >= 4.0, < 6.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.74.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [rds](#module\_rds) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_subnets.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | +| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `"poc"` | no | +| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `"arc"` | no | +| [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | Instance or Cluster ARN | +| [database](#output\_database) | Database name | +| [endpoint](#output\_endpoint) | Instance or Cluster Endpoint | +| [id](#output\_id) | Instance or Cluster ID | +| [identifier](#output\_identifier) | Instance or Cluster Identifier | +| [kms\_key\_id](#output\_kms\_key\_id) | Instance or Cluster KMS Key ID | +| [monitoring\_role\_arn](#output\_monitoring\_role\_arn) | Instance or Cluster Monitoring Role ARN | +| [performance\_insights\_kms\_key\_id](#output\_performance\_insights\_kms\_key\_id) | Instance or Cluster Performance Insights KMS Key ID | +| [port](#output\_port) | Database server port | +| [username](#output\_username) | Username for the Database | + diff --git a/examples/rds-proxy/data.tf b/examples/rds-proxy/data.tf new file mode 100644 index 0000000..4fca06e --- /dev/null +++ b/examples/rds-proxy/data.tf @@ -0,0 +1,24 @@ +################################################ +## imports +################################################ +## vpc +data "aws_vpc" "vpc" { + filter { + name = "tag:Name" + values = ["${var.namespace}-${var.environment}-vpc"] + } +} + +## network +data "aws_subnets" "private" { + filter { + name = "vpc-id" + values = [data.aws_vpc.vpc.id] + } + filter { + name = "tag:Name" + values = [ + "*private*" + ] + } +} diff --git a/examples/rds-proxy/main.tf b/examples/rds-proxy/main.tf new file mode 100644 index 0000000..3d1b6e7 --- /dev/null +++ b/examples/rds-proxy/main.tf @@ -0,0 +1,142 @@ +################################################################################ +## defaults +################################################################################ +terraform { + required_version = "~> 1.3, < 2.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0, < 6.0" + } + } +} + +provider "aws" { + region = var.region +} + +locals { + rds_security_group_data = { + create = true + description = "Security Group for RDS instance" + + ingress_rules = [ + { + description = "Allow traffic from local network" + cidr_block = data.aws_vpc.vpc.cidr_block + from_port = 5432 + ip_protocol = "tcp" + to_port = 5432 + } + ] + + egress_rules = [ + { + description = "Allow all outbound traffic" + cidr_block = "0.0.0.0/0" + from_port = -1 + ip_protocol = "-1" + to_port = -1 + } + ] + } + + proxy_security_group_data = { + create = true + description = "Security Group for RDS Proxy" + + ingress_rules = [ + { + description = "Allow traffic from local network" + cidr_block = data.aws_vpc.vpc.cidr_block + from_port = 5432 + ip_protocol = "tcp" + to_port = 5432 + } + ] + + egress_rules = [ + { + description = "Allow all outbound traffic" + cidr_block = "0.0.0.0/0" + from_port = -1 + ip_protocol = "-1" + to_port = -1 + } + ] + } + + + parameter_group_config = { + create = true + family = "postgres16" + parameters = { + "paramter-1" = { + name = "log_connections" + value = "1" + } } + } + +} + +module "rds" { + source = "../../" + + environment = var.environment + namespace = var.namespace + vpc_id = data.aws_vpc.vpc.id + + name = "${var.namespace}-${var.environment}-test-proxy-2" + engine_type = "rds" + db_server_class = "db.t3.small" + port = 5432 + username = "postgres" + engine = "postgres" + engine_version = "16.3" + + monitoring_interval = 60 + license_model = "postgresql-license" + db_subnet_group_data = { + name = "${var.namespace}-${var.environment}-subnet-group-proxy" + create = true + description = "Subnet group for rds instance" + subnet_ids = data.aws_subnets.private.ids + } + + performance_insights_enabled = true + + kms_data = { + create = true + description = "KMS for Performance insight and storage" + deletion_window_in_days = 7 + enable_key_rotation = true + } + + parameter_group_config = local.parameter_group_config + security_group_data = local.rds_security_group_data + + proxy_config = { + create = true + engine_family = "POSTGRESQL" + vpc_subnet_ids = data.aws_subnets.private.ids + security_group_data = local.proxy_security_group_data + require_tls = true + debug_logging = true + idle_client_timeout_secs = 3600 # 1 hour + + auth = { + auth_scheme = "SECRETS" + description = "Authentication for RDS Proxy" + iam_auth = "DISABLED" // REQUIRED + client_password_auth_type = "POSTGRES_SCRAM_SHA_256" + } + + additional_auth_list = [] + + connection_pool_config = { + max_connections_percent = 100 + max_idle_connections_percent = 50 + } + } +} diff --git a/examples/rds-proxy/output.tf b/examples/rds-proxy/output.tf new file mode 100644 index 0000000..3b64723 --- /dev/null +++ b/examples/rds-proxy/output.tf @@ -0,0 +1,49 @@ +output "id" { + value = module.rds.id + description = "Instance or Cluster ID" +} + +output "identifier" { + value = module.rds.identifier + description = "Instance or Cluster Identifier" +} + +output "arn" { + value = module.rds.arn + description = "Instance or Cluster ARN" +} + +output "username" { + value = module.rds.username + description = "Username for the Database" +} + +output "database" { + value = module.rds.database + description = "Database name" +} + +output "port" { + value = module.rds.port + description = "Database server port" +} + +output "endpoint" { + value = module.rds.endpoint + description = "Instance or Cluster Endpoint" +} + +output "kms_key_id" { + value = module.rds.kms_key_id + description = "Instance or Cluster KMS Key ID" +} + +output "performance_insights_kms_key_id" { + value = module.rds.performance_insights_kms_key_id + description = "Instance or Cluster Performance Insights KMS Key ID" +} + +output "monitoring_role_arn" { + value = module.rds.monitoring_role_arn + description = "Instance or Cluster Monitoring Role ARN" +} diff --git a/examples/rds-proxy/variables.tf b/examples/rds-proxy/variables.tf new file mode 100644 index 0000000..8e65782 --- /dev/null +++ b/examples/rds-proxy/variables.tf @@ -0,0 +1,20 @@ +################################################################################ +## shared +################################################################################ +variable "region" { + type = string + default = "us-east-1" + description = "AWS region" +} + +variable "environment" { + type = string + default = "poc" + description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" +} + +variable "namespace" { + type = string + default = "arc" + description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" +} diff --git a/examples/rds/.terraform-version b/examples/rds/.terraform-version new file mode 100644 index 0000000..7324740 --- /dev/null +++ b/examples/rds/.terraform-version @@ -0,0 +1 @@ +latest:^1.7 diff --git a/examples/rds/.terraform.lock.hcl b/examples/rds/.terraform.lock.hcl new file mode 100644 index 0000000..30c9869 --- /dev/null +++ b/examples/rds/.terraform.lock.hcl @@ -0,0 +1,65 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.74.0" + constraints = ">= 4.0.0, ~> 5.0, < 6.0.0" + hashes = [ + "h1:0Iq3x8RSdWedvATBO1RZbCQqRCHPNsdhkYVrRs9crEE=", + "zh:1e2d65add4d63af5b396ae33d55c48303eca6c86bd1be0f6fae13267a9b47bc4", + "zh:20ddec3dac3d06a188f12e58b6428854949b1295e937c5d4dca4866dc1c937af", + "zh:35b72de4e6a3e3d69efc07184fb413406262fe447b2d82d57eaf8c787a068a06", + "zh:44eada24a50cd869aadc4b29f9e791fdf262d7f426921e9ac2893bbb86013176", + "zh:455e666e3a9a2312b3b9f434b87a404b6515d64a8853751e20566a6548f9df9e", + "zh:58b3ae74abfca7b9b61f42f0c8b10d97f9b01aff18bd1d4ab091129c9d203707", + "zh:840a8a32d5923f9e7422f9c80d165c3f89bb6ea370b8283095081e39050a8ea8", + "zh:87cb6dbbdbc1b73bdde4b8b5d6d780914a3e8f1df0385da4ea7323dc1a68468f", + "zh:8b8953e39b0e6e6156c5570d1ca653450bfa0d9b280e2475f01ee5c51a6554db", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9bd750262e2fb0187a8420a561e55b0a1da738f690f53f5c7df170cb1f380459", + "zh:9d2474c1432dfa5e1db197e2dd6cd61a6a15452e0bc7acd09ca86b3cdb228871", + "zh:b763ecaf471c7737a5c6e4cf257b5318e922a6610fd83b36ed8eb68582a8642e", + "zh:c1344cd8fe03ff7433a19b14b14a1898c2ca5ba22a468fb8e1687f0a7f564d52", + "zh:dc0e0abf3be7402d0d022ced82816884356115ed27646df9c7222609e96840e6", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.3" + constraints = ">= 3.1.0" + hashes = [ + "h1:I0Um8UkrMUb81Fxq/dxbr3HLP2cecTH2WMJiwKSrwQY=", + "zh:22d062e5278d872fe7aed834f5577ba0a5afe34a3bdac2b81f828d8d3e6706d2", + "zh:23dead00493ad863729495dc212fd6c29b8293e707b055ce5ba21ee453ce552d", + "zh:28299accf21763ca1ca144d8f660688d7c2ad0b105b7202554ca60b02a3856d3", + "zh:55c9e8a9ac25a7652df8c51a8a9a422bd67d784061b1de2dc9fe6c3cb4e77f2f", + "zh:756586535d11698a216291c06b9ed8a5cc6a4ec43eee1ee09ecd5c6a9e297ac1", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:9d5eea62fdb587eeb96a8c4d782459f4e6b73baeece4d04b4a40e44faaee9301", + "zh:a6355f596a3fb8fc85c2fb054ab14e722991533f87f928e7169a486462c74670", + "zh:b5a65a789cff4ada58a5baffc76cb9767dc26ec6b45c00d2ec8b1b027f6db4ed", + "zh:db5ab669cf11d0e9f81dc380a6fdfcac437aea3d69109c7aef1a5426639d2d65", + "zh:de655d251c470197bcbb5ac45d289595295acb8f829f6c781d4a75c8c8b7c7dd", + "zh:f5c68199f2e6076bce92a12230434782bf768103a427e9bb9abee99b116af7b5", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.6.3" + constraints = ">= 3.4.0" + hashes = [ + "h1:zG9uFP8l9u+yGZZvi5Te7PV62j50azpgwPunq2vTm1E=", + "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", + "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", + "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe", + "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1", + "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36", + "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30", + "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615", + "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad", + "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556", + "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0", + ] +} diff --git a/examples/rds/README.md b/examples/rds/README.md new file mode 100644 index 0000000..6cf2958 --- /dev/null +++ b/examples/rds/README.md @@ -0,0 +1,50 @@ + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~> 1.3, < 2.0.0 | +| [aws](#requirement\_aws) | >= 4.0, < 6.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.74.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [rds](#module\_rds) | ../../ | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_subnets.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | +| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `"poc"` | no | +| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `"arc"` | no | +| [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | Instance or Cluster ARN | +| [database](#output\_database) | Database name | +| [endpoint](#output\_endpoint) | Instance or Cluster Endpoint | +| [id](#output\_id) | Instance or Cluster ID | +| [identifier](#output\_identifier) | Instance or Cluster Identifier | +| [kms\_key\_id](#output\_kms\_key\_id) | Instance or Cluster KMS Key ID | +| [monitoring\_role\_arn](#output\_monitoring\_role\_arn) | Instance or Cluster Monitoring Role ARN | +| [performance\_insights\_kms\_key\_id](#output\_performance\_insights\_kms\_key\_id) | Instance or Cluster Performance Insights KMS Key ID | +| [port](#output\_port) | Database server port | +| [username](#output\_username) | Username for the Database | + diff --git a/examples/rds/data.tf b/examples/rds/data.tf new file mode 100644 index 0000000..c24a28d --- /dev/null +++ b/examples/rds/data.tf @@ -0,0 +1,20 @@ +################################################ +## imports +################################################ +## vpc +data "aws_vpc" "vpc" { + filter { + name = "tag:Name" + values = ["${var.namespace}-${var.environment}-vpc"] + } +} + +## network +data "aws_subnets" "private" { + filter { + name = "tag:Name" + values = [ + "*private*" + ] + } +} diff --git a/examples/rds/main.tf b/examples/rds/main.tf new file mode 100644 index 0000000..b51baba --- /dev/null +++ b/examples/rds/main.tf @@ -0,0 +1,80 @@ +################################################################################ +## defaults +################################################################################ +terraform { + required_version = "~> 1.3, < 2.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0, < 6.0" + } + } +} + +provider "aws" { + region = var.region +} + +locals { + rds_security_group_data = { + create = true + description = "Security Group for RDS instance" + + ingress_rules = [ + { + description = "Allow traffic from local network" + cidr_block = data.aws_vpc.vpc.cidr_block + from_port = 5432 + ip_protocol = "tcp" + to_port = 5432 + } + ] + + egress_rules = [ + { + description = "Allow all outbound traffic" + cidr_block = "0.0.0.0/0" + from_port = -1 + ip_protocol = "-1" + to_port = -1 + } + ] + } +} + +module "rds" { + source = "../../" + + environment = var.environment + namespace = var.namespace + vpc_id = data.aws_vpc.vpc.id + + name = "${var.namespace}-${var.environment}-test" + engine_type = "rds" + db_server_class = "db.t3.small" + port = 5432 + username = "postgres" + manage_user_password = true + engine = "postgres" + engine_version = "16.3" + + license_model = "postgresql-license" + db_subnet_group_data = { + name = "${var.namespace}-${var.environment}-subnet-group" + create = true + description = "Subnet group for rds instance" + subnet_ids = data.aws_subnets.private.ids + } + + security_group_data = local.rds_security_group_data + performance_insights_enabled = true + monitoring_interval = 5 + + kms_data = { + create = true + description = "KMS for Performance insight and storage" + deletion_window_in_days = 7 + enable_key_rotation = true + } +} diff --git a/examples/rds/output.tf b/examples/rds/output.tf new file mode 100644 index 0000000..3b64723 --- /dev/null +++ b/examples/rds/output.tf @@ -0,0 +1,49 @@ +output "id" { + value = module.rds.id + description = "Instance or Cluster ID" +} + +output "identifier" { + value = module.rds.identifier + description = "Instance or Cluster Identifier" +} + +output "arn" { + value = module.rds.arn + description = "Instance or Cluster ARN" +} + +output "username" { + value = module.rds.username + description = "Username for the Database" +} + +output "database" { + value = module.rds.database + description = "Database name" +} + +output "port" { + value = module.rds.port + description = "Database server port" +} + +output "endpoint" { + value = module.rds.endpoint + description = "Instance or Cluster Endpoint" +} + +output "kms_key_id" { + value = module.rds.kms_key_id + description = "Instance or Cluster KMS Key ID" +} + +output "performance_insights_kms_key_id" { + value = module.rds.performance_insights_kms_key_id + description = "Instance or Cluster Performance Insights KMS Key ID" +} + +output "monitoring_role_arn" { + value = module.rds.monitoring_role_arn + description = "Instance or Cluster Monitoring Role ARN" +} diff --git a/examples/rds/variables.tf b/examples/rds/variables.tf new file mode 100644 index 0000000..8e65782 --- /dev/null +++ b/examples/rds/variables.tf @@ -0,0 +1,20 @@ +################################################################################ +## shared +################################################################################ +variable "region" { + type = string + default = "us-east-1" + description = "AWS region" +} + +variable "environment" { + type = string + default = "poc" + description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" +} + +variable "namespace" { + type = string + default = "arc" + description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" +} diff --git a/locals.tf b/locals.tf index a64bb39..43ba6b0 100644 --- a/locals.tf +++ b/locals.tf @@ -1,65 +1,34 @@ locals { - ## option group - instance_kms_id = "arn:aws:kms:${var.region}:${var.account_id}:key/${try(aws_kms_key.aurora_cluster_kms_key[0].key_id, aws_kms_key.rds_db_kms_key[0].key_id)}" - s3_kms_alias = try(var.s3_kms_alias_override ? var.s3_kms_alias_override != "" : var.s3_kms_alias_override, "arn:aws:kms:${var.region}:${var.account_id}:alias/aws/s3") - rds_instance_option_group_name = length(aws_db_option_group.this) > 0 ? aws_db_option_group.this[0].name : var.rds_instance_option_group_name + prefix = "${var.namespace}-${var.environment}" + security_group_ids_to_attach = var.security_group_data.create ? concat(var.security_group_data.security_group_ids_to_attach, [module.security_group[0].id]) : var.security_group_data.security_group_ids_to_attach + proxy_security_group_ids_to_attach = var.proxy_config.security_group_data.create ? concat(var.proxy_config.security_group_data.security_group_ids_to_attach, [module.proxy_security_group[0].id]) : var.proxy_config.security_group_data.security_group_ids_to_attach + secret_arn = var.manage_user_password == true ? (var.engine_type == "rds" ? aws_db_instance.this[0].master_user_secret[0].secret_arn : aws_rds_cluster.this[0].master_user_secret[0].secret_arn) : (var.proxy_config.create ? aws_secretsmanager_secret.this[0].arn : null) - ## aurora - aurora_cluster_name = var.aurora_cluster_name_override == true ? var.aurora_cluster_name : "${var.namespace}-${var.environment}-${var.aurora_cluster_name}" - aurora_ssm_params = var.aurora_cluster_enabled == true ? [ - { - name = "/${var.namespace}/${var.environment}/${var.aurora_cluster_name}/cluster_admin_db_password" - value = random_password.aurora_db_admin_password[0].result - type = "SecureString" - }, - { - name = "/${var.namespace}/${var.environment}/${var.aurora_cluster_name}/cluster_admin_db_username" - value = var.aurora_db_admin_username - type = "SecureString" - }, - { - name = "/${var.namespace}/${var.environment}/${var.aurora_cluster_name}/cluster_endpoint" - value = module.aurora_cluster[0].endpoint - type = "SecureString" - } - ] : [] + additional_secret_arn_list = [for auth in var.proxy_config.additional_auth_list : auth.secret_arn if auth.secret_arn != null] - aurora_ssm_tags = var.aurora_cluster_enabled == true ? { - AuroraName = "${var.namespace}-${var.environment}-db-cluster-ssm-param" - } : {} + secret_arn_list = concat([local.secret_arn], local.additional_secret_arn_list) - ## rds - rds_instance_name = var.rds_instance_name_override == true ? var.rds_instance_name : "${var.namespace}-${var.environment}-${var.rds_instance_name}" - rds_instance_ssm_params = var.rds_instance_enabled == true ? [ - { - name = "/${var.namespace}/${var.environment}/${var.rds_instance_name}/admin_db_password" - value = random_password.rds_db_admin_password[0].result - type = "SecureString" - }, - { - name = "/${var.namespace}/${var.environment}/${var.rds_instance_name}/admin_db_username" - value = var.rds_instance_database_user - type = "SecureString" - }, - { - name = "/${var.namespace}/${var.environment}/${var.rds_instance_name}/endpoint" - value = module.rds_instance[0].instance_endpoint - type = "SecureString" - } - ] : [] + // Adds inbound rule to RDS , so that proxy will be able to connect to RDS instance/cluster + db_ingress_rules = var.proxy_config.create ? concat(var.security_group_data.ingress_rules, + [ + { + description = "Allow traffic from RDS Proxy security group" + source_security_group_id = module.proxy_security_group[0].id + from_port = var.port + ip_protocol = "tcp" + to_port = var.port + } + ] + ) : var.security_group_data.ingress_rules - rds_instance_ssm_tags = var.rds_instance_enabled == true ? { - RDSName = "${var.namespace}-${var.environment}-rds-instance-ssm-param" - } : {} - ## concat locals - ssm_params = concat( - local.aurora_ssm_params, - local.rds_instance_ssm_params, - ) + username = var.engine_type == "rds" ? aws_db_instance.this[0].username : aws_rds_cluster.this[0].master_username + password = var.engine_type == "rds" ? aws_db_instance.this[0].password : aws_rds_cluster.this[0].master_password + database = var.engine_type == "rds" ? aws_db_instance.this[0].db_name : aws_rds_cluster.this[0].database_name + port = var.engine_type == "rds" ? aws_db_instance.this[0].port : aws_rds_cluster.this[0].port - ssm_tags = merge( - local.aurora_ssm_tags, - local.rds_instance_ssm_tags, - ) + kms_key_id = var.kms_data.create ? aws_kms_alias.this[0].target_key_arn : (var.kms_data.kms_key_id == null ? data.aws_kms_alias.rds.target_key_arn : var.kms_data.kms_key_id) + performance_insights_kms_key_id = var.kms_data.create ? aws_kms_alias.this[0].target_key_arn : (var.kms_data.performance_insights_kms_key_id == null ? data.aws_kms_alias.rds.target_key_arn : var.kms_data.performance_insights_kms_key_id) + monitoring_role_arn = var.monitoring_interval > 0 ? (var.monitoring_role_arn == null ? aws_iam_role.enhanced_monitoring[0].arn : var.monitoring_role_arn) : null + endpoint = var.engine_type == "rds" ? aws_db_instance.this[0].endpoint : aws_rds_cluster.this[0].endpoint } diff --git a/main.tf b/main.tf index 994aff4..e85e6fc 100644 --- a/main.tf +++ b/main.tf @@ -1,454 +1,54 @@ ################################################################################ -## lookups -################################################################################ -data "aws_partition" "this" {} - -################################################################################ -## kms -################################################################################ -## aurora -// TODO: add alarms -resource "aws_kms_key" "aurora_cluster_kms_key" { - count = var.aurora_cluster_enabled == true ? 1 : 0 - - description = "Aurora cluster KMS key" - deletion_window_in_days = var.deletion_window_in_days - enable_key_rotation = var.enable_key_rotation - - tags = merge(var.tags, tomap({ - Name = "${var.namespace}-${var.environment}-aurora-cluster-kms-key" // TODO - add support for custom names - })) -} - -resource "aws_kms_alias" "aurora_cluster_kms_key" { - count = var.aurora_cluster_enabled == true ? 1 : 0 - - name = "alias/${var.namespace}-${var.environment}-aurora-cluster-kms-key" // TODO - add support for custom names - target_key_id = aws_kms_key.aurora_cluster_kms_key[0].id -} - -## rds -resource "aws_kms_key" "rds_db_kms_key" { - count = var.rds_instance_enabled == true ? 1 : 0 - - description = "RDS DB KMS key" - deletion_window_in_days = var.deletion_window_in_days - enable_key_rotation = var.enable_key_rotation - - tags = merge(var.tags, tomap({ - Name = "${var.namespace}-${var.environment}-${var.rds_instance_name}" - })) -} - -resource "aws_kms_alias" "rds_db_kms_key" { - count = var.rds_instance_enabled == true ? 1 : 0 - - name = "alias/${local.rds_instance_name}" - target_key_id = aws_kms_key.rds_db_kms_key[0].id -} - -################################################################################ -## iam -################################################################################ -# create IAM role for monitoring -resource "aws_iam_role" "enhanced_monitoring" { - name = "${var.enhanced_monitoring_name}-role" - assume_role_policy = data.aws_iam_policy_document.enhanced_monitoring.json - - tags = merge(var.tags, tomap({ - Name = "${var.enhanced_monitoring_name}-role" - })) -} - -# Attach Amazon's managed policy for RDS enhanced monitoring -resource "aws_iam_role_policy_attachment" "enhanced_monitoring" { - role = aws_iam_role.enhanced_monitoring.name - policy_arn = var.enhanced_monitoring_arn -} - -# allow rds to assume this role -data "aws_iam_policy_document" "enhanced_monitoring" { - statement { - actions = [ - "sts:AssumeRole", - ] - - effect = "Allow" - - principals { - type = "Service" - identifiers = ["monitoring.rds.amazonaws.com"] - } - } -} - -################################################################################ -## password generation -################################################################################ -## aurora -resource "random_password" "aurora_db_admin_password" { - count = var.aurora_cluster_enabled == true ? 1 : 0 - - length = 41 - special = true - override_special = "!#*^" - - lifecycle { - ignore_changes = [ - length, - lower, - min_lower, - min_numeric, - min_special, - min_upper, - override_special, - special, - upper - ] - } -} - -## rds -resource "random_password" "rds_db_admin_password" { - count = var.rds_instance_enabled == true ? 1 : 0 - - length = var.rds_random_admin_password_length - special = true - override_special = "!#*^" - - lifecycle { - ignore_changes = [ - length, - lower, - min_lower, - min_numeric, - min_special, - min_upper, - override_special, - special, - upper - ] - } -} - -################################################################################ -## aurora cluster -################################################################################ -module "aurora_cluster" { - source = "git::https://github.com/cloudposse/terraform-aws-rds-cluster.git?ref=1.11.0" - count = var.aurora_cluster_enabled == true ? 1 : 0 - - name = local.aurora_cluster_name - - engine = var.aurora_engine - engine_mode = var.aurora_engine_mode - allow_major_version_upgrade = var.aurora_allow_major_version_upgrade - auto_minor_version_upgrade = var.aurora_auto_minor_version_upgrade - engine_version = var.aurora_engine_version - cluster_family = var.aurora_cluster_family - cluster_size = var.aurora_cluster_size - - admin_user = var.aurora_db_admin_username - admin_password = var.aurora_db_admin_password != "" ? var.aurora_db_admin_password : random_password.aurora_db_admin_password[0].result - db_name = var.aurora_db_name - instance_type = var.aurora_instance_type - db_port = var.aurora_db_port - - vpc_id = var.vpc_id - security_groups = var.aurora_security_groups - allowed_cidr_blocks = var.aurora_allowed_cidr_blocks - subnets = var.aurora_subnets +## RDS instance +################################################################################ +resource "aws_db_instance" "this" { + count = var.engine_type == "rds" ? 1 : 0 + + identifier = var.name + db_name = var.database_name + allocated_storage = var.allocated_storage + engine = var.engine + engine_version = var.engine_version + engine_lifecycle_support = var.engine_lifecycle_support + port = var.port + instance_class = var.db_server_class + + + username = var.username + password = var.password == null && var.manage_user_password == null ? random_password.master[0].result : var.password + manage_master_user_password = var.manage_user_password + + iops = var.iops + db_subnet_group_name = var.db_subnet_group_data.create ? aws_db_subnet_group.this[0].name : null + vpc_security_group_ids = local.security_group_ids_to_attach + multi_az = var.enable_multi_az + publicly_accessible = var.publicly_accessible + storage_type = var.storage_type + auto_minor_version_upgrade = var.auto_minor_version_upgrade + allow_major_version_upgrade = var.allow_major_version_upgrade + backup_retention_period = var.backup_retention_period + backup_window = var.preferred_backup_window + maintenance_window = var.preferred_maintenance_window + delete_automated_backups = var.delete_automated_backups + skip_final_snapshot = var.skip_final_snapshot + final_snapshot_identifier = var.final_snapshot_identifier iam_database_authentication_enabled = var.iam_database_authentication_enabled deletion_protection = var.deletion_protection - enable_http_endpoint = var.enable_http_endpoint + ca_cert_identifier = var.ca_cert_identifier - storage_encrypted = true - storage_type = var.aurora_storage_type - iops = var.aurora_iops - copy_tags_to_snapshot = true + option_group_name = var.option_group_config.create ? aws_db_option_group.this[0].name : var.option_group_config.name + parameter_group_name = var.parameter_group_config.create ? aws_db_parameter_group.this[0].name : var.parameter_group_config.name - rds_monitoring_interval = var.rds_monitoring_interval + storage_encrypted = var.storage_encrypted + kms_key_id = var.kms_data.create ? aws_kms_alias.this[0].target_key_arn : (var.kms_data.kms_key_id == null ? data.aws_kms_alias.rds.target_key_arn : var.kms_data.kms_key_id) performance_insights_enabled = var.performance_insights_enabled - performance_insights_kms_key_id = var.performance_insights_enabled ? coalesce(var.performance_insights_kms_key_id, aws_kms_key.aurora_cluster_kms_key[0].arn) : "" + performance_insights_kms_key_id = var.kms_data.create ? aws_kms_alias.this[0].target_key_arn : (var.kms_data.performance_insights_kms_key_id == null ? data.aws_kms_alias.rds.target_key_arn : var.kms_data.performance_insights_kms_key_id) performance_insights_retention_period = var.performance_insights_retention_period - enabled_cloudwatch_logs_exports = var.aurora_enabled_cloudwatch_logs_exports - - backup_window = var.aurora_backup_window - retention_period = var.aurora_backup_retention_period - - vpc_security_group_ids = var.vpc_security_group_ids - kms_key_arn = var.kms_key_arn - ca_cert_identifier = var.aurora_ca_cert_identifier - - # reference iam role created above - rds_monitoring_role_arn = aws_iam_role.enhanced_monitoring.arn - - scaling_configuration = var.aurora_scaling_configuration - - serverlessv2_scaling_configuration = var.aurora_serverlessv2_scaling_configuration - - tags = merge(var.tags, tomap({ - Name = var.aurora_cluster_name - Namespace = var.namespace - Environment = var.environment - Stage = var.environment - })) -} - -resource "aws_security_group_rule" "additional_ingress_rules_aurora" { - for_each = { for rule in var.additional_ingress_rules_aurora : rule.name => rule } - - security_group_id = module.aurora_cluster[0].security_group_id - type = each.value.type - from_port = each.value.from_port - to_port = each.value.to_port - protocol = each.value.protocol - cidr_blocks = each.value.cidr_blocks -} - -################################################################################ -## s3 db management -################################################################################ -module "db_management" { - source = "git::https://github.com/cloudposse/terraform-aws-s3-bucket?ref=4.5.0" - count = var.rds_enable_custom_option_group == true ? 1 : 0 - - name = "${local.rds_instance_name}-db-management" - - acl = "private" - enabled = true - user_enabled = false - versioning_enabled = true - bucket_key_enabled = true - kms_master_key_arn = "arn:${data.aws_partition.this.partition}:kms:${var.region}:${var.account_id}:alias/aws/s3" - sse_algorithm = "aws:kms" - - tags = merge(var.tags, tomap({ - Namespace = var.namespace - Environment = var.environment - Stage = var.environment - })) -} - -################################################################################ -## option group -################################################################################ -resource "aws_iam_role" "option_group" { - count = var.rds_enable_custom_option_group == true ? 1 : 0 - - name_prefix = "${var.namespace}-${var.environment}-${var.rds_instance_name}-" - - assume_role_policy = jsonencode( - { - Version = "2012-10-17", - Statement = [ - { - Effect = "Allow" - Action = "sts:AssumeRole", - Principal = { - Service = "rds.amazonaws.com" - }, - }, - ] - } - ) -} - -resource "aws_iam_policy" "option_group" { - count = var.rds_enable_custom_option_group == true ? 1 : 0 - - name_prefix = "${local.rds_instance_name}-" - - policy = jsonencode( - { - Version = "2012-10-17", - Statement = [ - { - Effect = "Allow", - Action = [ - "kms:DescribeKey", - "kms:GenerateDataKey", - "kms:Encrypt", - "kms:Decrypt" - ], - Resource = local.instance_kms_id - }, - { - Effect = "Allow", - Action = [ - "kms:DescribeKey", - "kms:GenerateDataKey", - "kms:Encrypt", - "kms:Decrypt" - ], - Resource = local.s3_kms_alias - }, - { - Effect = "Allow", - Action = [ - "s3:ListBucket", - "s3:GetBucketLocation" - ], - Resource = module.db_management[0].bucket_arn - }, - { - Effect = "Allow", - Action = [ - "s3:GetObjectAttributes", - "s3:GetObject", - "s3:PutObject", - "s3:PutObjectAcl", - "s3:ListMultipartUploadParts", - "s3:AbortMultipartUpload" - ], - Resource = "${module.db_management[0].bucket_arn}/*" - } - ] - } - ) -} - -resource "aws_iam_role_policy_attachment" "option_group" { - count = var.rds_enable_custom_option_group == true ? 1 : 0 - - role = aws_iam_role.option_group[0].name - policy_arn = aws_iam_policy.option_group[0].arn -} - -resource "aws_db_option_group" "this" { - count = var.rds_enable_custom_option_group == true ? 1 : 0 - - name = "${local.rds_instance_name}-option-group" - option_group_description = "${local.rds_instance_name} Custom Option Group" - engine_name = var.rds_instance_engine - major_engine_version = var.rds_instance_major_engine_version - - // TODO - add loop for more options - dynamic "option" { - for_each = var.rds_enable_custom_option_group == true && length(regexall("mariadb", var.rds_instance_engine)) == 0 ? [1] : [] // mariadb doesn't support this option - - content { - option_name = length(regexall("sqlserver", var.rds_instance_engine)) > 0 ? "SQLSERVER_BACKUP_RESTORE" : "S3_INTEGRATION" - db_security_group_memberships = [] // TODO - make variable - vpc_security_group_memberships = [] // TODO - make variable - port = 0 // TODO - make variable - # version = "1.0" // TODO - make variable - - // Only include the version attribute for S3_INTEGRATION - version = length(regexall("sqlserver", var.rds_instance_engine)) > 0 ? null : "1.0" - - dynamic "option_settings" { - for_each = length(regexall("sqlserver", var.rds_instance_engine)) > 0 ? [1] : [] - - content { - name = "IAM_ROLE_ARN" - value = try(aws_iam_role.option_group[0].arn, "") - } - } - } - } - - tags = merge(var.tags, tomap({ - Name = "${local.rds_instance_name}-option-group" - })) -} - -resource "aws_db_instance_role_association" "this" { - count = var.rds_enable_custom_option_group && length(regexall("oracle", var.rds_instance_engine)) > 0 ? 1 : 0 // mariadb doesn't support this option - - db_instance_identifier = module.rds_instance[0].instance_id - feature_name = "S3_INTEGRATION" - role_arn = aws_iam_role.option_group[0].arn -} - -################################################################################ -## rds -################################################################################ -module "rds_instance" { - count = var.rds_instance_enabled == true ? 1 : 0 - source = "git::https://github.com/cloudposse/terraform-aws-rds?ref=1.1.2" - - name = local.rds_instance_name - - dns_zone_id = var.rds_instance_dns_zone_id - host_name = var.rds_instance_host_name - vpc_id = var.vpc_id - multi_az = var.rds_instance_multi_az - storage_type = var.rds_instance_storage_type - instance_class = var.rds_instance_instance_class - allocated_storage = var.rds_instance_allocated_storage - storage_encrypted = var.rds_instance_storage_encrypted - security_group_ids = var.rds_instance_security_group_ids - allowed_cidr_blocks = var.rds_instance_allowed_cidr_blocks - subnet_ids = var.rds_instance_subnet_ids - license_model = var.rds_instance_license_model - deletion_protection = var.deletion_protection - iops = var.rds_instance_iops - - enabled_cloudwatch_logs_exports = var.rds_enabled_cloudwatch_logs_exports - monitoring_interval = var.rds_monitoring_interval - monitoring_role_arn = var.rds_monitoring_interval > 0 ? aws_iam_role.enhanced_monitoring.arn : null - 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 - - kms_key_arn = var.rds_instance_storage_encrypted == false ? "" : var.rds_kms_key_arn_override != "" ? var.rds_kms_key_arn_override : aws_kms_key.rds_db_kms_key[0].arn - database_name = var.rds_instance_database_name - database_user = var.rds_instance_database_user - database_password = var.rds_instance_database_password != "" ? var.rds_instance_database_password : random_password.rds_db_admin_password[0].result - database_port = var.rds_instance_database_port - engine = var.rds_instance_engine - engine_version = var.rds_instance_engine_version - major_engine_version = var.rds_instance_major_engine_version - parameter_group_name = var.rds_instance_db_parameter_group_name - db_parameter_group = var.rds_instance_db_parameter_group - db_parameter = var.rds_instance_db_parameter - db_options = var.rds_instance_db_options - option_group_name = local.rds_instance_option_group_name - ca_cert_identifier = var.rds_instance_ca_cert_identifier - publicly_accessible = var.rds_instance_publicly_accessible - snapshot_identifier = var.rds_instance_snapshot_identifier - auto_minor_version_upgrade = var.rds_instance_auto_minor_version_upgrade - allow_major_version_upgrade = var.rds_instance_allow_major_version_upgrade - apply_immediately = var.rds_instance_apply_immediately - maintenance_window = var.rds_instance_maintenance_window - skip_final_snapshot = var.rds_instance_skip_final_snapshot - copy_tags_to_snapshot = var.rds_instance_copy_tags_to_snapshot - backup_retention_period = var.rds_instance_backup_retention_period - backup_window = var.rds_instance_backup_window - iam_database_authentication_enabled = var.iam_database_authentication_enabled - timeouts = var.timeouts - - tags = merge(var.tags, tomap({ - Namespace = var.namespace - Environment = var.environment - Stage = var.environment - })) -} - - -resource "aws_security_group_rule" "additional_ingress_rules_rds" { - for_each = { for rule in var.additional_ingress_rules_rds : rule.name => rule } - - security_group_id = module.rds_instance[0].security_group_id - type = each.value.type - from_port = each.value.from_port - to_port = each.value.to_port - protocol = each.value.protocol - cidr_blocks = each.value.cidr_blocks -} - -################################################################################ -## ssm parameters -################################################################################ -resource "aws_ssm_parameter" "this" { - for_each = { for x in local.ssm_params : x.name => x } - - name = lookup(each.value, "name", null) - value = lookup(each.value, "value", null) - description = lookup(each.value, "description", "Managed by Terraform") - type = lookup(each.value, "type", null) - overwrite = lookup(each.value, "overwrite", true) + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports + monitoring_interval = var.monitoring_interval + monitoring_role_arn = var.monitoring_interval > 0 ? (var.monitoring_role_arn == null ? aws_iam_role.enhanced_monitoring[0].arn : var.monitoring_role_arn) : null - tags = merge(var.tags, local.ssm_tags) + license_model = var.license_model + apply_immediately = var.apply_immediately + tags = var.tags } diff --git a/modules/security-group/.terraform.lock.hcl b/modules/security-group/.terraform.lock.hcl new file mode 100644 index 0000000..6e902b8 --- /dev/null +++ b/modules/security-group/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.68.0" + constraints = "~> 5.0" + hashes = [ + "h1:n1X7MVAm1J+cxX4nTWTQRBx+VFQ0ma2AMJ5Ll3URlLo=", + "zh:045f37b115a6c94a05c6a5f2aacfe4cecbaf4b40b56917ba852d988d487e94bf", + "zh:0c388f1a94e7941cf7e6abcd8d958a3e325e513cb60affa3cac82e75c7bbbb73", + "zh:15b1f2587c06bff35a15f2d1c22eab395d549908daf05582608d729cdf54ba40", + "zh:16a9c0c7fa7a33aa22313d4444aeecde20831bf51f9b481a0406e3cf583378fc", + "zh:3330c0d49fb329dff6de17913e1a774e75aa0913106c3197814c73c3a12a4c3f", + "zh:40920318f774ff397c7b6a01b5e89e46eb1a55d7dc9943a310669a9357b9b501", + "zh:838fbac358bb72f46c8d359a28a3effb6a9d7137cdd72b9e4d2f0fcf803dc462", + "zh:84e694c0720bf54b3b8521bf6e05700abe4a1b3e7dd2a104efd1eb55ae5866a0", + "zh:90606c399498027d7d07ab78a71b574a5d8b982c4372e6b67479f7e39e153e2f", + "zh:9162cf25d5c0fdf672c9bbc4c3c84dd87ab6a15b4971df1f32aea6b477c0e028", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9cd8ec40a88b25e9f0f7d7f51460a921f4529554a260ffbe5083ddeba2f41ae3", + "zh:adeffac1d01a35bc8d2497ccceb9978b4746872143016c2c631de6cb38b6aa8d", + "zh:c7b682c81f9ae850669deb6239a66d8aa960abed984aad25db2d3954c09c2616", + "zh:d10b9f40934e14d55cfc5731d728507e50d014561322e9e0c84b33ab255a4d51", + ] +} diff --git a/modules/security-group/main.tf b/modules/security-group/main.tf new file mode 100644 index 0000000..b8ba2cb --- /dev/null +++ b/modules/security-group/main.tf @@ -0,0 +1,43 @@ +resource "aws_security_group" "this" { + name = var.name + description = var.description == null ? "Allow inbound traffic and outbound traffic" : var.description + vpc_id = var.vpc_id + tags = merge( + var.tags, + { + Name = var.name + } + ) +} + +resource "aws_vpc_security_group_egress_rule" "this" { + for_each = { + for idx, rule in var.egress_rules : idx => rule + } + + security_group_id = aws_security_group.this.id + description = each.value.description + cidr_ipv4 = each.value.cidr_block + referenced_security_group_id = each.value.destination_security_group_id + from_port = each.value.from_port + ip_protocol = each.value.ip_protocol + to_port = each.value.to_port + + depends_on = [aws_security_group.this] +} + +resource "aws_vpc_security_group_ingress_rule" "this" { + for_each = { + for idx, rule in var.ingress_rules : idx => rule + } + + security_group_id = aws_security_group.this.id + description = each.value.description + cidr_ipv4 = each.value.cidr_block + referenced_security_group_id = each.value.self ? aws_security_group.this.id : each.value.source_security_group_id + from_port = each.value.from_port + ip_protocol = each.value.ip_protocol + to_port = each.value.to_port + + depends_on = [aws_security_group.this] +} diff --git a/modules/security-group/output.tf b/modules/security-group/output.tf new file mode 100644 index 0000000..e30e32d --- /dev/null +++ b/modules/security-group/output.tf @@ -0,0 +1,4 @@ +output "id" { + description = "Security Groupo ID" + value = aws_security_group.this.id +} diff --git a/modules/security-group/variables.tf b/modules/security-group/variables.tf new file mode 100644 index 0000000..ddaa754 --- /dev/null +++ b/modules/security-group/variables.tf @@ -0,0 +1,50 @@ +# Cluster identifier +variable "name" { + description = "The identifier for the RDS cluster." + type = string +} + +variable "vpc_id" { + type = string + description = "VPC Id for creating security group" +} + +variable "description" { + type = string + description = "(optional) Description of Security Group" + default = null +} + +variable "ingress_rules" { + description = "(optional) List of ingress rules for the security group." + type = list(object({ + description = optional(string, null) + cidr_block = optional(string, null) + source_security_group_id = optional(string, null) + from_port = number + ip_protocol = string + to_port = string + self = optional(bool, false) + })) + default = [] +} + +variable "egress_rules" { + description = "(optional) List of egress rules for the security group." + type = list(object({ + description = optional(string, null) + cidr_block = optional(string, null) + destination_security_group_id = optional(string, null) + from_port = number + ip_protocol = string + to_port = string + })) + default = [] +} + + +variable "tags" { + description = "A map of tags to assign to the DB Cluster." + type = map(string) + default = {} +} diff --git a/modules/security-group/version.tf b/modules/security-group/version.tf new file mode 100644 index 0000000..9121a5f --- /dev/null +++ b/modules/security-group/version.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.5.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} diff --git a/outputs.tf b/outputs.tf index d98f483..06ac2d1 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,80 +1,49 @@ -################################################################################ -## aurora -################################################################################ -output "aurora_name" { - value = try(module.aurora_cluster[0].database_name, null) - description = "Database name" +output "id" { + value = var.engine_type == "rds" ? aws_db_instance.this[0].id : aws_rds_cluster.this[0].id + description = "Instance or Cluster ID" } -output "aurora_master_username" { - value = try(module.aurora_cluster[0].master_username, null) - description = "Username for the master DB user" +output "identifier" { + value = var.engine_type == "rds" ? aws_db_instance.this[0].id : aws_rds_cluster.this[0].id + description = "Instance or Cluster Identifier " } -output "aurora_cluster_identifier" { - value = try(module.aurora_cluster[0].cluster_identifier, null) - description = "Cluster Identifier" +output "arn" { + value = var.engine_type == "rds" ? aws_db_instance.this[0].arn : aws_rds_cluster.this[0].arn + description = "Instance or Cluster ARN" } -output "aurora_arn" { - value = try(module.aurora_cluster[0].arn, null) - description = "Amazon Resource Name (ARN) of cluster" +output "username" { + value = local.username + description = "Username for the Database" } -output "aurora_endpoint" { - value = try(module.aurora_cluster[0].endpoint, null) - description = "The DNS address of the RDS instance" +output "database" { + value = local.database + description = "database name" } -output "aurora_reader_endpoint" { - value = try(module.aurora_cluster[0].reader_endpoint, null) - description = "A read-only endpoint for the Aurora cluster, automatically load-balanced across replicas" +output "port" { + value = local.port + description = "Dtabase server port" } -output "aurora_master_host" { - value = try(module.aurora_cluster[0].master_host, null) - description = "DB Master hostname" +output "endpoint" { + value = var.engine_type == "rds" ? aws_db_instance.this[0].endpoint : aws_rds_cluster.this[0].endpoint + description = "Instance or Cluster Endpoint" } -output "aurora_replicas_host" { - value = try(module.aurora_cluster[0].replicas_host, null) - description = "Replicas hostname" +output "kms_key_id" { + value = local.kms_key_id + description = "Instance or Cluster KM Key ID" } -################################################################################ -## rds -################################################################################ -output "rds_instance_arn" { - value = try(module.rds_instance[0].instance_arn, null) - description = "The RDS Instance AWS ARN." +output "performance_insights_kms_key_id" { + value = local.performance_insights_kms_key_id + description = "Instance or Cluster Performance insight KM Key ID" } -output "rds_instance_endpoint" { - value = try(module.rds_instance[0].instance_endpoint, null) - description = "The DNS address to the RDS Instance." -} - -output "rds_instance_hostname" { - value = try(module.rds_instance[0].hostname, null) - description = "Hostname of the RDS Instance." -} - -output "rds_instance_id" { - value = try(module.rds_instance[0].instance_id, null) - description = "The RDS Instance AWS ID." -} - -output "rds_instance_resource_id" { - value = try(module.rds_instance[0].resource_id, null) - description = "The RDS Instance AWS resource ID." -} - -output "rds_instance_kms_arn" { - value = var.rds_kms_key_arn_override != "" ? var.rds_kms_key_arn_override : try(aws_kms_key.rds_db_kms_key[0].arn, null) - description = "RDS KMS Key ARN" -} - -output "rds_instance_kms_id" { - value = var.rds_kms_key_id_override != "" ? var.rds_kms_key_id_override : try(aws_kms_key.rds_db_kms_key[0].key_id, null) - description = "Output RDS KMS Key ID if the var.rds_kms_key_arn_override is \"\"" +output "monitoring_role_arn" { + value = local.monitoring_role_arn + description = "Instance or Cluster Monitoring role arn" } diff --git a/proxy.tf b/proxy.tf new file mode 100644 index 0000000..0b827fe --- /dev/null +++ b/proxy.tf @@ -0,0 +1,178 @@ +resource "aws_kms_key" "secret" { + description = "KMS key for encrypting Secrets Manager secrets" + deletion_window_in_days = var.kms_data.deletion_window_in_days + enable_key_rotation = var.kms_data.enable_key_rotation + + policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Sid = "Enable IAM User Permissions", + Effect = "Allow", + Principal = { + AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" + }, + Action = "kms:*", + Resource = "*" + }, + { + Sid = "Allow Secrets Manager to use the key", + Effect = "Allow", + Principal = { + Service = "secretsmanager.amazonaws.com" + }, + Action = [ + "kms:GenerateDataKey", + "kms:Decrypt" + ], + Resource = "*" + } + ] + }) + + tags = var.tags +} + +resource "aws_secretsmanager_secret" "this" { + count = var.manage_user_password == null && var.proxy_config.create ? 1 : 0 + + name = "${local.prefix}-${var.name}-secret" + description = "Credentials for RDS Proxy" + kms_key_id = var.kms_data.create ? aws_kms_key.secret.id : null + + tags = var.tags +} + +resource "aws_secretsmanager_secret_version" "db_secret_version" { + count = var.manage_user_password == null && var.proxy_config.create ? 1 : 0 + + secret_id = aws_secretsmanager_secret.this[0].id + secret_string = jsonencode({ + "username" = local.username + "password" = local.password + "database" = local.database + "endpoint" = local.endpoint + "port" = local.port + }) +} + + +resource "aws_db_proxy" "this" { + count = var.proxy_config.create ? 1 : 0 + + name = var.proxy_config.name == null ? var.name : var.proxy_config.name + engine_family = var.proxy_config.engine_family # Replace with your DB engine (MYSQL, POSTGRESQL, etc.) + role_arn = var.proxy_config.role_arn == null ? aws_iam_role.proxy[0].arn : var.proxy_config.role_arn + vpc_subnet_ids = var.proxy_config.vpc_subnet_ids + vpc_security_group_ids = local.proxy_security_group_ids_to_attach + require_tls = var.proxy_config.require_tls + debug_logging = var.proxy_config.debug_logging + idle_client_timeout = var.proxy_config.idle_client_timeout_secs + + auth { + auth_scheme = var.proxy_config.auth.auth_scheme + description = var.proxy_config.auth.description == null ? "Auth for RDS Proxy" : var.proxy_config.auth.description + iam_auth = var.proxy_config.auth.iam_auth + secret_arn = var.manage_user_password == true ? (var.engine_type == "rds" ? aws_db_instance.this[0].master_user_secret[0].secret_arn : aws_rds_cluster.this[0].master_user_secret[0].secret_arn) : aws_secretsmanager_secret.this[0].arn + username = var.proxy_config.auth.auth_scheme == "SECRETS" ? null : (var.engine_type == "rds" ? aws_db_instance.this[0].username : aws_rds_cluster.this[0].master_username) + client_password_auth_type = var.proxy_config.auth.client_password_auth_type + } + + dynamic "auth" { + for_each = var.proxy_config.additional_auth_list + content { + auth_scheme = auth.value.auth_scheme + description = auth.value.description == null ? "Auth for RDS Proxy" : auth.value.description + iam_auth = auth.value.iam_auth + secret_arn = auth.value.secret_arn + client_password_auth_type = auth.value.client_password_auth_type + } + } + + tags = var.tags +} + +resource "aws_db_proxy_default_target_group" "this" { + count = var.proxy_config.create ? 1 : 0 + + db_proxy_name = aws_db_proxy.this[0].name + + connection_pool_config { + connection_borrow_timeout = var.proxy_config.connection_pool_config.connection_borrow_timeout + init_query = var.proxy_config.connection_pool_config.init_query + max_connections_percent = var.proxy_config.connection_pool_config.max_connections_percent + max_idle_connections_percent = var.proxy_config.connection_pool_config.max_idle_connections_percent + session_pinning_filters = var.proxy_config.connection_pool_config.session_pinning_filters + } +} + +resource "aws_db_proxy_target" "this" { + count = var.proxy_config.create ? 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.engine_type == "cluster" ? aws_rds_cluster.this[0].cluster_identifier : null + db_instance_identifier = var.engine_type == "rds" ? aws_db_instance.this[0].identifier : null + depends_on = [aws_db_instance.this, aws_rds_cluster.this] +} + + +resource "aws_iam_role" "proxy" { + count = var.proxy_config.create && var.proxy_config.role_arn == null ? 1 : 0 + + name = "${local.prefix}-${var.name}-proxy" + assume_role_policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [{ + "Action" : "sts:AssumeRole", + "Effect" : "Allow", + "Principal" : { + "Service" : "rds.amazonaws.com" + } + }] + }) +} + +resource "aws_iam_policy" "read_secrets" { + count = var.proxy_config.create && var.proxy_config.role_arn == null ? 1 : 0 + + name = "${var.name}-read-secret-proxy" + description = "IAM policy to grant read access to secrets in AWS Secrets Manager" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = [ + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret", + "secretsmanager:ListSecretVersionIds" + ] + Resource = local.secret_arn_list + } + ] + }) + + depends_on = [aws_rds_cluster.this, aws_db_instance.this, aws_secretsmanager_secret.this] +} + + +resource "aws_iam_role_policy_attachment" "proxy" { + count = var.proxy_config.create && var.proxy_config.role_arn == null ? 1 : 0 + + role = aws_iam_role.proxy[0].name + policy_arn = aws_iam_policy.read_secrets[0].arn +} + +module "proxy_security_group" { + source = "./modules/security-group" + + count = var.proxy_config.security_group_data.create ? 1 : 0 + + name = "${var.name}-proxy-security-group" + description = var.proxy_config.security_group_data.description == null ? "Allow inbound traffic and outbound traffic" : var.proxy_config.security_group_data.description + vpc_id = var.vpc_id + egress_rules = var.proxy_config.security_group_data.egress_rules + ingress_rules = var.proxy_config.security_group_data.ingress_rules +} diff --git a/variables.tf b/variables.tf index 326b4c1..52797cc 100644 --- a/variables.tf +++ b/variables.tf @@ -1,598 +1,528 @@ -################################################################################ -## shared -################################################################################ -variable "vpc_id" { +variable "environment" { type = string - description = "vpc_id for the VPC to run the cluster." + description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" } -variable "enhanced_monitoring_name" { +variable "namespace" { type = string - description = "Name to assign the enhanced monitoring resources." + description = "Namespace for the resources." } -variable "enhanced_monitoring_arn" { + +variable "name" { + description = "The identifier for the RDS instance or cluster." type = string - description = "ARN to the enhanced monitoring policy" - default = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole" } -variable "deletion_protection" { - description = "Protect the instance from being deleted" - type = bool - default = false +variable "vpc_id" { + type = string + description = "VPC Id for creating security group" } - -variable "timeouts" { +variable "serverlessv2_scaling_config" { type = object({ - create = string - update = string - delete = string + max_capacity = number + min_capacity = number }) - description = "A list of DB timeouts to apply to the running code while creating, updating, or deleting the DB instance." default = { - create = "40m" - update = "80m" - delete = "60m" + max_capacity = 1.0 + min_capacity = 0.5 } + description = <