Compare commits

...

33 commits

Author SHA1 Message Date
semantic-release-bot
cf3a8f41f6 chore(release): version 4.2.1 [skip ci]
## [4.2.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v4.2.0...v4.2.1) (2025-10-21)

### Bug Fixes

* Update CI workflow versions to latest ([#40](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/40)) ([5deff22](5deff22cf4))
2025-10-21 09:10:15 +00:00
Bryant Biggs
5deff22cf4
fix: Update CI workflow versions to latest (#40) 2025-10-21 11:09:40 +02:00
semantic-release-bot
c0b0204344 chore(release): version 4.2.0 [skip ci]
## [4.2.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v4.1.0...v4.2.0) (2025-10-14)

### Features

* Support `default_auth_scheme` ([#39](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/39)) ([c2073a0](c2073a031c))
2025-10-14 13:10:34 +00:00
Melissa Greenbaum
c2073a031c
feat: Support default_auth_scheme (#39) 2025-10-14 08:10:07 -05:00
semantic-release-bot
c65b5f03a7 chore(release): version 4.1.0 [skip ci]
## [4.1.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v4.0.0...v4.1.0) (2025-10-01)

### Features

* Add Terragrunt wrappers ([#38](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/38)) ([33b43c7](33b43c72ab))
2025-10-01 14:13:37 +00:00
flora-five
33b43c72ab
feat: Add Terragrunt wrappers (#38) 2025-10-01 09:13:12 -05:00
semantic-release-bot
3cd004baa3 chore(release): version 4.0.0 [skip ci]
## [4.0.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.2.1...v4.0.0) (2025-09-16)

### ⚠ BREAKING CHANGES

* Upgrade AWS provider and min required Terraform version to `6.0` and `1.5.7` respectively (#34)

### Features

* 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](47c0fcad4b))
2025-09-16 14:29:24 +00:00
mrobinson1022
47c0fcad4b
feat!: Upgrade AWS provider and min required Terraform version to 6.0 and 1.5.7 respectively (#34)
Co-authored-by: Bryant Biggs <bryantbiggs@gmail.com>
2025-09-16 09:28:55 -05:00
semantic-release-bot
e8ffe8f2f1 chore(release): version 3.2.1 [skip ci]
## [3.2.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.2.0...v3.2.1) (2025-05-22)

### Bug Fixes

* Correct service principal to rds.amazonaws.com (incl China) ([#32](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/32)) ([bbbf50c](bbbf50ce87))
2025-05-22 09:51:36 +00:00
vladislav-orlovskiy
bbbf50ce87
fix: Correct service principal to rds.amazonaws.com (incl China) (#32)
Co-authored-by: Bryant Biggs <bryantbiggs@gmail.com>
Co-authored-by: Anton Babenko <anton@antonbabenko.com>
2025-05-22 11:51:06 +02:00
semantic-release-bot
99df7e3913 chore(release): version 3.2.0 [skip ci]
## [3.2.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.1.1...v3.2.0) (2024-11-19)

### Features

* Add CloudWatch log group name to outputs ([#28](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/28)) ([0fc0e19](0fc0e19e64))

### Bug Fixes

* Update CI workflow versions to latest ([#27](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/27)) ([b6f22be](b6f22becf6))
2024-11-19 19:29:43 +00:00
Kevin Kortum
0fc0e19e64
feat: Add CloudWatch log group name to outputs (#28)
* feat: adds cloudwatch group name to module outputs

* test: align tests with the new output
2024-11-19 13:29:15 -06:00
Bryant Biggs
b6f22becf6
fix: Update CI workflow versions to latest (#27) 2024-10-11 18:25:27 +02:00
semantic-release-bot
56a832c60d chore(release): version 3.1.1 [skip ci]
## [3.1.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.1.0...v3.1.1) (2024-03-06)

### Bug Fixes

* Update CI workflow versions to remove deprecated runtime warnings ([#26](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/26)) ([a31a810](a31a81097b))
2024-03-06 19:15:03 +00:00
Bryant Biggs
a31a81097b
fix: Update CI workflow versions to remove deprecated runtime warnings (#26) 2024-03-06 11:14:39 -08:00
semantic-release-bot
67116fc717 chore(release): version 3.1.0 [skip ci]
## [3.1.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.0.0...v3.1.0) (2023-08-30)

### Features

* Add IAM role output ([#22](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/22)) ([d18ae45](d18ae45d9e))
2023-08-30 23:59:54 +00:00
Matt McLane
d18ae45d9e
feat: Add IAM role output (#22)
Co-authored-by: Bryant Biggs <bryantbiggs@gmail.com>
2023-08-30 19:59:28 -04:00
Akihiro YAMAZAKI
4e5c8068b9
chore: Fix broken links to examples (#21) 2023-06-27 13:19:28 +02:00
semantic-release-bot
cb79f9c5dc chore(release): version 3.0.0 [skip ci]
## [3.0.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v2.1.2...v3.0.0) (2023-06-09)

### ⚠ BREAKING CHANGES

* Increase Terraform and AWS provider minimum supported versions; update `auth` configuration schema (#17)

### Features

* 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](cc39e9d029))
2023-06-09 11:31:21 +00:00
jatalocks
cc39e9d029
feat!: Increase Terraform and AWS provider minimum supported versions; update auth configuration schema (#17)
Co-authored-by: Orest Kapko <orest.kapko@welltech.com>
Co-authored-by: Amitai Getzler <amitai.getzler@explorium.ai>
Co-authored-by: Orest Kapko <kapko2311@gmail.com>
Co-authored-by: Bryant Biggs <bryantbiggs@gmail.com>
Co-authored-by: Anton Babenko <anton@antonbabenko.com>
2023-06-09 07:30:52 -04:00
Pål-Magnus Slåtto
5d1c5e67ea
chore: Upgrade CI workflows to use non-deprecated runtimes (#15) 2023-01-24 13:44:33 -08:00
semantic-release-bot
8670cc32f3 chore(release): version 2.1.2 [skip ci]
### [2.1.2](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v2.1.1...v2.1.2) (2022-10-27)

### Bug Fixes

* Update CI configuration files to use latest version ([#13](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/13)) ([2e11175](2e111751a3))
2022-10-27 19:09:02 +00:00
Bryant Biggs
2e111751a3
fix: Update CI configuration files to use latest version (#13) 2022-10-27 21:08:36 +02:00
semantic-release-bot
8d5c48782d chore(release): version 2.1.1 [skip ci]
### [2.1.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v2.1.0...v2.1.1) (2022-08-10)

### Bug Fixes

* Disable endpoint creation when setting `create_proxy = false` ([#12](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/12)) ([26724ab](26724abef9))
* Update documentation to remove prior notice and deprecated workflow ([#9](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/issues/9)) ([8c1720c](8c1720cee3))
2022-08-10 18:35:22 +00:00
Gavin Williams
26724abef9
fix: Disable endpoint creation when setting create_proxy = false (#12)
Co-authored-by: Bryant Biggs <bryantbiggs@gmail.com>
2022-08-10 14:34:48 -04:00
Bryant Biggs
8c1720cee3
fix: Update documentation to remove prior notice and deprecated workflow (#9) 2022-04-21 09:56:38 +02:00
semantic-release-bot
6506401d6f chore(release): version 2.1.0 [skip ci]
## [2.1.0](https://github.com/clowdhaus/terraform-aws-rds-proxy/compare/v2.0.1...v2.1.0) (2022-04-20)

### Features

* Repo has moved to [terraform-aws-modules](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy) organization ([ec9c760](ec9c76000e))
2022-04-20 22:50:21 +00:00
Bryant Biggs
ec9c76000e feat: Repo has moved to [terraform-aws-modules](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy) organization 2022-04-20 18:48:34 -04:00
Bryant Biggs
2f5444105f chore: update reference in README documentation 2021-11-17 08:08:07 -05:00
Bryant Biggs
affe754727 fix: remove un-used variables and update linting checks to ensure this is catched in the future 2021-11-17 08:04:41 -05:00
Bryant Biggs
9c80ff9ac5
chore: update examples and CI workflows (#7) 2021-11-03 13:58:02 -04:00
Bryant Biggs
9af356bced chore: update README link to svg 2021-09-19 13:17:39 -04:00
Bryant Biggs
4bbca899ca
chore: update examples for security best practices and Bridgecrew monitoring (#6) 2021-09-19 12:41:40 -04:00
51 changed files with 1830 additions and 1795 deletions

2
.github/CODEOWNERS vendored
View file

@ -1,2 +0,0 @@
# Default owners - required for review/approval
* @bryantbiggs

View file

@ -1,76 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at contact@clowd.haus. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

21
.github/workflows/lock.yml vendored Normal file
View file

@ -0,0 +1,21 @@
name: 'Lock Threads'
on:
schedule:
- cron: '50 1 * * *'
jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
issue-comment: >
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.
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.
issue-inactive-days: '30'
pr-comment: >
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.
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.
pr-inactive-days: '30'

52
.github/workflows/pr-title.yml vendored Normal file
View file

@ -0,0 +1,52 @@
name: 'Validate PR title'
on:
pull_request_target:
types:
- opened
- edited
- synchronize
jobs:
main:
name: Validate PR title
runs-on: ubuntu-latest
steps:
# Please look up the latest version from
# https://github.com/amannn/action-semantic-pull-request/releases
- uses: amannn/action-semantic-pull-request@v6.1.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Configure which types are allowed.
# Default: https://github.com/commitizen/conventional-commit-types
types: |
fix
feat
docs
ci
chore
# Configure that a scope must always be provided.
requireScope: false
# Configure additional validation for the subject based on a regex.
# This example ensures the subject starts with an uppercase character.
subjectPattern: ^[A-Z].+$
# If `subjectPattern` is configured, you can use this property to override
# the default error message that is shown when the pattern doesn't match.
# The variables `subject` and `title` can be used within the message.
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}"
didn't match the configured pattern. Please ensure that the subject
starts with an uppercase character.
# For work-in-progress PRs you can typically use draft pull requests
# from Github. However, private repositories on the free plan don't have
# this option and therefore this action allows you to opt-in to using the
# special "[WIP]" prefix to indicate this state. This will avoid the
# validation of the PR title and the pull request checks remain pending.
# Note that a second check will be reported if this is enabled.
wip: true
# When using "Squash and merge" on a PR with only one commit, GitHub
# will suggest using that commit message instead of the PR title for the
# merge commit, and it's easy to commit this by mistake. Enable this option
# to also validate the commit message for one commit PRs.
validateSingleCommit: false

168
.github/workflows/pre-commit.yml vendored Normal file
View file

@ -0,0 +1,168 @@
name: Pre-Commit
on:
pull_request:
branches:
- main
- master
env:
TERRAFORM_DOCS_VERSION: v0.20.0
TFLINT_VERSION: v0.59.1
jobs:
collectInputs:
name: Collect workflow inputs
runs-on: ubuntu-latest
outputs:
directories: ${{ steps.dirs.outputs.directories }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Get root directories
id: dirs
uses: clowdhaus/terraform-composite-actions/directories@v1.14.0
preCommitMinVersions:
name: Min TF pre-commit
needs: collectInputs
runs-on: ubuntu-latest
strategy:
matrix:
directory: ${{ fromJson(needs.collectInputs.outputs.directories) }}
steps:
- name: Install rmz
uses: jaxxstorm/action-install-gh-release@v2.1.0
with:
repo: SUPERCILEX/fuc
asset-name: x86_64-unknown-linux-gnu-rmz
rename-to: rmz
chmod: 0755
extension-matching: disable
# https://github.com/orgs/community/discussions/25678#discussioncomment-5242449
- name: Delete unnecessary files
run: |
formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); }
getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); }
BEFORE=$(getAvailableSpace)
ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz
rmz -f /opt/hostedtoolcache/CodeQL &
rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk &
rmz -f /opt/hostedtoolcache/PyPy &
rmz -f /opt/hostedtoolcache/Ruby &
rmz -f /opt/hostedtoolcache/go &
wait
AFTER=$(getAvailableSpace)
SAVED=$((AFTER-BEFORE))
echo "=> Saved $(formatByteCount $SAVED)"
- name: Checkout
uses: actions/checkout@v5
- name: Terraform min/max versions
id: minMax
uses: clowdhaus/terraform-min-max@v2.1.0
with:
directory: ${{ matrix.directory }}
- name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }}
# Run only validate pre-commit check on min version supported
if: ${{ matrix.directory != '.' }}
uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0
with:
terraform-version: ${{ steps.minMax.outputs.minVersion }}
tflint-version: ${{ env.TFLINT_VERSION }}
args: 'terraform_validate --color=always --show-diff-on-failure --files ${{ matrix.directory }}/*'
- name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }}
# Run only validate pre-commit check on min version supported
if: ${{ matrix.directory == '.' }}
uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0
with:
terraform-version: ${{ steps.minMax.outputs.minVersion }}
tflint-version: ${{ env.TFLINT_VERSION }}
args: 'terraform_validate --color=always --show-diff-on-failure --files $(ls *.tf)'
preCommitMaxVersion:
name: Max TF pre-commit
runs-on: ubuntu-latest
needs: collectInputs
steps:
- name: Install rmz
uses: jaxxstorm/action-install-gh-release@v2.1.0
with:
repo: SUPERCILEX/fuc
asset-name: x86_64-unknown-linux-gnu-rmz
rename-to: rmz
chmod: 0755
extension-matching: disable
# https://github.com/orgs/community/discussions/25678#discussioncomment-5242449
- name: Delete unnecessary files
run: |
formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); }
getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); }
BEFORE=$(getAvailableSpace)
ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz
rmz -f /opt/hostedtoolcache/CodeQL &
rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk &
rmz -f /opt/hostedtoolcache/PyPy &
rmz -f /opt/hostedtoolcache/Ruby &
rmz -f /opt/hostedtoolcache/go &
sudo rmz -f /usr/local/lib/android &
if [[ ${{ github.repository }} == terraform-aws-modules/terraform-aws-security-group ]]; then
sudo rmz -f /usr/share/dotnet &
sudo rmz -f /usr/local/.ghcup &
sudo apt-get -qq remove -y 'azure-.*'
sudo apt-get -qq remove -y 'cpp-.*'
sudo apt-get -qq remove -y 'dotnet-runtime-.*'
sudo apt-get -qq remove -y 'google-.*'
sudo apt-get -qq remove -y 'libclang-.*'
sudo apt-get -qq remove -y 'libllvm.*'
sudo apt-get -qq remove -y 'llvm-.*'
sudo apt-get -qq remove -y 'mysql-.*'
sudo apt-get -qq remove -y 'postgresql-.*'
sudo apt-get -qq remove -y 'php.*'
sudo apt-get -qq remove -y 'temurin-.*'
sudo apt-get -qq remove -y kubectl firefox mono-devel
sudo apt-get -qq autoremove -y
sudo apt-get -qq clean
fi
wait
AFTER=$(getAvailableSpace)
SAVED=$((AFTER-BEFORE))
echo "=> Saved $(formatByteCount $SAVED)"
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Terraform min/max versions
id: minMax
uses: clowdhaus/terraform-min-max@v2.1.0
- name: Hide template dir
# Special to this repo, we don't want to check this dir
if: ${{ github.repository == 'terraform-aws-modules/terraform-aws-security-group' }}
run: rm -rf modules/_templates
- name: Pre-commit Terraform ${{ steps.minMax.outputs.maxVersion }}
uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0
with:
terraform-version: ${{ steps.minMax.outputs.maxVersion }}
tflint-version: ${{ env.TFLINT_VERSION }}
terraform-docs-version: ${{ env.TERRAFORM_DOCS_VERSION }}
install-hcledit: true

45
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,45 @@
name: Release
on:
workflow_dispatch:
push:
branches:
- main
- master
paths:
- '**/*.tpl'
- '**/*.py'
- '**/*.tf'
- '.github/workflows/release.yml'
jobs:
release:
name: Release
runs-on: ubuntu-latest
# Skip running release workflow on forks
if: github.repository_owner == 'terraform-aws-modules'
steps:
- name: Checkout
uses: actions/checkout@v5
with:
persist-credentials: false
fetch-depth: 0
- name: Set correct Node.js version
uses: actions/setup-node@v6
with:
node-version: 24
- name: Install dependencies
run: |
npm install \
@semantic-release/changelog@6.0.3 \
@semantic-release/git@10.0.1 \
conventional-changelog-conventionalcommits@9.1.0
- name: Release
uses: cycjimmy/semantic-release-action@v5
with:
semantic_version: 25.0.0
env:
GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }}

View file

@ -1,30 +0,0 @@
name: Release
on:
push:
branches:
- main
paths:
- '**.tf'
- '!examples/**.tf'
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 14
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: npx semantic-release

32
.github/workflows/stale-actions.yaml vendored Normal file
View file

@ -0,0 +1,32 @@
name: 'Mark or close stale issues and PRs'
on:
schedule:
- cron: '0 0 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
# Staling issues and PR's
days-before-stale: 30
stale-issue-label: stale
stale-pr-label: stale
stale-issue-message: |
This issue has been automatically marked as stale because it has been open 30 days
with no activity. Remove stale label or comment or this issue will be closed in 10 days
stale-pr-message: |
This PR has been automatically marked as stale because it has been open 30 days
with no activity. Remove stale label or comment or this PR will be closed in 10 days
# Not stale if have this labels or part of milestone
exempt-issue-labels: bug,wip,on-hold
exempt-pr-labels: bug,wip,on-hold
exempt-all-milestones: true
# Close issue operations
# Label will be automatically removed if the issues are no longer closed nor locked.
days-before-close: 10
delete-branch: true
close-issue-message: This issue was automatically closed because of stale in 10 days
close-pr-message: This PR was automatically closed because of stale in 10 days

View file

@ -1,77 +0,0 @@
name: static-checks
on:
pull_request:
jobs:
versionExtract:
name: Get min/max versions
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Terraform min/max versions
id: minMax
uses: clowdhaus/terraform-min-max@main
outputs:
minVersion: ${{ steps.minMax.outputs.minVersion }}
maxVersion: ${{ steps.minMax.outputs.maxVersion }}
versionEvaluate:
name: Evaluate Terraform versions
runs-on: ubuntu-latest
needs: versionExtract
strategy:
fail-fast: false
matrix:
version:
- ${{ needs.versionExtract.outputs.minVersion }}
- ${{ needs.versionExtract.outputs.maxVersion }}
directory:
- examples/mysql_iam_cluster
- examples/mysql_iam_instance
- examples/postgresql_iam_cluster
- examples/postgresql_iam_instance
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Terraform v${{ matrix.version }}
uses: hashicorp/setup-terraform@v1
with:
terraform_version: ${{ matrix.version }}
- name: Init & validate v${{ matrix.version }}
run: |
cd ${{ matrix.directory }}
terraform init
terraform validate
- name: tflint
uses: reviewdog/action-tflint@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
working_directory: ${{ matrix.directory }}
fail_on_error: 'true'
filter_mode: 'nofilter'
flags: '--module'
format:
name: Check code format
runs-on: ubuntu-latest
needs: versionExtract
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Terraform v${{ needs.versionExtract.outputs.maxVersion }}
uses: hashicorp/setup-terraform@v1
with:
terraform_version: ${{ needs.versionExtract.outputs.maxVersion }}
- name: Check Terraform format changes
run: terraform fmt --recursive -check=true

24
.gitignore vendored
View file

@ -1,13 +1,13 @@
# Local .terraform directories
**/.terraform/*
# Terraform lockfile
.terraform.lock.hcl
# .tfstate files
*.tfstate
*.tfstate.*
# terraform lockfile
.terraform.lock.hcl
# Crash log files
crash.log
@ -15,7 +15,6 @@ crash.log
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
#
*.tfvars
# Ignore override files as they are usually used to override resources locally and so
@ -25,13 +24,16 @@ override.tf.json
*_override.tf
*_override.tf.json
# Include override files you do wish to add to version control using negated pattern
#
# !example_override.tf
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
# Ignore CLI configuration files
.terraformrc
terraform.rc
# Lambda build artifacts
builds/
__pycache__/
*.zip
.tox
# Local editors/macos files
.DS_Store
.idea

View file

@ -1,10 +1,31 @@
repos:
- repo: git://github.com/antonbabenko/pre-commit-terraform
rev: v1.50.0
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.103.0
hooks:
- id: terraform_fmt
- id: terraform_wrapper_module_for_each
- id: terraform_docs
- repo: git://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0
args:
- '--args=--lockfile=false'
- id: terraform_tflint
args:
- '--args=--only=terraform_deprecated_interpolation'
- '--args=--only=terraform_deprecated_index'
- '--args=--only=terraform_unused_declarations'
- '--args=--only=terraform_comment_syntax'
- '--args=--only=terraform_documented_outputs'
- '--args=--only=terraform_documented_variables'
- '--args=--only=terraform_typed_variables'
- '--args=--only=terraform_module_pinned_source'
- '--args=--only=terraform_naming_convention'
- '--args=--only=terraform_required_version'
- '--args=--only=terraform_required_providers'
- '--args=--only=terraform_standard_module_structure'
- '--args=--only=terraform_workspace_remote'
- id: terraform_validate
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-merge-conflict
- id: end-of-file-fixer
- id: trailing-whitespace

View file

@ -1,10 +1,45 @@
{
"branches": [
"main"
"main",
"master"
],
"ci": false,
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits"
}
],
[
"@semantic-release/release-notes-generator",
"@semantic-release/github"
{
"preset": "conventionalcommits"
}
],
[
"@semantic-release/github",
{
"successComment": "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:",
"labels": false,
"releasedLabels": false
}
],
[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md",
"changelogTitle": "# Changelog\n\nAll notable changes to this project will be documented in this file."
}
],
[
"@semantic-release/git",
{
"assets": [
"CHANGELOG.md"
],
"message": "chore(release): version ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
}

100
CHANGELOG.md Normal file
View file

@ -0,0 +1,100 @@
# Changelog
All notable changes to this project will be documented in this file.
## [4.2.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v4.2.0...v4.2.1) (2025-10-21)
### Bug Fixes
* 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))
## [4.2.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v4.1.0...v4.2.0) (2025-10-14)
### Features
* 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))
## [4.1.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v4.0.0...v4.1.0) (2025-10-01)
### Features
* 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))
## [4.0.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.2.1...v4.0.0) (2025-09-16)
### ⚠ BREAKING CHANGES
* Upgrade AWS provider and min required Terraform version to `6.0` and `1.5.7` respectively (#34)
### Features
* 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))
## [3.2.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.2.0...v3.2.1) (2025-05-22)
### Bug Fixes
* 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))
## [3.2.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.1.1...v3.2.0) (2024-11-19)
### Features
* 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))
### Bug Fixes
* 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))
## [3.1.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.1.0...v3.1.1) (2024-03-06)
### Bug Fixes
* 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))
## [3.1.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v3.0.0...v3.1.0) (2023-08-30)
### Features
* 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))
## [3.0.0](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v2.1.2...v3.0.0) (2023-06-09)
### ⚠ BREAKING CHANGES
* Increase Terraform and AWS provider minimum supported versions; update `auth` configuration schema (#17)
### Features
* 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))
### [2.1.2](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v2.1.1...v2.1.2) (2022-10-27)
### Bug Fixes
* 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))
### [2.1.1](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/compare/v2.1.0...v2.1.1) (2022-08-10)
### Bug Fixes
* 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))
* 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))
## [2.1.0](https://github.com/clowdhaus/terraform-aws-rds-proxy/compare/v2.0.1...v2.1.0) (2022-04-20)
### Features
* 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))

25
LICENSE
View file

@ -174,28 +174,3 @@
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2021 Clowd Haus, LLC.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -4,18 +4,18 @@ Terraform module which creates an AWS RDS Proxy and its supporting resources.
## Usage
See [`examples`](./examples) directory for working examples to reference:
See [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) directory for working examples to reference:
```hcl
module "rds_proxy" {
source = "clowdhaus/rds-proxy/aws"
source = "terraform-aws-modules/rds-proxy/aws"
name = "rds-proxy"
iam_role_name = "rds-proxy-role"
vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"]
vpc_security_group_ids = ["sg-f1d03a88"]
db_proxy_endpoints = {
endpoints = {
read_write = {
name = "read-write-endpoint"
vpc_subnet_ids = ["subnet-30ef7b3c", "subnet-1ecda77b", "subnet-ca09ddbc"]
@ -29,21 +29,17 @@ module "rds_proxy" {
}
}
secrets = {
auth = {
"superuser" = {
description = "Aurora PostgreSQL superuser password"
arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD"
kms_key_id = "6ca29066-552a-46c5-a7d7-7bf9a15fc255"
secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD"
}
}
engine_family = "POSTGRESQL"
db_host = "myendpoint.cluster-custom-123456789012.us-east-1.rds.amazonaws.com"
db_name = "example"
# Target Aurora cluster
engine_family = "POSTGRESQL"
target_db_cluster = true
db_cluster_identifier = "myendpoint"
db_cluster_identifier = "my-endpoint"
tags = {
Terraform = "true"
@ -54,26 +50,26 @@ module "rds_proxy" {
## Examples
Examples codified under the [`examples`](./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!
Examples codified under the [`examples`](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples) are intended to give users references for how to use the module(s) as well as testing/validating changes to the source code of the module(s). If contributing to the project, please be sure to make any appropriate updates to the relevant examples to allow maintainers to test your changes and to keep the examples up to date for users. Thank you!
- [IAM auth. w/ MySQL Aurora cluster](./examples/mysql_iam_cluster)
- [IAM auth. w/ MySQL RDS instance](./examples/mysql_iam_instance)
- [IAM auth. w/ PostgreSQL Aurora cluster](./examples/postgresql_iam_cluster)
- [IAM auth. w/ PostgreSQL RDS instance](./examples/postgresql_iam_instance)
- [IAM auth. w/ MySQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-cluster)
- [IAM auth. w/ MySQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/mysql-iam-instance)
- [IAM auth. w/ PostgreSQL Aurora cluster](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-cluster)
- [IAM auth. w/ PostgreSQL RDS instance](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/tree/master/examples/postgresql-iam-instance)
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.38 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.15 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.38 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.15 |
## Modules
@ -93,27 +89,25 @@ No modules.
| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
| [aws_service_principal.rds](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/service_principal) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_auth"></a> [auth](#input\_auth) | Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters | `map(string)` | `{}` | no |
| <a name="input_auth_scheme"></a> [auth\_scheme](#input\_auth\_scheme) | The type of authentication that the proxy uses for connections from the proxy to the underlying database. One of `SECRETS` | `string` | `"SECRETS"` | no |
| <a name="input_auth"></a> [auth](#input\_auth) | Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters | <pre>map(object({<br/> auth_scheme = optional(string)<br/> client_password_auth_type = optional(string)<br/> description = optional(string)<br/> iam_auth = optional(string)<br/> secret_arn = optional(string)<br/> username = optional(string)<br/> }))</pre> | <pre>{<br/> "default": {<br/> "auth_scheme": "SECRETS"<br/> }<br/>}</pre> | no |
| <a name="input_connection_borrow_timeout"></a> [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 |
| <a name="input_create"></a> [create](#input\_create) | Whether cluster should be created (affects nearly all resources) | `bool` | `true` | no |
| <a name="input_create_iam_policy"></a> [create\_iam\_policy](#input\_create\_iam\_policy) | Determines whether an IAM policy is created | `bool` | `true` | no |
| <a name="input_create_iam_role"></a> [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created | `bool` | `true` | no |
| <a name="input_create_proxy"></a> [create\_proxy](#input\_create\_proxy) | Determines whether a proxy and its resources will be created | `bool` | `true` | no |
| <a name="input_db_cluster_identifier"></a> [db\_cluster\_identifier](#input\_db\_cluster\_identifier) | DB cluster identifier | `string` | `""` | no |
| <a name="input_db_host"></a> [db\_host](#input\_db\_host) | The identifier to use for the database endpoint | `string` | `""` | no |
| <a name="input_db_instance_identifier"></a> [db\_instance\_identifier](#input\_db\_instance\_identifier) | DB instance identifier | `string` | `""` | no |
| <a name="input_db_name"></a> [db\_name](#input\_db\_name) | The name of the database | `string` | `""` | no |
| <a name="input_db_proxy_endpoints"></a> [db\_proxy\_endpoints](#input\_db\_proxy\_endpoints) | Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`) | `any` | `{}` | no |
| <a name="input_debug_logging"></a> [debug\_logging](#input\_debug\_logging) | Whether the proxy includes detailed information about SQL statements in its logs | `bool` | `false` | no |
| <a name="input_default_auth_scheme"></a> [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 |
| <a name="input_endpoints"></a> [endpoints](#input\_endpoints) | Map of DB proxy endpoints to create and their attributes | <pre>map(object({<br/> name = optional(string)<br/> vpc_subnet_ids = list(string)<br/> vpc_security_group_ids = optional(list(string))<br/> target_role = optional(string)<br/> tags = optional(map(string), {})<br/> }))</pre> | `{}` | no |
| <a name="input_engine_family"></a> [engine\_family](#input\_engine\_family) | The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL` | `string` | `""` | no |
| <a name="input_iam_auth"></a> [iam\_auth](#input\_iam\_auth) | Whether to require or disallow AWS Identity and Access Management (IAM) authentication for connections to the proxy. One of `DISABLED`, `REQUIRED` | `string` | `"REQUIRED"` | no |
| <a name="input_iam_creation_wait_duration"></a> [iam\_creation\_wait\_duration](#input\_iam\_creation\_wait\_duration) | Time duration delay to wait for IAM resource creation/propagation. For example, 30s for 30 seconds or 5m for 5 minutes. Updating this value by itself will not trigger a delay. | `string` | `"30s"` | no |
| <a name="input_iam_policy_name"></a> [iam\_policy\_name](#input\_iam\_policy\_name) | The name of the role policy. If omitted, Terraform will assign a random, unique name | `string` | `""` | no |
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | The description of the role | `string` | `""` | no |
| <a name="input_iam_role_force_detach_policies"></a> [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 |
@ -124,6 +118,8 @@ No modules.
| <a name="input_iam_role_tags"></a> [iam\_role\_tags](#input\_iam\_role\_tags) | A map of tags to apply to the IAM role | `map(string)` | `{}` | no |
| <a name="input_idle_client_timeout"></a> [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 |
| <a name="input_init_query"></a> [init\_query](#input\_init\_query) | One or more SQL statements for the proxy to run when opening each new database connection | `string` | `""` | no |
| <a name="input_kms_key_arns"></a> [kms\_key\_arns](#input\_kms\_key\_arns) | List of KMS Key ARNs to allow access to decrypt SecretsManager secrets | `list(string)` | `[]` | no |
| <a name="input_log_group_class"></a> [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 |
| <a name="input_log_group_kms_key_id"></a> [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 |
| <a name="input_log_group_retention_in_days"></a> [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 |
| <a name="input_log_group_tags"></a> [log\_group\_tags](#input\_log\_group\_tags) | A map of tags to apply to the CloudWatch log group | `map(string)` | `{}` | no |
@ -132,13 +128,13 @@ No modules.
| <a name="input_max_idle_connections_percent"></a> [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 |
| <a name="input_name"></a> [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 |
| <a name="input_proxy_tags"></a> [proxy\_tags](#input\_proxy\_tags) | A map of tags to apply to the RDS Proxy | `map(string)` | `{}` | no |
| <a name="input_region"></a> [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no |
| <a name="input_require_tls"></a> [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 |
| <a name="input_role_arn"></a> [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 |
| <a name="input_secrets"></a> [secrets](#input\_secrets) | Map of secerets to be used by RDS Proxy for authentication to the database | `map(object({ arn = string, description = string, kms_key_id = string }))` | `{}` | no |
| <a name="input_session_pinning_filters"></a> [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 |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to use on all resources | `map(string)` | `{}` | no |
| <a name="input_target_db_cluster"></a> [target\_db\_cluster](#input\_target\_db\_cluster) | Determines whether DB cluster is targetted by proxy | `bool` | `false` | no |
| <a name="input_target_db_instance"></a> [target\_db\_instance](#input\_target\_db\_instance) | Determines whether DB instance is targetted by proxy | `bool` | `false` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |
| <a name="input_target_db_cluster"></a> [target\_db\_cluster](#input\_target\_db\_cluster) | Determines whether DB cluster is targeted by proxy | `bool` | `false` | no |
| <a name="input_target_db_instance"></a> [target\_db\_instance](#input\_target\_db\_instance) | Determines whether DB instance is targeted by proxy | `bool` | `false` | no |
| <a name="input_use_policy_name_prefix"></a> [use\_policy\_name\_prefix](#input\_use\_policy\_name\_prefix) | Whether to use unique name beginning with the specified `iam_policy_name` | `bool` | `false` | no |
| <a name="input_use_role_name_prefix"></a> [use\_role\_name\_prefix](#input\_use\_role\_name\_prefix) | Whether to use unique name beginning with the specified `iam_role_name` | `bool` | `false` | no |
| <a name="input_vpc_security_group_ids"></a> [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 |
@ -149,7 +145,11 @@ No modules.
| Name | Description |
|------|-------------|
| <a name="output_db_proxy_endpoints"></a> [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created |
| <a name="output_iam_role_arn"></a> [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. |
| <a name="output_iam_role_name"></a> [iam\_role\_name](#output\_iam\_role\_name) | IAM role name |
| <a name="output_iam_role_unique_id"></a> [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role |
| <a name="output_log_group_arn"></a> [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group |
| <a name="output_log_group_name"></a> [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group |
| <a name="output_proxy_arn"></a> [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy |
| <a name="output_proxy_default_target_group_arn"></a> [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group |
| <a name="output_proxy_default_target_group_id"></a> [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group |
@ -163,8 +163,8 @@ No modules.
| <a name="output_proxy_target_target_arn"></a> [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 |
| <a name="output_proxy_target_tracked_cluster_id"></a> [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 |
| <a name="output_proxy_target_type"></a> [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END_TF_DOCS -->
## License
Apache-2.0 Licensed. See [LICENSE](LICENSE).
Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE).

79
docs/UPGRADE-3.0.md Normal file
View file

@ -0,0 +1,79 @@
# Upgrade from v2.x to v3.x
If you have any questions regarding this upgrade process, please consult the `examples` directory.
If you find a bug, please open an issue with supporting configuration to reproduce.
## List of backwards incompatible changes
- Minimum supported Terraform version is now 1.0
- Minimum supported AWS provider version is now 5.0
- The manner in which authentication is configured has changed - previously auth settings were provided under `secrets` in conjunction with `auth_scheme` and `iam_auth` variables. Now, auth settings are provided under the `auth` variable for multiple auth entries.
### Variable and output changes
1. Removed variables:
- `auth_scheme` is now set under the `auth` variable for a given auth entry
- `iam_auth` is now set under the `auth` variable for a given auth entry
2. Renamed variables:
- `create_proxy` -> `create`
- `secrets` -> `auth`
- `db_proxy_endpoints` -> `endpoints`
3. Added variables:
- `kms_key_arns` - list of KMS key ARNs to use allowing permission to decrypt SecretsManager secrets
4. Removed outputs:
- None
5. Renamed outputs:
- None
6. Added outputs:
- None
## Diff of Before (v2.x) vs After (v3.x)
```diff
module "rds_proxy" {
source = "terraform-aws-modules/rds-proxy/aws"
- version = "~> 2.0"
+ version = "~> 3.0"
# Only the affected attributes are shown
- create_proxy = true
+ create = true
- db_proxy_endpoints = {
- ...
- }
+ endpoints = {
+ ...
+ }
- secrets = {
- "superuser" = {
- description = "Aurora PostgreSQL superuser password"
- arn = "arn:aws:secretsmanager:eu-west-1:123456789012:secret:superuser-6gsjLD"
- kms_key_id = "6ca29066-552a-46c5-a7d7-7bf9a15fc255"
- }
- }
+ auth = {
+ "superuser" = {
+ description = "Aurora PostgreSQL superuser password"
+ secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:superuser-6gsjLD"
+ }
+ }
+ kms_key_arns = ["arn:aws:kms:eu-west-1:123456789012:key/6ca29066-552a-46c5-a7d7-7bf9a15fc255"]
}
```
### State Changes
- None

8
examples/README.md Normal file
View file

@ -0,0 +1,8 @@
# Examples
Please note - the examples provided serve two primary means:
1. Show users working examples of the various ways in which the module can be configured and features supported
2. A means of testing/validating module changes
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.

View file

@ -25,52 +25,34 @@ An EC2 instance configuration has been provided for use in validating the exampl
3. Copy the output from `superuser_proxy_iam_connect` and paste it into the window
4. You should now be connected to the `example` database in the RDS instance via the AWS Proxy using IAM authentication
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.38 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.15 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.38 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.15 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_ec2_instance"></a> [ec2\_instance](#module\_ec2\_instance) | terraform-aws-modules/ec2-instance/aws | ~> 2 |
| <a name="module_ec2_sg"></a> [ec2\_sg](#module\_ec2\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_rds"></a> [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 4 |
| <a name="module_rds_proxy"></a> [rds\_proxy](#module\_rds\_proxy) | ../../ | |
| <a name="module_rds_proxy_sg"></a> [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3 |
| <a name="module_rds"></a> [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 9.0 |
| <a name="module_rds_proxy"></a> [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a |
| <a name="module_rds_proxy_sg"></a> [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
| Name | Type |
|------|------|
| [aws_db_parameter_group.aurora_db_mysql57_parameter_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource |
| [aws_iam_instance_profile.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
| [aws_iam_role.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_role_policy_attachment.ec2_ssm](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_rds_cluster_parameter_group.aurora_cluster_mysql57_parameter_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_parameter_group) | resource |
| [aws_secretsmanager_secret.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
| [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
| [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |
| [aws_ami.ubuntu](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.ec2_test_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
## Inputs
@ -82,6 +64,7 @@ No inputs.
|------|-------------|
| <a name="output_db_proxy_endpoints"></a> [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created |
| <a name="output_log_group_arn"></a> [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group |
| <a name="output_log_group_name"></a> [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group |
| <a name="output_proxy_arn"></a> [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy |
| <a name="output_proxy_default_target_group_arn"></a> [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group |
| <a name="output_proxy_default_target_group_id"></a> [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group |
@ -95,9 +78,6 @@ No inputs.
| <a name="output_proxy_target_target_arn"></a> [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 |
| <a name="output_proxy_target_tracked_cluster_id"></a> [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 |
| <a name="output_proxy_target_type"></a> [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
| <a name="output_superuser_db_password_connect"></a> [superuser\_db\_password\_connect](#output\_superuser\_db\_password\_connect) | Connect to database using superuser with username/password directly to database |
| <a name="output_superuser_proxy_iam_connect"></a> [superuser\_proxy\_iam\_connect](#output\_superuser\_proxy\_iam\_connect) | Connect to RDS Proxy using IAM auth via token generated |
| <a name="output_superuser_proxy_iam_token"></a> [superuser\_proxy\_iam\_token](#output\_superuser\_proxy\_iam\_token) | Gerate connection token for connecting to RDS Proxy with IAM auth |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END_TF_DOCS -->
Apache-2.0 Licensed. See [LICENSE](../../LICENSE).
Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE).

View file

@ -0,0 +1,144 @@
provider "aws" {
region = local.region
}
data "aws_availability_zones" "available" {}
locals {
name = "ex-${basename(path.cwd)}"
region = "eu-west-1"
vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Example = local.name
GithubRepo = "terraform-aws-rds-proxy"
GithubOrg = "terraform-aws-modules"
}
}
################################################################################
# RDS Proxy
################################################################################
module "rds_proxy" {
source = "../../"
name = local.name
iam_role_name = local.name
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
endpoints = {
read_write = {
name = "read-write-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
tags = local.tags
},
read_only = {
name = "read-only-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
target_role = "READ_ONLY"
tags = local.tags
}
}
auth = {
"root" = {
description = "Cluster generated master user password"
secret_arn = module.rds.cluster_master_user_secret[0].secret_arn
}
}
engine_family = "MYSQL"
debug_logging = true
# Target Aurora cluster
target_db_cluster = true
db_cluster_identifier = module.rds.cluster_id
tags = local.tags
}
################################################################################
# Supporting Resources
################################################################################
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)]
tags = local.tags
}
module "rds" {
source = "terraform-aws-modules/rds-aurora/aws"
version = "~> 9.0"
name = local.name
engine = "aurora-mysql"
engine_version = "8.0"
master_username = "root"
# When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM
iam_database_authentication_enabled = false
instance_class = "db.r6g.large"
instances = {
1 = {}
2 = {}
}
vpc_id = module.vpc.vpc_id
db_subnet_group_name = module.vpc.database_subnet_group_name
security_group_rules = {
vpc_ingress = {
cidr_blocks = module.vpc.private_subnets_cidr_blocks
}
}
apply_immediately = true
skip_final_snapshot = true
tags = local.tags
}
module "rds_proxy_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 5.0"
name = "${local.name}-proxy"
description = "PostgreSQL RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet MySQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
egress_with_cidr_blocks = [
{
description = "Database subnet MySQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks)
},
]
tags = local.tags
}

View file

@ -66,7 +66,7 @@ output "proxy_target_type" {
value = module.rds_proxy.proxy_target_type
}
# DB proxy endponts
# DB proxy endpoints
output "db_proxy_endpoints" {
description = "Array containing the full resource object and attributes for all DB proxy endpoints created"
value = module.rds_proxy.db_proxy_endpoints
@ -78,19 +78,7 @@ output "log_group_arn" {
value = module.rds_proxy.log_group_arn
}
# For aiding in testing & verification
output "superuser_db_password_connect" {
description = "Connect to database using superuser with username/password directly to database"
value = "mysql --host=${module.rds.rds_cluster_endpoint} --user=${local.db_username} --password=${local.db_password} ${module.rds.rds_cluster_database_name}"
sensitive = true
}
output "superuser_proxy_iam_token" {
description = "Gerate connection token for connecting to RDS Proxy with IAM auth"
value = "TOKEN=$(aws rds generate-db-auth-token --hostname ${module.rds_proxy.proxy_endpoint} --port 3306 --region ${local.region} --username ${local.db_username})"
}
output "superuser_proxy_iam_connect" {
description = "Connect to RDS Proxy using IAM auth via token generated"
value = "mysql --host=${module.rds_proxy.proxy_endpoint} --user=${local.db_username} --password=$TOKEN ${module.rds.rds_cluster_database_name} --ssl-ca=/home/ssm-user/AmazonRootCA1.pem --enable-cleartext-plugin"
output "log_group_name" {
description = "The name of the CloudWatch log group"
value = module.rds_proxy.log_group_name
}

View file

View file

@ -1,10 +1,10 @@
terraform {
required_version = ">= 0.13.1"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.38"
version = ">= 6.15"
}
}
}

View file

@ -25,51 +25,42 @@ An EC2 instance configuration has been provided for use in validating the exampl
3. Copy the output from `superuser_proxy_iam_connect` and paste it into the window
4. You should now be connected to the `example` database in the Aurora cluster via the AWS Proxy using IAM authentication
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.38 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.15 |
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.38 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.15 |
| <a name="provider_random"></a> [random](#provider\_random) | >= 2.0 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_ec2_instance"></a> [ec2\_instance](#module\_ec2\_instance) | terraform-aws-modules/ec2-instance/aws | ~> 2 |
| <a name="module_ec2_sg"></a> [ec2\_sg](#module\_ec2\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_rds"></a> [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 3 |
| <a name="module_rds_proxy"></a> [rds\_proxy](#module\_rds\_proxy) | ../../ | |
| <a name="module_rds_proxy_sg"></a> [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_rds_sg"></a> [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3 |
| <a name="module_rds"></a> [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 6.0 |
| <a name="module_rds_proxy"></a> [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a |
| <a name="module_rds_proxy_sg"></a> [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 |
| <a name="module_rds_sg"></a> [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
| Name | Type |
|------|------|
| [aws_iam_instance_profile.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
| [aws_iam_role.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_role_policy_attachment.ec2_ssm](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_secretsmanager_secret.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
| [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
| [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |
| [aws_ami.ubuntu](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.ec2_test_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
| [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
## Inputs
@ -81,6 +72,7 @@ No inputs.
|------|-------------|
| <a name="output_db_proxy_endpoints"></a> [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created |
| <a name="output_log_group_arn"></a> [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group |
| <a name="output_log_group_name"></a> [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group |
| <a name="output_proxy_arn"></a> [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy |
| <a name="output_proxy_default_target_group_arn"></a> [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group |
| <a name="output_proxy_default_target_group_id"></a> [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group |
@ -94,9 +86,6 @@ No inputs.
| <a name="output_proxy_target_target_arn"></a> [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 |
| <a name="output_proxy_target_tracked_cluster_id"></a> [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 |
| <a name="output_proxy_target_type"></a> [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
| <a name="output_superuser_db_password_connect"></a> [superuser\_db\_password\_connect](#output\_superuser\_db\_password\_connect) | Connect to database using superuser with username/password directly to database |
| <a name="output_superuser_proxy_iam_connect"></a> [superuser\_proxy\_iam\_connect](#output\_superuser\_proxy\_iam\_connect) | Connect to RDS Proxy using IAM auth via token generated |
| <a name="output_superuser_proxy_iam_token"></a> [superuser\_proxy\_iam\_token](#output\_superuser\_proxy\_iam\_token) | Gerate connection token for connecting to RDS Proxy with IAM auth |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END_TF_DOCS -->
Apache-2.0 Licensed. See [LICENSE](../../LICENSE).
Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE).

View file

@ -0,0 +1,200 @@
provider "aws" {
region = local.region
}
data "aws_availability_zones" "available" {}
locals {
name = "ex-${basename(path.cwd)}"
region = "eu-west-1"
db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account
db_password = random_password.password.result
vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Example = local.name
GithubRepo = "terraform-aws-rds-proxy"
GithubOrg = "terraform-aws-modules"
}
}
################################################################################
# RDS Proxy
################################################################################
module "rds_proxy" {
source = "../../"
name = local.name
iam_role_name = local.name
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
endpoints = {
read_write = {
name = "read-write-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
tags = local.tags
},
read_only = {
name = "read-only-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
target_role = "READ_ONLY"
tags = local.tags
}
}
auth = {
(local.db_username) = {
description = aws_secretsmanager_secret.superuser.description
secret_arn = aws_secretsmanager_secret.superuser.arn
}
}
engine_family = "MYSQL"
debug_logging = true
# Target RDS instance
target_db_instance = true
db_instance_identifier = module.rds.db_instance_identifier
tags = local.tags
}
################################################################################
# Supporting Resources
################################################################################
resource "random_pet" "users" {
length = 2
separator = "_"
}
resource "random_password" "password" {
length = 16
special = false
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)]
tags = local.tags
}
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "~> 6.0"
username = local.db_username
password = local.db_password
# When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM
iam_database_authentication_enabled = false
identifier = local.name
engine = "mysql"
engine_version = "8.0"
family = "mysql8.0" # DB parameter group
major_engine_version = "8.0" # DB option group
instance_class = "db.t4g.large"
allocated_storage = 20
port = 3306
apply_immediately = true
db_subnet_group_name = module.vpc.database_subnet_group
vpc_security_group_ids = [module.rds_sg.security_group_id]
multi_az = true
backup_retention_period = 0
deletion_protection = false
tags = local.tags
}
module "rds_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 5.0"
name = "rds"
description = "MySQL RDS example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet MySQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
tags = local.tags
}
module "rds_proxy_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 5.0"
name = "${local.name}-proxy"
description = "PostgreSQL RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet MySQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
egress_with_cidr_blocks = [
{
description = "Database subnet MySQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks)
},
]
tags = local.tags
}
################################################################################
# Secrets - DB user passwords
################################################################################
data "aws_kms_alias" "secretsmanager" {
name = "alias/aws/secretsmanager"
}
resource "aws_secretsmanager_secret" "superuser" {
name = local.db_username
description = "Database superuser, ${local.db_username}, database connection values"
kms_key_id = data.aws_kms_alias.secretsmanager.id
tags = local.tags
}
resource "aws_secretsmanager_secret_version" "superuser" {
secret_id = aws_secretsmanager_secret.superuser.id
secret_string = jsonencode({
username = local.db_username
password = local.db_password
})
}

View file

@ -66,7 +66,7 @@ output "proxy_target_type" {
value = module.rds_proxy.proxy_target_type
}
# DB proxy endponts
# DB proxy endpoints
output "db_proxy_endpoints" {
description = "Array containing the full resource object and attributes for all DB proxy endpoints created"
value = module.rds_proxy.db_proxy_endpoints
@ -78,19 +78,7 @@ output "log_group_arn" {
value = module.rds_proxy.log_group_arn
}
# For aiding in testing & verification
output "superuser_db_password_connect" {
description = "Connect to database using superuser with username/password directly to database"
value = "PGPASSWORD=${local.db_password} psql -h ${module.rds.db_instance_address} -p 5432 -d ${module.rds.db_instance_name} -U ${local.db_username} --set=sslmode=require"
sensitive = true
}
output "superuser_proxy_iam_token" {
description = "Gerate connection token for connecting to RDS Proxy with IAM auth"
value = "TOKEN=$(aws rds generate-db-auth-token --hostname ${module.rds_proxy.proxy_endpoint} --port 5432 --region ${local.region} --username ${local.db_username})"
}
output "superuser_proxy_iam_connect" {
description = "Connect to RDS Proxy using IAM auth via token generated"
value = "psql \"host=${module.rds_proxy.proxy_endpoint} port=5432 sslmode=verify-full sslrootcert=/home/ssm-user/AmazonRootCA1.pem dbname=${module.rds.db_instance_name} user=${local.db_username} password=$TOKEN\""
output "log_group_name" {
description = "The name of the CloudWatch log group"
value = module.rds_proxy.log_group_name
}

View file

View file

@ -0,0 +1,14 @@
terraform {
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 6.15"
}
random = {
source = "hashicorp/random"
version = ">= 2.0"
}
}
}

View file

@ -1,300 +0,0 @@
provider "aws" {
region = local.region
}
locals {
region = "us-east-1"
name = "example-${replace(basename(path.cwd), "_", "-")}"
db_name = "example"
db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account
db_password = random_password.password.result
db_proxy_resource_id = element(split(":", module.rds_proxy.proxy_arn), 6)
db_iam_connect_prefix = "arn:aws:rds-db:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:dbuser:${local.db_proxy_resource_id}"
tags = {
Example = local.name
Environment = "dev"
}
}
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
################################################################################
# Supporting Resources
################################################################################
resource "random_pet" "users" {
length = 2
separator = "_"
}
resource "random_password" "password" {
length = 16
special = false
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 3"
name = local.name
cidr = "10.0.0.0/18"
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
create_database_subnet_group = true
enable_nat_gateway = true
single_nat_gateway = true
tags = local.tags
}
module "rds" {
source = "terraform-aws-modules/rds-aurora/aws"
version = "~> 4"
name = local.name
database_name = local.db_name
username = local.db_username
password = local.db_password
# When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM
iam_database_authentication_enabled = false
engine = "aurora-mysql"
engine_version = "5.7"
replica_count = 1
instance_type = "db.t3.medium"
storage_encrypted = false
apply_immediately = true
skip_final_snapshot = true
vpc_id = module.vpc.vpc_id
subnets = module.vpc.database_subnets
allowed_security_groups = [module.rds_proxy_sg.security_group_id]
db_subnet_group_name = local.name # Created by VPC module
db_parameter_group_name = aws_db_parameter_group.aurora_db_mysql57_parameter_group.id
db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.aurora_cluster_mysql57_parameter_group.id
tags = local.tags
}
resource "aws_db_parameter_group" "aurora_db_mysql57_parameter_group" {
name = "example-aurora-db-57-parameter-group"
family = "aurora-mysql5.7"
description = "example-aurora-db-57-parameter-group"
}
resource "aws_rds_cluster_parameter_group" "aurora_cluster_mysql57_parameter_group" {
name = "example-aurora-57-cluster-parameter-group"
family = "aurora-mysql5.7"
description = "example-aurora-57-cluster-parameter-group"
}
################################################################################
# Test Resources
################################################################################
resource "aws_iam_instance_profile" "ec2_test" {
name_prefix = local.name
role = aws_iam_role.ec2_test.name
}
data "aws_iam_policy_document" "ec2_test_assume" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role" "ec2_test" {
name_prefix = local.name
force_detach_policies = true
assume_role_policy = data.aws_iam_policy_document.ec2_test_assume.json
}
data "aws_iam_policy_document" "ec2_test" {
statement {
actions = ["rds-db:connect"]
resources = ["${local.db_iam_connect_prefix}/${local.db_username}"]
}
}
resource "aws_iam_role_policy" "ec2_test" {
name_prefix = local.name
role = aws_iam_role.ec2_test.id
policy = data.aws_iam_policy_document.ec2_test.json
}
resource "aws_iam_role_policy_attachment" "ec2_ssm" {
role = aws_iam_role.ec2_test.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["679593333241"]
filter {
name = "name"
values = ["ubuntu-minimal/images/hvm-ssd/ubuntu-focal-20.04-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
module "ec2_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "ec2"
description = "EC2 RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
egress_rules = ["all-all"]
tags = local.tags
}
module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "~> 2"
name = local.name
instance_count = 1
associate_public_ip_address = true
iam_instance_profile = aws_iam_instance_profile.ec2_test.name
user_data = <<-EOT
#!/usr/bin/env bash
mkdir -p /home/ssm-user/ && wget -O /home/ssm-user/AmazonRootCA1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
apt update
apt install awscli mysql-server -y
EOT
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
vpc_security_group_ids = [module.ec2_sg.security_group_id]
subnet_ids = module.vpc.private_subnets
tags = local.tags
}
################################################################################
# Secrets - DB user passwords
################################################################################
data "aws_kms_alias" "secretsmanager" {
name = "alias/aws/secretsmanager"
}
resource "aws_secretsmanager_secret" "superuser" {
name = local.db_username
description = "Database superuser, ${local.db_username}, databse connection values"
kms_key_id = data.aws_kms_alias.secretsmanager.id
tags = local.tags
}
resource "aws_secretsmanager_secret_version" "superuser" {
secret_id = aws_secretsmanager_secret.superuser.id
secret_string = jsonencode({
username = local.db_username
password = local.db_password
})
}
################################################################################
# RDS Proxy
################################################################################
module "rds_proxy_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "rds_proxy"
description = "PostgreSQL RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet MySQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
egress_with_cidr_blocks = [
{
description = "Database subnet MySQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks)
},
]
tags = local.tags
}
module "rds_proxy" {
source = "../../"
create_proxy = true
name = local.name
iam_role_name = local.name
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
db_proxy_endpoints = {
read_write = {
name = "read-write-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
tags = local.tags
},
read_only = {
name = "read-only-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
target_role = "READ_ONLY"
tags = local.tags
}
}
secrets = {
"${local.db_username}" = {
description = aws_secretsmanager_secret.superuser.description
arn = aws_secretsmanager_secret.superuser.arn
kms_key_id = aws_secretsmanager_secret.superuser.kms_key_id
}
}
engine_family = "MYSQL"
db_host = module.rds.rds_cluster_endpoint
db_name = module.rds.rds_cluster_database_name
debug_logging = true
# Target Aurora cluster
target_db_cluster = true
db_cluster_identifier = module.rds.rds_cluster_id
tags = local.tags
}

View file

@ -1,310 +0,0 @@
provider "aws" {
region = local.region
}
locals {
region = "us-east-1"
name = "example-${replace(basename(path.cwd), "_", "-")}"
db_name = "example"
db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account
db_password = random_password.password.result
db_proxy_resource_id = element(split(":", module.rds_proxy.proxy_arn), 6)
db_iam_connect_prefix = "arn:aws:rds-db:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:dbuser:${local.db_proxy_resource_id}"
tags = {
Example = local.name
Environment = "dev"
}
}
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
################################################################################
# Supporting Resources
################################################################################
resource "random_pet" "users" {
length = 2
separator = "_"
}
resource "random_password" "password" {
length = 16
special = false
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 3"
name = local.name
cidr = "10.0.0.0/18"
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
tags = local.tags
}
module "rds_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "rds"
description = "MySQL RDS example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet MySQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
tags = local.tags
}
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "~> 3"
name = local.db_name
username = local.db_username
password = local.db_password
# When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM
iam_database_authentication_enabled = false
identifier = local.name
engine = "mysql"
engine_version = "5.7.31"
family = "mysql5.7"
major_engine_version = "5.7"
port = 3306
instance_class = "db.t3.micro"
allocated_storage = 5
storage_encrypted = false
apply_immediately = true
vpc_security_group_ids = [module.rds_sg.security_group_id]
subnet_ids = module.vpc.database_subnets
maintenance_window = "Mon:00:00-Mon:03:00"
backup_window = "03:00-06:00"
backup_retention_period = 0
deletion_protection = false
tags = local.tags
}
################################################################################
# Test Resources
################################################################################
resource "aws_iam_instance_profile" "ec2_test" {
name_prefix = local.name
role = aws_iam_role.ec2_test.name
}
data "aws_iam_policy_document" "ec2_test_assume" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role" "ec2_test" {
name_prefix = local.name
force_detach_policies = true
assume_role_policy = data.aws_iam_policy_document.ec2_test_assume.json
}
data "aws_iam_policy_document" "ec2_test" {
statement {
actions = ["rds-db:connect"]
resources = ["${local.db_iam_connect_prefix}/${local.db_username}"]
}
}
resource "aws_iam_role_policy" "ec2_test" {
name_prefix = local.name
role = aws_iam_role.ec2_test.id
policy = data.aws_iam_policy_document.ec2_test.json
}
resource "aws_iam_role_policy_attachment" "ec2_ssm" {
role = aws_iam_role.ec2_test.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["679593333241"]
filter {
name = "name"
values = ["ubuntu-minimal/images/hvm-ssd/ubuntu-focal-20.04-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
module "ec2_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "ec2"
description = "EC2 RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
egress_rules = ["all-all"]
tags = local.tags
}
module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "~> 2"
name = local.name
instance_count = 1
associate_public_ip_address = true
iam_instance_profile = aws_iam_instance_profile.ec2_test.name
user_data = <<-EOT
#!/usr/bin/env bash
mkdir -p /home/ssm-user/ && wget -O /home/ssm-user/AmazonRootCA1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
apt update
apt install awscli mysql-server -y
EOT
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
vpc_security_group_ids = [module.ec2_sg.security_group_id]
subnet_ids = module.vpc.private_subnets
tags = local.tags
}
################################################################################
# Secrets - DB user passwords
################################################################################
data "aws_kms_alias" "secretsmanager" {
name = "alias/aws/secretsmanager"
}
resource "aws_secretsmanager_secret" "superuser" {
name = local.db_username
description = "Database superuser, ${local.db_username}, databse connection values"
kms_key_id = data.aws_kms_alias.secretsmanager.id
tags = local.tags
}
resource "aws_secretsmanager_secret_version" "superuser" {
secret_id = aws_secretsmanager_secret.superuser.id
secret_string = jsonencode({
username = local.db_username
password = local.db_password
})
}
################################################################################
# RDS Proxy
################################################################################
module "rds_proxy_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "rds_proxy"
description = "MySQL RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet PostgreSQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
egress_with_cidr_blocks = [
{
description = "Database subnet MySQL access"
rule = "mysql-tcp"
cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks)
},
]
tags = local.tags
}
module "rds_proxy" {
source = "../../"
create_proxy = true
name = local.name
iam_role_name = local.name
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
db_proxy_endpoints = {
read_write = {
name = "read-write-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
tags = local.tags
},
read_only = {
name = "read-only-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
target_role = "READ_ONLY"
tags = local.tags
}
}
secrets = {
"${local.db_username}" = {
description = aws_secretsmanager_secret.superuser.description
arn = aws_secretsmanager_secret.superuser.arn
kms_key_id = aws_secretsmanager_secret.superuser.kms_key_id
}
}
engine_family = "MYSQL"
db_host = module.rds.db_instance_address
db_name = module.rds.db_instance_name
debug_logging = true
# Target RDS instance
target_db_instance = true
db_instance_identifier = module.rds.db_instance_id
tags = local.tags
}

View file

@ -25,52 +25,34 @@ An EC2 instance configuration has been provided for use in validating the exampl
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...`
4. You should now be connected to the `example` database in the RDS instance via the AWS Proxy using IAM authentication
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.38 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.15 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.38 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.15 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_ec2_instance"></a> [ec2\_instance](#module\_ec2\_instance) | terraform-aws-modules/ec2-instance/aws | ~> 2 |
| <a name="module_ec2_sg"></a> [ec2\_sg](#module\_ec2\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_rds"></a> [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 5 |
| <a name="module_rds_proxy"></a> [rds\_proxy](#module\_rds\_proxy) | ../../ | |
| <a name="module_rds_proxy_sg"></a> [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3 |
| <a name="module_rds"></a> [rds](#module\_rds) | terraform-aws-modules/rds-aurora/aws | ~> 9.0 |
| <a name="module_rds_proxy"></a> [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a |
| <a name="module_rds_proxy_sg"></a> [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
| Name | Type |
|------|------|
| [aws_db_parameter_group.aurora_db_postgres11_parameter_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_parameter_group) | resource |
| [aws_iam_instance_profile.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
| [aws_iam_role.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_role_policy_attachment.ec2_ssm](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_rds_cluster_parameter_group.aurora_cluster_postgres11_parameter_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rds_cluster_parameter_group) | resource |
| [aws_secretsmanager_secret.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
| [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
| [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |
| [aws_ami.ubuntu](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.ec2_test_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
## Inputs
@ -81,7 +63,11 @@ No inputs.
| Name | Description |
|------|-------------|
| <a name="output_db_proxy_endpoints"></a> [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created |
| <a name="output_iam_role_arn"></a> [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the role proxy uses to access secrets |
| <a name="output_iam_role_name"></a> [iam\_role\_name](#output\_iam\_role\_name) | The name of the role proxy uses to access secrets |
| <a name="output_iam_role_unique_id"></a> [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the role proxy uses to access secrets |
| <a name="output_log_group_arn"></a> [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group |
| <a name="output_log_group_name"></a> [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group |
| <a name="output_proxy_arn"></a> [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy |
| <a name="output_proxy_default_target_group_arn"></a> [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group |
| <a name="output_proxy_default_target_group_id"></a> [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group |
@ -95,9 +81,6 @@ No inputs.
| <a name="output_proxy_target_target_arn"></a> [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 |
| <a name="output_proxy_target_tracked_cluster_id"></a> [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 |
| <a name="output_proxy_target_type"></a> [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
| <a name="output_superuser_db_password_connect"></a> [superuser\_db\_password\_connect](#output\_superuser\_db\_password\_connect) | Connect to database using superuser with username/password directly to database |
| <a name="output_superuser_proxy_iam_connect"></a> [superuser\_proxy\_iam\_connect](#output\_superuser\_proxy\_iam\_connect) | Connect to RDS Proxy using IAM auth via token generated |
| <a name="output_superuser_proxy_iam_token"></a> [superuser\_proxy\_iam\_token](#output\_superuser\_proxy\_iam\_token) | Gerate connection token for connecting to RDS Proxy with IAM auth |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END_TF_DOCS -->
Apache-2.0 Licensed. See [LICENSE](../../LICENSE).
Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE).

View file

@ -0,0 +1,144 @@
provider "aws" {
region = local.region
}
data "aws_availability_zones" "available" {}
locals {
name = "ex-${basename(path.cwd)}"
region = "eu-west-1"
vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Example = local.name
GithubRepo = "terraform-aws-rds-proxy"
GithubOrg = "terraform-aws-modules"
}
}
################################################################################
# RDS Proxy
################################################################################
module "rds_proxy" {
source = "../../"
name = local.name
iam_role_name = local.name
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
endpoints = {
read_write = {
name = "read-write-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
tags = local.tags
},
read_only = {
name = "read-only-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
target_role = "READ_ONLY"
tags = local.tags
}
}
auth = {
"root" = {
description = "Cluster generated master user password"
secret_arn = module.rds.cluster_master_user_secret[0].secret_arn
}
}
engine_family = "POSTGRESQL"
debug_logging = true
# Target Aurora cluster
target_db_cluster = true
db_cluster_identifier = module.rds.cluster_id
tags = local.tags
}
################################################################################
# Supporting Resources
################################################################################
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)]
tags = local.tags
}
module "rds" {
source = "terraform-aws-modules/rds-aurora/aws"
version = "~> 9.0"
name = local.name
engine = "aurora-postgresql"
engine_version = "17.5"
master_username = "root"
# When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM
iam_database_authentication_enabled = false
instance_class = "db.r6g.large"
instances = {
1 = {}
2 = {}
}
vpc_id = module.vpc.vpc_id
db_subnet_group_name = module.vpc.database_subnet_group_name
security_group_rules = {
vpc_ingress = {
cidr_blocks = module.vpc.private_subnets_cidr_blocks
}
}
apply_immediately = true
skip_final_snapshot = true
tags = local.tags
}
module "rds_proxy_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 5.0"
name = "${local.name}-proxy"
description = "PostgreSQL RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
egress_with_cidr_blocks = [
{
description = "Database subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks)
},
]
tags = local.tags
}

View file

@ -66,7 +66,7 @@ output "proxy_target_type" {
value = module.rds_proxy.proxy_target_type
}
# DB proxy endponts
# DB proxy endpoints
output "db_proxy_endpoints" {
description = "Array containing the full resource object and attributes for all DB proxy endpoints created"
value = module.rds_proxy.db_proxy_endpoints
@ -78,19 +78,23 @@ output "log_group_arn" {
value = module.rds_proxy.log_group_arn
}
# For aiding in testing & verification
output "superuser_db_password_connect" {
description = "Connect to database using superuser with username/password directly to database"
value = "mysql --host=${module.rds.db_instance_address} --user=${local.db_username} --password=${local.db_password} ${module.rds.db_instance_name}"
sensitive = true
output "log_group_name" {
description = "The name of the CloudWatch log group"
value = module.rds_proxy.log_group_name
}
output "superuser_proxy_iam_token" {
description = "Gerate connection token for connecting to RDS Proxy with IAM auth"
value = "TOKEN=$(aws rds generate-db-auth-token --hostname ${module.rds_proxy.proxy_endpoint} --port 3306 --region ${local.region} --username ${local.db_username})"
# IAM role
output "iam_role_arn" {
description = "The Amazon Resource Name (ARN) specifying the role proxy uses to access secrets"
value = module.rds_proxy.iam_role_arn
}
output "superuser_proxy_iam_connect" {
description = "Connect to RDS Proxy using IAM auth via token generated"
value = "mysql --host=${module.rds_proxy.proxy_endpoint} --user=${local.db_username} --password=$TOKEN ${module.rds.db_instance_name} --ssl-ca=/home/ssm-user/AmazonRootCA1.pem --enable-cleartext-plugin"
output "iam_role_name" {
description = "The name of the role proxy uses to access secrets"
value = module.rds_proxy.iam_role_name
}
output "iam_role_unique_id" {
description = "Stable and unique string identifying the role proxy uses to access secrets"
value = module.rds_proxy.iam_role_unique_id
}

View file

@ -1,10 +1,10 @@
terraform {
required_version = ">= 0.13.1"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.38"
version = ">= 6.15"
}
}
}

View file

@ -25,51 +25,42 @@ An EC2 instance configuration has been provided for use in validating the exampl
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...`
4. You should now be connected to the `example` database in the Aurora cluster via the AWS Proxy using IAM authentication
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.38 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.15 |
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.38 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.15 |
| <a name="provider_random"></a> [random](#provider\_random) | >= 2.0 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_ec2_instance"></a> [ec2\_instance](#module\_ec2\_instance) | terraform-aws-modules/ec2-instance/aws | ~> 2 |
| <a name="module_ec2_sg"></a> [ec2\_sg](#module\_ec2\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_rds"></a> [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 3 |
| <a name="module_rds_proxy"></a> [rds\_proxy](#module\_rds\_proxy) | ../../ | |
| <a name="module_rds_proxy_sg"></a> [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_rds_sg"></a> [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 4 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3 |
| <a name="module_rds"></a> [rds](#module\_rds) | terraform-aws-modules/rds/aws | ~> 6.0 |
| <a name="module_rds_proxy"></a> [rds\_proxy](#module\_rds\_proxy) | ../../ | n/a |
| <a name="module_rds_proxy_sg"></a> [rds\_proxy\_sg](#module\_rds\_proxy\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 |
| <a name="module_rds_sg"></a> [rds\_sg](#module\_rds\_sg) | terraform-aws-modules/security-group/aws | ~> 5.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 6.0 |
## Resources
| Name | Type |
|------|------|
| [aws_iam_instance_profile.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
| [aws_iam_role.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_role_policy_attachment.ec2_ssm](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_secretsmanager_secret.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
| [aws_secretsmanager_secret_version.superuser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
| [random_pet.users](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |
| [aws_ami.ubuntu](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.ec2_test](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.ec2_test_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
| [aws_kms_alias.secretsmanager](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
## Inputs
@ -81,6 +72,7 @@ No inputs.
|------|-------------|
| <a name="output_db_proxy_endpoints"></a> [db\_proxy\_endpoints](#output\_db\_proxy\_endpoints) | Array containing the full resource object and attributes for all DB proxy endpoints created |
| <a name="output_log_group_arn"></a> [log\_group\_arn](#output\_log\_group\_arn) | The Amazon Resource Name (ARN) of the CloudWatch log group |
| <a name="output_log_group_name"></a> [log\_group\_name](#output\_log\_group\_name) | The name of the CloudWatch log group |
| <a name="output_proxy_arn"></a> [proxy\_arn](#output\_proxy\_arn) | The Amazon Resource Name (ARN) for the proxy |
| <a name="output_proxy_default_target_group_arn"></a> [proxy\_default\_target\_group\_arn](#output\_proxy\_default\_target\_group\_arn) | The Amazon Resource Name (ARN) for the default target group |
| <a name="output_proxy_default_target_group_id"></a> [proxy\_default\_target\_group\_id](#output\_proxy\_default\_target\_group\_id) | The ID for the default target group |
@ -94,9 +86,6 @@ No inputs.
| <a name="output_proxy_target_target_arn"></a> [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 |
| <a name="output_proxy_target_tracked_cluster_id"></a> [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 |
| <a name="output_proxy_target_type"></a> [proxy\_target\_type](#output\_proxy\_target\_type) | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
| <a name="output_superuser_db_password_connect"></a> [superuser\_db\_password\_connect](#output\_superuser\_db\_password\_connect) | Connect to database using superuser with username/password directly to database |
| <a name="output_superuser_proxy_iam_connect"></a> [superuser\_proxy\_iam\_connect](#output\_superuser\_proxy\_iam\_connect) | Connect to RDS Proxy using IAM auth via token generated |
| <a name="output_superuser_proxy_iam_token"></a> [superuser\_proxy\_iam\_token](#output\_superuser\_proxy\_iam\_token) | Gerate connection token for connecting to RDS Proxy with IAM auth |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END_TF_DOCS -->
Apache-2.0 Licensed. See [LICENSE](../../LICENSE).
Apache-2.0 Licensed. See [LICENSE](https://github.com/terraform-aws-modules/terraform-aws-rds-proxy/blob/master/LICENSE).

View file

@ -0,0 +1,200 @@
provider "aws" {
region = local.region
}
data "aws_availability_zones" "available" {}
locals {
name = "ex-${basename(path.cwd)}"
region = "eu-west-1"
db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account
db_password = random_password.password.result
vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Example = local.name
GithubRepo = "terraform-aws-rds-proxy"
GithubOrg = "terraform-aws-modules"
}
}
################################################################################
# RDS Proxy
################################################################################
module "rds_proxy" {
source = "../../"
name = local.name
iam_role_name = local.name
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
endpoints = {
read_write = {
name = "read-write-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
tags = local.tags
},
read_only = {
name = "read-only-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
target_role = "READ_ONLY"
tags = local.tags
}
}
auth = {
(local.db_username) = {
description = aws_secretsmanager_secret.superuser.description
secret_arn = aws_secretsmanager_secret.superuser.arn
}
}
engine_family = "POSTGRESQL"
debug_logging = true
# Target RDS instance
target_db_instance = true
db_instance_identifier = module.rds.db_instance_identifier
tags = local.tags
}
################################################################################
# Supporting Resources
################################################################################
resource "random_pet" "users" {
length = 2
separator = "_"
}
resource "random_password" "password" {
length = 16
special = false
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)]
tags = local.tags
}
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "~> 6.0"
username = local.db_username
password = local.db_password
# When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM
iam_database_authentication_enabled = false
identifier = local.name
engine = "postgres"
engine_version = "14"
family = "postgres14" # DB parameter group
major_engine_version = "14" # DB option group
instance_class = "db.t4g.large"
allocated_storage = 20
port = 5432
apply_immediately = true
db_subnet_group_name = module.vpc.database_subnet_group
vpc_security_group_ids = [module.rds_sg.security_group_id]
multi_az = true
backup_retention_period = 0
deletion_protection = false
tags = local.tags
}
module "rds_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 5.0"
name = "rds"
description = "PostgreSQL RDS example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
tags = local.tags
}
module "rds_proxy_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 5.0"
name = "rds_proxy"
description = "PostgreSQL RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
egress_with_cidr_blocks = [
{
description = "Database subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks)
},
]
tags = local.tags
}
################################################################################
# Secrets - DB user passwords
################################################################################
data "aws_kms_alias" "secretsmanager" {
name = "alias/aws/secretsmanager"
}
resource "aws_secretsmanager_secret" "superuser" {
name = local.db_username
description = "Database superuser, ${local.db_username}, database connection values"
kms_key_id = data.aws_kms_alias.secretsmanager.id
tags = local.tags
}
resource "aws_secretsmanager_secret_version" "superuser" {
secret_id = aws_secretsmanager_secret.superuser.id
secret_string = jsonencode({
username = local.db_username
password = local.db_password
})
}

View file

@ -66,7 +66,7 @@ output "proxy_target_type" {
value = module.rds_proxy.proxy_target_type
}
# DB proxy endponts
# DB proxy endpoints
output "db_proxy_endpoints" {
description = "Array containing the full resource object and attributes for all DB proxy endpoints created"
value = module.rds_proxy.db_proxy_endpoints
@ -78,19 +78,7 @@ output "log_group_arn" {
value = module.rds_proxy.log_group_arn
}
# For aiding in testing & verification
output "superuser_db_password_connect" {
description = "Connect to database using superuser with username/password directly to database"
value = "PGPASSWORD=${local.db_password} psql -h ${module.rds.rds_cluster_endpoint} -p 5432 -d ${module.rds.rds_cluster_database_name} -U ${local.db_username} --set=sslmode=require"
sensitive = true
}
output "superuser_proxy_iam_token" {
description = "Gerate connection token for connecting to RDS Proxy with IAM auth"
value = "TOKEN=$(aws rds generate-db-auth-token --hostname ${module.rds_proxy.proxy_endpoint} --port 5432 --region ${local.region} --username ${local.db_username})"
}
output "superuser_proxy_iam_connect" {
description = "Connect to RDS Proxy using IAM auth via token generated"
value = "psql \"host=${module.rds_proxy.proxy_endpoint} port=5432 sslmode=verify-full sslrootcert=/home/ssm-user/AmazonRootCA1.pem dbname=${module.rds.rds_cluster_database_name} user=${local.db_username} password=$TOKEN\""
output "log_group_name" {
description = "The name of the CloudWatch log group"
value = module.rds_proxy.log_group_name
}

View file

@ -0,0 +1,14 @@
terraform {
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 6.15"
}
random = {
source = "hashicorp/random"
version = ">= 2.0"
}
}
}

View file

@ -1,300 +0,0 @@
provider "aws" {
region = local.region
}
locals {
region = "us-east-1"
name = "example-${replace(basename(path.cwd), "_", "-")}"
db_name = "example"
db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account
db_password = random_password.password.result
db_proxy_resource_id = element(split(":", module.rds_proxy.proxy_arn), 6)
db_iam_connect_prefix = "arn:aws:rds-db:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:dbuser:${local.db_proxy_resource_id}"
tags = {
Example = local.name
Environment = "dev"
}
}
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
################################################################################
# Supporting Resources
################################################################################
resource "random_pet" "users" {
length = 2
separator = "_"
}
resource "random_password" "password" {
length = 16
special = false
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 3"
name = local.name
cidr = "10.0.0.0/18"
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
create_database_subnet_group = true
enable_nat_gateway = true
single_nat_gateway = true
tags = local.tags
}
module "rds" {
source = "terraform-aws-modules/rds-aurora/aws"
version = "~> 5"
name = local.name
database_name = local.db_name
username = local.db_username
password = local.db_password
# When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM
iam_database_authentication_enabled = false
engine = "aurora-postgresql"
engine_version = "11.9"
replica_count = 1
instance_type = "db.t3.medium"
storage_encrypted = false
apply_immediately = true
skip_final_snapshot = true
vpc_id = module.vpc.vpc_id
subnets = module.vpc.database_subnets
allowed_security_groups = [module.rds_proxy_sg.security_group_id]
db_subnet_group_name = local.name # Created by VPC module
db_parameter_group_name = aws_db_parameter_group.aurora_db_postgres11_parameter_group.id
db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.aurora_cluster_postgres11_parameter_group.id
tags = local.tags
}
resource "aws_db_parameter_group" "aurora_db_postgres11_parameter_group" {
name = "example-aurora-db-postgres11-parameter-group"
family = "aurora-postgresql11"
description = "test-aurora-db-postgres11-parameter-group"
}
resource "aws_rds_cluster_parameter_group" "aurora_cluster_postgres11_parameter_group" {
name = "example-aurora-postgres11-cluster-parameter-group"
family = "aurora-postgresql11"
description = "example-aurora-postgres11-cluster-parameter-group"
}
################################################################################
# Test Resources
################################################################################
resource "aws_iam_instance_profile" "ec2_test" {
name_prefix = local.name
role = aws_iam_role.ec2_test.name
}
data "aws_iam_policy_document" "ec2_test_assume" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role" "ec2_test" {
name_prefix = local.name
force_detach_policies = true
assume_role_policy = data.aws_iam_policy_document.ec2_test_assume.json
}
data "aws_iam_policy_document" "ec2_test" {
statement {
actions = ["rds-db:connect"]
resources = ["${local.db_iam_connect_prefix}/${local.db_username}"]
}
}
resource "aws_iam_role_policy" "ec2_test" {
name_prefix = local.name
role = aws_iam_role.ec2_test.id
policy = data.aws_iam_policy_document.ec2_test.json
}
resource "aws_iam_role_policy_attachment" "ec2_ssm" {
role = aws_iam_role.ec2_test.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["679593333241"]
filter {
name = "name"
values = ["ubuntu-minimal/images/hvm-ssd/ubuntu-focal-20.04-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
module "ec2_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "ec2"
description = "EC2 RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
egress_rules = ["all-all"]
tags = local.tags
}
module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "~> 2"
name = local.name
instance_count = 1
associate_public_ip_address = true
iam_instance_profile = aws_iam_instance_profile.ec2_test.name
user_data = <<-EOT
#!/usr/bin/env bash
mkdir -p /home/ssm-user/ && wget -O /home/ssm-user/AmazonRootCA1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
apt update
apt install awscli postgresql-client -y
EOT
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
vpc_security_group_ids = [module.ec2_sg.security_group_id]
subnet_ids = module.vpc.private_subnets
tags = local.tags
}
################################################################################
# Secrets - DB user passwords
################################################################################
data "aws_kms_alias" "secretsmanager" {
name = "alias/aws/secretsmanager"
}
resource "aws_secretsmanager_secret" "superuser" {
name = local.db_username
description = "Database superuser, ${local.db_username}, databse connection values"
kms_key_id = data.aws_kms_alias.secretsmanager.id
tags = local.tags
}
resource "aws_secretsmanager_secret_version" "superuser" {
secret_id = aws_secretsmanager_secret.superuser.id
secret_string = jsonencode({
username = local.db_username
password = local.db_password
})
}
################################################################################
# RDS Proxy
################################################################################
module "rds_proxy_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "rds_proxy"
description = "PostgreSQL RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
egress_with_cidr_blocks = [
{
description = "Database subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks)
},
]
tags = local.tags
}
module "rds_proxy" {
source = "../../"
create_proxy = true
name = local.name
iam_role_name = local.name
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
db_proxy_endpoints = {
read_write = {
name = "read-write-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
tags = local.tags
},
read_only = {
name = "read-only-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
target_role = "READ_ONLY"
tags = local.tags
}
}
secrets = {
"${local.db_username}" = {
description = aws_secretsmanager_secret.superuser.description
arn = aws_secretsmanager_secret.superuser.arn
kms_key_id = aws_secretsmanager_secret.superuser.kms_key_id
}
}
engine_family = "POSTGRESQL"
db_host = module.rds.rds_cluster_endpoint
db_name = module.rds.rds_cluster_database_name
debug_logging = true
# Target Aurora cluster
target_db_cluster = true
db_cluster_identifier = module.rds.rds_cluster_id
tags = local.tags
}

View file

@ -1,310 +0,0 @@
provider "aws" {
region = local.region
}
locals {
region = "us-east-1"
name = "example-${replace(basename(path.cwd), "_", "-")}"
db_name = "example"
db_username = random_pet.users.id # using random here due to secrets taking at least 7 days before fully deleting from account
db_password = random_password.password.result
db_proxy_resource_id = element(split(":", module.rds_proxy.proxy_arn), 6)
db_iam_connect_prefix = "arn:aws:rds-db:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:dbuser:${local.db_proxy_resource_id}"
tags = {
Example = local.name
Environment = "dev"
}
}
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
################################################################################
# Supporting Resources
################################################################################
resource "random_pet" "users" {
length = 2
separator = "_"
}
resource "random_password" "password" {
length = 16
special = false
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 3"
name = local.name
cidr = "10.0.0.0/18"
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
tags = local.tags
}
module "rds_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "rds"
description = "PostgreSQL RDS example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
tags = local.tags
}
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "~> 3"
name = local.db_name
username = local.db_username
password = local.db_password
# When using RDS Proxy w/ IAM auth - Database must be username/password auth, not IAM
iam_database_authentication_enabled = false
identifier = local.name
engine = "postgres"
engine_version = "11.9"
family = "postgres11"
major_engine_version = "11"
port = 5432
instance_class = "db.t3.micro"
allocated_storage = 5
storage_encrypted = false
apply_immediately = true
vpc_security_group_ids = [module.rds_sg.security_group_id]
subnet_ids = module.vpc.database_subnets
maintenance_window = "Mon:00:00-Mon:03:00"
backup_window = "03:00-06:00"
backup_retention_period = 0
deletion_protection = false
tags = local.tags
}
################################################################################
# Test Resources
################################################################################
resource "aws_iam_instance_profile" "ec2_test" {
name_prefix = local.name
role = aws_iam_role.ec2_test.name
}
data "aws_iam_policy_document" "ec2_test_assume" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role" "ec2_test" {
name_prefix = local.name
force_detach_policies = true
assume_role_policy = data.aws_iam_policy_document.ec2_test_assume.json
}
data "aws_iam_policy_document" "ec2_test" {
statement {
actions = ["rds-db:connect"]
resources = ["${local.db_iam_connect_prefix}/${local.db_username}"]
}
}
resource "aws_iam_role_policy" "ec2_test" {
name_prefix = local.name
role = aws_iam_role.ec2_test.id
policy = data.aws_iam_policy_document.ec2_test.json
}
resource "aws_iam_role_policy_attachment" "ec2_ssm" {
role = aws_iam_role.ec2_test.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["679593333241"]
filter {
name = "name"
values = ["ubuntu-minimal/images/hvm-ssd/ubuntu-focal-20.04-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
module "ec2_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "ec2"
description = "EC2 RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
egress_rules = ["all-all"]
tags = local.tags
}
module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "~> 2"
name = local.name
instance_count = 1
associate_public_ip_address = true
iam_instance_profile = aws_iam_instance_profile.ec2_test.name
user_data = <<-EOT
#!/usr/bin/env bash
mkdir -p /home/ssm-user/ && wget -O /home/ssm-user/AmazonRootCA1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
apt update
apt install awscli postgresql -y
EOT
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
vpc_security_group_ids = [module.ec2_sg.security_group_id]
subnet_ids = module.vpc.private_subnets
tags = local.tags
}
################################################################################
# Secrets - DB user passwords
################################################################################
data "aws_kms_alias" "secretsmanager" {
name = "alias/aws/secretsmanager"
}
resource "aws_secretsmanager_secret" "superuser" {
name = local.db_username
description = "Database superuser, ${local.db_username}, databse connection values"
kms_key_id = data.aws_kms_alias.secretsmanager.id
tags = local.tags
}
resource "aws_secretsmanager_secret_version" "superuser" {
secret_id = aws_secretsmanager_secret.superuser.id
secret_string = jsonencode({
username = local.db_username
password = local.db_password
})
}
################################################################################
# RDS Proxy
################################################################################
module "rds_proxy_sg" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4"
name = "rds_proxy"
description = "PostgreSQL RDS Proxy example security group"
vpc_id = module.vpc.vpc_id
revoke_rules_on_delete = true
ingress_with_cidr_blocks = [
{
description = "Private subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
}
]
egress_with_cidr_blocks = [
{
description = "Database subnet PostgreSQL access"
rule = "postgresql-tcp"
cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks)
},
]
tags = local.tags
}
module "rds_proxy" {
source = "../../"
create_proxy = true
name = local.name
iam_role_name = local.name
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
db_proxy_endpoints = {
read_write = {
name = "read-write-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
tags = local.tags
},
read_only = {
name = "read-only-endpoint"
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.rds_proxy_sg.security_group_id]
target_role = "READ_ONLY"
tags = local.tags
}
}
secrets = {
"${local.db_username}" = {
description = aws_secretsmanager_secret.superuser.description
arn = aws_secretsmanager_secret.superuser.arn
kms_key_id = aws_secretsmanager_secret.superuser.kms_key_id
}
}
engine_family = "POSTGRESQL"
db_host = module.rds.db_instance_address
db_name = module.rds.db_instance_name
debug_logging = true
# Target RDS instance
target_db_instance = true
db_instance_identifier = module.rds.db_instance_id
tags = local.tags
}

View file

@ -1,10 +0,0 @@
terraform {
required_version = ">= 0.13.1"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.38"
}
}
}

140
main.tf
View file

@ -1,47 +1,48 @@
locals {
db_identifier_key = var.db_instance_identifier != "" ? "dbInstanceIdentifier" : "dbClusterIdentifier"
db_identifier_value = var.db_instance_identifier != "" ? var.db_instance_identifier : var.db_cluster_identifier
role_arn = var.create_proxy && var.create_iam_role ? aws_iam_role.this[0].arn : var.role_arn
role_name = coalesce(var.iam_role_name, var.name)
policy_name = coalesce(var.iam_policy_name, var.name)
}
data "aws_region" "current" {}
################################################################################
# RDS Proxy
################################################################################
resource "aws_db_proxy" "this" {
count = var.create_proxy ? 1 : 0
count = var.create ? 1 : 0
name = var.name
debug_logging = var.debug_logging
engine_family = var.engine_family
idle_client_timeout = var.idle_client_timeout
require_tls = var.require_tls
role_arn = local.role_arn
vpc_security_group_ids = var.vpc_security_group_ids
vpc_subnet_ids = var.vpc_subnet_ids
region = var.region
dynamic "auth" {
for_each = var.secrets
for_each = var.auth
content {
auth_scheme = var.auth_scheme
auth_scheme = auth.value.auth_scheme
client_password_auth_type = auth.value.client_password_auth_type
description = auth.value.description
iam_auth = var.iam_auth
secret_arn = auth.value.arn
iam_auth = auth.value.iam_auth
secret_arn = auth.value.secret_arn
username = auth.value.username
}
}
debug_logging = var.debug_logging
default_auth_scheme = var.default_auth_scheme
engine_family = var.engine_family
idle_client_timeout = var.idle_client_timeout
name = var.name
require_tls = var.require_tls
role_arn = try(aws_iam_role.this[0].arn, var.role_arn)
vpc_security_group_ids = var.vpc_security_group_ids
vpc_subnet_ids = var.vpc_subnet_ids
tags = merge(var.tags, var.proxy_tags)
depends_on = [aws_cloudwatch_log_group.this]
}
################################################################################
# Default Target Group
################################################################################
resource "aws_db_proxy_default_target_group" "this" {
count = var.create_proxy ? 1 : 0
count = var.create ? 1 : 0
region = var.region
db_proxy_name = aws_db_proxy.this[0].name
@ -54,8 +55,14 @@ resource "aws_db_proxy_default_target_group" "this" {
}
}
################################################################################
# Target(s)
################################################################################
resource "aws_db_proxy_target" "db_instance" {
count = var.create_proxy && var.target_db_instance ? 1 : 0
count = var.create && var.target_db_instance ? 1 : 0
region = var.region
db_proxy_name = aws_db_proxy.this[0].name
target_group_name = aws_db_proxy_default_target_group.this[0].name
@ -63,35 +70,46 @@ resource "aws_db_proxy_target" "db_instance" {
}
resource "aws_db_proxy_target" "db_cluster" {
count = var.create_proxy && var.target_db_cluster ? 1 : 0
count = var.create && var.target_db_cluster ? 1 : 0
region = var.region
db_proxy_name = aws_db_proxy.this[0].name
target_group_name = aws_db_proxy_default_target_group.this[0].name
db_cluster_identifier = var.db_cluster_identifier
}
################################################################################
# Endpoint(s)
################################################################################
resource "aws_db_proxy_endpoint" "this" {
for_each = var.db_proxy_endpoints
for_each = { for k, v in var.endpoints : k => v if var.create }
region = var.region
db_proxy_name = aws_db_proxy.this[0].name
db_proxy_endpoint_name = each.value.name
db_proxy_endpoint_name = coalesce(each.value.name, each.key)
vpc_subnet_ids = each.value.vpc_subnet_ids
vpc_security_group_ids = lookup(each.value, "vpc_security_group_ids", null)
target_role = lookup(each.value, "target_role", null)
vpc_security_group_ids = each.value.vpc_security_group_ids
target_role = each.value.target_role
tags = lookup(each.value, "tags", var.tags)
tags = merge(var.tags, each.value.tags)
}
################################################################################
# CloudWatch Logs
# CloudWatch Log Group
################################################################################
resource "aws_cloudwatch_log_group" "this" {
count = var.create_proxy && var.manage_log_group ? 1 : 0
count = var.create && var.manage_log_group ? 1 : 0
region = var.region
name = "/aws/rds/proxy/${var.name}"
retention_in_days = var.log_group_retention_in_days
kms_key_id = var.log_group_kms_key_id
log_group_class = var.log_group_class
tags = merge(var.tags, var.log_group_tags)
}
@ -100,8 +118,37 @@ resource "aws_cloudwatch_log_group" "this" {
# IAM Role
################################################################################
locals {
create_iam_role = var.create && var.create_iam_role
role_name = coalesce(var.iam_role_name, var.name)
policy_name = coalesce(var.iam_policy_name, var.name)
partition = try(data.aws_partition.current[0].partition, "aws")
dns_suffix = try(data.aws_partition.current[0].dns_suffix, "amazonaws.com")
region = try(data.aws_region.current[0].region, var.region)
}
data "aws_region" "current" {
count = local.create_iam_role ? 1 : 0
region = var.region
}
data "aws_partition" "current" {
count = local.create_iam_role ? 1 : 0
}
data "aws_service_principal" "rds" {
count = local.create_iam_role ? 1 : 0
service_name = "rds"
region = data.aws_region.current[0].region
}
data "aws_iam_policy_document" "assume_role" {
count = var.create_proxy && var.create_iam_role ? 1 : 0
count = local.create_iam_role ? 1 : 0
statement {
sid = "RDSAssume"
@ -110,13 +157,13 @@ data "aws_iam_policy_document" "assume_role" {
principals {
type = "Service"
identifiers = ["rds.amazonaws.com"]
identifiers = [data.aws_service_principal.rds[0].name]
}
}
}
resource "aws_iam_role" "this" {
count = var.create_proxy && var.create_iam_role ? 1 : 0
count = local.create_iam_role ? 1 : 0
name = var.use_role_name_prefix ? null : local.role_name
name_prefix = var.use_role_name_prefix ? "${local.role_name}-" : null
@ -131,20 +178,27 @@ resource "aws_iam_role" "this" {
tags = merge(var.tags, var.iam_role_tags)
}
################################################################################
# IAM Role Policy
################################################################################
data "aws_iam_policy_document" "this" {
count = var.create_proxy && var.create_iam_role ? 1 : 0
count = local.create_iam_role && var.create_iam_policy ? 1 : 0
statement {
sid = "DecryptSecrets"
effect = "Allow"
actions = ["kms:Decrypt"]
resources = distinct([for secret in var.secrets : secret.kms_key_id])
resources = coalescelist(
var.kms_key_arns,
["arn:${local.partition}:kms:*:*:key/*"]
)
condition {
test = "StringEquals"
variable = "kms:ViaService"
values = [
"secretsmanager.${data.aws_region.current.name}.amazonaws.com"
"secretsmanager.${local.region}.${local.dns_suffix}"
]
}
}
@ -169,12 +223,12 @@ data "aws_iam_policy_document" "this" {
"secretsmanager:ListSecretVersionIds",
]
resources = distinct([for secret in var.secrets : secret.arn])
resources = distinct([for auth in var.auth : auth.secret_arn])
}
}
resource "aws_iam_role_policy" "this" {
count = var.create_proxy && var.create_iam_role && var.create_iam_policy ? 1 : 0
count = local.create_iam_role && var.create_iam_policy ? 1 : 0
name = var.use_policy_name_prefix ? null : local.policy_name
name_prefix = var.use_policy_name_prefix ? "${local.policy_name}-" : null

View file

@ -1,79 +1,118 @@
################################################################################
# RDS Proxy
################################################################################
output "proxy_id" {
description = "The ID for the proxy"
value = element(concat(aws_db_proxy.this.*.id, [""]), 0)
value = try(aws_db_proxy.this[0].id, null)
}
output "proxy_arn" {
description = "The Amazon Resource Name (ARN) for the proxy"
value = element(concat(aws_db_proxy.this.*.arn, [""]), 0)
value = try(aws_db_proxy.this[0].arn, null)
}
output "proxy_endpoint" {
description = "The endpoint that you can use to connect to the proxy"
value = element(concat(aws_db_proxy.this.*.endpoint, [""]), 0)
value = try(aws_db_proxy.this[0].endpoint, null)
}
# Proxy Default Target Group
################################################################################
# Default Target Group
################################################################################
output "proxy_default_target_group_id" {
description = "The ID for the default target group"
value = element(concat(aws_db_proxy_default_target_group.this.*.id, [""]), 0)
value = try(aws_db_proxy_default_target_group.this[0].id, null)
}
output "proxy_default_target_group_arn" {
description = "The Amazon Resource Name (ARN) for the default target group"
value = element(concat(aws_db_proxy_default_target_group.this.*.arn, [""]), 0)
value = try(aws_db_proxy_default_target_group.this[0].arn, null)
}
output "proxy_default_target_group_name" {
description = "The name of the default target group"
value = element(concat(aws_db_proxy_default_target_group.this.*.name, [""]), 0)
value = try(aws_db_proxy_default_target_group.this[0].name, null)
}
# Proxy Target
################################################################################
# Target(s)
################################################################################
output "proxy_target_endpoint" {
description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type"
value = element(concat(aws_db_proxy_target.db_instance.*.endpoint, aws_db_proxy_target.db_cluster.*.endpoint, [""]), 0)
value = try(aws_db_proxy_target.db_instance[0].endpoint, aws_db_proxy_target.db_cluster[0].endpoint, null)
}
output "proxy_target_id" {
description = "Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/)"
value = element(concat(aws_db_proxy_target.db_instance.*.id, aws_db_proxy_target.db_cluster.*.id, [""]), 0)
value = try(aws_db_proxy_target.db_instance[0].id, aws_db_proxy_target.db_cluster[0].id, null)
}
output "proxy_target_port" {
description = "Port for the target RDS DB Instance or Aurora DB Cluster"
value = element(concat(aws_db_proxy_target.db_instance.*.port, aws_db_proxy_target.db_cluster.*.port, [""]), 0)
value = try(aws_db_proxy_target.db_instance[0].port, aws_db_proxy_target.db_cluster[0].port, null)
}
output "proxy_target_rds_resource_id" {
description = "Identifier representing the DB Instance or DB Cluster target"
value = element(concat(aws_db_proxy_target.db_instance.*.rds_resource_id, aws_db_proxy_target.db_cluster.*.rds_resource_id, [""]), 0)
value = try(aws_db_proxy_target.db_instance[0].rds_resource_id, aws_db_proxy_target.db_cluster[0].rds_resource_id, null)
}
output "proxy_target_target_arn" {
description = "Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API"
value = element(concat(aws_db_proxy_target.db_instance.*.target_arn, aws_db_proxy_target.db_cluster.*.target_arn, [""]), 0)
value = try(aws_db_proxy_target.db_instance[0].target_arn, aws_db_proxy_target.db_cluster[0].target_arn, null)
}
output "proxy_target_tracked_cluster_id" {
description = "DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS_INSTANCE target that is part of a DB Cluster"
value = element(concat(aws_db_proxy_target.db_cluster.*.tracked_cluster_id, [""]), 0)
value = try(aws_db_proxy_target.db_cluster[0].tracked_cluster_id, null)
}
output "proxy_target_type" {
description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`"
value = element(concat(aws_db_proxy_target.db_instance.*.type, aws_db_proxy_target.db_cluster.*.type, [""]), 0)
value = try(aws_db_proxy_target.db_instance[0].type, aws_db_proxy_target.db_cluster[0].type, null)
}
# DB proxy endponts
################################################################################
# Endpoint(s)
################################################################################
output "db_proxy_endpoints" {
description = "Array containing the full resource object and attributes for all DB proxy endpoints created"
value = aws_db_proxy_endpoint.this
}
# CloudWatch logs
################################################################################
# CloudWatch Log Group
################################################################################
output "log_group_arn" {
description = "The Amazon Resource Name (ARN) of the CloudWatch log group"
value = element(concat(aws_cloudwatch_log_group.this.*.arn, [""]), 0)
value = try(aws_cloudwatch_log_group.this[0].arn, null)
}
output "log_group_name" {
description = "The name of the CloudWatch log group"
value = try(aws_cloudwatch_log_group.this[0].name, null)
}
################################################################################
# IAM Role
################################################################################
output "iam_role_arn" {
description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager."
value = try(aws_iam_role.this[0].arn, null)
}
output "iam_role_name" {
description = "IAM role name"
value = try(aws_iam_role.this[0].name, null)
}
output "iam_role_unique_id" {
description = "Stable and unique string identifying the IAM role"
value = try(aws_iam_role.this[0].unique_id, null)
}

View file

@ -1,15 +1,24 @@
variable "create" {
description = "Whether cluster should be created (affects nearly all resources)"
type = bool
default = true
}
variable "region" {
description = "Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration"
type = string
default = null
}
variable "tags" {
description = "A map of tags to use on all resources"
description = "A map of tags to add to all resources"
type = map(string)
default = {}
}
################################################################################
# RDS Proxy
variable "create_proxy" {
description = "Determines whether a proxy and its resources will be created"
type = bool
default = true
}
################################################################################
variable "name" {
description = "The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens"
@ -19,8 +28,19 @@ variable "name" {
variable "auth" {
description = "Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters"
type = map(string)
default = {}
type = 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 = {
default = {
auth_scheme = "SECRETS"
}
}
}
variable "debug_logging" {
@ -29,6 +49,12 @@ variable "debug_logging" {
default = false
}
variable "default_auth_scheme" {
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"
type = string
default = null
}
variable "engine_family" {
description = "The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL`"
type = string
@ -65,43 +91,16 @@ variable "vpc_subnet_ids" {
default = []
}
variable "auth_scheme" {
description = "The type of authentication that the proxy uses for connections from the proxy to the underlying database. One of `SECRETS`"
type = string
default = "SECRETS"
}
variable "iam_auth" {
description = "Whether to require or disallow AWS Identity and Access Management (IAM) authentication for connections to the proxy. One of `DISABLED`, `REQUIRED`"
type = string
default = "REQUIRED"
}
variable "proxy_tags" {
description = "A map of tags to apply to the RDS Proxy"
type = map(string)
default = {}
}
variable "secrets" {
description = "Map of secerets to be used by RDS Proxy for authentication to the database"
type = map(object({ arn = string, description = string, kms_key_id = string }))
default = {}
}
################################################################################
# Default Target Group
################################################################################
variable "db_host" {
description = "The identifier to use for the database endpoint"
type = string
default = ""
}
variable "db_name" {
description = "The name of the database"
type = string
default = ""
}
# Proxy Default Target Group
variable "connection_borrow_timeout" {
description = "The number of seconds for a proxy to wait for a connection to become available in the connection pool"
type = number
@ -132,9 +131,12 @@ variable "session_pinning_filters" {
default = []
}
# Proxy Target
################################################################################
# Target(s)
################################################################################
variable "target_db_instance" {
description = "Determines whether DB instance is targetted by proxy"
description = "Determines whether DB instance is targeted by proxy"
type = bool
default = false
}
@ -146,7 +148,7 @@ variable "db_instance_identifier" {
}
variable "target_db_cluster" {
description = "Determines whether DB cluster is targetted by proxy"
description = "Determines whether DB cluster is targeted by proxy"
type = bool
default = false
}
@ -157,14 +159,26 @@ variable "db_cluster_identifier" {
default = ""
}
# Proxy endpoints
variable "db_proxy_endpoints" {
description = "Map of DB proxy endpoints to create and their attributes (see `aws_db_proxy_endpoint`)"
type = any
################################################################################
# Endpoint(s)
################################################################################
variable "endpoints" {
description = "Map of DB proxy endpoints to create and their attributes"
type = 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), {})
}))
default = {}
}
################################################################################
# CloudWatch Logs
################################################################################
variable "manage_log_group" {
description = "Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist"
type = bool
@ -183,13 +197,22 @@ variable "log_group_kms_key_id" {
default = null
}
variable "log_group_class" {
description = "Specified the log class of the log group. Possible values are: `STANDARD` or `INFREQUENT_ACCESS`"
type = string
default = null
}
variable "log_group_tags" {
description = "A map of tags to apply to the CloudWatch log group"
type = map(string)
default = {}
}
################################################################################
# IAM Role
################################################################################
variable "create_iam_role" {
description = "Determines whether an IAM role is created"
type = bool
@ -244,7 +267,10 @@ variable "iam_role_tags" {
default = {}
}
# IAM Policy
################################################################################
# IAM Role Policy
################################################################################
variable "create_iam_policy" {
description = "Determines whether an IAM policy is created"
type = bool
@ -263,8 +289,8 @@ variable "use_policy_name_prefix" {
default = false
}
variable "iam_creation_wait_duration" {
description = "Time duration delay to wait for IAM resource creation/propagation. For example, 30s for 30 seconds or 5m for 5 minutes. Updating this value by itself will not trigger a delay."
type = string
default = "30s"
variable "kms_key_arns" {
description = "List of KMS Key ARNs to allow access to decrypt SecretsManager secrets"
type = list(string)
default = []
}

View file

@ -1,10 +1,10 @@
terraform {
required_version = ">= 0.13.1"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.38"
version = ">= 6.15"
}
}
}

100
wrappers/README.md Normal file
View file

@ -0,0 +1,100 @@
# Wrapper for the root module
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).
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.
This wrapper does not implement any extra functionality.
## Usage with Terragrunt
`terragrunt.hcl`:
```hcl
terraform {
source = "tfr:///terraform-aws-modules/rds-proxy/aws//wrappers"
# Alternative source:
# source = "git::git@github.com:terraform-aws-modules/terraform-aws-rds-proxy.git//wrappers?ref=master"
}
inputs = {
defaults = { # Default values
create = true
tags = {
Terraform = "true"
Environment = "dev"
}
}
items = {
my-item = {
# omitted... can be any argument supported by the module
}
my-second-item = {
# omitted... can be any argument supported by the module
}
# omitted...
}
}
```
## Usage with Terraform
```hcl
module "wrapper" {
source = "terraform-aws-modules/rds-proxy/aws//wrappers"
defaults = { # Default values
create = true
tags = {
Terraform = "true"
Environment = "dev"
}
}
items = {
my-item = {
# omitted... can be any argument supported by the module
}
my-second-item = {
# omitted... can be any argument supported by the module
}
# omitted...
}
}
```
## Example: Manage multiple S3 buckets in one Terragrunt layer
`eu-west-1/s3-buckets/terragrunt.hcl`:
```hcl
terraform {
source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers"
# Alternative source:
# source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git//wrappers?ref=master"
}
inputs = {
defaults = {
force_destroy = true
attach_elb_log_delivery_policy = true
attach_lb_log_delivery_policy = true
attach_deny_insecure_transport_policy = true
attach_require_latest_tls_policy = true
}
items = {
bucket1 = {
bucket = "my-random-bucket-1"
}
bucket2 = {
bucket = "my-random-bucket-2"
tags = {
Secure = "probably"
}
}
}
}
```

52
wrappers/main.tf Normal file
View file

@ -0,0 +1,52 @@
module "wrapper" {
source = "../"
for_each = var.items
auth = try(each.value.auth, var.defaults.auth, {
default = {
auth_scheme = "SECRETS"
}
})
connection_borrow_timeout = try(each.value.connection_borrow_timeout, var.defaults.connection_borrow_timeout, null)
create = try(each.value.create, var.defaults.create, true)
create_iam_policy = try(each.value.create_iam_policy, var.defaults.create_iam_policy, true)
create_iam_role = try(each.value.create_iam_role, var.defaults.create_iam_role, true)
db_cluster_identifier = try(each.value.db_cluster_identifier, var.defaults.db_cluster_identifier, "")
db_instance_identifier = try(each.value.db_instance_identifier, var.defaults.db_instance_identifier, "")
debug_logging = try(each.value.debug_logging, var.defaults.debug_logging, false)
default_auth_scheme = try(each.value.default_auth_scheme, var.defaults.default_auth_scheme, null)
endpoints = try(each.value.endpoints, var.defaults.endpoints, {})
engine_family = try(each.value.engine_family, var.defaults.engine_family, "")
iam_policy_name = try(each.value.iam_policy_name, var.defaults.iam_policy_name, "")
iam_role_description = try(each.value.iam_role_description, var.defaults.iam_role_description, "")
iam_role_force_detach_policies = try(each.value.iam_role_force_detach_policies, var.defaults.iam_role_force_detach_policies, true)
iam_role_max_session_duration = try(each.value.iam_role_max_session_duration, var.defaults.iam_role_max_session_duration, 43200)
iam_role_name = try(each.value.iam_role_name, var.defaults.iam_role_name, "")
iam_role_path = try(each.value.iam_role_path, var.defaults.iam_role_path, null)
iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.defaults.iam_role_permissions_boundary, null)
iam_role_tags = try(each.value.iam_role_tags, var.defaults.iam_role_tags, {})
idle_client_timeout = try(each.value.idle_client_timeout, var.defaults.idle_client_timeout, 1800)
init_query = try(each.value.init_query, var.defaults.init_query, "")
kms_key_arns = try(each.value.kms_key_arns, var.defaults.kms_key_arns, [])
log_group_class = try(each.value.log_group_class, var.defaults.log_group_class, null)
log_group_kms_key_id = try(each.value.log_group_kms_key_id, var.defaults.log_group_kms_key_id, null)
log_group_retention_in_days = try(each.value.log_group_retention_in_days, var.defaults.log_group_retention_in_days, 30)
log_group_tags = try(each.value.log_group_tags, var.defaults.log_group_tags, {})
manage_log_group = try(each.value.manage_log_group, var.defaults.manage_log_group, true)
max_connections_percent = try(each.value.max_connections_percent, var.defaults.max_connections_percent, 90)
max_idle_connections_percent = try(each.value.max_idle_connections_percent, var.defaults.max_idle_connections_percent, 50)
name = try(each.value.name, var.defaults.name, "")
proxy_tags = try(each.value.proxy_tags, var.defaults.proxy_tags, {})
region = try(each.value.region, var.defaults.region, null)
require_tls = try(each.value.require_tls, var.defaults.require_tls, true)
role_arn = try(each.value.role_arn, var.defaults.role_arn, "")
session_pinning_filters = try(each.value.session_pinning_filters, var.defaults.session_pinning_filters, [])
tags = try(each.value.tags, var.defaults.tags, {})
target_db_cluster = try(each.value.target_db_cluster, var.defaults.target_db_cluster, false)
target_db_instance = try(each.value.target_db_instance, var.defaults.target_db_instance, false)
use_policy_name_prefix = try(each.value.use_policy_name_prefix, var.defaults.use_policy_name_prefix, false)
use_role_name_prefix = try(each.value.use_role_name_prefix, var.defaults.use_role_name_prefix, false)
vpc_security_group_ids = try(each.value.vpc_security_group_ids, var.defaults.vpc_security_group_ids, [])
vpc_subnet_ids = try(each.value.vpc_subnet_ids, var.defaults.vpc_subnet_ids, [])
}

5
wrappers/outputs.tf Normal file
View file

@ -0,0 +1,5 @@
output "wrapper" {
description = "Map of outputs of a wrapper."
value = module.wrapper
# sensitive = false # No sensitive module output found
}

11
wrappers/variables.tf Normal file
View file

@ -0,0 +1,11 @@
variable "defaults" {
description = "Map of default values which will be used for each item."
type = any
default = {}
}
variable "items" {
description = "Maps of items to create a wrapper from. Values are passed through to the module."
type = any
default = {}
}

View file

@ -1,10 +1,10 @@
terraform {
required_version = ">= 0.13.1"
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.38"
version = ">= 6.15"
}
}
}