From cc39e9d0295495574c406acfed9e288fb6d5df3c Mon Sep 17 00:00:00 2001 From: jatalocks <99724952+jatalocks@users.noreply.github.com> Date: Fri, 9 Jun 2023 14:30:52 +0300 Subject: [PATCH] feat!: Increase Terraform and AWS provider minimum supported versions; update `auth` configuration schema (#17) Co-authored-by: Orest Kapko Co-authored-by: Amitai Getzler Co-authored-by: Orest Kapko Co-authored-by: Bryant Biggs Co-authored-by: Anton Babenko --- .pre-commit-config.yaml | 4 +- README.md | 33 ++- UPGRADE-3.0.md | 79 +++++++ .../README.md | 22 +- examples/mysql-iam-cluster/main.tf | 144 ++++++++++++ .../outputs.tf | 2 +- .../variables.tf | 0 examples/mysql-iam-cluster/versions.tf | 10 + .../README.md | 15 +- .../main.tf | 124 ++++------ .../outputs.tf | 2 +- .../variables.tf | 0 .../versions.tf | 4 +- examples/mysql_iam_cluster/main.tf | 217 ------------------ examples/mysql_iam_cluster/versions.tf | 14 -- .../README.md | 22 +- examples/postgresql-iam-cluster/main.tf | 144 ++++++++++++ .../outputs.tf | 2 +- .../variables.tf | 0 examples/postgresql-iam-cluster/versions.tf | 10 + .../README.md | 15 +- .../main.tf | 118 ++++------ .../outputs.tf | 2 +- .../variables.tf | 0 .../versions.tf | 4 +- examples/postgresql_iam_cluster/main.tf | 217 ------------------ examples/postgresql_iam_instance/versions.tf | 14 -- main.tf | 67 +++--- outputs.tf | 30 +-- variables.tf | 57 ++--- versions.tf | 4 +- 31 files changed, 626 insertions(+), 750 deletions(-) create mode 100644 UPGRADE-3.0.md rename examples/{mysql_iam_cluster => mysql-iam-cluster}/README.md (75%) create mode 100644 examples/mysql-iam-cluster/main.tf rename examples/{mysql_iam_instance => mysql-iam-cluster}/outputs.tf (99%) rename examples/{mysql_iam_cluster => mysql-iam-cluster}/variables.tf (100%) create mode 100644 examples/mysql-iam-cluster/versions.tf rename examples/{mysql_iam_instance => mysql-iam-instance}/README.md (92%) rename examples/{mysql_iam_instance => mysql-iam-instance}/main.tf (64%) rename examples/{postgresql_iam_cluster => mysql-iam-instance}/outputs.tf (99%) rename examples/{mysql_iam_instance => mysql-iam-instance}/variables.tf (100%) rename examples/{mysql_iam_instance => mysql-iam-instance}/versions.tf (74%) delete mode 100644 examples/mysql_iam_cluster/main.tf delete mode 100644 examples/mysql_iam_cluster/versions.tf rename examples/{postgresql_iam_cluster => postgresql-iam-cluster}/README.md (76%) create mode 100644 examples/postgresql-iam-cluster/main.tf rename examples/{mysql_iam_cluster => postgresql-iam-cluster}/outputs.tf (99%) rename examples/{postgresql_iam_cluster => postgresql-iam-cluster}/variables.tf (100%) create mode 100644 examples/postgresql-iam-cluster/versions.tf rename examples/{postgresql_iam_instance => postgresql-iam-instance}/README.md (92%) rename examples/{postgresql_iam_instance => postgresql-iam-instance}/main.tf (66%) rename examples/{postgresql_iam_instance => postgresql-iam-instance}/outputs.tf (99%) rename examples/{postgresql_iam_instance => postgresql-iam-instance}/variables.tf (100%) rename examples/{postgresql_iam_cluster => postgresql-iam-instance}/versions.tf (74%) delete mode 100644 examples/postgresql_iam_cluster/main.tf delete mode 100644 examples/postgresql_iam_instance/versions.tf diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 74f3751..dabb150 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.76.0 + rev: v1.80.0 hooks: - id: terraform_fmt - id: terraform_validate @@ -23,7 +23,7 @@ repos: - '--args=--only=terraform_standard_module_structure' - '--args=--only=terraform_workspace_remote' - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.4.0 hooks: - id: check-merge-conflict - id: end-of-file-fixer diff --git a/README.md b/README.md index 128a454..21f345a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ module "rds_proxy" { vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] vpc_security_group_ids = ["sg-f1d03a88"] - db_proxy_endpoints = { + endpoints = { read_write = { name = "read-write-endpoint" vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] @@ -29,18 +29,17 @@ module "rds_proxy" { } } - secrets = { + auth = { "superuser" = { - description = "Aurora PostgreSQL superuser password" - arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD" - kms_key_id = "6ca29066-552a-46c5-a7d7-7bf9a15fc255" + description = "Aurora PostgreSQL superuser password" + secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD" } } # Target Aurora cluster engine_family = "POSTGRESQL" target_db_cluster = true - db_cluster_identifier = "myendpoint" + db_cluster_identifier = "my-endpoint" tags = { Terraform = "true" @@ -63,14 +62,14 @@ Examples codified under the [`examples`](https://github.com/terraform-aws-module | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 3.38 | +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3.38 | +| [aws](#provider\_aws) | >= 5.0 | ## Modules @@ -90,23 +89,23 @@ No modules. | [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | | [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | | [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [auth\_scheme](#input\_auth\_scheme) | The type of authentication that the proxy uses for connections from the proxy to the underlying database. One of `SECRETS` | `string` | `"SECRETS"` | no | +| [auth](#input\_auth) | Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters | `any` | `{}` | no | | [connection\_borrow\_timeout](#input\_connection\_borrow\_timeout) | The number of seconds for a proxy to wait for a connection to become available in the connection pool | `number` | `null` | no | +| [create](#input\_create) | Whether cluster should be created (affects nearly all resources) | `bool` | `true` | no | | [create\_iam\_policy](#input\_create\_iam\_policy) | Determines whether an IAM policy is created | `bool` | `true` | no | | [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created | `bool` | `true` | no | -| [create\_proxy](#input\_create\_proxy) | Determines whether a proxy and its resources will be created | `bool` | `true` | no | | [db\_cluster\_identifier](#input\_db\_cluster\_identifier) | DB cluster identifier | `string` | `""` | no | | [db\_instance\_identifier](#input\_db\_instance\_identifier) | DB instance identifier | `string` | `""` | no | -| [db\_proxy\_endpoints](#input\_db\_proxy\_endpoints) | Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`) | `any` | `{}` | no | | [debug\_logging](#input\_debug\_logging) | Whether the proxy includes detailed information about SQL statements in its logs | `bool` | `false` | no | +| [endpoints](#input\_endpoints) | Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`) | `any` | `{}` | no | | [engine\_family](#input\_engine\_family) | The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL` | `string` | `""` | no | -| [iam\_auth](#input\_iam\_auth) | Whether to require or disallow AWS Identity and Access Management (IAM) authentication for connections to the proxy. One of `DISABLED`, `REQUIRED` | `string` | `"REQUIRED"` | no | | [iam\_policy\_name](#input\_iam\_policy\_name) | The name of the role policy. If omitted, Terraform will assign a random, unique name | `string` | `""` | no | | [iam\_role\_description](#input\_iam\_role\_description) | The description of the role | `string` | `""` | no | | [iam\_role\_force\_detach\_policies](#input\_iam\_role\_force\_detach\_policies) | Specifies to force detaching any policies the role has before destroying it | `bool` | `true` | no | @@ -117,6 +116,7 @@ No modules. | [iam\_role\_tags](#input\_iam\_role\_tags) | A map of tags to apply to the IAM role | `map(string)` | `{}` | no | | [idle\_client\_timeout](#input\_idle\_client\_timeout) | The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it | `number` | `1800` | no | | [init\_query](#input\_init\_query) | One or more SQL statements for the proxy to run when opening each new database connection | `string` | `""` | no | +| [kms\_key\_arns](#input\_kms\_key\_arns) | List of KMS Key ARNs to allow access to decrypt SecretsManager secrets | `list(string)` | `[]` | no | | [log\_group\_kms\_key\_id](#input\_log\_group\_kms\_key\_id) | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no | | [log\_group\_retention\_in\_days](#input\_log\_group\_retention\_in\_days) | Specifies the number of days you want to retain log events in the log group | `number` | `30` | no | | [log\_group\_tags](#input\_log\_group\_tags) | A map of tags to apply to the CloudWatch log group | `map(string)` | `{}` | no | @@ -127,11 +127,10 @@ No modules. | [proxy\_tags](#input\_proxy\_tags) | A map of tags to apply to the RDS Proxy | `map(string)` | `{}` | no | | [require\_tls](#input\_require\_tls) | A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy | `bool` | `true` | no | | [role\_arn](#input\_role\_arn) | The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager | `string` | `""` | no | -| [secrets](#input\_secrets) | Map of secerets to be used by RDS Proxy for authentication to the database | `map(object({ arn = string, description = string, kms_key_id = string }))` | `{}` | no | | [session\_pinning\_filters](#input\_session\_pinning\_filters) | Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection | `list(string)` | `[]` | no | -| [tags](#input\_tags) | A map of tags to use on all resources | `map(string)` | `{}` | no | -| [target\_db\_cluster](#input\_target\_db\_cluster) | Determines whether DB cluster is targetted by proxy | `bool` | `false` | no | -| [target\_db\_instance](#input\_target\_db\_instance) | Determines whether DB instance is targetted by proxy | `bool` | `false` | no | +| [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | +| [target\_db\_cluster](#input\_target\_db\_cluster) | Determines whether DB cluster is targeted by proxy | `bool` | `false` | no | +| [target\_db\_instance](#input\_target\_db\_instance) | Determines whether DB instance is targeted by proxy | `bool` | `false` | no | | [use\_policy\_name\_prefix](#input\_use\_policy\_name\_prefix) | Whether to use unique name beginning with the specified `iam_policy_name` | `bool` | `false` | no | | [use\_role\_name\_prefix](#input\_use\_role\_name\_prefix) | Whether to use unique name beginning with the specified `iam_role_name` | `bool` | `false` | no | | [vpc\_security\_group\_ids](#input\_vpc\_security\_group\_ids) | One or more VPC security group IDs to associate with the new proxy | `list(string)` | `[]` | no | diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md new file mode 100644 index 0000000..d199f37 --- /dev/null +++ b/UPGRADE-3.0.md @@ -0,0 +1,79 @@ +# Upgrade from v2.x to v3.x + +If you have any questions regarding this upgrade process, please consult the `examples` directory. +If you find a bug, please open an issue with supporting configuration to reproduce. + +## List of backwards incompatible changes + +- Minimum supported Terraform version is now 1.0 +- Minimum supported AWS provider version is now 5.0 +- The manner in which authentication is configured has changed - previously auth settings were provided under `secrets` in conjunction with `auth_scheme` and `iam_auth` variables. Now, auth settings are provided under the `auth` variable for multiple auth entries. + +### Variable and output changes + +1. Removed variables: + + - `auth_scheme` is now set under the `auth` variable for a given auth entry + - `iam_auth` is now set under the `auth` variable for a given auth entry + +2. Renamed variables: + + - `create_proxy` -> `create` + - `secrets` -> `auth` + - `db_proxy_endpoints` -> `endpoints` + +3. Added variables: + + - `kms_key_arns` - list of KMS key ARNs to use allowing permission to decrypt SecretsManager secrets + +4. Removed outputs: + + - None + +5. Renamed outputs: + + - None + +6. Added outputs: + + - None + +## Diff of Before (v2.x) vs After (v3.x) + +```diff +module "rds_proxy" { + source = "terraform-aws-modules/rds-proxy/aws" +- version = "~> 2.0" ++ version = "~> 3.0" + + # Only the affected attributes are shown +- create_proxy = true ++ create = true + +- db_proxy_endpoints = { +- ... +- } ++ endpoints = { ++ ... ++ } + +- secrets = { +- "superuser" = { +- description = "Aurora PostgreSQL superuser password" +- arn = "arn:aws:secretsmanager:eu-west-1:123456789012:secret:superuser-6gsjLD" +- kms_key_id = "6ca29066-552a-46c5-a7d7-7bf9a15fc255" +- } +- } ++ auth = { ++ "superuser" = { ++ description = "Aurora PostgreSQL superuser password" ++ secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD" ++ } ++ } ++ kms_key_arns = ["arn:aws:kms:eu-west-1:123456789012:key/6ca29066-552a-46c5-a7d7-7bf9a15fc255"] +} +``` + +### State Changes + +- None diff --git a/examples/mysql_iam_cluster/README.md b/examples/mysql-iam-cluster/README.md similarity index 75% rename from examples/mysql_iam_cluster/README.md rename to examples/mysql-iam-cluster/README.md index de5ff55..0d405c7 100644 --- a/examples/mysql_iam_cluster/README.md +++ b/examples/mysql-iam-cluster/README.md @@ -30,37 +30,29 @@ An EC2 instance configuration has been provided for use in validating the exampl | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 3.38 | -| [random](#requirement\_random) | >= 2.0 | +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3.38 | -| [random](#provider\_random) | >= 2.0 | +| [aws](#provider\_aws) | >= 5.0 | ## Modules | Name | Source | Version | |------|--------|---------| -| [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 6.0 | +| [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 8.0 | | [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a | -| [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 | +| [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 | ## Resources | Name | Type | |------|------| -| [aws_db_parameter_group.aurora_db_mysql57_parameter_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource | -| [aws_rds_cluster_parameter_group.aurora_cluster_mysql57_parameter_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_parameter_group) | resource | -| [aws_secretsmanager_secret.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource | -| [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource | -| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | -| [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | -| [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | +| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | ## Inputs diff --git a/examples/mysql-iam-cluster/main.tf b/examples/mysql-iam-cluster/main.tf new file mode 100644 index 0000000..ea10621 --- /dev/null +++ b/examples/mysql-iam-cluster/main.tf @@ -0,0 +1,144 @@ +provider "aws" { + region = local.region +} + +data "aws_availability_zones" "available" {} + +locals { + name = "ex-${basename(path.cwd)}" + region = "eu-west-1" + + vpc_cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + tags = { + Example = local.name + GithubRepo = "terraform-aws-rds-proxy" + GithubOrg = "terraform-aws-modules" + } +} + +################################################################################ +# RDS Proxy +################################################################################ + +module "rds_proxy" { + source = "../../" + + name = local.name + iam_role_name = local.name + vpc_subnet_ids = module.vpc.private_subnets + vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] + + endpoints = { + read_write = { + name = "read-write-endpoint" + vpc_subnet_ids = module.vpc.private_subnets + vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] + tags = local.tags + }, + read_only = { + name = "read-only-endpoint" + vpc_subnet_ids = module.vpc.private_subnets + vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] + target_role = "READ_ONLY" + tags = local.tags + } + } + + auth = { + "root" = { + description = "Cluster generated master user password" + secret_arn = module.rds.cluster_master_user_secret[0].secret_arn + } + } + + engine_family = "MYSQL" + debug_logging = true + + # Target Aurora cluster + target_db_cluster = true + db_cluster_identifier = module.rds.cluster_id + + tags = local.tags +} + +################################################################################ +# Supporting Resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 5.0" + + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] + database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] + + tags = local.tags +} + +module "rds" { + source = "terraform-aws-modules/rds-aurora/aws" + version = "~> 8.0" + + name = local.name + engine = "aurora-mysql" + engine_version = "8.0" + master_username = "root" + + # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM + iam_database_authentication_enabled = false + + instance_class = "db.r6g.large" + instances = { + 1 = {} + 2 = {} + } + + vpc_id = module.vpc.vpc_id + db_subnet_group_name = module.vpc.database_subnet_group_name + security_group_rules = { + vpc_ingress = { + cidr_blocks = module.vpc.private_subnets_cidr_blocks + } + } + + apply_immediately = true + skip_final_snapshot = true + + tags = local.tags +} + +module "rds_proxy_sg" { + source = "terraform-aws-modules/security-group/aws" + version = "~> 5.0" + + name = "${local.name}-proxy" + description = "PostgreSQL RDS Proxy example security group" + vpc_id = module.vpc.vpc_id + + revoke_rules_on_delete = true + + ingress_with_cidr_blocks = [ + { + description = "Private subnet MySQL access" + rule = "mysql-tcp" + cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) + } + ] + + egress_with_cidr_blocks = [ + { + description = "Database subnet MySQL access" + rule = "mysql-tcp" + cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks) + }, + ] + + tags = local.tags +} diff --git a/examples/mysql_iam_instance/outputs.tf b/examples/mysql-iam-cluster/outputs.tf similarity index 99% rename from examples/mysql_iam_instance/outputs.tf rename to examples/mysql-iam-cluster/outputs.tf index 3d97324..4b07beb 100644 --- a/examples/mysql_iam_instance/outputs.tf +++ b/examples/mysql-iam-cluster/outputs.tf @@ -66,7 +66,7 @@ output "proxy_target_type" { value = module.rds_proxy.proxy_target_type } -# DB proxy endponts +# DB proxy endpoints output "db_proxy_endpoints" { description = "Array containing the full resource object and attributes for all DB proxy endpoints created" value = module.rds_proxy.db_proxy_endpoints diff --git a/examples/mysql_iam_cluster/variables.tf b/examples/mysql-iam-cluster/variables.tf similarity index 100% rename from examples/mysql_iam_cluster/variables.tf rename to examples/mysql-iam-cluster/variables.tf diff --git a/examples/mysql-iam-cluster/versions.tf b/examples/mysql-iam-cluster/versions.tf new file mode 100644 index 0000000..ddfcb0e --- /dev/null +++ b/examples/mysql-iam-cluster/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} diff --git a/examples/mysql_iam_instance/README.md b/examples/mysql-iam-instance/README.md similarity index 92% rename from examples/mysql_iam_instance/README.md rename to examples/mysql-iam-instance/README.md index f687d36..7e3e02c 100644 --- a/examples/mysql_iam_instance/README.md +++ b/examples/mysql-iam-instance/README.md @@ -30,26 +30,26 @@ An EC2 instance configuration has been provided for use in validating the exampl | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 3.38 | +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | | [random](#requirement\_random) | >= 2.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3.38 | +| [aws](#provider\_aws) | >= 5.0 | | [random](#provider\_random) | >= 2.0 | ## Modules | Name | Source | Version | |------|--------|---------| -| [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 3.0 | +| [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 5.0 | | [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a | -| [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 | -| [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 | +| [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | +| [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 | ## Resources @@ -59,6 +59,7 @@ An EC2 instance configuration has been provided for use in validating the exampl | [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource | | [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | | [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | +| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | | [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | ## Inputs diff --git a/examples/mysql_iam_instance/main.tf b/examples/mysql-iam-instance/main.tf similarity index 64% rename from examples/mysql_iam_instance/main.tf rename to examples/mysql-iam-instance/main.tf index 53348a4..5fed116 100644 --- a/examples/mysql_iam_instance/main.tf +++ b/examples/mysql-iam-instance/main.tf @@ -2,17 +2,22 @@ provider "aws" { region = local.region } +data "aws_availability_zones" "available" {} + locals { - region = "us-east-1" - name = "rds-proxy-ex-${replace(basename(path.cwd), "_", "-")}" + name = "ex-${basename(path.cwd)}" + region = "eu-west-1" db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account db_password = random_password.password.result + vpc_cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + tags = { - Name = local.name Example = local.name - Repository = "https://github.com/terraform-aws-modules/terraform-aws-rds-proxy" + GithubRepo = "terraform-aws-rds-proxy" + GithubOrg = "terraform-aws-modules" } } @@ -23,14 +28,12 @@ locals { module "rds_proxy" { source = "../../" - create_proxy = true - name = local.name iam_role_name = local.name vpc_subnet_ids = module.vpc.private_subnets vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - db_proxy_endpoints = { + endpoints = { read_write = { name = "read-write-endpoint" vpc_subnet_ids = module.vpc.private_subnets @@ -46,11 +49,10 @@ module "rds_proxy" { } } - secrets = { + auth = { (local.db_username) = { description = aws_secretsmanager_secret.superuser.description - arn = aws_secretsmanager_secret.superuser.arn - kms_key_id = aws_secretsmanager_secret.superuser.kms_key_id + secret_arn = aws_secretsmanager_secret.superuser.arn } } @@ -80,38 +82,52 @@ resource "random_password" "password" { module "vpc" { source = "terraform-aws-modules/vpc/aws" - version = "~> 3.0" + version = "~> 5.0" name = local.name - cidr = "10.0.0.0/18" + cidr = local.vpc_cidr - azs = ["${local.region}a", "${local.region}b", "${local.region}c"] - public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"] - private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"] - database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"] + azs = local.azs + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] + database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] - create_database_subnet_group = true - enable_nat_gateway = true - single_nat_gateway = true - map_public_ip_on_launch = false + tags = local.tags +} - manage_default_security_group = true - default_security_group_ingress = [] - default_security_group_egress = [] +module "rds" { + source = "terraform-aws-modules/rds/aws" + version = "~> 5.0" - enable_flow_log = true - flow_log_destination_type = "cloud-watch-logs" - create_flow_log_cloudwatch_log_group = true - create_flow_log_cloudwatch_iam_role = true - flow_log_max_aggregation_interval = 60 - flow_log_log_format = "$${version} $${account-id} $${interface-id} $${srcaddr} $${dstaddr} $${srcport} $${dstport} $${protocol} $${packets} $${bytes} $${start} $${end} $${action} $${log-status} $${vpc-id} $${subnet-id} $${instance-id} $${tcp-flags} $${type} $${pkt-srcaddr} $${pkt-dstaddr} $${region} $${az-id} $${sublocation-type} $${sublocation-id}" + username = local.db_username + password = local.db_password + + # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM + iam_database_authentication_enabled = false + + identifier = local.name + engine = "mysql" + engine_version = "8.0" + family = "mysql8.0" # DB parameter group + major_engine_version = "8.0" # DB option group + instance_class = "db.t4g.large" + allocated_storage = 20 + port = 3306 + apply_immediately = true + + db_subnet_group_name = module.vpc.database_subnet_group + vpc_security_group_ids = [module.rds_sg.security_group_id] + multi_az = true + + backup_retention_period = 0 + deletion_protection = false tags = local.tags } module "rds_sg" { source = "terraform-aws-modules/security-group/aws" - version = "~> 4.0" + version = "~> 5.0" name = "rds" description = "MySQL RDS example security group" @@ -130,57 +146,19 @@ module "rds_sg" { tags = local.tags } -module "rds" { - source = "terraform-aws-modules/rds/aws" - version = "~> 3.0" - - name = "example" - username = local.db_username - password = local.db_password - - # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM - iam_database_authentication_enabled = false - - identifier = local.name - engine = "mysql" - engine_version = "5.7.31" - family = "mysql5.7" - major_engine_version = "5.7" - port = 3306 - instance_class = "db.t3.micro" - allocated_storage = 5 - storage_encrypted = true - apply_immediately = true - - enabled_cloudwatch_logs_exports = ["general", "error", "slowquery"] - monitoring_interval = 60 - create_monitoring_role = true - - vpc_security_group_ids = [module.rds_sg.security_group_id] - subnet_ids = module.vpc.database_subnets - multi_az = true - - maintenance_window = "Mon:00:00-Mon:03:00" - backup_window = "03:00-06:00" - backup_retention_period = 0 - deletion_protection = false - - tags = local.tags -} - module "rds_proxy_sg" { source = "terraform-aws-modules/security-group/aws" - version = "~> 4.0" + version = "~> 5.0" - name = "rds_proxy" - description = "MySQL RDS Proxy example security group" + name = "${local.name}-proxy" + description = "PostgreSQL RDS Proxy example security group" vpc_id = module.vpc.vpc_id revoke_rules_on_delete = true ingress_with_cidr_blocks = [ { - description = "Private subnet PostgreSQL access" + description = "Private subnet MySQL access" rule = "mysql-tcp" cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) } @@ -207,7 +185,7 @@ data "aws_kms_alias" "secretsmanager" { resource "aws_secretsmanager_secret" "superuser" { name = local.db_username - description = "Database superuser, ${local.db_username}, databse connection values" + description = "Database superuser, ${local.db_username}, database connection values" kms_key_id = data.aws_kms_alias.secretsmanager.id tags = local.tags diff --git a/examples/postgresql_iam_cluster/outputs.tf b/examples/mysql-iam-instance/outputs.tf similarity index 99% rename from examples/postgresql_iam_cluster/outputs.tf rename to examples/mysql-iam-instance/outputs.tf index 3d97324..4b07beb 100644 --- a/examples/postgresql_iam_cluster/outputs.tf +++ b/examples/mysql-iam-instance/outputs.tf @@ -66,7 +66,7 @@ output "proxy_target_type" { value = module.rds_proxy.proxy_target_type } -# DB proxy endponts +# DB proxy endpoints output "db_proxy_endpoints" { description = "Array containing the full resource object and attributes for all DB proxy endpoints created" value = module.rds_proxy.db_proxy_endpoints diff --git a/examples/mysql_iam_instance/variables.tf b/examples/mysql-iam-instance/variables.tf similarity index 100% rename from examples/mysql_iam_instance/variables.tf rename to examples/mysql-iam-instance/variables.tf diff --git a/examples/mysql_iam_instance/versions.tf b/examples/mysql-iam-instance/versions.tf similarity index 74% rename from examples/mysql_iam_instance/versions.tf rename to examples/mysql-iam-instance/versions.tf index 31a0e14..b80a85f 100644 --- a/examples/mysql_iam_instance/versions.tf +++ b/examples/mysql-iam-instance/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 0.13.1" + required_version = ">= 1.0" required_providers { aws = { source = "hashicorp/aws" - version = ">= 3.38" + version = ">= 5.0" } random = { source = "hashicorp/random" diff --git a/examples/mysql_iam_cluster/main.tf b/examples/mysql_iam_cluster/main.tf deleted file mode 100644 index ef274d6..0000000 --- a/examples/mysql_iam_cluster/main.tf +++ /dev/null @@ -1,217 +0,0 @@ -provider "aws" { - region = local.region -} - -locals { - region = "us-east-1" - name = "rds-proxy-ex-${replace(basename(path.cwd), "_", "-")}" - - db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account - db_password = random_password.password.result - - tags = { - Name = local.name - Example = local.name - Repository = "https://github.com/terraform-aws-modules/terraform-aws-rds-proxy" - } -} - -################################################################################ -# RDS Proxy -################################################################################ - -module "rds_proxy" { - source = "../../" - - create_proxy = true - - name = local.name - iam_role_name = local.name - vpc_subnet_ids = module.vpc.private_subnets - vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - - db_proxy_endpoints = { - read_write = { - name = "read-write-endpoint" - vpc_subnet_ids = module.vpc.private_subnets - vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - tags = local.tags - }, - read_only = { - name = "read-only-endpoint" - vpc_subnet_ids = module.vpc.private_subnets - vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - target_role = "READ_ONLY" - tags = local.tags - } - } - - secrets = { - (local.db_username) = { - description = aws_secretsmanager_secret.superuser.description - arn = aws_secretsmanager_secret.superuser.arn - kms_key_id = aws_secretsmanager_secret.superuser.kms_key_id - } - } - - engine_family = "MYSQL" - debug_logging = true - - # Target Aurora cluster - target_db_cluster = true - db_cluster_identifier = module.rds.cluster_id - - tags = local.tags -} - -################################################################################ -# Supporting Resources -################################################################################ - -resource "random_pet" "users" { - length = 2 - separator = "_" -} - -resource "random_password" "password" { - length = 16 - special = false -} - -module "vpc" { - source = "terraform-aws-modules/vpc/aws" - version = "~> 3.0" - - name = local.name - cidr = "10.0.0.0/18" - - azs = ["${local.region}a", "${local.region}b", "${local.region}c"] - public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"] - private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"] - database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"] - - create_database_subnet_group = true - enable_nat_gateway = true - single_nat_gateway = true - map_public_ip_on_launch = false - - manage_default_security_group = true - default_security_group_ingress = [] - default_security_group_egress = [] - - enable_flow_log = true - flow_log_destination_type = "cloud-watch-logs" - create_flow_log_cloudwatch_log_group = true - create_flow_log_cloudwatch_iam_role = true - flow_log_max_aggregation_interval = 60 - flow_log_log_format = "$${version} $${account-id} $${interface-id} $${srcaddr} $${dstaddr} $${srcport} $${dstport} $${protocol} $${packets} $${bytes} $${start} $${end} $${action} $${log-status} $${vpc-id} $${subnet-id} $${instance-id} $${tcp-flags} $${type} $${pkt-srcaddr} $${pkt-dstaddr} $${region} $${az-id} $${sublocation-type} $${sublocation-id}" - - tags = local.tags -} - -module "rds" { - source = "terraform-aws-modules/rds-aurora/aws" - version = "~> 6.0" - - name = local.name - database_name = "example" - master_username = local.db_username - master_password = local.db_password - - # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM - iam_database_authentication_enabled = false - - engine = "aurora-mysql" - engine_version = "5.7.12" - instance_class = "db.r6g.large" - instances = { 1 = {}, 2 = {} } - - storage_encrypted = true - apply_immediately = true - skip_final_snapshot = true - - enabled_cloudwatch_logs_exports = ["general", "error", "slowquery"] - monitoring_interval = 60 - create_monitoring_role = true - - vpc_id = module.vpc.vpc_id - subnets = module.vpc.database_subnets - create_security_group = false - vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - - db_subnet_group_name = local.name # Created by VPC module - create_db_subnet_group = false - db_parameter_group_name = aws_db_parameter_group.aurora_db_mysql57_parameter_group.id - db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.aurora_cluster_mysql57_parameter_group.id - - tags = local.tags -} - -resource "aws_db_parameter_group" "aurora_db_mysql57_parameter_group" { - name = "example-aurora-db-57-parameter-group" - family = "aurora-mysql5.7" - description = "example-aurora-db-57-parameter-group" - - tags = local.tags -} - -resource "aws_rds_cluster_parameter_group" "aurora_cluster_mysql57_parameter_group" { - name = "example-aurora-57-cluster-parameter-group" - family = "aurora-mysql5.7" - description = "example-aurora-57-cluster-parameter-group" - - tags = local.tags -} - -module "rds_proxy_sg" { - source = "terraform-aws-modules/security-group/aws" - version = "~> 4.0" - - name = "rds_proxy" - description = "PostgreSQL RDS Proxy example security group" - vpc_id = module.vpc.vpc_id - - revoke_rules_on_delete = true - - ingress_with_cidr_blocks = [ - { - description = "Private subnet MySQL access" - rule = "mysql-tcp" - cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) - } - ] - - egress_with_cidr_blocks = [ - { - description = "Database subnet MySQL access" - rule = "mysql-tcp" - cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks) - }, - ] - - tags = local.tags -} - -################################################################################ -# Secrets - DB user passwords -################################################################################ - -data "aws_kms_alias" "secretsmanager" { - name = "alias/aws/secretsmanager" -} - -resource "aws_secretsmanager_secret" "superuser" { - name = local.db_username - description = "Database superuser, ${local.db_username}, databse connection values" - kms_key_id = data.aws_kms_alias.secretsmanager.id - - tags = local.tags -} - -resource "aws_secretsmanager_secret_version" "superuser" { - secret_id = aws_secretsmanager_secret.superuser.id - secret_string = jsonencode({ - username = local.db_username - password = local.db_password - }) -} diff --git a/examples/mysql_iam_cluster/versions.tf b/examples/mysql_iam_cluster/versions.tf deleted file mode 100644 index 31a0e14..0000000 --- a/examples/mysql_iam_cluster/versions.tf +++ /dev/null @@ -1,14 +0,0 @@ -terraform { - required_version = ">= 0.13.1" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 3.38" - } - random = { - source = "hashicorp/random" - version = ">= 2.0" - } - } -} diff --git a/examples/postgresql_iam_cluster/README.md b/examples/postgresql-iam-cluster/README.md similarity index 76% rename from examples/postgresql_iam_cluster/README.md rename to examples/postgresql-iam-cluster/README.md index 7267e8b..d895eb3 100644 --- a/examples/postgresql_iam_cluster/README.md +++ b/examples/postgresql-iam-cluster/README.md @@ -30,37 +30,29 @@ An EC2 instance configuration has been provided for use in validating the exampl | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 3.38 | -| [random](#requirement\_random) | >= 2.0 | +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3.38 | -| [random](#provider\_random) | >= 2.0 | +| [aws](#provider\_aws) | >= 5.0 | ## Modules | Name | Source | Version | |------|--------|---------| -| [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 6.0 | +| [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 8.0 | | [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a | -| [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 | +| [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 | ## Resources | Name | Type | |------|------| -| [aws_db_parameter_group.aurora_db_postgres11_parameter_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource | -| [aws_rds_cluster_parameter_group.aurora_cluster_postgres11_parameter_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_parameter_group) | resource | -| [aws_secretsmanager_secret.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource | -| [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource | -| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | -| [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | -| [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | +| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | ## Inputs diff --git a/examples/postgresql-iam-cluster/main.tf b/examples/postgresql-iam-cluster/main.tf new file mode 100644 index 0000000..6347ef6 --- /dev/null +++ b/examples/postgresql-iam-cluster/main.tf @@ -0,0 +1,144 @@ +provider "aws" { + region = local.region +} + +data "aws_availability_zones" "available" {} + +locals { + name = "ex-${basename(path.cwd)}" + region = "eu-west-1" + + vpc_cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + tags = { + Example = local.name + GithubRepo = "terraform-aws-rds-proxy" + GithubOrg = "terraform-aws-modules" + } +} + +################################################################################ +# RDS Proxy +################################################################################ + +module "rds_proxy" { + source = "../../" + + name = local.name + iam_role_name = local.name + vpc_subnet_ids = module.vpc.private_subnets + vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] + + endpoints = { + read_write = { + name = "read-write-endpoint" + vpc_subnet_ids = module.vpc.private_subnets + vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] + tags = local.tags + }, + read_only = { + name = "read-only-endpoint" + vpc_subnet_ids = module.vpc.private_subnets + vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] + target_role = "READ_ONLY" + tags = local.tags + } + } + + auth = { + "root" = { + description = "Cluster generated master user password" + secret_arn = module.rds.cluster_master_user_secret[0].secret_arn + } + } + + engine_family = "POSTGRESQL" + debug_logging = true + + # Target Aurora cluster + target_db_cluster = true + db_cluster_identifier = module.rds.cluster_id + + tags = local.tags +} + +################################################################################ +# Supporting Resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 5.0" + + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] + database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] + + tags = local.tags +} + +module "rds" { + source = "terraform-aws-modules/rds-aurora/aws" + version = "~> 8.0" + + name = local.name + engine = "aurora-postgresql" + engine_version = "14.7" + master_username = "root" + + # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM + iam_database_authentication_enabled = false + + instance_class = "db.r6g.large" + instances = { + 1 = {} + 2 = {} + } + + vpc_id = module.vpc.vpc_id + db_subnet_group_name = module.vpc.database_subnet_group_name + security_group_rules = { + vpc_ingress = { + cidr_blocks = module.vpc.private_subnets_cidr_blocks + } + } + + apply_immediately = true + skip_final_snapshot = true + + tags = local.tags +} + +module "rds_proxy_sg" { + source = "terraform-aws-modules/security-group/aws" + version = "~> 5.0" + + name = "${local.name}-proxy" + description = "PostgreSQL RDS Proxy example security group" + vpc_id = module.vpc.vpc_id + + revoke_rules_on_delete = true + + ingress_with_cidr_blocks = [ + { + description = "Private subnet PostgreSQL access" + rule = "postgresql-tcp" + cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) + } + ] + + egress_with_cidr_blocks = [ + { + description = "Database subnet PostgreSQL access" + rule = "postgresql-tcp" + cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks) + }, + ] + + tags = local.tags +} diff --git a/examples/mysql_iam_cluster/outputs.tf b/examples/postgresql-iam-cluster/outputs.tf similarity index 99% rename from examples/mysql_iam_cluster/outputs.tf rename to examples/postgresql-iam-cluster/outputs.tf index 3d97324..4b07beb 100644 --- a/examples/mysql_iam_cluster/outputs.tf +++ b/examples/postgresql-iam-cluster/outputs.tf @@ -66,7 +66,7 @@ output "proxy_target_type" { value = module.rds_proxy.proxy_target_type } -# DB proxy endponts +# DB proxy endpoints output "db_proxy_endpoints" { description = "Array containing the full resource object and attributes for all DB proxy endpoints created" value = module.rds_proxy.db_proxy_endpoints diff --git a/examples/postgresql_iam_cluster/variables.tf b/examples/postgresql-iam-cluster/variables.tf similarity index 100% rename from examples/postgresql_iam_cluster/variables.tf rename to examples/postgresql-iam-cluster/variables.tf diff --git a/examples/postgresql-iam-cluster/versions.tf b/examples/postgresql-iam-cluster/versions.tf new file mode 100644 index 0000000..ddfcb0e --- /dev/null +++ b/examples/postgresql-iam-cluster/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} diff --git a/examples/postgresql_iam_instance/README.md b/examples/postgresql-iam-instance/README.md similarity index 92% rename from examples/postgresql_iam_instance/README.md rename to examples/postgresql-iam-instance/README.md index 5535014..efb94a1 100644 --- a/examples/postgresql_iam_instance/README.md +++ b/examples/postgresql-iam-instance/README.md @@ -30,26 +30,26 @@ An EC2 instance configuration has been provided for use in validating the exampl | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 3.38 | +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | | [random](#requirement\_random) | >= 2.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3.38 | +| [aws](#provider\_aws) | >= 5.0 | | [random](#provider\_random) | >= 2.0 | ## Modules | Name | Source | Version | |------|--------|---------| -| [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 3.0 | +| [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 5.0 | | [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a | -| [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 | -| [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 4.0 | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 | +| [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | +| [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 | ## Resources @@ -59,6 +59,7 @@ An EC2 instance configuration has been provided for use in validating the exampl | [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource | | [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | | [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | +| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | | [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | ## Inputs diff --git a/examples/postgresql_iam_instance/main.tf b/examples/postgresql-iam-instance/main.tf similarity index 66% rename from examples/postgresql_iam_instance/main.tf rename to examples/postgresql-iam-instance/main.tf index 7dc47c9..5a0a254 100644 --- a/examples/postgresql_iam_instance/main.tf +++ b/examples/postgresql-iam-instance/main.tf @@ -2,17 +2,22 @@ provider "aws" { region = local.region } +data "aws_availability_zones" "available" {} + locals { - region = "us-east-1" - name = "rds-proxy-ex-${replace(basename(path.cwd), "_", "-")}" + name = "ex-${basename(path.cwd)}" + region = "eu-west-1" db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account db_password = random_password.password.result + vpc_cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + tags = { - Name = local.name Example = local.name - Repository = "https://github.com/terraform-aws-modules/terraform-aws-rds-proxy" + GithubRepo = "terraform-aws-rds-proxy" + GithubOrg = "terraform-aws-modules" } } @@ -23,14 +28,12 @@ locals { module "rds_proxy" { source = "../../" - create_proxy = true - name = local.name iam_role_name = local.name vpc_subnet_ids = module.vpc.private_subnets vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - db_proxy_endpoints = { + endpoints = { read_write = { name = "read-write-endpoint" vpc_subnet_ids = module.vpc.private_subnets @@ -46,11 +49,10 @@ module "rds_proxy" { } } - secrets = { + auth = { (local.db_username) = { description = aws_secretsmanager_secret.superuser.description - arn = aws_secretsmanager_secret.superuser.arn - kms_key_id = aws_secretsmanager_secret.superuser.kms_key_id + secret_arn = aws_secretsmanager_secret.superuser.arn } } @@ -80,38 +82,52 @@ resource "random_password" "password" { module "vpc" { source = "terraform-aws-modules/vpc/aws" - version = "~> 3.0" + version = "~> 5.0" name = local.name - cidr = "10.0.0.0/18" + cidr = local.vpc_cidr - azs = ["${local.region}a", "${local.region}b", "${local.region}c"] - public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"] - private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"] - database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"] + azs = local.azs + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] + database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] - create_database_subnet_group = true - enable_nat_gateway = true - single_nat_gateway = true - map_public_ip_on_launch = false + tags = local.tags +} - manage_default_security_group = true - default_security_group_ingress = [] - default_security_group_egress = [] +module "rds" { + source = "terraform-aws-modules/rds/aws" + version = "~> 5.0" - enable_flow_log = true - flow_log_destination_type = "cloud-watch-logs" - create_flow_log_cloudwatch_log_group = true - create_flow_log_cloudwatch_iam_role = true - flow_log_max_aggregation_interval = 60 - flow_log_log_format = "$${version} $${account-id} $${interface-id} $${srcaddr} $${dstaddr} $${srcport} $${dstport} $${protocol} $${packets} $${bytes} $${start} $${end} $${action} $${log-status} $${vpc-id} $${subnet-id} $${instance-id} $${tcp-flags} $${type} $${pkt-srcaddr} $${pkt-dstaddr} $${region} $${az-id} $${sublocation-type} $${sublocation-id}" + username = local.db_username + password = local.db_password + + # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM + iam_database_authentication_enabled = false + + identifier = local.name + engine = "postgres" + engine_version = "14" + family = "postgres14" # DB parameter group + major_engine_version = "14" # DB option group + instance_class = "db.t4g.large" + allocated_storage = 20 + port = 5432 + apply_immediately = true + + db_subnet_group_name = module.vpc.database_subnet_group + vpc_security_group_ids = [module.rds_sg.security_group_id] + multi_az = true + + backup_retention_period = 0 + deletion_protection = false tags = local.tags } module "rds_sg" { source = "terraform-aws-modules/security-group/aws" - version = "~> 4.0" + version = "~> 5.0" name = "rds" description = "PostgreSQL RDS example security group" @@ -130,47 +146,9 @@ module "rds_sg" { tags = local.tags } -module "rds" { - source = "terraform-aws-modules/rds/aws" - version = "~> 3.0" - - name = "example" - username = local.db_username - password = local.db_password - - # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM - iam_database_authentication_enabled = false - - identifier = local.name - engine = "postgres" - engine_version = "11.12" - family = "postgres11" - major_engine_version = "11" - port = 5432 - instance_class = "db.t3.micro" - allocated_storage = 5 - storage_encrypted = true - apply_immediately = true - - enabled_cloudwatch_logs_exports = ["postgresql"] - monitoring_interval = 60 - create_monitoring_role = true - - vpc_security_group_ids = [module.rds_sg.security_group_id] - subnet_ids = module.vpc.database_subnets - multi_az = true - - maintenance_window = "Mon:00:00-Mon:03:00" - backup_window = "03:00-06:00" - backup_retention_period = 0 - deletion_protection = false - - tags = local.tags -} - module "rds_proxy_sg" { source = "terraform-aws-modules/security-group/aws" - version = "~> 4.0" + version = "~> 5.0" name = "rds_proxy" description = "PostgreSQL RDS Proxy example security group" @@ -207,7 +185,7 @@ data "aws_kms_alias" "secretsmanager" { resource "aws_secretsmanager_secret" "superuser" { name = local.db_username - description = "Database superuser, ${local.db_username}, databse connection values" + description = "Database superuser, ${local.db_username}, database connection values" kms_key_id = data.aws_kms_alias.secretsmanager.id tags = local.tags diff --git a/examples/postgresql_iam_instance/outputs.tf b/examples/postgresql-iam-instance/outputs.tf similarity index 99% rename from examples/postgresql_iam_instance/outputs.tf rename to examples/postgresql-iam-instance/outputs.tf index 3d97324..4b07beb 100644 --- a/examples/postgresql_iam_instance/outputs.tf +++ b/examples/postgresql-iam-instance/outputs.tf @@ -66,7 +66,7 @@ output "proxy_target_type" { value = module.rds_proxy.proxy_target_type } -# DB proxy endponts +# DB proxy endpoints output "db_proxy_endpoints" { description = "Array containing the full resource object and attributes for all DB proxy endpoints created" value = module.rds_proxy.db_proxy_endpoints diff --git a/examples/postgresql_iam_instance/variables.tf b/examples/postgresql-iam-instance/variables.tf similarity index 100% rename from examples/postgresql_iam_instance/variables.tf rename to examples/postgresql-iam-instance/variables.tf diff --git a/examples/postgresql_iam_cluster/versions.tf b/examples/postgresql-iam-instance/versions.tf similarity index 74% rename from examples/postgresql_iam_cluster/versions.tf rename to examples/postgresql-iam-instance/versions.tf index 31a0e14..b80a85f 100644 --- a/examples/postgresql_iam_cluster/versions.tf +++ b/examples/postgresql-iam-instance/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 0.13.1" + required_version = ">= 1.0" required_providers { aws = { source = "hashicorp/aws" - version = ">= 3.38" + version = ">= 5.0" } random = { source = "hashicorp/random" diff --git a/examples/postgresql_iam_cluster/main.tf b/examples/postgresql_iam_cluster/main.tf deleted file mode 100644 index 26f85f1..0000000 --- a/examples/postgresql_iam_cluster/main.tf +++ /dev/null @@ -1,217 +0,0 @@ -provider "aws" { - region = local.region -} - -locals { - region = "us-east-1" - name = "rds-proxy-ex-${replace(basename(path.cwd), "_", "-")}" - - db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account - db_password = random_password.password.result - - tags = { - Name = local.name - Example = local.name - Repository = "https://github.com/terraform-aws-modules/terraform-aws-rds-proxy" - } -} - -################################################################################ -# RDS Proxy -################################################################################ - -module "rds_proxy" { - source = "../../" - - create_proxy = true - - name = local.name - iam_role_name = local.name - vpc_subnet_ids = module.vpc.private_subnets - vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - - db_proxy_endpoints = { - read_write = { - name = "read-write-endpoint" - vpc_subnet_ids = module.vpc.private_subnets - vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - tags = local.tags - }, - read_only = { - name = "read-only-endpoint" - vpc_subnet_ids = module.vpc.private_subnets - vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - target_role = "READ_ONLY" - tags = local.tags - } - } - - secrets = { - (local.db_username) = { - description = aws_secretsmanager_secret.superuser.description - arn = aws_secretsmanager_secret.superuser.arn - kms_key_id = aws_secretsmanager_secret.superuser.kms_key_id - } - } - - engine_family = "POSTGRESQL" - debug_logging = true - - # Target Aurora cluster - target_db_cluster = true - db_cluster_identifier = module.rds.cluster_id - - tags = local.tags -} - -################################################################################ -# Supporting Resources -################################################################################ - -resource "random_pet" "users" { - length = 2 - separator = "_" -} - -resource "random_password" "password" { - length = 16 - special = false -} - -module "vpc" { - source = "terraform-aws-modules/vpc/aws" - version = "~> 3.0" - - name = local.name - cidr = "10.0.0.0/18" - - azs = ["${local.region}a", "${local.region}b", "${local.region}c"] - public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"] - private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"] - database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"] - - create_database_subnet_group = true - enable_nat_gateway = true - single_nat_gateway = true - map_public_ip_on_launch = false - - manage_default_security_group = true - default_security_group_ingress = [] - default_security_group_egress = [] - - enable_flow_log = true - flow_log_destination_type = "cloud-watch-logs" - create_flow_log_cloudwatch_log_group = true - create_flow_log_cloudwatch_iam_role = true - flow_log_max_aggregation_interval = 60 - flow_log_log_format = "$${version} $${account-id} $${interface-id} $${srcaddr} $${dstaddr} $${srcport} $${dstport} $${protocol} $${packets} $${bytes} $${start} $${end} $${action} $${log-status} $${vpc-id} $${subnet-id} $${instance-id} $${tcp-flags} $${type} $${pkt-srcaddr} $${pkt-dstaddr} $${region} $${az-id} $${sublocation-type} $${sublocation-id}" - - tags = local.tags -} - -module "rds" { - source = "terraform-aws-modules/rds-aurora/aws" - version = "~> 6.0" - - name = local.name - database_name = "example" - master_username = local.db_username - master_password = local.db_password - - # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM - iam_database_authentication_enabled = false - - engine = "aurora-postgresql" - engine_version = "11.12" - instance_class = "db.r6g.large" - instances = { 1 = {}, 2 = {} } - - storage_encrypted = true - apply_immediately = true - skip_final_snapshot = true - - enabled_cloudwatch_logs_exports = ["postgresql"] - monitoring_interval = 60 - create_monitoring_role = true - - vpc_id = module.vpc.vpc_id - subnets = module.vpc.database_subnets - create_security_group = false - vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] - - db_subnet_group_name = local.name # Created by VPC module - create_db_subnet_group = false - db_parameter_group_name = aws_db_parameter_group.aurora_db_postgres11_parameter_group.id - db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.aurora_cluster_postgres11_parameter_group.id - - tags = local.tags -} - -resource "aws_db_parameter_group" "aurora_db_postgres11_parameter_group" { - name = "example-aurora-db-postgres11-parameter-group" - family = "aurora-postgresql11" - description = "test-aurora-db-postgres11-parameter-group" - - tags = local.tags -} - -resource "aws_rds_cluster_parameter_group" "aurora_cluster_postgres11_parameter_group" { - name = "example-aurora-postgres11-cluster-parameter-group" - family = "aurora-postgresql11" - description = "example-aurora-postgres11-cluster-parameter-group" - - tags = local.tags -} - -module "rds_proxy_sg" { - source = "terraform-aws-modules/security-group/aws" - version = "~> 4.0" - - name = "rds_proxy" - description = "PostgreSQL RDS Proxy example security group" - vpc_id = module.vpc.vpc_id - - revoke_rules_on_delete = true - - ingress_with_cidr_blocks = [ - { - description = "Private subnet PostgreSQL access" - rule = "postgresql-tcp" - cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) - } - ] - - egress_with_cidr_blocks = [ - { - description = "Database subnet PostgreSQL access" - rule = "postgresql-tcp" - cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks) - }, - ] - - tags = local.tags -} - -################################################################################ -# Secrets - DB user passwords -################################################################################ - -data "aws_kms_alias" "secretsmanager" { - name = "alias/aws/secretsmanager" -} - -resource "aws_secretsmanager_secret" "superuser" { - name = local.db_username - description = "Database superuser, ${local.db_username}, databse connection values" - kms_key_id = data.aws_kms_alias.secretsmanager.id - - tags = local.tags -} - -resource "aws_secretsmanager_secret_version" "superuser" { - secret_id = aws_secretsmanager_secret.superuser.id - secret_string = jsonencode({ - username = local.db_username - password = local.db_password - }) -} diff --git a/examples/postgresql_iam_instance/versions.tf b/examples/postgresql_iam_instance/versions.tf deleted file mode 100644 index 31a0e14..0000000 --- a/examples/postgresql_iam_instance/versions.tf +++ /dev/null @@ -1,14 +0,0 @@ -terraform { - required_version = ">= 0.13.1" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 3.38" - } - random = { - source = "hashicorp/random" - version = ">= 2.0" - } - } -} diff --git a/main.tf b/main.tf index fb4d0f0..a16f796 100644 --- a/main.tf +++ b/main.tf @@ -1,44 +1,48 @@ locals { - role_arn = var.create_proxy && var.create_iam_role ? aws_iam_role.this[0].arn : var.role_arn + role_arn = var.create && var.create_iam_role ? aws_iam_role.this[0].arn : var.role_arn role_name = coalesce(var.iam_role_name, var.name) policy_name = coalesce(var.iam_policy_name, var.name) } data "aws_region" "current" {} +data "aws_partition" "current" {} ################################################################################ # RDS Proxy ################################################################################ resource "aws_db_proxy" "this" { - count = var.create_proxy ? 1 : 0 + count = var.create ? 1 : 0 + + dynamic "auth" { + for_each = var.auth + + content { + auth_scheme = try(auth.value.auth_scheme, "SECRETS") + client_password_auth_type = try(auth.value.client_password_auth_type, null) + description = try(auth.value.description, null) + iam_auth = try(auth.value.iam_auth, null) + secret_arn = try(auth.value.secret_arn, null) + username = try(auth.value.username, null) + } + } - name = var.name debug_logging = var.debug_logging engine_family = var.engine_family idle_client_timeout = var.idle_client_timeout + name = var.name require_tls = var.require_tls role_arn = local.role_arn vpc_security_group_ids = var.vpc_security_group_ids vpc_subnet_ids = var.vpc_subnet_ids - dynamic "auth" { - for_each = var.secrets - content { - auth_scheme = var.auth_scheme - description = auth.value.description - iam_auth = var.iam_auth - secret_arn = auth.value.arn - } - } - tags = merge(var.tags, var.proxy_tags) depends_on = [aws_cloudwatch_log_group.this] } resource "aws_db_proxy_default_target_group" "this" { - count = var.create_proxy ? 1 : 0 + count = var.create ? 1 : 0 db_proxy_name = aws_db_proxy.this[0].name @@ -52,7 +56,7 @@ resource "aws_db_proxy_default_target_group" "this" { } resource "aws_db_proxy_target" "db_instance" { - count = var.create_proxy && var.target_db_instance ? 1 : 0 + count = var.create && var.target_db_instance ? 1 : 0 db_proxy_name = aws_db_proxy.this[0].name target_group_name = aws_db_proxy_default_target_group.this[0].name @@ -60,7 +64,7 @@ resource "aws_db_proxy_target" "db_instance" { } resource "aws_db_proxy_target" "db_cluster" { - count = var.create_proxy && var.target_db_cluster ? 1 : 0 + count = var.create && var.target_db_cluster ? 1 : 0 db_proxy_name = aws_db_proxy.this[0].name target_group_name = aws_db_proxy_default_target_group.this[0].name @@ -68,7 +72,7 @@ resource "aws_db_proxy_target" "db_cluster" { } resource "aws_db_proxy_endpoint" "this" { - for_each = { for k, v in var.db_proxy_endpoints : k => v if var.create_proxy } + for_each = { for k, v in var.endpoints : k => v if var.create } db_proxy_name = aws_db_proxy.this[0].name db_proxy_endpoint_name = each.value.name @@ -84,7 +88,7 @@ resource "aws_db_proxy_endpoint" "this" { ################################################################################ resource "aws_cloudwatch_log_group" "this" { - count = var.create_proxy && var.manage_log_group ? 1 : 0 + count = var.create && var.manage_log_group ? 1 : 0 name = "/aws/rds/proxy/${var.name}" retention_in_days = var.log_group_retention_in_days @@ -98,7 +102,7 @@ resource "aws_cloudwatch_log_group" "this" { ################################################################################ data "aws_iam_policy_document" "assume_role" { - count = var.create_proxy && var.create_iam_role ? 1 : 0 + count = var.create && var.create_iam_role ? 1 : 0 statement { sid = "RDSAssume" @@ -107,13 +111,13 @@ data "aws_iam_policy_document" "assume_role" { principals { type = "Service" - identifiers = ["rds.amazonaws.com"] + identifiers = ["rds.${data.aws_partition.current.dns_suffix}"] } } } resource "aws_iam_role" "this" { - count = var.create_proxy && var.create_iam_role ? 1 : 0 + count = var.create && var.create_iam_role ? 1 : 0 name = var.use_role_name_prefix ? null : local.role_name name_prefix = var.use_role_name_prefix ? "${local.role_name}-" : null @@ -129,19 +133,22 @@ resource "aws_iam_role" "this" { } data "aws_iam_policy_document" "this" { - count = var.create_proxy && var.create_iam_role ? 1 : 0 + count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 statement { - sid = "DecryptSecrets" - effect = "Allow" - actions = ["kms:Decrypt"] - resources = distinct([for secret in var.secrets : secret.kms_key_id]) + sid = "DecryptSecrets" + effect = "Allow" + actions = ["kms:Decrypt"] + resources = coalescelist( + var.kms_key_arns, + ["arn:${data.aws_partition.current.partition}:kms:*:*:key/*"] + ) + condition { test = "StringEquals" variable = "kms:ViaService" - values = [ - "secretsmanager.${data.aws_region.current.name}.amazonaws.com" + "secretsmanager.${data.aws_region.current.name}.${data.aws_partition.current.dns_suffix}" ] } } @@ -166,12 +173,12 @@ data "aws_iam_policy_document" "this" { "secretsmanager:ListSecretVersionIds", ] - resources = distinct([for secret in var.secrets : secret.arn]) + resources = distinct([for auth in var.auth : auth.secret_arn]) } } resource "aws_iam_role_policy" "this" { - count = var.create_proxy && var.create_iam_role && var.create_iam_policy ? 1 : 0 + count = var.create && var.create_iam_role && var.create_iam_policy ? 1 : 0 name = var.use_policy_name_prefix ? null : local.policy_name name_prefix = var.use_policy_name_prefix ? "${local.policy_name}-" : null diff --git a/outputs.tf b/outputs.tf index eda1189..06931ca 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,72 +1,72 @@ # RDS Proxy output "proxy_id" { description = "The ID for the proxy" - value = try(aws_db_proxy.this[0].id, "") + value = try(aws_db_proxy.this[0].id, null) } output "proxy_arn" { description = "The Amazon Resource Name (ARN) for the proxy" - value = try(aws_db_proxy.this[0].arn, "") + value = try(aws_db_proxy.this[0].arn, null) } output "proxy_endpoint" { description = "The endpoint that you can use to connect to the proxy" - value = try(aws_db_proxy.this[0].endpoint, "") + value = try(aws_db_proxy.this[0].endpoint, null) } # Proxy Default Target Group output "proxy_default_target_group_id" { description = "The ID for the default target group" - value = try(aws_db_proxy_default_target_group.this[0].id, "") + value = try(aws_db_proxy_default_target_group.this[0].id, null) } output "proxy_default_target_group_arn" { description = "The Amazon Resource Name (ARN) for the default target group" - value = try(aws_db_proxy_default_target_group.this[0].arn, "") + value = try(aws_db_proxy_default_target_group.this[0].arn, null) } output "proxy_default_target_group_name" { description = "The name of the default target group" - value = try(aws_db_proxy_default_target_group.this[0].name, "") + value = try(aws_db_proxy_default_target_group.this[0].name, null) } # Proxy Target output "proxy_target_endpoint" { description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type" - value = try(aws_db_proxy_target.db_instance[0].endpoint, aws_db_proxy_target.db_cluster[0].endpoint, "") + value = try(aws_db_proxy_target.db_instance[0].endpoint, aws_db_proxy_target.db_cluster[0].endpoint, null) } output "proxy_target_id" { description = "Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/)" - value = try(aws_db_proxy_target.db_instance[0].id, aws_db_proxy_target.db_cluster[0].id, "") + value = try(aws_db_proxy_target.db_instance[0].id, aws_db_proxy_target.db_cluster[0].id, null) } output "proxy_target_port" { description = "Port for the target RDS DB Instance or Aurora DB Cluster" - value = try(aws_db_proxy_target.db_instance[0].port, aws_db_proxy_target.db_cluster[0].port, "") + value = try(aws_db_proxy_target.db_instance[0].port, aws_db_proxy_target.db_cluster[0].port, null) } output "proxy_target_rds_resource_id" { description = "Identifier representing the DB Instance or DB Cluster target" - value = try(aws_db_proxy_target.db_instance[0].rds_resource_id, aws_db_proxy_target.db_cluster[0].rds_resource_id, "") + value = try(aws_db_proxy_target.db_instance[0].rds_resource_id, aws_db_proxy_target.db_cluster[0].rds_resource_id, null) } output "proxy_target_target_arn" { description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API" - value = try(aws_db_proxy_target.db_instance[0].target_arn, aws_db_proxy_target.db_cluster[0].target_arn, "") + value = try(aws_db_proxy_target.db_instance[0].target_arn, aws_db_proxy_target.db_cluster[0].target_arn, null) } output "proxy_target_tracked_cluster_id" { description = "DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS_INSTANCE target that is part of a DB Cluster" - value = try(aws_db_proxy_target.db_cluster[0].tracked_cluster_id, "") + value = try(aws_db_proxy_target.db_cluster[0].tracked_cluster_id, null) } output "proxy_target_type" { description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`" - value = try(aws_db_proxy_target.db_instance[0].type, aws_db_proxy_target.db_cluster[0].type, "") + value = try(aws_db_proxy_target.db_instance[0].type, aws_db_proxy_target.db_cluster[0].type, null) } -# DB proxy endponts +# DB proxy endpoints output "db_proxy_endpoints" { description = "Array containing the full resource object and attributes for all DB proxy endpoints created" value = aws_db_proxy_endpoint.this @@ -75,5 +75,5 @@ output "db_proxy_endpoints" { # CloudWatch logs output "log_group_arn" { description = "The Amazon Resource Name (ARN) of the CloudWatch log group" - value = try(aws_cloudwatch_log_group.this[0].arn, "") + value = try(aws_cloudwatch_log_group.this[0].arn, null) } diff --git a/variables.tf b/variables.tf index cb4254f..41657a9 100644 --- a/variables.tf +++ b/variables.tf @@ -1,15 +1,18 @@ +variable "create" { + description = "Whether cluster should be created (affects nearly all resources)" + type = bool + default = true +} + variable "tags" { - description = "A map of tags to use on all resources" + description = "A map of tags to add to all resources" type = map(string) default = {} } +################################################################################ # RDS Proxy -variable "create_proxy" { - description = "Determines whether a proxy and its resources will be created" - type = bool - default = true -} +################################################################################ variable "name" { description = "The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens" @@ -17,6 +20,12 @@ variable "name" { default = "" } +variable "auth" { + description = "Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters" + type = any + default = {} +} + variable "debug_logging" { description = "Whether the proxy includes detailed information about SQL statements in its logs" type = bool @@ -59,30 +68,12 @@ variable "vpc_subnet_ids" { default = [] } -variable "auth_scheme" { - description = "The type of authentication that the proxy uses for connections from the proxy to the underlying database. One of `SECRETS`" - type = string - default = "SECRETS" -} - -variable "iam_auth" { - description = "Whether to require or disallow AWS Identity and Access Management (IAM) authentication for connections to the proxy. One of `DISABLED`, `REQUIRED`" - type = string - default = "REQUIRED" -} - variable "proxy_tags" { description = "A map of tags to apply to the RDS Proxy" type = map(string) default = {} } -variable "secrets" { - description = "Map of secerets to be used by RDS Proxy for authentication to the database" - type = map(object({ arn = string, description = string, kms_key_id = string })) - default = {} -} - # Proxy Default Target Group variable "connection_borrow_timeout" { description = "The number of seconds for a proxy to wait for a connection to become available in the connection pool" @@ -116,7 +107,7 @@ variable "session_pinning_filters" { # Proxy Target variable "target_db_instance" { - description = "Determines whether DB instance is targetted by proxy" + description = "Determines whether DB instance is targeted by proxy" type = bool default = false } @@ -128,7 +119,7 @@ variable "db_instance_identifier" { } variable "target_db_cluster" { - description = "Determines whether DB cluster is targetted by proxy" + description = "Determines whether DB cluster is targeted by proxy" type = bool default = false } @@ -140,13 +131,16 @@ variable "db_cluster_identifier" { } # Proxy endpoints -variable "db_proxy_endpoints" { +variable "endpoints" { description = "Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`)" type = any default = {} } +################################################################################ # CloudWatch Logs +################################################################################ + variable "manage_log_group" { description = "Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist" type = bool @@ -171,7 +165,10 @@ variable "log_group_tags" { default = {} } +################################################################################ # IAM Role +################################################################################ + variable "create_iam_role" { description = "Determines whether an IAM role is created" type = bool @@ -244,3 +241,9 @@ variable "use_policy_name_prefix" { type = bool default = false } + +variable "kms_key_arns" { + description = "List of KMS Key ARNs to allow access to decrypt SecretsManager secrets" + type = list(string) + default = [] +} diff --git a/versions.tf b/versions.tf index 7f7a34a..ddfcb0e 100644 --- a/versions.tf +++ b/versions.tf @@ -1,10 +1,10 @@ terraform { - required_version = ">= 0.13.1" + required_version = ">= 1.0" required_providers { aws = { source = "hashicorp/aws" - version = ">= 3.38" + version = ">= 5.0" } } }