├── examples ├── mysql-iam-cluster │ ├── variables.tf │ ├── versions.tf │ ├── outputs.tf │ ├── main.tf │ └── README.md ├── mysql-iam-instance │ ├── variables.tf │ ├── versions.tf │ ├── outputs.tf │ ├── main.tf │ └── README.md ├── postgresql-iam-cluster │ ├── variables.tf │ ├── versions.tf │ ├── outputs.tf │ ├── main.tf │ └── README.md ├── postgresql-iam-instance │ ├── variables.tf │ ├── versions.tf │ ├── outputs.tf │ ├── main.tf │ └── README.md └── README.md ├── wrappers ├── outputs.tf ├── versions.tf ├── variables.tf ├── README.md └── main.tf ├── versions.tf ├── .editorconfig ├── .gitignore ├── .github └── workflows │ ├── lock.yml │ ├── release.yml │ ├── stale-actions.yaml │ ├── pr-title.yml │ └── pre-commit.yml ├── .releaserc.json ├── .pre-commit-config.yaml ├── docs └── UPGRADE-3.0.md ├── outputs.tf ├── CHANGELOG.md ├── main.tf ├── variables.tf ├── LICENSE └── README.md /examples/mysql-iam-cluster/variables.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/mysql-iam-instance/variables.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/postgresql-iam-cluster/variables.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/postgresql-iam-instance/variables.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /wrappers/outputs.tf: -------------------------------------------------------------------------------- 1 | output "wrapper" { 2 | description = "Map of outputs of a wrapper." 3 | value = module.wrapper 4 | # sensitive = false # No sensitive module output found 5 | } 6 | -------------------------------------------------------------------------------- /versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.7" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 6.15" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /wrappers/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.7" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 6.15" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/mysql-iam-cluster/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.7" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 6.15" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/postgresql-iam-cluster/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.7" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 6.15" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/mysql-iam-instance/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.7" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 6.15" 8 | } 9 | random = { 10 | source = "hashicorp/random" 11 | version = ">= 2.0" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/postgresql-iam-instance/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.5.7" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 6.15" 8 | } 9 | random = { 10 | source = "hashicorp/random" 11 | version = ">= 2.0" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /wrappers/variables.tf: -------------------------------------------------------------------------------- 1 | variable "defaults" { 2 | description = "Map of default values which will be used for each item." 3 | type = any 4 | default = {} 5 | } 6 | 7 | variable "items" { 8 | description = "Maps of items to create a wrapper from. Values are passed through to the module." 9 | type = any 10 | default = {} 11 | } 12 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | Please note - the examples provided serve two primary means: 4 | 5 | 1. Show users working examples of the various ways in which the module can be configured and features supported 6 | 2. A means of testing/validating module changes 7 | 8 | Please do not mistake the examples provided as "best practices". It is up to users to consult the AWS service documentation for best practices, usage recommendations, etc. 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | # Uses editorconfig to maintain consistent coding styles 3 | 4 | # top-most EditorConfig file 5 | root = true 6 | 7 | # Unix-style newlines with a newline ending every file 8 | [*] 9 | charset = utf-8 10 | end_of_line = lf 11 | indent_size = 2 12 | indent_style = space 13 | insert_final_newline = true 14 | max_line_length = 80 15 | trim_trailing_whitespace = true 16 | 17 | [*.{tf,tfvars}] 18 | indent_size = 2 19 | indent_style = space 20 | 21 | [*.md] 22 | max_line_length = 0 23 | trim_trailing_whitespace = false 24 | 25 | [Makefile] 26 | tab_width = 2 27 | indent_style = tab 28 | 29 | [COMMIT_EDITMSG] 30 | max_line_length = 0 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # Terraform lockfile 5 | .terraform.lock.hcl 6 | 7 | # .tfstate files 8 | *.tfstate 9 | *.tfstate.* 10 | 11 | # Crash log files 12 | crash.log 13 | 14 | # Exclude all .tfvars files, which are likely to contain sentitive data, such as 15 | # password, private keys, and other secrets. These should not be part of version 16 | # control as they are data points which are potentially sensitive and subject 17 | # to change depending on the environment. 18 | *.tfvars 19 | 20 | # Ignore override files as they are usually used to override resources locally and so 21 | # are not checked in 22 | override.tf 23 | override.tf.json 24 | *_override.tf 25 | *_override.tf.json 26 | 27 | # Ignore CLI configuration files 28 | .terraformrc 29 | terraform.rc 30 | 31 | # Lambda build artifacts 32 | builds/ 33 | __pycache__/ 34 | *.zip 35 | .tox 36 | 37 | # Local editors/macos files 38 | .DS_Store 39 | .idea 40 | -------------------------------------------------------------------------------- /.github/workflows/lock.yml: -------------------------------------------------------------------------------- 1 | name: 'Lock Threads' 2 | 3 | on: 4 | schedule: 5 | - cron: '50 1 * * *' 6 | 7 | jobs: 8 | lock: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: dessant/lock-threads@v5 12 | with: 13 | github-token: ${{ secrets.GITHUB_TOKEN }} 14 | issue-comment: > 15 | I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues. 16 | If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. 17 | issue-inactive-days: '30' 18 | pr-comment: > 19 | I'm going to lock this pull request because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues. 20 | If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. 21 | pr-inactive-days: '30' 22 | -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "branches": [ 3 | "main", 4 | "master" 5 | ], 6 | "ci": false, 7 | "plugins": [ 8 | [ 9 | "@semantic-release/commit-analyzer", 10 | { 11 | "preset": "conventionalcommits" 12 | } 13 | ], 14 | [ 15 | "@semantic-release/release-notes-generator", 16 | { 17 | "preset": "conventionalcommits" 18 | } 19 | ], 20 | [ 21 | "@semantic-release/github", 22 | { 23 | "successComment": "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:", 24 | "labels": false, 25 | "releasedLabels": false 26 | } 27 | ], 28 | [ 29 | "@semantic-release/changelog", 30 | { 31 | "changelogFile": "CHANGELOG.md", 32 | "changelogTitle": "# Changelog\n\nAll notable changes to this project will be documented in this file." 33 | } 34 | ], 35 | [ 36 | "@semantic-release/git", 37 | { 38 | "assets": [ 39 | "CHANGELOG.md" 40 | ], 41 | "message": "chore(release): version ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" 42 | } 43 | ] 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | - master 9 | paths: 10 | - '**/*.tpl' 11 | - '**/*.py' 12 | - '**/*.tf' 13 | - '.github/workflows/release.yml' 14 | 15 | jobs: 16 | release: 17 | name: Release 18 | runs-on: ubuntu-latest 19 | # Skip running release workflow on forks 20 | if: github.repository_owner == 'terraform-aws-modules' 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v5 24 | with: 25 | persist-credentials: false 26 | fetch-depth: 0 27 | 28 | - name: Set correct Node.js version 29 | uses: actions/setup-node@v6 30 | with: 31 | node-version: 24 32 | 33 | - name: Install dependencies 34 | run: | 35 | npm install \ 36 | @semantic-release/changelog@6.0.3 \ 37 | @semantic-release/git@10.0.1 \ 38 | conventional-changelog-conventionalcommits@9.1.0 39 | 40 | - name: Release 41 | uses: cycjimmy/semantic-release-action@v5 42 | with: 43 | semantic_version: 25.0.0 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }} 46 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/antonbabenko/pre-commit-terraform 3 | rev: v1.103.0 4 | hooks: 5 | - id: terraform_fmt 6 | - id: terraform_wrapper_module_for_each 7 | - id: terraform_docs 8 | args: 9 | - '--args=--lockfile=false' 10 | - id: terraform_tflint 11 | args: 12 | - '--args=--only=terraform_deprecated_interpolation' 13 | - '--args=--only=terraform_deprecated_index' 14 | - '--args=--only=terraform_unused_declarations' 15 | - '--args=--only=terraform_comment_syntax' 16 | - '--args=--only=terraform_documented_outputs' 17 | - '--args=--only=terraform_documented_variables' 18 | - '--args=--only=terraform_typed_variables' 19 | - '--args=--only=terraform_module_pinned_source' 20 | - '--args=--only=terraform_naming_convention' 21 | - '--args=--only=terraform_required_version' 22 | - '--args=--only=terraform_required_providers' 23 | - '--args=--only=terraform_standard_module_structure' 24 | - '--args=--only=terraform_workspace_remote' 25 | - id: terraform_validate 26 | - repo: https://github.com/pre-commit/pre-commit-hooks 27 | rev: v6.0.0 28 | hooks: 29 | - id: check-merge-conflict 30 | - id: end-of-file-fixer 31 | - id: trailing-whitespace 32 | -------------------------------------------------------------------------------- /.github/workflows/stale-actions.yaml: -------------------------------------------------------------------------------- 1 | name: 'Mark or close stale issues and PRs' 2 | on: 3 | schedule: 4 | - cron: '0 0 * * *' 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v10 11 | with: 12 | repo-token: ${{ secrets.GITHUB_TOKEN }} 13 | # Staling issues and PR's 14 | days-before-stale: 30 15 | stale-issue-label: stale 16 | stale-pr-label: stale 17 | stale-issue-message: | 18 | This issue has been automatically marked as stale because it has been open 30 days 19 | with no activity. Remove stale label or comment or this issue will be closed in 10 days 20 | stale-pr-message: | 21 | This PR has been automatically marked as stale because it has been open 30 days 22 | with no activity. Remove stale label or comment or this PR will be closed in 10 days 23 | # Not stale if have this labels or part of milestone 24 | exempt-issue-labels: bug,wip,on-hold 25 | exempt-pr-labels: bug,wip,on-hold 26 | exempt-all-milestones: true 27 | # Close issue operations 28 | # Label will be automatically removed if the issues are no longer closed nor locked. 29 | days-before-close: 10 30 | delete-branch: true 31 | close-issue-message: This issue was automatically closed because of stale in 10 days 32 | close-pr-message: This PR was automatically closed because of stale in 10 days 33 | -------------------------------------------------------------------------------- /docs/UPGRADE-3.0.md: -------------------------------------------------------------------------------- 1 | # Upgrade from v2.x to v3.x 2 | 3 | If you have any questions regarding this upgrade process, please consult the `examples` directory. 4 | If you find a bug, please open an issue with supporting configuration to reproduce. 5 | 6 | ## List of backwards incompatible changes 7 | 8 | - Minimum supported Terraform version is now 1.0 9 | - Minimum supported AWS provider version is now 5.0 10 | - 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. 11 | 12 | ### Variable and output changes 13 | 14 | 1. Removed variables: 15 | 16 | - `auth_scheme` is now set under the `auth` variable for a given auth entry 17 | - `iam_auth` is now set under the `auth` variable for a given auth entry 18 | 19 | 2. Renamed variables: 20 | 21 | - `create_proxy` -> `create` 22 | - `secrets` -> `auth` 23 | - `db_proxy_endpoints` -> `endpoints` 24 | 25 | 3. Added variables: 26 | 27 | - `kms_key_arns` - list of KMS key ARNs to use allowing permission to decrypt SecretsManager secrets 28 | 29 | 4. Removed outputs: 30 | 31 | - None 32 | 33 | 5. Renamed outputs: 34 | 35 | - None 36 | 37 | 6. Added outputs: 38 | 39 | - None 40 | 41 | ## Diff of Before (v2.x) vs After (v3.x) 42 | 43 | ```diff 44 | module "rds_proxy" { 45 | source = "terraform-aws-modules/rds-proxy/aws" 46 | - version = "~> 2.0" 47 | + version = "~> 3.0" 48 | 49 | # Only the affected attributes are shown 50 | - create_proxy = true 51 | + create = true 52 | 53 | - db_proxy_endpoints = { 54 | - ... 55 | - } 56 | + endpoints = { 57 | + ... 58 | + } 59 | 60 | - secrets = { 61 | - "superuser" = { 62 | - description = "Aurora PostgreSQL superuser password" 63 | - arn = "arn:aws:secretsmanager:eu-west-1:123456789012:secret:superuser-6gsjLD" 64 | - kms_key_id = "6ca29066-552a-46c5-a7d7-7bf9a15fc255" 65 | - } 66 | - } 67 | + auth = { 68 | + "superuser" = { 69 | + description = "Aurora PostgreSQL superuser password" 70 | + secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD" 71 | + } 72 | + } 73 | + kms_key_arns = ["arn:aws:kms:eu-west-1:123456789012:key/6ca29066-552a-46c5-a7d7-7bf9a15fc255"] 74 | } 75 | ``` 76 | 77 | ### State Changes 78 | 79 | - None 80 | -------------------------------------------------------------------------------- /.github/workflows/pr-title.yml: -------------------------------------------------------------------------------- 1 | name: 'Validate PR title' 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | jobs: 11 | main: 12 | name: Validate PR title 13 | runs-on: ubuntu-latest 14 | steps: 15 | # Please look up the latest version from 16 | # https://github.com/amannn/action-semantic-pull-request/releases 17 | - uses: amannn/action-semantic-pull-request@v6.1.1 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | with: 21 | # Configure which types are allowed. 22 | # Default: https://github.com/commitizen/conventional-commit-types 23 | types: | 24 | fix 25 | feat 26 | docs 27 | ci 28 | chore 29 | # Configure that a scope must always be provided. 30 | requireScope: false 31 | # Configure additional validation for the subject based on a regex. 32 | # This example ensures the subject starts with an uppercase character. 33 | subjectPattern: ^[A-Z].+$ 34 | # If `subjectPattern` is configured, you can use this property to override 35 | # the default error message that is shown when the pattern doesn't match. 36 | # The variables `subject` and `title` can be used within the message. 37 | subjectPatternError: | 38 | The subject "{subject}" found in the pull request title "{title}" 39 | didn't match the configured pattern. Please ensure that the subject 40 | starts with an uppercase character. 41 | # For work-in-progress PRs you can typically use draft pull requests 42 | # from Github. However, private repositories on the free plan don't have 43 | # this option and therefore this action allows you to opt-in to using the 44 | # special "[WIP]" prefix to indicate this state. This will avoid the 45 | # validation of the PR title and the pull request checks remain pending. 46 | # Note that a second check will be reported if this is enabled. 47 | wip: true 48 | # When using "Squash and merge" on a PR with only one commit, GitHub 49 | # will suggest using that commit message instead of the PR title for the 50 | # merge commit, and it's easy to commit this by mistake. Enable this option 51 | # to also validate the commit message for one commit PRs. 52 | validateSingleCommit: false 53 | -------------------------------------------------------------------------------- /wrappers/README.md: -------------------------------------------------------------------------------- 1 | # Wrapper for the root module 2 | 3 | The configuration in this directory contains an implementation of a single module wrapper pattern, which allows managing several copies of a module in places where using the native Terraform 0.13+ `for_each` feature is not feasible (e.g., with Terragrunt). 4 | 5 | You may want to use a single Terragrunt configuration file to manage multiple resources without duplicating `terragrunt.hcl` files for each copy of the same module. 6 | 7 | This wrapper does not implement any extra functionality. 8 | 9 | ## Usage with Terragrunt 10 | 11 | `terragrunt.hcl`: 12 | 13 | ```hcl 14 | terraform { 15 | source = "tfr:///terraform-aws-modules/rds-proxy/aws//wrappers" 16 | # Alternative source: 17 | # source = "git::git@github.com:terraform-aws-modules/terraform-aws-rds-proxy.git//wrappers?ref=master" 18 | } 19 | 20 | inputs = { 21 | defaults = { # Default values 22 | create = true 23 | tags = { 24 | Terraform = "true" 25 | Environment = "dev" 26 | } 27 | } 28 | 29 | items = { 30 | my-item = { 31 | # omitted... can be any argument supported by the module 32 | } 33 | my-second-item = { 34 | # omitted... can be any argument supported by the module 35 | } 36 | # omitted... 37 | } 38 | } 39 | ``` 40 | 41 | ## Usage with Terraform 42 | 43 | ```hcl 44 | module "wrapper" { 45 | source = "terraform-aws-modules/rds-proxy/aws//wrappers" 46 | 47 | defaults = { # Default values 48 | create = true 49 | tags = { 50 | Terraform = "true" 51 | Environment = "dev" 52 | } 53 | } 54 | 55 | items = { 56 | my-item = { 57 | # omitted... can be any argument supported by the module 58 | } 59 | my-second-item = { 60 | # omitted... can be any argument supported by the module 61 | } 62 | # omitted... 63 | } 64 | } 65 | ``` 66 | 67 | ## Example: Manage multiple S3 buckets in one Terragrunt layer 68 | 69 | `eu-west-1/s3-buckets/terragrunt.hcl`: 70 | 71 | ```hcl 72 | terraform { 73 | source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers" 74 | # Alternative source: 75 | # source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git//wrappers?ref=master" 76 | } 77 | 78 | inputs = { 79 | defaults = { 80 | force_destroy = true 81 | 82 | attach_elb_log_delivery_policy = true 83 | attach_lb_log_delivery_policy = true 84 | attach_deny_insecure_transport_policy = true 85 | attach_require_latest_tls_policy = true 86 | } 87 | 88 | items = { 89 | bucket1 = { 90 | bucket = "my-random-bucket-1" 91 | } 92 | bucket2 = { 93 | bucket = "my-random-bucket-2" 94 | tags = { 95 | Secure = "probably" 96 | } 97 | } 98 | } 99 | } 100 | ``` 101 | -------------------------------------------------------------------------------- /examples/mysql-iam-cluster/outputs.tf: -------------------------------------------------------------------------------- 1 | # RDS Proxy 2 | output "proxy_id" { 3 | description = "The ID for the proxy" 4 | value = module.rds_proxy.proxy_id 5 | } 6 | 7 | output "proxy_arn" { 8 | description = "The Amazon Resource Name (ARN) for the proxy" 9 | value = module.rds_proxy.proxy_arn 10 | } 11 | 12 | output "proxy_endpoint" { 13 | description = "The endpoint that you can use to connect to the proxy" 14 | value = module.rds_proxy.proxy_endpoint 15 | } 16 | 17 | # Proxy Default Target Group 18 | output "proxy_default_target_group_id" { 19 | description = "The ID for the default target group" 20 | value = module.rds_proxy.proxy_default_target_group_id 21 | } 22 | 23 | output "proxy_default_target_group_arn" { 24 | description = "The Amazon Resource Name (ARN) for the default target group" 25 | value = module.rds_proxy.proxy_default_target_group_arn 26 | } 27 | 28 | output "proxy_default_target_group_name" { 29 | description = "The name of the default target group" 30 | value = module.rds_proxy.proxy_default_target_group_name 31 | } 32 | 33 | # Proxy Target 34 | output "proxy_target_endpoint" { 35 | description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type" 36 | value = module.rds_proxy.proxy_target_endpoint 37 | } 38 | 39 | output "proxy_target_id" { 40 | 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 (/)" 41 | value = module.rds_proxy.proxy_target_id 42 | } 43 | 44 | output "proxy_target_port" { 45 | description = "Port for the target RDS DB Instance or Aurora DB Cluster" 46 | value = module.rds_proxy.proxy_target_port 47 | } 48 | 49 | output "proxy_target_rds_resource_id" { 50 | description = "Identifier representing the DB Instance or DB Cluster target" 51 | value = module.rds_proxy.proxy_target_rds_resource_id 52 | } 53 | 54 | output "proxy_target_target_arn" { 55 | description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API" 56 | value = module.rds_proxy.proxy_target_target_arn 57 | } 58 | 59 | output "proxy_target_tracked_cluster_id" { 60 | 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" 61 | value = module.rds_proxy.proxy_target_tracked_cluster_id 62 | } 63 | 64 | output "proxy_target_type" { 65 | description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`" 66 | value = module.rds_proxy.proxy_target_type 67 | } 68 | 69 | # DB proxy endpoints 70 | output "db_proxy_endpoints" { 71 | description = "Array containing the full resource object and attributes for all DB proxy endpoints created" 72 | value = module.rds_proxy.db_proxy_endpoints 73 | } 74 | 75 | # CloudWatch logs 76 | output "log_group_arn" { 77 | description = "The Amazon Resource Name (ARN) of the CloudWatch log group" 78 | value = module.rds_proxy.log_group_arn 79 | } 80 | 81 | output "log_group_name" { 82 | description = "The name of the CloudWatch log group" 83 | value = module.rds_proxy.log_group_name 84 | } 85 | -------------------------------------------------------------------------------- /examples/mysql-iam-instance/outputs.tf: -------------------------------------------------------------------------------- 1 | # RDS Proxy 2 | output "proxy_id" { 3 | description = "The ID for the proxy" 4 | value = module.rds_proxy.proxy_id 5 | } 6 | 7 | output "proxy_arn" { 8 | description = "The Amazon Resource Name (ARN) for the proxy" 9 | value = module.rds_proxy.proxy_arn 10 | } 11 | 12 | output "proxy_endpoint" { 13 | description = "The endpoint that you can use to connect to the proxy" 14 | value = module.rds_proxy.proxy_endpoint 15 | } 16 | 17 | # Proxy Default Target Group 18 | output "proxy_default_target_group_id" { 19 | description = "The ID for the default target group" 20 | value = module.rds_proxy.proxy_default_target_group_id 21 | } 22 | 23 | output "proxy_default_target_group_arn" { 24 | description = "The Amazon Resource Name (ARN) for the default target group" 25 | value = module.rds_proxy.proxy_default_target_group_arn 26 | } 27 | 28 | output "proxy_default_target_group_name" { 29 | description = "The name of the default target group" 30 | value = module.rds_proxy.proxy_default_target_group_name 31 | } 32 | 33 | # Proxy Target 34 | output "proxy_target_endpoint" { 35 | description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type" 36 | value = module.rds_proxy.proxy_target_endpoint 37 | } 38 | 39 | output "proxy_target_id" { 40 | 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 (/)" 41 | value = module.rds_proxy.proxy_target_id 42 | } 43 | 44 | output "proxy_target_port" { 45 | description = "Port for the target RDS DB Instance or Aurora DB Cluster" 46 | value = module.rds_proxy.proxy_target_port 47 | } 48 | 49 | output "proxy_target_rds_resource_id" { 50 | description = "Identifier representing the DB Instance or DB Cluster target" 51 | value = module.rds_proxy.proxy_target_rds_resource_id 52 | } 53 | 54 | output "proxy_target_target_arn" { 55 | description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API" 56 | value = module.rds_proxy.proxy_target_target_arn 57 | } 58 | 59 | output "proxy_target_tracked_cluster_id" { 60 | 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" 61 | value = module.rds_proxy.proxy_target_tracked_cluster_id 62 | } 63 | 64 | output "proxy_target_type" { 65 | description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`" 66 | value = module.rds_proxy.proxy_target_type 67 | } 68 | 69 | # DB proxy endpoints 70 | output "db_proxy_endpoints" { 71 | description = "Array containing the full resource object and attributes for all DB proxy endpoints created" 72 | value = module.rds_proxy.db_proxy_endpoints 73 | } 74 | 75 | # CloudWatch logs 76 | output "log_group_arn" { 77 | description = "The Amazon Resource Name (ARN) of the CloudWatch log group" 78 | value = module.rds_proxy.log_group_arn 79 | } 80 | 81 | output "log_group_name" { 82 | description = "The name of the CloudWatch log group" 83 | value = module.rds_proxy.log_group_name 84 | } 85 | -------------------------------------------------------------------------------- /examples/postgresql-iam-instance/outputs.tf: -------------------------------------------------------------------------------- 1 | # RDS Proxy 2 | output "proxy_id" { 3 | description = "The ID for the proxy" 4 | value = module.rds_proxy.proxy_id 5 | } 6 | 7 | output "proxy_arn" { 8 | description = "The Amazon Resource Name (ARN) for the proxy" 9 | value = module.rds_proxy.proxy_arn 10 | } 11 | 12 | output "proxy_endpoint" { 13 | description = "The endpoint that you can use to connect to the proxy" 14 | value = module.rds_proxy.proxy_endpoint 15 | } 16 | 17 | # Proxy Default Target Group 18 | output "proxy_default_target_group_id" { 19 | description = "The ID for the default target group" 20 | value = module.rds_proxy.proxy_default_target_group_id 21 | } 22 | 23 | output "proxy_default_target_group_arn" { 24 | description = "The Amazon Resource Name (ARN) for the default target group" 25 | value = module.rds_proxy.proxy_default_target_group_arn 26 | } 27 | 28 | output "proxy_default_target_group_name" { 29 | description = "The name of the default target group" 30 | value = module.rds_proxy.proxy_default_target_group_name 31 | } 32 | 33 | # Proxy Target 34 | output "proxy_target_endpoint" { 35 | description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type" 36 | value = module.rds_proxy.proxy_target_endpoint 37 | } 38 | 39 | output "proxy_target_id" { 40 | 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 (/)" 41 | value = module.rds_proxy.proxy_target_id 42 | } 43 | 44 | output "proxy_target_port" { 45 | description = "Port for the target RDS DB Instance or Aurora DB Cluster" 46 | value = module.rds_proxy.proxy_target_port 47 | } 48 | 49 | output "proxy_target_rds_resource_id" { 50 | description = "Identifier representing the DB Instance or DB Cluster target" 51 | value = module.rds_proxy.proxy_target_rds_resource_id 52 | } 53 | 54 | output "proxy_target_target_arn" { 55 | description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API" 56 | value = module.rds_proxy.proxy_target_target_arn 57 | } 58 | 59 | output "proxy_target_tracked_cluster_id" { 60 | 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" 61 | value = module.rds_proxy.proxy_target_tracked_cluster_id 62 | } 63 | 64 | output "proxy_target_type" { 65 | description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`" 66 | value = module.rds_proxy.proxy_target_type 67 | } 68 | 69 | # DB proxy endpoints 70 | output "db_proxy_endpoints" { 71 | description = "Array containing the full resource object and attributes for all DB proxy endpoints created" 72 | value = module.rds_proxy.db_proxy_endpoints 73 | } 74 | 75 | # CloudWatch logs 76 | output "log_group_arn" { 77 | description = "The Amazon Resource Name (ARN) of the CloudWatch log group" 78 | value = module.rds_proxy.log_group_arn 79 | } 80 | 81 | output "log_group_name" { 82 | description = "The name of the CloudWatch log group" 83 | value = module.rds_proxy.log_group_name 84 | } 85 | -------------------------------------------------------------------------------- /examples/postgresql-iam-cluster/outputs.tf: -------------------------------------------------------------------------------- 1 | # RDS Proxy 2 | output "proxy_id" { 3 | description = "The ID for the proxy" 4 | value = module.rds_proxy.proxy_id 5 | } 6 | 7 | output "proxy_arn" { 8 | description = "The Amazon Resource Name (ARN) for the proxy" 9 | value = module.rds_proxy.proxy_arn 10 | } 11 | 12 | output "proxy_endpoint" { 13 | description = "The endpoint that you can use to connect to the proxy" 14 | value = module.rds_proxy.proxy_endpoint 15 | } 16 | 17 | # Proxy Default Target Group 18 | output "proxy_default_target_group_id" { 19 | description = "The ID for the default target group" 20 | value = module.rds_proxy.proxy_default_target_group_id 21 | } 22 | 23 | output "proxy_default_target_group_arn" { 24 | description = "The Amazon Resource Name (ARN) for the default target group" 25 | value = module.rds_proxy.proxy_default_target_group_arn 26 | } 27 | 28 | output "proxy_default_target_group_name" { 29 | description = "The name of the default target group" 30 | value = module.rds_proxy.proxy_default_target_group_name 31 | } 32 | 33 | # Proxy Target 34 | output "proxy_target_endpoint" { 35 | description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type" 36 | value = module.rds_proxy.proxy_target_endpoint 37 | } 38 | 39 | output "proxy_target_id" { 40 | 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 (/)" 41 | value = module.rds_proxy.proxy_target_id 42 | } 43 | 44 | output "proxy_target_port" { 45 | description = "Port for the target RDS DB Instance or Aurora DB Cluster" 46 | value = module.rds_proxy.proxy_target_port 47 | } 48 | 49 | output "proxy_target_rds_resource_id" { 50 | description = "Identifier representing the DB Instance or DB Cluster target" 51 | value = module.rds_proxy.proxy_target_rds_resource_id 52 | } 53 | 54 | output "proxy_target_target_arn" { 55 | description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API" 56 | value = module.rds_proxy.proxy_target_target_arn 57 | } 58 | 59 | output "proxy_target_tracked_cluster_id" { 60 | 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" 61 | value = module.rds_proxy.proxy_target_tracked_cluster_id 62 | } 63 | 64 | output "proxy_target_type" { 65 | description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`" 66 | value = module.rds_proxy.proxy_target_type 67 | } 68 | 69 | # DB proxy endpoints 70 | output "db_proxy_endpoints" { 71 | description = "Array containing the full resource object and attributes for all DB proxy endpoints created" 72 | value = module.rds_proxy.db_proxy_endpoints 73 | } 74 | 75 | # CloudWatch logs 76 | output "log_group_arn" { 77 | description = "The Amazon Resource Name (ARN) of the CloudWatch log group" 78 | value = module.rds_proxy.log_group_arn 79 | } 80 | 81 | output "log_group_name" { 82 | description = "The name of the CloudWatch log group" 83 | value = module.rds_proxy.log_group_name 84 | } 85 | 86 | # IAM role 87 | output "iam_role_arn" { 88 | description = "The Amazon Resource Name (ARN) specifying the role proxy uses to access secrets" 89 | value = module.rds_proxy.iam_role_arn 90 | } 91 | 92 | output "iam_role_name" { 93 | description = "The name of the role proxy uses to access secrets" 94 | value = module.rds_proxy.iam_role_name 95 | } 96 | 97 | output "iam_role_unique_id" { 98 | description = "Stable and unique string identifying the role proxy uses to access secrets" 99 | value = module.rds_proxy.iam_role_unique_id 100 | } 101 | -------------------------------------------------------------------------------- /examples/mysql-iam-cluster/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = local.region 3 | } 4 | 5 | data "aws_availability_zones" "available" {} 6 | 7 | locals { 8 | name = "ex-${basename(path.cwd)}" 9 | region = "eu-west-1" 10 | 11 | vpc_cidr = "10.0.0.0/16" 12 | azs = slice(data.aws_availability_zones.available.names, 0, 3) 13 | 14 | tags = { 15 | Example = local.name 16 | GithubRepo = "terraform-aws-rds-proxy" 17 | GithubOrg = "terraform-aws-modules" 18 | } 19 | } 20 | 21 | ################################################################################ 22 | # RDS Proxy 23 | ################################################################################ 24 | 25 | module "rds_proxy" { 26 | source = "../../" 27 | 28 | name = local.name 29 | iam_role_name = local.name 30 | vpc_subnet_ids = module.vpc.private_subnets 31 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 32 | 33 | endpoints = { 34 | read_write = { 35 | name = "read-write-endpoint" 36 | vpc_subnet_ids = module.vpc.private_subnets 37 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 38 | tags = local.tags 39 | }, 40 | read_only = { 41 | name = "read-only-endpoint" 42 | vpc_subnet_ids = module.vpc.private_subnets 43 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 44 | target_role = "READ_ONLY" 45 | tags = local.tags 46 | } 47 | } 48 | 49 | auth = { 50 | "root" = { 51 | description = "Cluster generated master user password" 52 | secret_arn = module.rds.cluster_master_user_secret[0].secret_arn 53 | } 54 | } 55 | 56 | engine_family = "MYSQL" 57 | debug_logging = true 58 | 59 | # Target Aurora cluster 60 | target_db_cluster = true 61 | db_cluster_identifier = module.rds.cluster_id 62 | 63 | tags = local.tags 64 | } 65 | 66 | ################################################################################ 67 | # Supporting Resources 68 | ################################################################################ 69 | 70 | module "vpc" { 71 | source = "terraform-aws-modules/vpc/aws" 72 | version = "~> 6.0" 73 | 74 | name = local.name 75 | cidr = local.vpc_cidr 76 | 77 | azs = local.azs 78 | public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] 79 | private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] 80 | database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] 81 | 82 | tags = local.tags 83 | } 84 | 85 | module "rds" { 86 | source = "terraform-aws-modules/rds-aurora/aws" 87 | version = "~> 9.0" 88 | 89 | name = local.name 90 | engine = "aurora-mysql" 91 | engine_version = "8.0" 92 | master_username = "root" 93 | 94 | # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM 95 | iam_database_authentication_enabled = false 96 | 97 | instance_class = "db.r6g.large" 98 | instances = { 99 | 1 = {} 100 | 2 = {} 101 | } 102 | 103 | vpc_id = module.vpc.vpc_id 104 | db_subnet_group_name = module.vpc.database_subnet_group_name 105 | security_group_rules = { 106 | vpc_ingress = { 107 | cidr_blocks = module.vpc.private_subnets_cidr_blocks 108 | } 109 | } 110 | 111 | apply_immediately = true 112 | skip_final_snapshot = true 113 | 114 | tags = local.tags 115 | } 116 | 117 | module "rds_proxy_sg" { 118 | source = "terraform-aws-modules/security-group/aws" 119 | version = "~> 5.0" 120 | 121 | name = "${local.name}-proxy" 122 | description = "PostgreSQL RDS Proxy example security group" 123 | vpc_id = module.vpc.vpc_id 124 | 125 | revoke_rules_on_delete = true 126 | 127 | ingress_with_cidr_blocks = [ 128 | { 129 | description = "Private subnet MySQL access" 130 | rule = "mysql-tcp" 131 | cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) 132 | } 133 | ] 134 | 135 | egress_with_cidr_blocks = [ 136 | { 137 | description = "Database subnet MySQL access" 138 | rule = "mysql-tcp" 139 | cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks) 140 | }, 141 | ] 142 | 143 | tags = local.tags 144 | } 145 | -------------------------------------------------------------------------------- /examples/postgresql-iam-cluster/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = local.region 3 | } 4 | 5 | data "aws_availability_zones" "available" {} 6 | 7 | locals { 8 | name = "ex-${basename(path.cwd)}" 9 | region = "eu-west-1" 10 | 11 | vpc_cidr = "10.0.0.0/16" 12 | azs = slice(data.aws_availability_zones.available.names, 0, 3) 13 | 14 | tags = { 15 | Example = local.name 16 | GithubRepo = "terraform-aws-rds-proxy" 17 | GithubOrg = "terraform-aws-modules" 18 | } 19 | } 20 | 21 | ################################################################################ 22 | # RDS Proxy 23 | ################################################################################ 24 | 25 | module "rds_proxy" { 26 | source = "../../" 27 | 28 | name = local.name 29 | iam_role_name = local.name 30 | vpc_subnet_ids = module.vpc.private_subnets 31 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 32 | 33 | endpoints = { 34 | read_write = { 35 | name = "read-write-endpoint" 36 | vpc_subnet_ids = module.vpc.private_subnets 37 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 38 | tags = local.tags 39 | }, 40 | read_only = { 41 | name = "read-only-endpoint" 42 | vpc_subnet_ids = module.vpc.private_subnets 43 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 44 | target_role = "READ_ONLY" 45 | tags = local.tags 46 | } 47 | } 48 | 49 | auth = { 50 | "root" = { 51 | description = "Cluster generated master user password" 52 | secret_arn = module.rds.cluster_master_user_secret[0].secret_arn 53 | } 54 | } 55 | 56 | engine_family = "POSTGRESQL" 57 | debug_logging = true 58 | 59 | # Target Aurora cluster 60 | target_db_cluster = true 61 | db_cluster_identifier = module.rds.cluster_id 62 | 63 | tags = local.tags 64 | } 65 | 66 | ################################################################################ 67 | # Supporting Resources 68 | ################################################################################ 69 | 70 | module "vpc" { 71 | source = "terraform-aws-modules/vpc/aws" 72 | version = "~> 6.0" 73 | 74 | name = local.name 75 | cidr = local.vpc_cidr 76 | 77 | azs = local.azs 78 | public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] 79 | private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] 80 | database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] 81 | 82 | tags = local.tags 83 | } 84 | 85 | module "rds" { 86 | source = "terraform-aws-modules/rds-aurora/aws" 87 | version = "~> 9.0" 88 | 89 | name = local.name 90 | engine = "aurora-postgresql" 91 | engine_version = "17.5" 92 | master_username = "root" 93 | 94 | # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM 95 | iam_database_authentication_enabled = false 96 | 97 | instance_class = "db.r6g.large" 98 | instances = { 99 | 1 = {} 100 | 2 = {} 101 | } 102 | 103 | vpc_id = module.vpc.vpc_id 104 | db_subnet_group_name = module.vpc.database_subnet_group_name 105 | security_group_rules = { 106 | vpc_ingress = { 107 | cidr_blocks = module.vpc.private_subnets_cidr_blocks 108 | } 109 | } 110 | 111 | apply_immediately = true 112 | skip_final_snapshot = true 113 | 114 | tags = local.tags 115 | } 116 | 117 | module "rds_proxy_sg" { 118 | source = "terraform-aws-modules/security-group/aws" 119 | version = "~> 5.0" 120 | 121 | name = "${local.name}-proxy" 122 | description = "PostgreSQL RDS Proxy example security group" 123 | vpc_id = module.vpc.vpc_id 124 | 125 | revoke_rules_on_delete = true 126 | 127 | ingress_with_cidr_blocks = [ 128 | { 129 | description = "Private subnet PostgreSQL access" 130 | rule = "postgresql-tcp" 131 | cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) 132 | } 133 | ] 134 | 135 | egress_with_cidr_blocks = [ 136 | { 137 | description = "Database subnet PostgreSQL access" 138 | rule = "postgresql-tcp" 139 | cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks) 140 | }, 141 | ] 142 | 143 | tags = local.tags 144 | } 145 | -------------------------------------------------------------------------------- /wrappers/main.tf: -------------------------------------------------------------------------------- 1 | module "wrapper" { 2 | source = "../" 3 | 4 | for_each = var.items 5 | 6 | auth = try(each.value.auth, var.defaults.auth, { 7 | default = { 8 | auth_scheme = "SECRETS" 9 | } 10 | }) 11 | connection_borrow_timeout = try(each.value.connection_borrow_timeout, var.defaults.connection_borrow_timeout, null) 12 | create = try(each.value.create, var.defaults.create, true) 13 | create_iam_policy = try(each.value.create_iam_policy, var.defaults.create_iam_policy, true) 14 | create_iam_role = try(each.value.create_iam_role, var.defaults.create_iam_role, true) 15 | db_cluster_identifier = try(each.value.db_cluster_identifier, var.defaults.db_cluster_identifier, "") 16 | db_instance_identifier = try(each.value.db_instance_identifier, var.defaults.db_instance_identifier, "") 17 | debug_logging = try(each.value.debug_logging, var.defaults.debug_logging, false) 18 | default_auth_scheme = try(each.value.default_auth_scheme, var.defaults.default_auth_scheme, null) 19 | endpoints = try(each.value.endpoints, var.defaults.endpoints, {}) 20 | engine_family = try(each.value.engine_family, var.defaults.engine_family, "") 21 | iam_policy_name = try(each.value.iam_policy_name, var.defaults.iam_policy_name, "") 22 | iam_role_description = try(each.value.iam_role_description, var.defaults.iam_role_description, "") 23 | iam_role_force_detach_policies = try(each.value.iam_role_force_detach_policies, var.defaults.iam_role_force_detach_policies, true) 24 | iam_role_max_session_duration = try(each.value.iam_role_max_session_duration, var.defaults.iam_role_max_session_duration, 43200) 25 | iam_role_name = try(each.value.iam_role_name, var.defaults.iam_role_name, "") 26 | iam_role_path = try(each.value.iam_role_path, var.defaults.iam_role_path, null) 27 | iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.defaults.iam_role_permissions_boundary, null) 28 | iam_role_tags = try(each.value.iam_role_tags, var.defaults.iam_role_tags, {}) 29 | idle_client_timeout = try(each.value.idle_client_timeout, var.defaults.idle_client_timeout, 1800) 30 | init_query = try(each.value.init_query, var.defaults.init_query, "") 31 | kms_key_arns = try(each.value.kms_key_arns, var.defaults.kms_key_arns, []) 32 | log_group_class = try(each.value.log_group_class, var.defaults.log_group_class, null) 33 | log_group_kms_key_id = try(each.value.log_group_kms_key_id, var.defaults.log_group_kms_key_id, null) 34 | log_group_retention_in_days = try(each.value.log_group_retention_in_days, var.defaults.log_group_retention_in_days, 30) 35 | log_group_tags = try(each.value.log_group_tags, var.defaults.log_group_tags, {}) 36 | manage_log_group = try(each.value.manage_log_group, var.defaults.manage_log_group, true) 37 | max_connections_percent = try(each.value.max_connections_percent, var.defaults.max_connections_percent, 90) 38 | max_idle_connections_percent = try(each.value.max_idle_connections_percent, var.defaults.max_idle_connections_percent, 50) 39 | name = try(each.value.name, var.defaults.name, "") 40 | proxy_tags = try(each.value.proxy_tags, var.defaults.proxy_tags, {}) 41 | region = try(each.value.region, var.defaults.region, null) 42 | require_tls = try(each.value.require_tls, var.defaults.require_tls, true) 43 | role_arn = try(each.value.role_arn, var.defaults.role_arn, "") 44 | session_pinning_filters = try(each.value.session_pinning_filters, var.defaults.session_pinning_filters, []) 45 | tags = try(each.value.tags, var.defaults.tags, {}) 46 | target_db_cluster = try(each.value.target_db_cluster, var.defaults.target_db_cluster, false) 47 | target_db_instance = try(each.value.target_db_instance, var.defaults.target_db_instance, false) 48 | use_policy_name_prefix = try(each.value.use_policy_name_prefix, var.defaults.use_policy_name_prefix, false) 49 | use_role_name_prefix = try(each.value.use_role_name_prefix, var.defaults.use_role_name_prefix, false) 50 | vpc_security_group_ids = try(each.value.vpc_security_group_ids, var.defaults.vpc_security_group_ids, []) 51 | vpc_subnet_ids = try(each.value.vpc_subnet_ids, var.defaults.vpc_subnet_ids, []) 52 | } 53 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # RDS Proxy 3 | ################################################################################ 4 | 5 | output "proxy_id" { 6 | description = "The ID for the proxy" 7 | value = try(aws_db_proxy.this[0].id, null) 8 | } 9 | 10 | output "proxy_arn" { 11 | description = "The Amazon Resource Name (ARN) for the proxy" 12 | value = try(aws_db_proxy.this[0].arn, null) 13 | } 14 | 15 | output "proxy_endpoint" { 16 | description = "The endpoint that you can use to connect to the proxy" 17 | value = try(aws_db_proxy.this[0].endpoint, null) 18 | } 19 | 20 | ################################################################################ 21 | # Default Target Group 22 | ################################################################################ 23 | 24 | output "proxy_default_target_group_id" { 25 | description = "The ID for the default target group" 26 | value = try(aws_db_proxy_default_target_group.this[0].id, null) 27 | } 28 | 29 | output "proxy_default_target_group_arn" { 30 | description = "The Amazon Resource Name (ARN) for the default target group" 31 | value = try(aws_db_proxy_default_target_group.this[0].arn, null) 32 | } 33 | 34 | output "proxy_default_target_group_name" { 35 | description = "The name of the default target group" 36 | value = try(aws_db_proxy_default_target_group.this[0].name, null) 37 | } 38 | 39 | ################################################################################ 40 | # Target(s) 41 | ################################################################################ 42 | 43 | output "proxy_target_endpoint" { 44 | description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type" 45 | value = try(aws_db_proxy_target.db_instance[0].endpoint, aws_db_proxy_target.db_cluster[0].endpoint, null) 46 | } 47 | 48 | output "proxy_target_id" { 49 | 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 (/)" 50 | value = try(aws_db_proxy_target.db_instance[0].id, aws_db_proxy_target.db_cluster[0].id, null) 51 | } 52 | 53 | output "proxy_target_port" { 54 | description = "Port for the target RDS DB Instance or Aurora DB Cluster" 55 | value = try(aws_db_proxy_target.db_instance[0].port, aws_db_proxy_target.db_cluster[0].port, null) 56 | } 57 | 58 | output "proxy_target_rds_resource_id" { 59 | description = "Identifier representing the DB Instance or DB Cluster target" 60 | value = try(aws_db_proxy_target.db_instance[0].rds_resource_id, aws_db_proxy_target.db_cluster[0].rds_resource_id, null) 61 | } 62 | 63 | output "proxy_target_target_arn" { 64 | description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API" 65 | value = try(aws_db_proxy_target.db_instance[0].target_arn, aws_db_proxy_target.db_cluster[0].target_arn, null) 66 | } 67 | 68 | output "proxy_target_tracked_cluster_id" { 69 | 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" 70 | value = try(aws_db_proxy_target.db_cluster[0].tracked_cluster_id, null) 71 | } 72 | 73 | output "proxy_target_type" { 74 | description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`" 75 | value = try(aws_db_proxy_target.db_instance[0].type, aws_db_proxy_target.db_cluster[0].type, null) 76 | } 77 | 78 | ################################################################################ 79 | # Endpoint(s) 80 | ################################################################################ 81 | 82 | output "db_proxy_endpoints" { 83 | description = "Array containing the full resource object and attributes for all DB proxy endpoints created" 84 | value = aws_db_proxy_endpoint.this 85 | } 86 | 87 | ################################################################################ 88 | # CloudWatch Log Group 89 | ################################################################################ 90 | 91 | output "log_group_arn" { 92 | description = "The Amazon Resource Name (ARN) of the CloudWatch log group" 93 | value = try(aws_cloudwatch_log_group.this[0].arn, null) 94 | } 95 | 96 | output "log_group_name" { 97 | description = "The name of the CloudWatch log group" 98 | value = try(aws_cloudwatch_log_group.this[0].name, null) 99 | } 100 | 101 | ################################################################################ 102 | # IAM Role 103 | ################################################################################ 104 | 105 | output "iam_role_arn" { 106 | description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager." 107 | value = try(aws_iam_role.this[0].arn, null) 108 | } 109 | 110 | output "iam_role_name" { 111 | description = "IAM role name" 112 | value = try(aws_iam_role.this[0].name, null) 113 | } 114 | 115 | output "iam_role_unique_id" { 116 | description = "Stable and unique string identifying the IAM role" 117 | value = try(aws_iam_role.this[0].unique_id, null) 118 | } 119 | -------------------------------------------------------------------------------- /examples/mysql-iam-cluster/README.md: -------------------------------------------------------------------------------- 1 | # RDS Proxy - IAM Authentication & MySQL Cluster 2 | 3 | Configuration in this directory creates: 4 | 5 | - AWS RDS Proxy w/ IAM authentication enabled for an RDS Aurora MySQL cluster 6 | 7 | ## Usage 8 | 9 | To run this example you need to execute: 10 | 11 | ```bash 12 | $ terraform init 13 | $ terraform plan 14 | $ terraform apply 15 | ``` 16 | 17 | Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources. 18 | 19 | ## Validation 20 | 21 | An EC2 instance configuration has been provided for use in validating the example configuration. After provisioning the configuration, there are some outputs that have been provided to aid in validating changes. To perform validation, after the EC2 instance finishes provisioning: 22 | 23 | 1. Connect to the EC2 instance using Session Manager 24 | 2. Copy the output from `superuser_proxy_iam_token` and paste it into the Session Manager window - this generates the token for connecting to the proxy with IAM auth. 25 | 3. Copy the output from `superuser_proxy_iam_connect` and paste it into the window 26 | 4. You should now be connected to the `example` database in the RDS instance via the AWS Proxy using IAM authentication 27 | 28 | 29 | ## Requirements 30 | 31 | | Name | Version | 32 | |------|---------| 33 | | [terraform](#requirement\_terraform) | >= 1.5.7 | 34 | | [aws](#requirement\_aws) | >= 6.15 | 35 | 36 | ## Providers 37 | 38 | | Name | Version | 39 | |------|---------| 40 | | [aws](#provider\_aws) | >= 6.15 | 41 | 42 | ## Modules 43 | 44 | | Name | Source | Version | 45 | |------|--------|---------| 46 | | [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 9.0 | 47 | | [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a | 48 | | [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | 49 | | [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 | 50 | 51 | ## Resources 52 | 53 | | Name | Type | 54 | |------|------| 55 | | [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | 56 | 57 | ## Inputs 58 | 59 | No inputs. 60 | 61 | ## Outputs 62 | 63 | | Name | Description | 64 | |------|-------------| 65 | | [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created | 66 | | [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group | 67 | | [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group | 68 | | [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy | 69 | | [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group | 70 | | [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group | 71 | | [proxy\_default\_target\_group\_name](#output\_proxy\_default\_target\_group\_name) | The name of the default target group | 72 | | [proxy\_endpoint](#output\_proxy\_endpoint) | The endpoint that you can use to connect to the proxy | 73 | | [proxy\_id](#output\_proxy\_id) | The ID for the proxy | 74 | | [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | 75 | | [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) | 76 | | [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB Instance or Aurora DB Cluster | 77 | | [proxy\_target\_rds\_resource\_id](#output\_proxy\_target\_rds\_resource\_id) | Identifier representing the DB Instance or DB Cluster target | 78 | | [proxy\_target\_target\_arn](#output\_proxy\_target\_target\_arn) | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API | 79 | | [proxy\_target\_tracked\_cluster\_id](#output\_proxy\_target\_tracked\_cluster\_id) | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster | 80 | | [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` | 81 | 82 | 83 | Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE). 84 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [4.2.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v4.2.0...v4.2.1) (2025-10-21) 6 | 7 | ### Bug Fixes 8 | 9 | * Update CI workflow versions to latest ([#40](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/40)) ([5deff22](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/5deff22cf4c471ce824c016687c3b933cd8b783c)) 10 | 11 | ## [4.2.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v4.1.0...v4.2.0) (2025-10-14) 12 | 13 | 14 | ### Features 15 | 16 | * Support `default_auth_scheme` ([#39](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/39)) ([c2073a0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/c2073a031c947270dac3f17c7f76e2996cd1b5b1)) 17 | 18 | ## [4.1.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v4.0.0...v4.1.0) (2025-10-01) 19 | 20 | 21 | ### Features 22 | 23 | * Add Terragrunt wrappers ([#38](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/38)) ([33b43c7](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/33b43c72abdad0b01655238d844e56dabca5e6d4)) 24 | 25 | ## [4.0.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.2.1...v4.0.0) (2025-09-16) 26 | 27 | 28 | ### ⚠ BREAKING CHANGES 29 | 30 | * Upgrade AWS provider and min required Terraform version to `6.0` and `1.5.7` respectively (#34) 31 | 32 | ### Features 33 | 34 | * Upgrade AWS provider and min required Terraform version to `6.0` and `1.5.7` respectively ([#34](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/34)) ([47c0fca](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/47c0fcad4b3e40ef112544028dba1a4c10ee50dc)) 35 | 36 | ## [3.2.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.2.0...v3.2.1) (2025-05-22) 37 | 38 | 39 | ### Bug Fixes 40 | 41 | * Correct service principal to rds.amazonaws.com (incl China) ([#32](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/32)) ([bbbf50c](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/bbbf50ce8734f05d4ac69fa41c23c88094b82356)) 42 | 43 | ## [3.2.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.1.1...v3.2.0) (2024-11-19) 44 | 45 | 46 | ### Features 47 | 48 | * Add CloudWatch log group name to outputs ([#28](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/28)) ([0fc0e19](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/0fc0e19e642a2fdcd8f546bf219f78b5db252c65)) 49 | 50 | 51 | ### Bug Fixes 52 | 53 | * Update CI workflow versions to latest ([#27](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/27)) ([b6f22be](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/b6f22becf63614f365e72a81151c1955ab0d4df3)) 54 | 55 | ## [3.1.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.1.0...v3.1.1) (2024-03-06) 56 | 57 | 58 | ### Bug Fixes 59 | 60 | * Update CI workflow versions to remove deprecated runtime warnings ([#26](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/26)) ([a31a810](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/a31a81097b9828776e91864973783d0e9530e12d)) 61 | 62 | ## [3.1.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.0.0...v3.1.0) (2023-08-30) 63 | 64 | 65 | ### Features 66 | 67 | * Add IAM role output ([#22](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/22)) ([d18ae45](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/d18ae45d9ebf8253f7144e6bdc6ef39af9a4863f)) 68 | 69 | ## [3.0.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v2.1.2...v3.0.0) (2023-06-09) 70 | 71 | 72 | ### ⚠ BREAKING CHANGES 73 | 74 | * Increase Terraform and AWS provider minimum supported versions; update `auth` configuration schema (#17) 75 | 76 | ### Features 77 | 78 | * Increase Terraform and AWS provider minimum supported versions; update `auth` configuration schema ([#17](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/17)) ([cc39e9d](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/cc39e9d0295495574c406acfed9e288fb6d5df3c)) 79 | 80 | ### [2.1.2](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v2.1.1...v2.1.2) (2022-10-27) 81 | 82 | 83 | ### Bug Fixes 84 | 85 | * Update CI configuration files to use latest version ([#13](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/13)) ([2e11175](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/2e111751a3b6d6a28ac3c7bf8924ac5dcf07e10e)) 86 | 87 | ### [2.1.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v2.1.0...v2.1.1) (2022-08-10) 88 | 89 | 90 | ### Bug Fixes 91 | 92 | * Disable endpoint creation when setting `create_proxy = false` ([#12](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/12)) ([26724ab](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/26724abef985c1669d223ff4e12e43cfd35c529a)) 93 | * Update documentation to remove prior notice and deprecated workflow ([#9](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/9)) ([8c1720c](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/commit/8c1720cee3a1402a2114c46990061672befcd6b9)) 94 | 95 | ## [2.1.0](https://github.com/clowdhaus/terraform-aws-rds-proxy/compare/v2.0.1...v2.1.0) (2022-04-20) 96 | 97 | 98 | ### Features 99 | 100 | * Repo has moved to [terraform-aws-modules](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy) organization ([ec9c760](https://github.com/clowdhaus/terraform-aws-rds-proxy/commit/ec9c76000eb6a2df12759fbfdd1a44c0207cd6b4)) 101 | -------------------------------------------------------------------------------- /examples/postgresql-iam-cluster/README.md: -------------------------------------------------------------------------------- 1 | # RDS Proxy - IAM Authentication & PostgreSQL Cluster 2 | 3 | Configuration in this directory creates: 4 | 5 | - AWS RDS Proxy w/ IAM authentication enabled for an RDS Aurora PostgreSQL cluster 6 | 7 | ## Usage 8 | 9 | To run this example you need to execute: 10 | 11 | ```bash 12 | $ terraform init 13 | $ terraform plan 14 | $ terraform apply 15 | ``` 16 | 17 | Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources. 18 | 19 | ## Validation 20 | 21 | An EC2 instance configuration has been provided for use in validating the example configuration. After provisioning the configuration, there are some outputs that have been provided to aid in validating changes. To perform validation, after the EC2 instance finishes provisioning: 22 | 23 | 1. Connect to the EC2 instance using Session Manager 24 | 2. Copy the output from `superuser_proxy_iam_token` and paste it into the Session Manager window - this generates the token for connecting to the proxy with IAM auth. 25 | 3. Copy the output from `superuser_proxy_iam_connect` and paste it into the window - NOTE: remove the string escape slashes `psql \"host...` -> `psql "host...` 26 | 4. You should now be connected to the `example` database in the RDS instance via the AWS Proxy using IAM authentication 27 | 28 | 29 | ## Requirements 30 | 31 | | Name | Version | 32 | |------|---------| 33 | | [terraform](#requirement\_terraform) | >= 1.5.7 | 34 | | [aws](#requirement\_aws) | >= 6.15 | 35 | 36 | ## Providers 37 | 38 | | Name | Version | 39 | |------|---------| 40 | | [aws](#provider\_aws) | >= 6.15 | 41 | 42 | ## Modules 43 | 44 | | Name | Source | Version | 45 | |------|--------|---------| 46 | | [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 9.0 | 47 | | [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a | 48 | | [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | 49 | | [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 | 50 | 51 | ## Resources 52 | 53 | | Name | Type | 54 | |------|------| 55 | | [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | 56 | 57 | ## Inputs 58 | 59 | No inputs. 60 | 61 | ## Outputs 62 | 63 | | Name | Description | 64 | |------|-------------| 65 | | [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created | 66 | | [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the role proxy uses to access secrets | 67 | | [iam\_role\_name](#output\_iam\_role\_name) | The name of the role proxy uses to access secrets | 68 | | [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the role proxy uses to access secrets | 69 | | [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group | 70 | | [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group | 71 | | [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy | 72 | | [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group | 73 | | [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group | 74 | | [proxy\_default\_target\_group\_name](#output\_proxy\_default\_target\_group\_name) | The name of the default target group | 75 | | [proxy\_endpoint](#output\_proxy\_endpoint) | The endpoint that you can use to connect to the proxy | 76 | | [proxy\_id](#output\_proxy\_id) | The ID for the proxy | 77 | | [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | 78 | | [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) | 79 | | [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB Instance or Aurora DB Cluster | 80 | | [proxy\_target\_rds\_resource\_id](#output\_proxy\_target\_rds\_resource\_id) | Identifier representing the DB Instance or DB Cluster target | 81 | | [proxy\_target\_target\_arn](#output\_proxy\_target\_target\_arn) | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API | 82 | | [proxy\_target\_tracked\_cluster\_id](#output\_proxy\_target\_tracked\_cluster\_id) | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster | 83 | | [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` | 84 | 85 | 86 | Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE). 87 | -------------------------------------------------------------------------------- /examples/mysql-iam-instance/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = local.region 3 | } 4 | 5 | data "aws_availability_zones" "available" {} 6 | 7 | locals { 8 | name = "ex-${basename(path.cwd)}" 9 | region = "eu-west-1" 10 | 11 | db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account 12 | db_password = random_password.password.result 13 | 14 | vpc_cidr = "10.0.0.0/16" 15 | azs = slice(data.aws_availability_zones.available.names, 0, 3) 16 | 17 | tags = { 18 | Example = local.name 19 | GithubRepo = "terraform-aws-rds-proxy" 20 | GithubOrg = "terraform-aws-modules" 21 | } 22 | } 23 | 24 | ################################################################################ 25 | # RDS Proxy 26 | ################################################################################ 27 | 28 | module "rds_proxy" { 29 | source = "../../" 30 | 31 | name = local.name 32 | iam_role_name = local.name 33 | vpc_subnet_ids = module.vpc.private_subnets 34 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 35 | 36 | endpoints = { 37 | read_write = { 38 | name = "read-write-endpoint" 39 | vpc_subnet_ids = module.vpc.private_subnets 40 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 41 | tags = local.tags 42 | }, 43 | read_only = { 44 | name = "read-only-endpoint" 45 | vpc_subnet_ids = module.vpc.private_subnets 46 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 47 | target_role = "READ_ONLY" 48 | tags = local.tags 49 | } 50 | } 51 | 52 | auth = { 53 | (local.db_username) = { 54 | description = aws_secretsmanager_secret.superuser.description 55 | secret_arn = aws_secretsmanager_secret.superuser.arn 56 | } 57 | } 58 | 59 | engine_family = "MYSQL" 60 | debug_logging = true 61 | 62 | # Target RDS instance 63 | target_db_instance = true 64 | db_instance_identifier = module.rds.db_instance_identifier 65 | 66 | tags = local.tags 67 | } 68 | 69 | ################################################################################ 70 | # Supporting Resources 71 | ################################################################################ 72 | 73 | resource "random_pet" "users" { 74 | length = 2 75 | separator = "_" 76 | } 77 | 78 | resource "random_password" "password" { 79 | length = 16 80 | special = false 81 | } 82 | 83 | module "vpc" { 84 | source = "terraform-aws-modules/vpc/aws" 85 | version = "~> 6.0" 86 | 87 | name = local.name 88 | cidr = local.vpc_cidr 89 | 90 | azs = local.azs 91 | public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] 92 | private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] 93 | database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] 94 | 95 | tags = local.tags 96 | } 97 | 98 | module "rds" { 99 | source = "terraform-aws-modules/rds/aws" 100 | version = "~> 6.0" 101 | 102 | username = local.db_username 103 | password = local.db_password 104 | 105 | # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM 106 | iam_database_authentication_enabled = false 107 | 108 | identifier = local.name 109 | engine = "mysql" 110 | engine_version = "8.0" 111 | family = "mysql8.0" # DB parameter group 112 | major_engine_version = "8.0" # DB option group 113 | instance_class = "db.t4g.large" 114 | allocated_storage = 20 115 | port = 3306 116 | apply_immediately = true 117 | 118 | db_subnet_group_name = module.vpc.database_subnet_group 119 | vpc_security_group_ids = [module.rds_sg.security_group_id] 120 | multi_az = true 121 | 122 | backup_retention_period = 0 123 | deletion_protection = false 124 | 125 | tags = local.tags 126 | } 127 | 128 | module "rds_sg" { 129 | source = "terraform-aws-modules/security-group/aws" 130 | version = "~> 5.0" 131 | 132 | name = "rds" 133 | description = "MySQL RDS example security group" 134 | vpc_id = module.vpc.vpc_id 135 | 136 | revoke_rules_on_delete = true 137 | 138 | ingress_with_cidr_blocks = [ 139 | { 140 | description = "Private subnet MySQL access" 141 | rule = "mysql-tcp" 142 | cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) 143 | } 144 | ] 145 | 146 | tags = local.tags 147 | } 148 | 149 | module "rds_proxy_sg" { 150 | source = "terraform-aws-modules/security-group/aws" 151 | version = "~> 5.0" 152 | 153 | name = "${local.name}-proxy" 154 | description = "PostgreSQL RDS Proxy example security group" 155 | vpc_id = module.vpc.vpc_id 156 | 157 | revoke_rules_on_delete = true 158 | 159 | ingress_with_cidr_blocks = [ 160 | { 161 | description = "Private subnet MySQL access" 162 | rule = "mysql-tcp" 163 | cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) 164 | } 165 | ] 166 | 167 | egress_with_cidr_blocks = [ 168 | { 169 | description = "Database subnet MySQL access" 170 | rule = "mysql-tcp" 171 | cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks) 172 | }, 173 | ] 174 | 175 | tags = local.tags 176 | } 177 | 178 | ################################################################################ 179 | # Secrets - DB user passwords 180 | ################################################################################ 181 | 182 | data "aws_kms_alias" "secretsmanager" { 183 | name = "alias/aws/secretsmanager" 184 | } 185 | 186 | resource "aws_secretsmanager_secret" "superuser" { 187 | name = local.db_username 188 | description = "Database superuser, ${local.db_username}, database connection values" 189 | kms_key_id = data.aws_kms_alias.secretsmanager.id 190 | 191 | tags = local.tags 192 | } 193 | 194 | resource "aws_secretsmanager_secret_version" "superuser" { 195 | secret_id = aws_secretsmanager_secret.superuser.id 196 | secret_string = jsonencode({ 197 | username = local.db_username 198 | password = local.db_password 199 | }) 200 | } 201 | -------------------------------------------------------------------------------- /examples/postgresql-iam-instance/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = local.region 3 | } 4 | 5 | data "aws_availability_zones" "available" {} 6 | 7 | locals { 8 | name = "ex-${basename(path.cwd)}" 9 | region = "eu-west-1" 10 | 11 | db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account 12 | db_password = random_password.password.result 13 | 14 | vpc_cidr = "10.0.0.0/16" 15 | azs = slice(data.aws_availability_zones.available.names, 0, 3) 16 | 17 | tags = { 18 | Example = local.name 19 | GithubRepo = "terraform-aws-rds-proxy" 20 | GithubOrg = "terraform-aws-modules" 21 | } 22 | } 23 | 24 | ################################################################################ 25 | # RDS Proxy 26 | ################################################################################ 27 | 28 | module "rds_proxy" { 29 | source = "../../" 30 | 31 | name = local.name 32 | iam_role_name = local.name 33 | vpc_subnet_ids = module.vpc.private_subnets 34 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 35 | 36 | endpoints = { 37 | read_write = { 38 | name = "read-write-endpoint" 39 | vpc_subnet_ids = module.vpc.private_subnets 40 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 41 | tags = local.tags 42 | }, 43 | read_only = { 44 | name = "read-only-endpoint" 45 | vpc_subnet_ids = module.vpc.private_subnets 46 | vpc_security_group_ids = [module.rds_proxy_sg.security_group_id] 47 | target_role = "READ_ONLY" 48 | tags = local.tags 49 | } 50 | } 51 | 52 | auth = { 53 | (local.db_username) = { 54 | description = aws_secretsmanager_secret.superuser.description 55 | secret_arn = aws_secretsmanager_secret.superuser.arn 56 | } 57 | } 58 | 59 | engine_family = "POSTGRESQL" 60 | debug_logging = true 61 | 62 | # Target RDS instance 63 | target_db_instance = true 64 | db_instance_identifier = module.rds.db_instance_identifier 65 | 66 | tags = local.tags 67 | } 68 | 69 | ################################################################################ 70 | # Supporting Resources 71 | ################################################################################ 72 | 73 | resource "random_pet" "users" { 74 | length = 2 75 | separator = "_" 76 | } 77 | 78 | resource "random_password" "password" { 79 | length = 16 80 | special = false 81 | } 82 | 83 | module "vpc" { 84 | source = "terraform-aws-modules/vpc/aws" 85 | version = "~> 6.0" 86 | 87 | name = local.name 88 | cidr = local.vpc_cidr 89 | 90 | azs = local.azs 91 | public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] 92 | private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)] 93 | database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)] 94 | 95 | tags = local.tags 96 | } 97 | 98 | module "rds" { 99 | source = "terraform-aws-modules/rds/aws" 100 | version = "~> 6.0" 101 | 102 | username = local.db_username 103 | password = local.db_password 104 | 105 | # When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM 106 | iam_database_authentication_enabled = false 107 | 108 | identifier = local.name 109 | engine = "postgres" 110 | engine_version = "14" 111 | family = "postgres14" # DB parameter group 112 | major_engine_version = "14" # DB option group 113 | instance_class = "db.t4g.large" 114 | allocated_storage = 20 115 | port = 5432 116 | apply_immediately = true 117 | 118 | db_subnet_group_name = module.vpc.database_subnet_group 119 | vpc_security_group_ids = [module.rds_sg.security_group_id] 120 | multi_az = true 121 | 122 | backup_retention_period = 0 123 | deletion_protection = false 124 | 125 | tags = local.tags 126 | } 127 | 128 | module "rds_sg" { 129 | source = "terraform-aws-modules/security-group/aws" 130 | version = "~> 5.0" 131 | 132 | name = "rds" 133 | description = "PostgreSQL RDS example security group" 134 | vpc_id = module.vpc.vpc_id 135 | 136 | revoke_rules_on_delete = true 137 | 138 | ingress_with_cidr_blocks = [ 139 | { 140 | description = "Private subnet PostgreSQL access" 141 | rule = "postgresql-tcp" 142 | cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) 143 | } 144 | ] 145 | 146 | tags = local.tags 147 | } 148 | 149 | module "rds_proxy_sg" { 150 | source = "terraform-aws-modules/security-group/aws" 151 | version = "~> 5.0" 152 | 153 | name = "rds_proxy" 154 | description = "PostgreSQL RDS Proxy example security group" 155 | vpc_id = module.vpc.vpc_id 156 | 157 | revoke_rules_on_delete = true 158 | 159 | ingress_with_cidr_blocks = [ 160 | { 161 | description = "Private subnet PostgreSQL access" 162 | rule = "postgresql-tcp" 163 | cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks) 164 | } 165 | ] 166 | 167 | egress_with_cidr_blocks = [ 168 | { 169 | description = "Database subnet PostgreSQL access" 170 | rule = "postgresql-tcp" 171 | cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks) 172 | }, 173 | ] 174 | 175 | tags = local.tags 176 | } 177 | 178 | ################################################################################ 179 | # Secrets - DB user passwords 180 | ################################################################################ 181 | 182 | data "aws_kms_alias" "secretsmanager" { 183 | name = "alias/aws/secretsmanager" 184 | } 185 | 186 | resource "aws_secretsmanager_secret" "superuser" { 187 | name = local.db_username 188 | description = "Database superuser, ${local.db_username}, database connection values" 189 | kms_key_id = data.aws_kms_alias.secretsmanager.id 190 | 191 | tags = local.tags 192 | } 193 | 194 | resource "aws_secretsmanager_secret_version" "superuser" { 195 | secret_id = aws_secretsmanager_secret.superuser.id 196 | secret_string = jsonencode({ 197 | username = local.db_username 198 | password = local.db_password 199 | }) 200 | } 201 | -------------------------------------------------------------------------------- /examples/mysql-iam-instance/README.md: -------------------------------------------------------------------------------- 1 | # RDS Proxy - IAM Authentication & MySQL Instance 2 | 3 | Configuration in this directory creates: 4 | 5 | - AWS RDS Proxy w/ IAM authentication enabled for an RDS MySQL instance 6 | 7 | ## Usage 8 | 9 | To run this example you need to execute: 10 | 11 | ```bash 12 | $ terraform init 13 | $ terraform plan 14 | $ terraform apply 15 | ``` 16 | 17 | Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources. 18 | 19 | ## Validation 20 | 21 | An EC2 instance configuration has been provided for use in validating the example configuration. After provisioning the configuration, there are some outputs that have been provided to aid in validating changes. To perform validation, after the EC2 instance finishes provisioning: 22 | 23 | 1. Connect to the EC2 instance using Session Manager 24 | 2. Copy the output from `superuser_proxy_iam_token` and paste it into the Session Manager window - this generates the token for connecting to the proxy with IAM auth. 25 | 3. Copy the output from `superuser_proxy_iam_connect` and paste it into the window 26 | 4. You should now be connected to the `example` database in the Aurora cluster via the AWS Proxy using IAM authentication 27 | 28 | 29 | ## Requirements 30 | 31 | | Name | Version | 32 | |------|---------| 33 | | [terraform](#requirement\_terraform) | >= 1.5.7 | 34 | | [aws](#requirement\_aws) | >= 6.15 | 35 | | [random](#requirement\_random) | >= 2.0 | 36 | 37 | ## Providers 38 | 39 | | Name | Version | 40 | |------|---------| 41 | | [aws](#provider\_aws) | >= 6.15 | 42 | | [random](#provider\_random) | >= 2.0 | 43 | 44 | ## Modules 45 | 46 | | Name | Source | Version | 47 | |------|--------|---------| 48 | | [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 6.0 | 49 | | [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a | 50 | | [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | 51 | | [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | 52 | | [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 | 53 | 54 | ## Resources 55 | 56 | | Name | Type | 57 | |------|------| 58 | | [aws_secretsmanager_secret.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource | 59 | | [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource | 60 | | [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 61 | | [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | 62 | | [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | 63 | | [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | 64 | 65 | ## Inputs 66 | 67 | No inputs. 68 | 69 | ## Outputs 70 | 71 | | Name | Description | 72 | |------|-------------| 73 | | [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created | 74 | | [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group | 75 | | [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group | 76 | | [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy | 77 | | [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group | 78 | | [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group | 79 | | [proxy\_default\_target\_group\_name](#output\_proxy\_default\_target\_group\_name) | The name of the default target group | 80 | | [proxy\_endpoint](#output\_proxy\_endpoint) | The endpoint that you can use to connect to the proxy | 81 | | [proxy\_id](#output\_proxy\_id) | The ID for the proxy | 82 | | [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | 83 | | [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) | 84 | | [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB Instance or Aurora DB Cluster | 85 | | [proxy\_target\_rds\_resource\_id](#output\_proxy\_target\_rds\_resource\_id) | Identifier representing the DB Instance or DB Cluster target | 86 | | [proxy\_target\_target\_arn](#output\_proxy\_target\_target\_arn) | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API | 87 | | [proxy\_target\_tracked\_cluster\_id](#output\_proxy\_target\_tracked\_cluster\_id) | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster | 88 | | [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` | 89 | 90 | 91 | Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE). 92 | -------------------------------------------------------------------------------- /examples/postgresql-iam-instance/README.md: -------------------------------------------------------------------------------- 1 | # RDS Proxy - IAM Authentication & PostgreSQL Instance 2 | 3 | Configuration in this directory creates: 4 | 5 | - AWS RDS Proxy w/ IAM authentication enabled for an RDS PostgreSQL instance 6 | 7 | ## Usage 8 | 9 | To run this example you need to execute: 10 | 11 | ```bash 12 | $ terraform init 13 | $ terraform plan 14 | $ terraform apply 15 | ``` 16 | 17 | Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources. 18 | 19 | ## Validation 20 | 21 | An EC2 instance configuration has been provided for use in validating the example configuration. After provisioning the configuration, there are some outputs that have been provided to aid in validating changes. To perform validation, after the EC2 instance finishes provisioning: 22 | 23 | 1. Connect to the EC2 instance using Session Manager 24 | 2. Copy the output from `superuser_proxy_iam_token` and paste it into the Session Manager window - this generates the token for connecting to the proxy with IAM auth. 25 | 3. Copy the output from `superuser_proxy_iam_connect` and paste it into the window - NOTE: remove the string escape slashes `psql \"host...` -> `psql "host...` 26 | 4. You should now be connected to the `example` database in the Aurora cluster via the AWS Proxy using IAM authentication 27 | 28 | 29 | ## Requirements 30 | 31 | | Name | Version | 32 | |------|---------| 33 | | [terraform](#requirement\_terraform) | >= 1.5.7 | 34 | | [aws](#requirement\_aws) | >= 6.15 | 35 | | [random](#requirement\_random) | >= 2.0 | 36 | 37 | ## Providers 38 | 39 | | Name | Version | 40 | |------|---------| 41 | | [aws](#provider\_aws) | >= 6.15 | 42 | | [random](#provider\_random) | >= 2.0 | 43 | 44 | ## Modules 45 | 46 | | Name | Source | Version | 47 | |------|--------|---------| 48 | | [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 6.0 | 49 | | [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a | 50 | | [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | 51 | | [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 | 52 | | [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 | 53 | 54 | ## Resources 55 | 56 | | Name | Type | 57 | |------|------| 58 | | [aws_secretsmanager_secret.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource | 59 | | [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource | 60 | | [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 61 | | [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | 62 | | [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | 63 | | [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | 64 | 65 | ## Inputs 66 | 67 | No inputs. 68 | 69 | ## Outputs 70 | 71 | | Name | Description | 72 | |------|-------------| 73 | | [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created | 74 | | [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group | 75 | | [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group | 76 | | [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy | 77 | | [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group | 78 | | [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group | 79 | | [proxy\_default\_target\_group\_name](#output\_proxy\_default\_target\_group\_name) | The name of the default target group | 80 | | [proxy\_endpoint](#output\_proxy\_endpoint) | The endpoint that you can use to connect to the proxy | 81 | | [proxy\_id](#output\_proxy\_id) | The ID for the proxy | 82 | | [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | 83 | | [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) | 84 | | [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB Instance or Aurora DB Cluster | 85 | | [proxy\_target\_rds\_resource\_id](#output\_proxy\_target\_rds\_resource\_id) | Identifier representing the DB Instance or DB Cluster target | 86 | | [proxy\_target\_target\_arn](#output\_proxy\_target\_target\_arn) | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API | 87 | | [proxy\_target\_tracked\_cluster\_id](#output\_proxy\_target\_tracked\_cluster\_id) | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster | 88 | | [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` | 89 | 90 | 91 | Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE). 92 | -------------------------------------------------------------------------------- /.github/workflows/pre-commit.yml: -------------------------------------------------------------------------------- 1 | name: Pre-Commit 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | - master 8 | 9 | env: 10 | TERRAFORM_DOCS_VERSION: v0.20.0 11 | TFLINT_VERSION: v0.59.1 12 | 13 | jobs: 14 | collectInputs: 15 | name: Collect workflow inputs 16 | runs-on: ubuntu-latest 17 | outputs: 18 | directories: ${{ steps.dirs.outputs.directories }} 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v5 22 | 23 | - name: Get root directories 24 | id: dirs 25 | uses: clowdhaus/terraform-composite-actions/directories@v1.14.0 26 | 27 | preCommitMinVersions: 28 | name: Min TF pre-commit 29 | needs: collectInputs 30 | runs-on: ubuntu-latest 31 | strategy: 32 | matrix: 33 | directory: ${{ fromJson(needs.collectInputs.outputs.directories) }} 34 | steps: 35 | - name: Install rmz 36 | uses: jaxxstorm/action-install-gh-release@v2.1.0 37 | with: 38 | repo: SUPERCILEX/fuc 39 | asset-name: x86_64-unknown-linux-gnu-rmz 40 | rename-to: rmz 41 | chmod: 0755 42 | extension-matching: disable 43 | 44 | # https://github.com/orgs/community/discussions/25678#discussioncomment-5242449 45 | - name: Delete unnecessary files 46 | run: | 47 | formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); } 48 | getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); } 49 | 50 | BEFORE=$(getAvailableSpace) 51 | 52 | ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz 53 | rmz -f /opt/hostedtoolcache/CodeQL & 54 | rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk & 55 | rmz -f /opt/hostedtoolcache/PyPy & 56 | rmz -f /opt/hostedtoolcache/Ruby & 57 | rmz -f /opt/hostedtoolcache/go & 58 | 59 | wait 60 | 61 | AFTER=$(getAvailableSpace) 62 | SAVED=$((AFTER-BEFORE)) 63 | echo "=> Saved $(formatByteCount $SAVED)" 64 | 65 | - name: Checkout 66 | uses: actions/checkout@v5 67 | 68 | - name: Terraform min/max versions 69 | id: minMax 70 | uses: clowdhaus/terraform-min-max@v2.1.0 71 | with: 72 | directory: ${{ matrix.directory }} 73 | 74 | - name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }} 75 | # Run only validate pre-commit check on min version supported 76 | if: ${{ matrix.directory != '.' }} 77 | uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0 78 | with: 79 | terraform-version: ${{ steps.minMax.outputs.minVersion }} 80 | tflint-version: ${{ env.TFLINT_VERSION }} 81 | args: 'terraform_validate --color=always --show-diff-on-failure --files ${{ matrix.directory }}/*' 82 | 83 | - name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }} 84 | # Run only validate pre-commit check on min version supported 85 | if: ${{ matrix.directory == '.' }} 86 | uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0 87 | with: 88 | terraform-version: ${{ steps.minMax.outputs.minVersion }} 89 | tflint-version: ${{ env.TFLINT_VERSION }} 90 | args: 'terraform_validate --color=always --show-diff-on-failure --files $(ls *.tf)' 91 | 92 | preCommitMaxVersion: 93 | name: Max TF pre-commit 94 | runs-on: ubuntu-latest 95 | needs: collectInputs 96 | steps: 97 | - name: Install rmz 98 | uses: jaxxstorm/action-install-gh-release@v2.1.0 99 | with: 100 | repo: SUPERCILEX/fuc 101 | asset-name: x86_64-unknown-linux-gnu-rmz 102 | rename-to: rmz 103 | chmod: 0755 104 | extension-matching: disable 105 | 106 | # https://github.com/orgs/community/discussions/25678#discussioncomment-5242449 107 | - name: Delete unnecessary files 108 | run: | 109 | formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); } 110 | getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); } 111 | 112 | BEFORE=$(getAvailableSpace) 113 | 114 | ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz 115 | rmz -f /opt/hostedtoolcache/CodeQL & 116 | rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk & 117 | rmz -f /opt/hostedtoolcache/PyPy & 118 | rmz -f /opt/hostedtoolcache/Ruby & 119 | rmz -f /opt/hostedtoolcache/go & 120 | sudo rmz -f /usr/local/lib/android & 121 | 122 | if [[ ${{ github.repository }} == terraform-aws-modules/terraform-aws-security-group ]]; then 123 | sudo rmz -f /usr/share/dotnet & 124 | sudo rmz -f /usr/local/.ghcup & 125 | sudo apt-get -qq remove -y 'azure-.*' 126 | sudo apt-get -qq remove -y 'cpp-.*' 127 | sudo apt-get -qq remove -y 'dotnet-runtime-.*' 128 | sudo apt-get -qq remove -y 'google-.*' 129 | sudo apt-get -qq remove -y 'libclang-.*' 130 | sudo apt-get -qq remove -y 'libllvm.*' 131 | sudo apt-get -qq remove -y 'llvm-.*' 132 | sudo apt-get -qq remove -y 'mysql-.*' 133 | sudo apt-get -qq remove -y 'postgresql-.*' 134 | sudo apt-get -qq remove -y 'php.*' 135 | sudo apt-get -qq remove -y 'temurin-.*' 136 | sudo apt-get -qq remove -y kubectl firefox mono-devel 137 | sudo apt-get -qq autoremove -y 138 | sudo apt-get -qq clean 139 | fi 140 | 141 | wait 142 | 143 | AFTER=$(getAvailableSpace) 144 | SAVED=$((AFTER-BEFORE)) 145 | echo "=> Saved $(formatByteCount $SAVED)" 146 | 147 | - name: Checkout 148 | uses: actions/checkout@v5 149 | with: 150 | ref: ${{ github.event.pull_request.head.ref }} 151 | repository: ${{github.event.pull_request.head.repo.full_name}} 152 | 153 | - name: Terraform min/max versions 154 | id: minMax 155 | uses: clowdhaus/terraform-min-max@v2.1.0 156 | 157 | - name: Hide template dir 158 | # Special to this repo, we don't want to check this dir 159 | if: ${{ github.repository == 'terraform-aws-modules/terraform-aws-security-group' }} 160 | run: rm -rf modules/_templates 161 | 162 | - name: Pre-commit Terraform ${{ steps.minMax.outputs.maxVersion }} 163 | uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0 164 | with: 165 | terraform-version: ${{ steps.minMax.outputs.maxVersion }} 166 | tflint-version: ${{ env.TFLINT_VERSION }} 167 | terraform-docs-version: ${{ env.TERRAFORM_DOCS_VERSION }} 168 | install-hcledit: true 169 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # RDS Proxy 3 | ################################################################################ 4 | 5 | resource "aws_db_proxy" "this" { 6 | count = var.create ? 1 : 0 7 | 8 | region = var.region 9 | 10 | dynamic "auth" { 11 | for_each = var.auth 12 | 13 | content { 14 | auth_scheme = auth.value.auth_scheme 15 | client_password_auth_type = auth.value.client_password_auth_type 16 | description = auth.value.description 17 | iam_auth = auth.value.iam_auth 18 | secret_arn = auth.value.secret_arn 19 | username = auth.value.username 20 | } 21 | } 22 | 23 | debug_logging = var.debug_logging 24 | default_auth_scheme = var.default_auth_scheme 25 | engine_family = var.engine_family 26 | idle_client_timeout = var.idle_client_timeout 27 | name = var.name 28 | require_tls = var.require_tls 29 | role_arn = try(aws_iam_role.this[0].arn, var.role_arn) 30 | vpc_security_group_ids = var.vpc_security_group_ids 31 | vpc_subnet_ids = var.vpc_subnet_ids 32 | 33 | tags = merge(var.tags, var.proxy_tags) 34 | 35 | depends_on = [aws_cloudwatch_log_group.this] 36 | } 37 | 38 | ################################################################################ 39 | # Default Target Group 40 | ################################################################################ 41 | 42 | resource "aws_db_proxy_default_target_group" "this" { 43 | count = var.create ? 1 : 0 44 | 45 | region = var.region 46 | 47 | db_proxy_name = aws_db_proxy.this[0].name 48 | 49 | connection_pool_config { 50 | connection_borrow_timeout = var.connection_borrow_timeout 51 | init_query = var.init_query 52 | max_connections_percent = var.max_connections_percent 53 | max_idle_connections_percent = var.max_idle_connections_percent 54 | session_pinning_filters = var.session_pinning_filters 55 | } 56 | } 57 | 58 | ################################################################################ 59 | # Target(s) 60 | ################################################################################ 61 | 62 | resource "aws_db_proxy_target" "db_instance" { 63 | count = var.create && var.target_db_instance ? 1 : 0 64 | 65 | region = var.region 66 | 67 | db_proxy_name = aws_db_proxy.this[0].name 68 | target_group_name = aws_db_proxy_default_target_group.this[0].name 69 | db_instance_identifier = var.db_instance_identifier 70 | } 71 | 72 | resource "aws_db_proxy_target" "db_cluster" { 73 | count = var.create && var.target_db_cluster ? 1 : 0 74 | 75 | region = var.region 76 | 77 | db_proxy_name = aws_db_proxy.this[0].name 78 | target_group_name = aws_db_proxy_default_target_group.this[0].name 79 | db_cluster_identifier = var.db_cluster_identifier 80 | } 81 | 82 | ################################################################################ 83 | # Endpoint(s) 84 | ################################################################################ 85 | 86 | resource "aws_db_proxy_endpoint" "this" { 87 | for_each = { for k, v in var.endpoints : k => v if var.create } 88 | 89 | region = var.region 90 | 91 | db_proxy_name = aws_db_proxy.this[0].name 92 | db_proxy_endpoint_name = coalesce(each.value.name, each.key) 93 | vpc_subnet_ids = each.value.vpc_subnet_ids 94 | vpc_security_group_ids = each.value.vpc_security_group_ids 95 | target_role = each.value.target_role 96 | 97 | tags = merge(var.tags, each.value.tags) 98 | } 99 | 100 | ################################################################################ 101 | # CloudWatch Log Group 102 | ################################################################################ 103 | 104 | resource "aws_cloudwatch_log_group" "this" { 105 | count = var.create && var.manage_log_group ? 1 : 0 106 | 107 | region = var.region 108 | 109 | name = "/aws/rds/proxy/${var.name}" 110 | retention_in_days = var.log_group_retention_in_days 111 | kms_key_id = var.log_group_kms_key_id 112 | log_group_class = var.log_group_class 113 | 114 | tags = merge(var.tags, var.log_group_tags) 115 | } 116 | 117 | ################################################################################ 118 | # IAM Role 119 | ################################################################################ 120 | 121 | locals { 122 | create_iam_role = var.create && var.create_iam_role 123 | 124 | role_name = coalesce(var.iam_role_name, var.name) 125 | policy_name = coalesce(var.iam_policy_name, var.name) 126 | 127 | partition = try(data.aws_partition.current[0].partition, "aws") 128 | dns_suffix = try(data.aws_partition.current[0].dns_suffix, "amazonaws.com") 129 | region = try(data.aws_region.current[0].region, var.region) 130 | } 131 | 132 | data "aws_region" "current" { 133 | count = local.create_iam_role ? 1 : 0 134 | 135 | region = var.region 136 | } 137 | 138 | data "aws_partition" "current" { 139 | count = local.create_iam_role ? 1 : 0 140 | } 141 | 142 | data "aws_service_principal" "rds" { 143 | count = local.create_iam_role ? 1 : 0 144 | 145 | service_name = "rds" 146 | region = data.aws_region.current[0].region 147 | } 148 | 149 | 150 | data "aws_iam_policy_document" "assume_role" { 151 | count = local.create_iam_role ? 1 : 0 152 | 153 | statement { 154 | sid = "RDSAssume" 155 | effect = "Allow" 156 | actions = ["sts:AssumeRole"] 157 | 158 | principals { 159 | type = "Service" 160 | identifiers = [data.aws_service_principal.rds[0].name] 161 | } 162 | } 163 | } 164 | 165 | resource "aws_iam_role" "this" { 166 | count = local.create_iam_role ? 1 : 0 167 | 168 | name = var.use_role_name_prefix ? null : local.role_name 169 | name_prefix = var.use_role_name_prefix ? "${local.role_name}-" : null 170 | description = var.iam_role_description 171 | path = var.iam_role_path 172 | 173 | assume_role_policy = data.aws_iam_policy_document.assume_role[0].json 174 | force_detach_policies = var.iam_role_force_detach_policies 175 | max_session_duration = var.iam_role_max_session_duration 176 | permissions_boundary = var.iam_role_permissions_boundary 177 | 178 | tags = merge(var.tags, var.iam_role_tags) 179 | } 180 | 181 | ################################################################################ 182 | # IAM Role Policy 183 | ################################################################################ 184 | 185 | data "aws_iam_policy_document" "this" { 186 | count = local.create_iam_role && var.create_iam_policy ? 1 : 0 187 | 188 | statement { 189 | sid = "DecryptSecrets" 190 | effect = "Allow" 191 | actions = ["kms:Decrypt"] 192 | resources = coalescelist( 193 | var.kms_key_arns, 194 | ["arn:${local.partition}:kms:*:*:key/*"] 195 | ) 196 | 197 | condition { 198 | test = "StringEquals" 199 | variable = "kms:ViaService" 200 | values = [ 201 | "secretsmanager.${local.region}.${local.dns_suffix}" 202 | ] 203 | } 204 | } 205 | 206 | statement { 207 | sid = "ListSecrets" 208 | effect = "Allow" 209 | actions = [ 210 | "secretsmanager:GetRandomPassword", 211 | "secretsmanager:ListSecrets", 212 | ] 213 | resources = ["*"] 214 | } 215 | 216 | statement { 217 | sid = "GetSecrets" 218 | effect = "Allow" 219 | actions = [ 220 | "secretsmanager:GetResourcePolicy", 221 | "secretsmanager:GetSecretValue", 222 | "secretsmanager:DescribeSecret", 223 | "secretsmanager:ListSecretVersionIds", 224 | ] 225 | 226 | resources = distinct([for auth in var.auth : auth.secret_arn]) 227 | } 228 | } 229 | 230 | resource "aws_iam_role_policy" "this" { 231 | count = local.create_iam_role && var.create_iam_policy ? 1 : 0 232 | 233 | name = var.use_policy_name_prefix ? null : local.policy_name 234 | name_prefix = var.use_policy_name_prefix ? "${local.policy_name}-" : null 235 | policy = data.aws_iam_policy_document.this[0].json 236 | role = aws_iam_role.this[0].id 237 | } 238 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "create" { 2 | description = "Whether cluster should be created (affects nearly all resources)" 3 | type = bool 4 | default = true 5 | } 6 | 7 | variable "region" { 8 | description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration" 9 | type = string 10 | default = null 11 | } 12 | 13 | variable "tags" { 14 | description = "A map of tags to add to all resources" 15 | type = map(string) 16 | default = {} 17 | } 18 | 19 | ################################################################################ 20 | # RDS Proxy 21 | ################################################################################ 22 | 23 | variable "name" { 24 | 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" 25 | type = string 26 | default = "" 27 | } 28 | 29 | variable "auth" { 30 | description = "Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters" 31 | type = map(object({ 32 | auth_scheme = optional(string) 33 | client_password_auth_type = optional(string) 34 | description = optional(string) 35 | iam_auth = optional(string) 36 | secret_arn = optional(string) 37 | username = optional(string) 38 | })) 39 | default = { 40 | default = { 41 | auth_scheme = "SECRETS" 42 | } 43 | } 44 | } 45 | 46 | variable "debug_logging" { 47 | description = "Whether the proxy includes detailed information about SQL statements in its logs" 48 | type = bool 49 | default = false 50 | } 51 | 52 | variable "default_auth_scheme" { 53 | description = "Default authentication scheme that the proxy uses for client connections to the proxy and connections from the proxy to the underlying database. Valid values are NONE and IAM_AUTH. Defaults to NONE" 54 | type = string 55 | default = null 56 | } 57 | 58 | variable "engine_family" { 59 | description = "The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL`" 60 | type = string 61 | default = "" 62 | } 63 | 64 | variable "idle_client_timeout" { 65 | description = "The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it" 66 | type = number 67 | default = 1800 68 | } 69 | 70 | variable "require_tls" { 71 | description = "A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy" 72 | type = bool 73 | default = true 74 | } 75 | 76 | variable "role_arn" { 77 | description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager" 78 | type = string 79 | default = "" 80 | } 81 | 82 | variable "vpc_security_group_ids" { 83 | description = "One or more VPC security group IDs to associate with the new proxy" 84 | type = list(string) 85 | default = [] 86 | } 87 | 88 | variable "vpc_subnet_ids" { 89 | description = "One or more VPC subnet IDs to associate with the new proxy" 90 | type = list(string) 91 | default = [] 92 | } 93 | 94 | variable "proxy_tags" { 95 | description = "A map of tags to apply to the RDS Proxy" 96 | type = map(string) 97 | default = {} 98 | } 99 | 100 | ################################################################################ 101 | # Default Target Group 102 | ################################################################################ 103 | 104 | variable "connection_borrow_timeout" { 105 | description = "The number of seconds for a proxy to wait for a connection to become available in the connection pool" 106 | type = number 107 | default = null 108 | } 109 | 110 | variable "init_query" { 111 | description = "One or more SQL statements for the proxy to run when opening each new database connection" 112 | type = string 113 | default = "" 114 | } 115 | 116 | variable "max_connections_percent" { 117 | description = "The maximum size of the connection pool for each target in a target group" 118 | type = number 119 | default = 90 120 | } 121 | 122 | variable "max_idle_connections_percent" { 123 | description = "Controls how actively the proxy closes idle database connections in the connection pool" 124 | type = number 125 | default = 50 126 | } 127 | 128 | variable "session_pinning_filters" { 129 | description = "Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection" 130 | type = list(string) 131 | default = [] 132 | } 133 | 134 | ################################################################################ 135 | # Target(s) 136 | ################################################################################ 137 | 138 | variable "target_db_instance" { 139 | description = "Determines whether DB instance is targeted by proxy" 140 | type = bool 141 | default = false 142 | } 143 | 144 | variable "db_instance_identifier" { 145 | description = "DB instance identifier" 146 | type = string 147 | default = "" 148 | } 149 | 150 | variable "target_db_cluster" { 151 | description = "Determines whether DB cluster is targeted by proxy" 152 | type = bool 153 | default = false 154 | } 155 | 156 | variable "db_cluster_identifier" { 157 | description = "DB cluster identifier" 158 | type = string 159 | default = "" 160 | } 161 | 162 | ################################################################################ 163 | # Endpoint(s) 164 | ################################################################################ 165 | 166 | variable "endpoints" { 167 | description = "Map of DB proxy endpoints to create and their attributes" 168 | type = map(object({ 169 | name = optional(string) 170 | vpc_subnet_ids = list(string) 171 | vpc_security_group_ids = optional(list(string)) 172 | target_role = optional(string) 173 | tags = optional(map(string), {}) 174 | })) 175 | default = {} 176 | } 177 | 178 | ################################################################################ 179 | # CloudWatch Logs 180 | ################################################################################ 181 | 182 | variable "manage_log_group" { 183 | 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" 184 | type = bool 185 | default = true 186 | } 187 | 188 | variable "log_group_retention_in_days" { 189 | description = "Specifies the number of days you want to retain log events in the log group" 190 | type = number 191 | default = 30 192 | } 193 | 194 | variable "log_group_kms_key_id" { 195 | description = "The ARN of the KMS Key to use when encrypting log data" 196 | type = string 197 | default = null 198 | } 199 | 200 | variable "log_group_class" { 201 | description = "Specified the log class of the log group. Possible values are: `STANDARD` or `INFREQUENT_ACCESS`" 202 | type = string 203 | default = null 204 | } 205 | 206 | variable "log_group_tags" { 207 | description = "A map of tags to apply to the CloudWatch log group" 208 | type = map(string) 209 | default = {} 210 | } 211 | 212 | ################################################################################ 213 | # IAM Role 214 | ################################################################################ 215 | 216 | variable "create_iam_role" { 217 | description = "Determines whether an IAM role is created" 218 | type = bool 219 | default = true 220 | } 221 | 222 | variable "iam_role_name" { 223 | description = "The name of the role. If omitted, Terraform will assign a random, unique name" 224 | type = string 225 | default = "" 226 | } 227 | 228 | variable "use_role_name_prefix" { 229 | description = "Whether to use unique name beginning with the specified `iam_role_name`" 230 | type = bool 231 | default = false 232 | } 233 | 234 | variable "iam_role_description" { 235 | description = "The description of the role" 236 | type = string 237 | default = "" 238 | } 239 | 240 | variable "iam_role_path" { 241 | description = "The path to the role" 242 | type = string 243 | default = null 244 | } 245 | 246 | variable "iam_role_force_detach_policies" { 247 | description = "Specifies to force detaching any policies the role has before destroying it" 248 | type = bool 249 | default = true 250 | } 251 | 252 | variable "iam_role_max_session_duration" { 253 | description = "The maximum session duration (in seconds) that you want to set for the specified role" 254 | type = number 255 | default = 43200 # 12 hours 256 | } 257 | 258 | variable "iam_role_permissions_boundary" { 259 | description = "The ARN of the policy that is used to set the permissions boundary for the role" 260 | type = string 261 | default = null 262 | } 263 | 264 | variable "iam_role_tags" { 265 | description = "A map of tags to apply to the IAM role" 266 | type = map(string) 267 | default = {} 268 | } 269 | 270 | ################################################################################ 271 | # IAM Role Policy 272 | ################################################################################ 273 | 274 | variable "create_iam_policy" { 275 | description = "Determines whether an IAM policy is created" 276 | type = bool 277 | default = true 278 | } 279 | 280 | variable "iam_policy_name" { 281 | description = "The name of the role policy. If omitted, Terraform will assign a random, unique name" 282 | type = string 283 | default = "" 284 | } 285 | 286 | variable "use_policy_name_prefix" { 287 | description = "Whether to use unique name beginning with the specified `iam_policy_name`" 288 | type = bool 289 | default = false 290 | } 291 | 292 | variable "kms_key_arns" { 293 | description = "List of KMS Key ARNs to allow access to decrypt SecretsManager secrets" 294 | type = list(string) 295 | default = [] 296 | } 297 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS RDS Proxy Terraform module 2 | 3 | Terraform module which creates an AWS RDS Proxy and its supporting resources. 4 | 5 | ## Usage 6 | 7 | See [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) directory for working examples to reference: 8 | 9 | ```hcl 10 | module "rds_proxy" { 11 | source = "terraform-aws-modules/rds-proxy/aws" 12 | 13 | name = "rds-proxy" 14 | iam_role_name = "rds-proxy-role" 15 | vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] 16 | vpc_security_group_ids = ["sg-f1d03a88"] 17 | 18 | endpoints = { 19 | read_write = { 20 | name = "read-write-endpoint" 21 | vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] 22 | vpc_security_group_ids = ["sg-f1d03a88"] 23 | }, 24 | read_only = { 25 | name = "read-only-endpoint" 26 | vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"] 27 | vpc_security_group_ids = ["sg-f1d03a88"] 28 | target_role = "READ_ONLY" 29 | } 30 | } 31 | 32 | auth = { 33 | "superuser" = { 34 | description = "Aurora PostgreSQL superuser password" 35 | secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD" 36 | } 37 | } 38 | 39 | # Target Aurora cluster 40 | engine_family = "POSTGRESQL" 41 | target_db_cluster = true 42 | db_cluster_identifier = "my-endpoint" 43 | 44 | tags = { 45 | Terraform = "true" 46 | Environment = "dev" 47 | } 48 | } 49 | ``` 50 | 51 | ## Examples 52 | 53 | Examples codified under the [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module(s). If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you! 54 | 55 | - [IAM auth. w/ MySQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-cluster) 56 | - [IAM auth. w/ MySQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-instance) 57 | - [IAM auth. w/ PostgreSQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-cluster) 58 | - [IAM auth. w/ PostgreSQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-instance) 59 | 60 | 61 | ## Requirements 62 | 63 | | Name | Version | 64 | |------|---------| 65 | | [terraform](#requirement\_terraform) | >= 1.5.7 | 66 | | [aws](#requirement\_aws) | >= 6.15 | 67 | 68 | ## Providers 69 | 70 | | Name | Version | 71 | |------|---------| 72 | | [aws](#provider\_aws) | >= 6.15 | 73 | 74 | ## Modules 75 | 76 | No modules. 77 | 78 | ## Resources 79 | 80 | | Name | Type | 81 | |------|------| 82 | | [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | 83 | | [aws_db_proxy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy) | resource | 84 | | [aws_db_proxy_default_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_default_target_group) | resource | 85 | | [aws_db_proxy_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_endpoint) | resource | 86 | | [aws_db_proxy_target.db_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | 87 | | [aws_db_proxy_target.db_instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target) | resource | 88 | | [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | 89 | | [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | 90 | | [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | 91 | | [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | 92 | | [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | 93 | | [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | 94 | | [aws_service_principal.rds](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/service_principal) | data source | 95 | 96 | ## Inputs 97 | 98 | | Name | Description | Type | Default | Required | 99 | |------|-------------|------|---------|:--------:| 100 | | [auth](#input\_auth) | Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters |
map(object({
auth_scheme = optional(string)
client_password_auth_type = optional(string)
description = optional(string)
iam_auth = optional(string)
secret_arn = optional(string)
username = optional(string)
}))
|
{
"default": {
"auth_scheme": "SECRETS"
}
}
| no | 101 | | [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 | 102 | | [create](#input\_create) | Whether cluster should be created (affects nearly all resources) | `bool` | `true` | no | 103 | | [create\_iam\_policy](#input\_create\_iam\_policy) | Determines whether an IAM policy is created | `bool` | `true` | no | 104 | | [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created | `bool` | `true` | no | 105 | | [db\_cluster\_identifier](#input\_db\_cluster\_identifier) | DB cluster identifier | `string` | `""` | no | 106 | | [db\_instance\_identifier](#input\_db\_instance\_identifier) | DB instance identifier | `string` | `""` | no | 107 | | [debug\_logging](#input\_debug\_logging) | Whether the proxy includes detailed information about SQL statements in its logs | `bool` | `false` | no | 108 | | [default\_auth\_scheme](#input\_default\_auth\_scheme) | Default authentication scheme that the proxy uses for client connections to the proxy and connections from the proxy to the underlying database. Valid values are NONE and IAM\_AUTH. Defaults to NONE | `string` | `null` | no | 109 | | [endpoints](#input\_endpoints) | Map of DB proxy endpoints to create and their attributes |
map(object({
name = optional(string)
vpc_subnet_ids = list(string)
vpc_security_group_ids = optional(list(string))
target_role = optional(string)
tags = optional(map(string), {})
}))
| `{}` | no | 110 | | [engine\_family](#input\_engine\_family) | The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL` | `string` | `""` | no | 111 | | [iam\_policy\_name](#input\_iam\_policy\_name) | The name of the role policy. If omitted, Terraform will assign a random, unique name | `string` | `""` | no | 112 | | [iam\_role\_description](#input\_iam\_role\_description) | The description of the role | `string` | `""` | no | 113 | | [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 | 114 | | [iam\_role\_max\_session\_duration](#input\_iam\_role\_max\_session\_duration) | The maximum session duration (in seconds) that you want to set for the specified role | `number` | `43200` | no | 115 | | [iam\_role\_name](#input\_iam\_role\_name) | The name of the role. If omitted, Terraform will assign a random, unique name | `string` | `""` | no | 116 | | [iam\_role\_path](#input\_iam\_role\_path) | The path to the role | `string` | `null` | no | 117 | | [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | The ARN of the policy that is used to set the permissions boundary for the role | `string` | `null` | no | 118 | | [iam\_role\_tags](#input\_iam\_role\_tags) | A map of tags to apply to the IAM role | `map(string)` | `{}` | no | 119 | | [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 | 120 | | [init\_query](#input\_init\_query) | One or more SQL statements for the proxy to run when opening each new database connection | `string` | `""` | no | 121 | | [kms\_key\_arns](#input\_kms\_key\_arns) | List of KMS Key ARNs to allow access to decrypt SecretsManager secrets | `list(string)` | `[]` | no | 122 | | [log\_group\_class](#input\_log\_group\_class) | Specified the log class of the log group. Possible values are: `STANDARD` or `INFREQUENT_ACCESS` | `string` | `null` | no | 123 | | [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 | 124 | | [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 | 125 | | [log\_group\_tags](#input\_log\_group\_tags) | A map of tags to apply to the CloudWatch log group | `map(string)` | `{}` | no | 126 | | [manage\_log\_group](#input\_manage\_log\_group) | Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist | `bool` | `true` | no | 127 | | [max\_connections\_percent](#input\_max\_connections\_percent) | The maximum size of the connection pool for each target in a target group | `number` | `90` | no | 128 | | [max\_idle\_connections\_percent](#input\_max\_idle\_connections\_percent) | Controls how actively the proxy closes idle database connections in the connection pool | `number` | `50` | no | 129 | | [name](#input\_name) | The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens | `string` | `""` | no | 130 | | [proxy\_tags](#input\_proxy\_tags) | A map of tags to apply to the RDS Proxy | `map(string)` | `{}` | no | 131 | | [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no | 132 | | [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 | 133 | | [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 | 134 | | [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 | 135 | | [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | 136 | | [target\_db\_cluster](#input\_target\_db\_cluster) | Determines whether DB cluster is targeted by proxy | `bool` | `false` | no | 137 | | [target\_db\_instance](#input\_target\_db\_instance) | Determines whether DB instance is targeted by proxy | `bool` | `false` | no | 138 | | [use\_policy\_name\_prefix](#input\_use\_policy\_name\_prefix) | Whether to use unique name beginning with the specified `iam_policy_name` | `bool` | `false` | no | 139 | | [use\_role\_name\_prefix](#input\_use\_role\_name\_prefix) | Whether to use unique name beginning with the specified `iam_role_name` | `bool` | `false` | no | 140 | | [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 | 141 | | [vpc\_subnet\_ids](#input\_vpc\_subnet\_ids) | One or more VPC subnet IDs to associate with the new proxy | `list(string)` | `[]` | no | 142 | 143 | ## Outputs 144 | 145 | | Name | Description | 146 | |------|-------------| 147 | | [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created | 148 | | [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager. | 149 | | [iam\_role\_name](#output\_iam\_role\_name) | IAM role name | 150 | | [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | 151 | | [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group | 152 | | [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group | 153 | | [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy | 154 | | [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group | 155 | | [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group | 156 | | [proxy\_default\_target\_group\_name](#output\_proxy\_default\_target\_group\_name) | The name of the default target group | 157 | | [proxy\_endpoint](#output\_proxy\_endpoint) | The endpoint that you can use to connect to the proxy | 158 | | [proxy\_id](#output\_proxy\_id) | The ID for the proxy | 159 | | [proxy\_target\_endpoint](#output\_proxy\_target\_endpoint) | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type | 160 | | [proxy\_target\_id](#output\_proxy\_target\_id) | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) | 161 | | [proxy\_target\_port](#output\_proxy\_target\_port) | Port for the target RDS DB Instance or Aurora DB Cluster | 162 | | [proxy\_target\_rds\_resource\_id](#output\_proxy\_target\_rds\_resource\_id) | Identifier representing the DB Instance or DB Cluster target | 163 | | [proxy\_target\_target\_arn](#output\_proxy\_target\_target\_arn) | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API | 164 | | [proxy\_target\_tracked\_cluster\_id](#output\_proxy\_target\_tracked\_cluster\_id) | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster | 165 | | [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` | 166 | 167 | 168 | ## License 169 | 170 | Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE). 171 | --------------------------------------------------------------------------------