mirror of
https://github.com/terraform-aws-modules/terraform-aws-rds-proxy.git
synced 2025-12-16 16:01:11 +00:00
feat: initial release of terraform-aws-rds-proxy 🎉
This commit is contained in:
commit
402de162e6
27 changed files with 2843 additions and 0 deletions
30
.editorconfig
Normal file
30
.editorconfig
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
# Uses editorconfig to maintain consistent coding styles
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 80
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{tf,tfvars}]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.md]
|
||||
max_line_length = 0
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
tab_width = 2
|
||||
indent_style = tab
|
||||
|
||||
[COMMIT_EDITMSG]
|
||||
max_line_length = 0
|
||||
76
.github/CODE_OF_CONDUCT.md
vendored
Normal file
76
.github/CODE_OF_CONDUCT.md
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# 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
|
||||
37
.gitignore
vendored
Normal file
37
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Local .terraform directories
|
||||
**/.terraform/*
|
||||
|
||||
# .tfstate files
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
|
||||
# terraform lockfile
|
||||
.terraform.lock.hcl
|
||||
|
||||
# Crash log files
|
||||
crash.log
|
||||
|
||||
# Exclude all .tfvars files, which are likely to contain sentitive data, such as
|
||||
# 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
|
||||
# are not checked in
|
||||
override.tf
|
||||
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
|
||||
10
.pre-commit-config.yaml
Normal file
10
.pre-commit-config.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
repos:
|
||||
- repo: git://github.com/antonbabenko/pre-commit-terraform
|
||||
rev: v1.45.0
|
||||
hooks:
|
||||
- id: terraform_fmt
|
||||
- id: terraform_docs
|
||||
- repo: git://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
hooks:
|
||||
- id: check-merge-conflict
|
||||
10
.releaserc.json
Normal file
10
.releaserc.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"branches": [
|
||||
"master"
|
||||
],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/github"
|
||||
]
|
||||
}
|
||||
201
LICENSE
Normal file
201
LICENSE
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
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.
|
||||
141
README.md
Normal file
141
README.md
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
# AWS RDS Proxy Terraform module
|
||||
|
||||
Terraform module which creates an AWS RDS Proxy and its supporting resources.
|
||||
|
||||
The following resources are supported:
|
||||
|
||||
- [AWS RDS Proxy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy)
|
||||
- [AWS RDS Proxy Default Target Group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_default_target_group)
|
||||
- [AWS RDS Proxy Target](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_proxy_target)
|
||||
|
||||
## Usage
|
||||
|
||||
See [`examples`](./examples) directory for working examples to reference:
|
||||
|
||||
```hcl
|
||||
module "rds_proxy" {
|
||||
source = "clowdhaus/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"]
|
||||
|
||||
secrets = {
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
engine_family = "POSTGRESQL"
|
||||
db_host = "myendpoint.cluster-custom-123456789012.us-east-1.rds.amazonaws.com"
|
||||
db_name = "example"
|
||||
|
||||
# Target Aurora cluster
|
||||
target_db_cluster = true
|
||||
db_cluster_identifier = "myendpoint"
|
||||
|
||||
tags = {
|
||||
Terraform = "true"
|
||||
Environment = "dev"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 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!
|
||||
|
||||
- [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)
|
||||
|
||||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| terraform | >= 0.12.26 |
|
||||
| aws | >= 3.9 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| aws | >= 3.9 |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| auth | Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters | `map(string)` | `{}` | no |
|
||||
| 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 |
|
||||
| connection\_borrow\_timeout | The number of seconds for a proxy to wait for a connection to become available in the connection pool | `number` | `null` | no |
|
||||
| create\_iam\_policy | Determines whether an IAM policy is created | `bool` | `true` | no |
|
||||
| create\_iam\_role | Determines whether an IAM role is created | `bool` | `true` | no |
|
||||
| create\_proxy | Determines whether a proxy and its resources will be created | `bool` | `true` | no |
|
||||
| db\_cluster\_identifier | DB cluster identifier | `string` | `""` | no |
|
||||
| db\_host | The identifier to use for the database endpoint | `string` | `""` | no |
|
||||
| db\_instance\_identifier | DB instance identifier | `string` | `""` | no |
|
||||
| db\_name | The name of the database | `string` | `""` | no |
|
||||
| debug\_logging | Whether the proxy includes detailed information about SQL statements in its logs | `bool` | `false` | no |
|
||||
| engine\_family | The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL` | `string` | `""` | no |
|
||||
| iam\_auth | Whether to require or disallow AWS Identity and Access Management (IAM) authentication for connections to the proxy. One of `DISABLED`, `REQUIRED` | `string` | `"REQUIRED"` | no |
|
||||
| iam\_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 |
|
||||
| iam\_policy\_name | The name of the role policy. If omitted, Terraform will assign a random, unique name | `string` | `""` | no |
|
||||
| iam\_role\_description | The description of the role | `string` | `""` | no |
|
||||
| iam\_role\_force\_detach\_policies | Specifies to force detaching any policies the role has before destroying it | `bool` | `true` | no |
|
||||
| iam\_role\_max\_session\_duration | The maximum session duration (in seconds) that you want to set for the specified role | `number` | `43200` | no |
|
||||
| iam\_role\_name | The name of the role. If omitted, Terraform will assign a random, unique name | `string` | `""` | no |
|
||||
| iam\_role\_path | The path to the role | `string` | `null` | no |
|
||||
| iam\_role\_permissions\_boundary | The ARN of the policy that is used to set the permissions boundary for the role | `string` | `null` | no |
|
||||
| iam\_role\_tags | A map of tags to apply to the IAM role | `map(string)` | `{}` | no |
|
||||
| idle\_client\_timeout | The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it | `number` | `1800` | no |
|
||||
| init\_query | One or more SQL statements for the proxy to run when opening each new database connection | `string` | `""` | no |
|
||||
| log\_group\_kms\_key\_id | The ARN of the KMS Key to use when encrypting log data | `string` | `null` | no |
|
||||
| log\_group\_retention\_in\_days | Specifies the number of days you want to retain log events in the log group | `number` | `30` | no |
|
||||
| log\_group\_tags | A map of tags to apply to the CloudWatch log group | `map(string)` | `{}` | no |
|
||||
| manage\_log\_group | Determines whether Terraform will create/manage the CloudWatch log group or not. Note - this will fail if set to true after the log group has been created as the resource will already exist | `bool` | `true` | no |
|
||||
| max\_connections\_percent | The maximum size of the connection pool for each target in a target group | `number` | `90` | no |
|
||||
| max\_idle\_connections\_percent | Controls how actively the proxy closes idle database connections in the connection pool | `number` | `50` | no |
|
||||
| name | The identifier for the proxy. This name must be unique for all proxies owned by your AWS account in the specified AWS Region. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it can't end with a hyphen or contain two consecutive hyphens | `string` | `""` | no |
|
||||
| proxy\_tags | A map of tags to apply to the RDS Proxy | `map(string)` | `{}` | no |
|
||||
| require\_tls | A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy | `bool` | `true` | no |
|
||||
| role\_arn | The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager | `string` | `""` | no |
|
||||
| secrets | Map of secerets to be used by RDS Proxy for authentication to the database | `map(object({ arn = string, description = string, kms_key_id = string }))` | `{}` | no |
|
||||
| session\_pinning\_filters | Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection | `list(string)` | `[]` | no |
|
||||
| tags | A map of tags to use on all resources | `map(string)` | `{}` | no |
|
||||
| target\_db\_cluster | Determines whether DB cluster is targetted by proxy | `bool` | `false` | no |
|
||||
| target\_db\_instance | Determines whether DB instance is targetted by proxy | `bool` | `false` | no |
|
||||
| use\_policy\_name\_prefix | Whether to use unique name beginning with the specified `iam_policy_name` | `bool` | `false` | no |
|
||||
| use\_role\_name\_prefix | Whether to use unique name beginning with the specified `iam_role_name` | `bool` | `false` | no |
|
||||
| vpc\_security\_group\_ids | One or more VPC security group IDs to associate with the new proxy | `list(string)` | `[]` | no |
|
||||
| vpc\_subnet\_ids | One or more VPC subnet IDs to associate with the new proxy | `list(string)` | `[]` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| log\_group\_arn | The Amazon Resource Name (ARN) of the CloudWatch log group |
|
||||
| proxy\_arn | The Amazon Resource Name (ARN) for the proxy |
|
||||
| proxy\_default\_target\_group\_arn | The Amazon Resource Name (ARN) for the default target group |
|
||||
| proxy\_default\_target\_group\_id | The ID for the default target group |
|
||||
| proxy\_default\_target\_group\_name | The name of the default target group |
|
||||
| proxy\_endpoint | The endpoint that you can use to connect to the proxy |
|
||||
| proxy\_id | The ID for the proxy |
|
||||
| proxy\_target\_endpoint | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type |
|
||||
| proxy\_target\_id | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) |
|
||||
| proxy\_target\_port | Port for the target RDS DB Instance or Aurora DB Cluster |
|
||||
| proxy\_target\_rds\_resource\_id | Identifier representing the DB Instance or DB Cluster target |
|
||||
| proxy\_target\_target\_arn | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API |
|
||||
| proxy\_target\_tracked\_cluster\_id | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster |
|
||||
| proxy\_target\_type | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
|
||||
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0 Licensed. See [LICENSE](LICENSE).
|
||||
71
examples/mysql_iam_cluster/README.md
Normal file
71
examples/mysql_iam_cluster/README.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# RDS Proxy - IAM Authentication & MySQL Cluster
|
||||
|
||||
Configuration in this directory creates:
|
||||
|
||||
- AWS RDS Proxy w/ IAM authentication enabled for an RDS Aurora MySQL cluster
|
||||
|
||||
## Usage
|
||||
|
||||
To run this example you need to execute:
|
||||
|
||||
```bash
|
||||
$ terraform init
|
||||
$ terraform plan
|
||||
$ terraform apply
|
||||
```
|
||||
|
||||
Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources.
|
||||
|
||||
## Validation
|
||||
|
||||
An EC2 instance configuration has been provided for use in validating the example configuration. After provisioning the configuration, there are some outputs that have been provided to aid in validating changes. To perform validation, after the EC2 instance finishes provisioning:
|
||||
|
||||
1. Connect to the EC2 instance using Session Manager
|
||||
2. Copy the output from `superuser_proxy_iam_token` and paste it into the Session Manager window - this generates the token for connecting to the proxy with IAM auth.
|
||||
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 -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| terraform | >= 0.12.26 |
|
||||
| aws | >= 3.9 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| aws | >= 3.9 |
|
||||
| random | n/a |
|
||||
|
||||
## Inputs
|
||||
|
||||
No input.
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| log\_group\_arn | The Amazon Resource Name (ARN) of the CloudWatch log group |
|
||||
| proxy\_arn | The Amazon Resource Name (ARN) for the proxy |
|
||||
| proxy\_default\_target\_group\_arn | The Amazon Resource Name (ARN) for the default target group |
|
||||
| proxy\_default\_target\_group\_id | The ID for the default target group |
|
||||
| proxy\_default\_target\_group\_name | The name of the default target group |
|
||||
| proxy\_endpoint | The endpoint that you can use to connect to the proxy |
|
||||
| proxy\_id | The ID for the proxy |
|
||||
| proxy\_target\_endpoint | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type |
|
||||
| proxy\_target\_id | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) |
|
||||
| proxy\_target\_port | Port for the target RDS DB Instance or Aurora DB Cluster |
|
||||
| proxy\_target\_rds\_resource\_id | Identifier representing the DB Instance or DB Cluster target |
|
||||
| proxy\_target\_target\_arn | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API |
|
||||
| proxy\_target\_tracked\_cluster\_id | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster |
|
||||
| proxy\_target\_type | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
|
||||
| superuser\_db\_password\_connect | Connect to database using superuser with username/password directly to database |
|
||||
| superuser\_proxy\_iam\_connect | Connect to RDS Proxy using IAM auth via token generated |
|
||||
| superuser\_proxy\_iam\_token | Gerate connection token for connecting to RDS Proxy with IAM auth |
|
||||
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
|
||||
Apache-2.0 Licensed. See [LICENSE](../../LICENSE).
|
||||
284
examples/mysql_iam_cluster/main.tf
Normal file
284
examples/mysql_iam_cluster/main.tf
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
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 = "2.64.0"
|
||||
|
||||
name = local.name
|
||||
cidr = "10.0.0.0/18"
|
||||
|
||||
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
|
||||
public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
|
||||
private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
|
||||
database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
|
||||
|
||||
create_database_subnet_group = true
|
||||
enable_nat_gateway = true
|
||||
single_nat_gateway = true
|
||||
|
||||
tags = local.tags
|
||||
}
|
||||
|
||||
module "rds" {
|
||||
source = "terraform-aws-modules/rds-aurora/aws"
|
||||
version = "3.0.0"
|
||||
|
||||
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.this_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 = "3.17.0"
|
||||
|
||||
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.16.0"
|
||||
|
||||
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.this_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 = "3.17.0"
|
||||
|
||||
name = "rds_proxy"
|
||||
description = "PostgreSQL RDS Proxy example security group"
|
||||
vpc_id = module.vpc.vpc_id
|
||||
|
||||
revoke_rules_on_delete = true
|
||||
|
||||
ingress_with_cidr_blocks = [
|
||||
{
|
||||
description = "Private subnet MySQL access"
|
||||
rule = "mysql-tcp"
|
||||
cidr_blocks = join(",", module.vpc.private_subnets_cidr_blocks)
|
||||
}
|
||||
]
|
||||
|
||||
egress_with_cidr_blocks = [
|
||||
{
|
||||
description = "Database subnet MySQL access"
|
||||
rule = "mysql-tcp"
|
||||
cidr_blocks = join(",", module.vpc.database_subnets_cidr_blocks)
|
||||
},
|
||||
]
|
||||
|
||||
tags = local.tags
|
||||
}
|
||||
|
||||
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.this_security_group_id]
|
||||
|
||||
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.this_rds_cluster_endpoint
|
||||
db_name = module.rds.this_rds_cluster_database_name
|
||||
debug_logging = true
|
||||
|
||||
# Target Aurora cluster
|
||||
target_db_cluster = true
|
||||
db_cluster_identifier = module.rds.this_rds_cluster_id
|
||||
|
||||
tags = local.tags
|
||||
}
|
||||
89
examples/mysql_iam_cluster/outputs.tf
Normal file
89
examples/mysql_iam_cluster/outputs.tf
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# RDS Proxy
|
||||
output "proxy_id" {
|
||||
description = "The ID for the proxy"
|
||||
value = module.rds_proxy.proxy_id
|
||||
}
|
||||
|
||||
output "proxy_arn" {
|
||||
description = "The Amazon Resource Name (ARN) for the proxy"
|
||||
value = module.rds_proxy.proxy_arn
|
||||
}
|
||||
|
||||
output "proxy_endpoint" {
|
||||
description = "The endpoint that you can use to connect to the proxy"
|
||||
value = module.rds_proxy.proxy_endpoint
|
||||
}
|
||||
|
||||
# Proxy Default Target Group
|
||||
output "proxy_default_target_group_id" {
|
||||
description = "The ID for the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_id
|
||||
}
|
||||
|
||||
output "proxy_default_target_group_arn" {
|
||||
description = "The Amazon Resource Name (ARN) for the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_arn
|
||||
}
|
||||
|
||||
output "proxy_default_target_group_name" {
|
||||
description = "The name of the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_name
|
||||
}
|
||||
|
||||
# Proxy Target
|
||||
output "proxy_target_endpoint" {
|
||||
description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type"
|
||||
value = module.rds_proxy.proxy_target_endpoint
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_id
|
||||
}
|
||||
|
||||
output "proxy_target_port" {
|
||||
description = "Port for the target RDS DB Instance or Aurora DB Cluster"
|
||||
value = module.rds_proxy.proxy_target_port
|
||||
}
|
||||
|
||||
output "proxy_target_rds_resource_id" {
|
||||
description = "Identifier representing the DB Instance or DB Cluster target"
|
||||
value = module.rds_proxy.proxy_target_rds_resource_id
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_target_arn
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_tracked_cluster_id
|
||||
}
|
||||
|
||||
output "proxy_target_type" {
|
||||
description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`"
|
||||
value = module.rds_proxy.proxy_target_type
|
||||
}
|
||||
|
||||
# CloudWatch logs
|
||||
output "log_group_arn" {
|
||||
description = "The Amazon Resource Name (ARN) of the CloudWatch log group"
|
||||
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.this_rds_cluster_endpoint} --user=${local.db_username} --password=${local.db_password} ${module.rds.this_rds_cluster_database_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})"
|
||||
}
|
||||
|
||||
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.this_rds_cluster_database_name} --ssl-ca=/home/ssm-user/AmazonRootCA1.pem --enable-cleartext-plugin"
|
||||
}
|
||||
7
examples/mysql_iam_cluster/versions.tf
Normal file
7
examples/mysql_iam_cluster/versions.tf
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
terraform {
|
||||
required_version = ">= 0.12.26"
|
||||
|
||||
required_providers {
|
||||
aws = ">= 3.9"
|
||||
}
|
||||
}
|
||||
71
examples/mysql_iam_instance/README.md
Normal file
71
examples/mysql_iam_instance/README.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# RDS Proxy - IAM Authentication & MySQL Instance
|
||||
|
||||
Configuration in this directory creates:
|
||||
|
||||
- AWS RDS Proxy w/ IAM authentication enabled for an RDS MySQL instance
|
||||
|
||||
## Usage
|
||||
|
||||
To run this example you need to execute:
|
||||
|
||||
```bash
|
||||
$ terraform init
|
||||
$ terraform plan
|
||||
$ terraform apply
|
||||
```
|
||||
|
||||
Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources.
|
||||
|
||||
## Validation
|
||||
|
||||
An EC2 instance configuration has been provided for use in validating the example configuration. After provisioning the configuration, there are some outputs that have been provided to aid in validating changes. To perform validation, after the EC2 instance finishes provisioning:
|
||||
|
||||
1. Connect to the EC2 instance using Session Manager
|
||||
2. Copy the output from `superuser_proxy_iam_token` and paste it into the Session Manager window - this generates the token for connecting to the proxy with IAM auth.
|
||||
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 -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| terraform | >= 0.12.26 |
|
||||
| aws | >= 3.9 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| aws | >= 3.9 |
|
||||
| random | n/a |
|
||||
|
||||
## Inputs
|
||||
|
||||
No input.
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| log\_group\_arn | The Amazon Resource Name (ARN) of the CloudWatch log group |
|
||||
| proxy\_arn | The Amazon Resource Name (ARN) for the proxy |
|
||||
| proxy\_default\_target\_group\_arn | The Amazon Resource Name (ARN) for the default target group |
|
||||
| proxy\_default\_target\_group\_id | The ID for the default target group |
|
||||
| proxy\_default\_target\_group\_name | The name of the default target group |
|
||||
| proxy\_endpoint | The endpoint that you can use to connect to the proxy |
|
||||
| proxy\_id | The ID for the proxy |
|
||||
| proxy\_target\_endpoint | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type |
|
||||
| proxy\_target\_id | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) |
|
||||
| proxy\_target\_port | Port for the target RDS DB Instance or Aurora DB Cluster |
|
||||
| proxy\_target\_rds\_resource\_id | Identifier representing the DB Instance or DB Cluster target |
|
||||
| proxy\_target\_target\_arn | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API |
|
||||
| proxy\_target\_tracked\_cluster\_id | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster |
|
||||
| proxy\_target\_type | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
|
||||
| superuser\_db\_password\_connect | Connect to database using superuser with username/password directly to database |
|
||||
| superuser\_proxy\_iam\_connect | Connect to RDS Proxy using IAM auth via token generated |
|
||||
| superuser\_proxy\_iam\_token | Gerate connection token for connecting to RDS Proxy with IAM auth |
|
||||
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
|
||||
Apache-2.0 Licensed. See [LICENSE](../../LICENSE).
|
||||
294
examples/mysql_iam_instance/main.tf
Normal file
294
examples/mysql_iam_instance/main.tf
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
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 = "2.64.0"
|
||||
|
||||
name = local.name
|
||||
cidr = "10.0.0.0/18"
|
||||
|
||||
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
|
||||
public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
|
||||
private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
|
||||
database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
|
||||
|
||||
enable_nat_gateway = true
|
||||
single_nat_gateway = true
|
||||
|
||||
tags = local.tags
|
||||
}
|
||||
|
||||
module "rds_sg" {
|
||||
source = "terraform-aws-modules/security-group/aws"
|
||||
version = "3.17.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" {
|
||||
source = "terraform-aws-modules/rds/aws"
|
||||
version = "2.20.0"
|
||||
|
||||
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.this_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 = "3.17.0"
|
||||
|
||||
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.16.0"
|
||||
|
||||
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.this_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 = "3.17.0"
|
||||
|
||||
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.this_security_group_id]
|
||||
|
||||
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.this_db_instance_address
|
||||
db_name = module.rds.this_db_instance_name
|
||||
debug_logging = true
|
||||
|
||||
# Target RDS instance
|
||||
target_db_instance = true
|
||||
db_instance_identifier = module.rds.this_db_instance_id
|
||||
|
||||
tags = local.tags
|
||||
}
|
||||
89
examples/mysql_iam_instance/outputs.tf
Normal file
89
examples/mysql_iam_instance/outputs.tf
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# RDS Proxy
|
||||
output "proxy_id" {
|
||||
description = "The ID for the proxy"
|
||||
value = module.rds_proxy.proxy_id
|
||||
}
|
||||
|
||||
output "proxy_arn" {
|
||||
description = "The Amazon Resource Name (ARN) for the proxy"
|
||||
value = module.rds_proxy.proxy_arn
|
||||
}
|
||||
|
||||
output "proxy_endpoint" {
|
||||
description = "The endpoint that you can use to connect to the proxy"
|
||||
value = module.rds_proxy.proxy_endpoint
|
||||
}
|
||||
|
||||
# Proxy Default Target Group
|
||||
output "proxy_default_target_group_id" {
|
||||
description = "The ID for the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_id
|
||||
}
|
||||
|
||||
output "proxy_default_target_group_arn" {
|
||||
description = "The Amazon Resource Name (ARN) for the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_arn
|
||||
}
|
||||
|
||||
output "proxy_default_target_group_name" {
|
||||
description = "The name of the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_name
|
||||
}
|
||||
|
||||
# Proxy Target
|
||||
output "proxy_target_endpoint" {
|
||||
description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type"
|
||||
value = module.rds_proxy.proxy_target_endpoint
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_id
|
||||
}
|
||||
|
||||
output "proxy_target_port" {
|
||||
description = "Port for the target RDS DB Instance or Aurora DB Cluster"
|
||||
value = module.rds_proxy.proxy_target_port
|
||||
}
|
||||
|
||||
output "proxy_target_rds_resource_id" {
|
||||
description = "Identifier representing the DB Instance or DB Cluster target"
|
||||
value = module.rds_proxy.proxy_target_rds_resource_id
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_target_arn
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_tracked_cluster_id
|
||||
}
|
||||
|
||||
output "proxy_target_type" {
|
||||
description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`"
|
||||
value = module.rds_proxy.proxy_target_type
|
||||
}
|
||||
|
||||
# CloudWatch logs
|
||||
output "log_group_arn" {
|
||||
description = "The Amazon Resource Name (ARN) of the CloudWatch log group"
|
||||
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.this_db_instance_address} --user=${local.db_username} --password=${local.db_password} ${module.rds.this_db_instance_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})"
|
||||
}
|
||||
|
||||
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.this_db_instance_name} --ssl-ca=/home/ssm-user/AmazonRootCA1.pem --enable-cleartext-plugin"
|
||||
}
|
||||
7
examples/mysql_iam_instance/versions.tf
Normal file
7
examples/mysql_iam_instance/versions.tf
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
terraform {
|
||||
required_version = ">= 0.12.26"
|
||||
|
||||
required_providers {
|
||||
aws = ">= 3.9"
|
||||
}
|
||||
}
|
||||
71
examples/postgresql_iam_cluster/README.md
Normal file
71
examples/postgresql_iam_cluster/README.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# RDS Proxy - IAM Authentication & PostgreSQL Cluster
|
||||
|
||||
Configuration in this directory creates:
|
||||
|
||||
- AWS RDS Proxy w/ IAM authentication enabled for an RDS Aurora PostgreSQL cluster
|
||||
|
||||
## Usage
|
||||
|
||||
To run this example you need to execute:
|
||||
|
||||
```bash
|
||||
$ terraform init
|
||||
$ terraform plan
|
||||
$ terraform apply
|
||||
```
|
||||
|
||||
Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources.
|
||||
|
||||
## Validation
|
||||
|
||||
An EC2 instance configuration has been provided for use in validating the example configuration. After provisioning the configuration, there are some outputs that have been provided to aid in validating changes. To perform validation, after the EC2 instance finishes provisioning:
|
||||
|
||||
1. Connect to the EC2 instance using Session Manager
|
||||
2. Copy the output from `superuser_proxy_iam_token` and paste it into the Session Manager window - this generates the token for connecting to the proxy with IAM auth.
|
||||
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 -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| terraform | >= 0.12.26 |
|
||||
| aws | >= 3.9 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| aws | >= 3.9 |
|
||||
| random | n/a |
|
||||
|
||||
## Inputs
|
||||
|
||||
No input.
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| log\_group\_arn | The Amazon Resource Name (ARN) of the CloudWatch log group |
|
||||
| proxy\_arn | The Amazon Resource Name (ARN) for the proxy |
|
||||
| proxy\_default\_target\_group\_arn | The Amazon Resource Name (ARN) for the default target group |
|
||||
| proxy\_default\_target\_group\_id | The ID for the default target group |
|
||||
| proxy\_default\_target\_group\_name | The name of the default target group |
|
||||
| proxy\_endpoint | The endpoint that you can use to connect to the proxy |
|
||||
| proxy\_id | The ID for the proxy |
|
||||
| proxy\_target\_endpoint | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type |
|
||||
| proxy\_target\_id | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) |
|
||||
| proxy\_target\_port | Port for the target RDS DB Instance or Aurora DB Cluster |
|
||||
| proxy\_target\_rds\_resource\_id | Identifier representing the DB Instance or DB Cluster target |
|
||||
| proxy\_target\_target\_arn | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API |
|
||||
| proxy\_target\_tracked\_cluster\_id | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster |
|
||||
| proxy\_target\_type | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
|
||||
| superuser\_db\_password\_connect | Connect to database using superuser with username/password directly to database |
|
||||
| superuser\_proxy\_iam\_connect | Connect to RDS Proxy using IAM auth via token generated |
|
||||
| superuser\_proxy\_iam\_token | Gerate connection token for connecting to RDS Proxy with IAM auth |
|
||||
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
|
||||
Apache-2.0 Licensed. See [LICENSE](../../LICENSE).
|
||||
284
examples/postgresql_iam_cluster/main.tf
Normal file
284
examples/postgresql_iam_cluster/main.tf
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
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 = "2.64.0"
|
||||
|
||||
name = local.name
|
||||
cidr = "10.0.0.0/18"
|
||||
|
||||
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
|
||||
public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
|
||||
private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
|
||||
database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
|
||||
|
||||
create_database_subnet_group = true
|
||||
enable_nat_gateway = true
|
||||
single_nat_gateway = true
|
||||
|
||||
tags = local.tags
|
||||
}
|
||||
|
||||
module "rds" {
|
||||
source = "terraform-aws-modules/rds-aurora/aws"
|
||||
version = "3.0.0"
|
||||
|
||||
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.this_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 = "3.17.0"
|
||||
|
||||
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.16.0"
|
||||
|
||||
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.this_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 = "3.17.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
|
||||
}
|
||||
|
||||
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.this_security_group_id]
|
||||
|
||||
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.this_rds_cluster_endpoint
|
||||
db_name = module.rds.this_rds_cluster_database_name
|
||||
debug_logging = true
|
||||
|
||||
# Target Aurora cluster
|
||||
target_db_cluster = true
|
||||
db_cluster_identifier = module.rds.this_rds_cluster_id
|
||||
|
||||
tags = local.tags
|
||||
}
|
||||
89
examples/postgresql_iam_cluster/outputs.tf
Normal file
89
examples/postgresql_iam_cluster/outputs.tf
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# RDS Proxy
|
||||
output "proxy_id" {
|
||||
description = "The ID for the proxy"
|
||||
value = module.rds_proxy.proxy_id
|
||||
}
|
||||
|
||||
output "proxy_arn" {
|
||||
description = "The Amazon Resource Name (ARN) for the proxy"
|
||||
value = module.rds_proxy.proxy_arn
|
||||
}
|
||||
|
||||
output "proxy_endpoint" {
|
||||
description = "The endpoint that you can use to connect to the proxy"
|
||||
value = module.rds_proxy.proxy_endpoint
|
||||
}
|
||||
|
||||
# Proxy Default Target Group
|
||||
output "proxy_default_target_group_id" {
|
||||
description = "The ID for the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_id
|
||||
}
|
||||
|
||||
output "proxy_default_target_group_arn" {
|
||||
description = "The Amazon Resource Name (ARN) for the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_arn
|
||||
}
|
||||
|
||||
output "proxy_default_target_group_name" {
|
||||
description = "The name of the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_name
|
||||
}
|
||||
|
||||
# Proxy Target
|
||||
output "proxy_target_endpoint" {
|
||||
description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type"
|
||||
value = module.rds_proxy.proxy_target_endpoint
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_id
|
||||
}
|
||||
|
||||
output "proxy_target_port" {
|
||||
description = "Port for the target RDS DB Instance or Aurora DB Cluster"
|
||||
value = module.rds_proxy.proxy_target_port
|
||||
}
|
||||
|
||||
output "proxy_target_rds_resource_id" {
|
||||
description = "Identifier representing the DB Instance or DB Cluster target"
|
||||
value = module.rds_proxy.proxy_target_rds_resource_id
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_target_arn
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_tracked_cluster_id
|
||||
}
|
||||
|
||||
output "proxy_target_type" {
|
||||
description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`"
|
||||
value = module.rds_proxy.proxy_target_type
|
||||
}
|
||||
|
||||
# CloudWatch logs
|
||||
output "log_group_arn" {
|
||||
description = "The Amazon Resource Name (ARN) of the CloudWatch log group"
|
||||
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.this_rds_cluster_endpoint} -p 5432 -d ${module.rds.this_rds_cluster_database_name} -U ${local.db_username} --set=sslmode=require"
|
||||
}
|
||||
|
||||
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.this_rds_cluster_database_name} user=${local.db_username} password=$TOKEN\""
|
||||
}
|
||||
7
examples/postgresql_iam_cluster/versions.tf
Normal file
7
examples/postgresql_iam_cluster/versions.tf
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
terraform {
|
||||
required_version = ">= 0.12.26"
|
||||
|
||||
required_providers {
|
||||
aws = ">= 3.9"
|
||||
}
|
||||
}
|
||||
71
examples/postgresql_iam_instance/README.md
Normal file
71
examples/postgresql_iam_instance/README.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# RDS Proxy - IAM Authentication & PostgreSQL Instance
|
||||
|
||||
Configuration in this directory creates:
|
||||
|
||||
- AWS RDS Proxy w/ IAM authentication enabled for an RDS PostgreSQL instance
|
||||
|
||||
## Usage
|
||||
|
||||
To run this example you need to execute:
|
||||
|
||||
```bash
|
||||
$ terraform init
|
||||
$ terraform plan
|
||||
$ terraform apply
|
||||
```
|
||||
|
||||
Note that this example may create resources which will incur monetary charges on your AWS bill. Run `terraform destroy` when you no longer need these resources.
|
||||
|
||||
## Validation
|
||||
|
||||
An EC2 instance configuration has been provided for use in validating the example configuration. After provisioning the configuration, there are some outputs that have been provided to aid in validating changes. To perform validation, after the EC2 instance finishes provisioning:
|
||||
|
||||
1. Connect to the EC2 instance using Session Manager
|
||||
2. Copy the output from `superuser_proxy_iam_token` and paste it into the Session Manager window - this generates the token for connecting to the proxy with IAM auth.
|
||||
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 -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| terraform | >= 0.12.26 |
|
||||
| aws | >= 3.9 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| aws | >= 3.9 |
|
||||
| random | n/a |
|
||||
|
||||
## Inputs
|
||||
|
||||
No input.
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| log\_group\_arn | The Amazon Resource Name (ARN) of the CloudWatch log group |
|
||||
| proxy\_arn | The Amazon Resource Name (ARN) for the proxy |
|
||||
| proxy\_default\_target\_group\_arn | The Amazon Resource Name (ARN) for the default target group |
|
||||
| proxy\_default\_target\_group\_id | The ID for the default target group |
|
||||
| proxy\_default\_target\_group\_name | The name of the default target group |
|
||||
| proxy\_endpoint | The endpoint that you can use to connect to the proxy |
|
||||
| proxy\_id | The ID for the proxy |
|
||||
| proxy\_target\_endpoint | Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type |
|
||||
| proxy\_target\_id | Identifier of `db_proxy_name`, `target_group_name`, target type (e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`), and resource identifier separated by forward slashes (/) |
|
||||
| proxy\_target\_port | Port for the target RDS DB Instance or Aurora DB Cluster |
|
||||
| proxy\_target\_rds\_resource\_id | Identifier representing the DB Instance or DB Cluster target |
|
||||
| proxy\_target\_target\_arn | Amazon Resource Name (ARN) for the DB instance or DB cluster. Currently not returned by the RDS API |
|
||||
| proxy\_target\_tracked\_cluster\_id | DB Cluster identifier for the DB Instance target. Not returned unless manually importing an RDS\_INSTANCE target that is part of a DB Cluster |
|
||||
| proxy\_target\_type | Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER` |
|
||||
| superuser\_db\_password\_connect | Connect to database using superuser with username/password directly to database |
|
||||
| superuser\_proxy\_iam\_connect | Connect to RDS Proxy using IAM auth via token generated |
|
||||
| superuser\_proxy\_iam\_token | Gerate connection token for connecting to RDS Proxy with IAM auth |
|
||||
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
|
||||
Apache-2.0 Licensed. See [LICENSE](../../LICENSE).
|
||||
294
examples/postgresql_iam_instance/main.tf
Normal file
294
examples/postgresql_iam_instance/main.tf
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
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 = "2.64.0"
|
||||
|
||||
name = local.name
|
||||
cidr = "10.0.0.0/18"
|
||||
|
||||
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
|
||||
public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
|
||||
private_subnets = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
|
||||
database_subnets = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
|
||||
|
||||
enable_nat_gateway = true
|
||||
single_nat_gateway = true
|
||||
|
||||
tags = local.tags
|
||||
}
|
||||
|
||||
module "rds_sg" {
|
||||
source = "terraform-aws-modules/security-group/aws"
|
||||
version = "3.17.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" {
|
||||
source = "terraform-aws-modules/rds/aws"
|
||||
version = "2.20.0"
|
||||
|
||||
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.this_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 = "3.17.0"
|
||||
|
||||
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.16.0"
|
||||
|
||||
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.this_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 = "3.17.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
|
||||
}
|
||||
|
||||
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.this_security_group_id]
|
||||
|
||||
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.this_db_instance_address
|
||||
db_name = module.rds.this_db_instance_name
|
||||
debug_logging = true
|
||||
|
||||
# Target RDS instance
|
||||
target_db_instance = true
|
||||
db_instance_identifier = module.rds.this_db_instance_id
|
||||
|
||||
tags = local.tags
|
||||
}
|
||||
89
examples/postgresql_iam_instance/outputs.tf
Normal file
89
examples/postgresql_iam_instance/outputs.tf
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# RDS Proxy
|
||||
output "proxy_id" {
|
||||
description = "The ID for the proxy"
|
||||
value = module.rds_proxy.proxy_id
|
||||
}
|
||||
|
||||
output "proxy_arn" {
|
||||
description = "The Amazon Resource Name (ARN) for the proxy"
|
||||
value = module.rds_proxy.proxy_arn
|
||||
}
|
||||
|
||||
output "proxy_endpoint" {
|
||||
description = "The endpoint that you can use to connect to the proxy"
|
||||
value = module.rds_proxy.proxy_endpoint
|
||||
}
|
||||
|
||||
# Proxy Default Target Group
|
||||
output "proxy_default_target_group_id" {
|
||||
description = "The ID for the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_id
|
||||
}
|
||||
|
||||
output "proxy_default_target_group_arn" {
|
||||
description = "The Amazon Resource Name (ARN) for the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_arn
|
||||
}
|
||||
|
||||
output "proxy_default_target_group_name" {
|
||||
description = "The name of the default target group"
|
||||
value = module.rds_proxy.proxy_default_target_group_name
|
||||
}
|
||||
|
||||
# Proxy Target
|
||||
output "proxy_target_endpoint" {
|
||||
description = "Hostname for the target RDS DB Instance. Only returned for `RDS_INSTANCE` type"
|
||||
value = module.rds_proxy.proxy_target_endpoint
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_id
|
||||
}
|
||||
|
||||
output "proxy_target_port" {
|
||||
description = "Port for the target RDS DB Instance or Aurora DB Cluster"
|
||||
value = module.rds_proxy.proxy_target_port
|
||||
}
|
||||
|
||||
output "proxy_target_rds_resource_id" {
|
||||
description = "Identifier representing the DB Instance or DB Cluster target"
|
||||
value = module.rds_proxy.proxy_target_rds_resource_id
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_target_arn
|
||||
}
|
||||
|
||||
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 = module.rds_proxy.proxy_target_tracked_cluster_id
|
||||
}
|
||||
|
||||
output "proxy_target_type" {
|
||||
description = "Type of target. e.g. `RDS_INSTANCE` or `TRACKED_CLUSTER`"
|
||||
value = module.rds_proxy.proxy_target_type
|
||||
}
|
||||
|
||||
# CloudWatch logs
|
||||
output "log_group_arn" {
|
||||
description = "The Amazon Resource Name (ARN) of the CloudWatch log group"
|
||||
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.this_db_instance_address} -p 5432 -d ${module.rds.this_db_instance_name} -U ${local.db_username} --set=sslmode=require"
|
||||
}
|
||||
|
||||
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.this_db_instance_name} user=${local.db_username} password=$TOKEN\""
|
||||
}
|
||||
7
examples/postgresql_iam_instance/versions.tf
Normal file
7
examples/postgresql_iam_instance/versions.tf
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
terraform {
|
||||
required_version = ">= 0.12.26"
|
||||
|
||||
required_providers {
|
||||
aws = ">= 3.9"
|
||||
}
|
||||
}
|
||||
171
main.tf
Normal file
171
main.tf
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
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
|
||||
|
||||
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
|
||||
|
||||
dynamic "auth" {
|
||||
for_each = var.secrets
|
||||
content {
|
||||
auth_scheme = var.auth_scheme
|
||||
description = auth.value.description
|
||||
iam_auth = var.iam_auth
|
||||
secret_arn = auth.value.arn
|
||||
}
|
||||
}
|
||||
|
||||
tags = merge(var.tags, var.proxy_tags)
|
||||
|
||||
depends_on = [aws_cloudwatch_log_group.this]
|
||||
}
|
||||
|
||||
resource "aws_db_proxy_default_target_group" "this" {
|
||||
count = var.create_proxy ? 1 : 0
|
||||
|
||||
db_proxy_name = aws_db_proxy.this[0].name
|
||||
|
||||
connection_pool_config {
|
||||
connection_borrow_timeout = var.connection_borrow_timeout
|
||||
init_query = var.init_query
|
||||
max_connections_percent = var.max_connections_percent
|
||||
max_idle_connections_percent = var.max_idle_connections_percent
|
||||
session_pinning_filters = var.session_pinning_filters
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_db_proxy_target" "db_instance" {
|
||||
count = var.create_proxy && var.target_db_instance ? 1 : 0
|
||||
|
||||
db_proxy_name = aws_db_proxy.this[0].name
|
||||
target_group_name = aws_db_proxy_default_target_group.this[0].name
|
||||
db_instance_identifier = var.db_instance_identifier
|
||||
}
|
||||
|
||||
resource "aws_db_proxy_target" "db_cluster" {
|
||||
count = var.create_proxy && var.target_db_cluster ? 1 : 0
|
||||
|
||||
db_proxy_name = aws_db_proxy.this[0].name
|
||||
target_group_name = aws_db_proxy_default_target_group.this[0].name
|
||||
db_cluster_identifier = var.db_cluster_identifier
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# CloudWatch Logs
|
||||
################################################################################
|
||||
|
||||
resource "aws_cloudwatch_log_group" "this" {
|
||||
count = var.create_proxy && var.manage_log_group && var.debug_logging ? 1 : 0
|
||||
|
||||
name = "/aws/rds/proxy/${var.name}"
|
||||
retention_in_days = var.log_group_retention_in_days
|
||||
kms_key_id = var.log_group_kms_key_id
|
||||
|
||||
tags = merge(var.tags, var.log_group_tags)
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# IAM Role
|
||||
################################################################################
|
||||
|
||||
data "aws_iam_policy_document" "assume_role" {
|
||||
count = var.create_proxy && var.create_iam_role ? 1 : 0
|
||||
|
||||
statement {
|
||||
sid = "RDSAssume"
|
||||
effect = "Allow"
|
||||
actions = ["sts:AssumeRole"]
|
||||
|
||||
principals {
|
||||
type = "Service"
|
||||
identifiers = ["rds.amazonaws.com"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "this" {
|
||||
count = var.create_proxy && var.create_iam_role ? 1 : 0
|
||||
|
||||
name = var.use_role_name_prefix ? null : local.role_name
|
||||
name_prefix = var.use_role_name_prefix ? "${local.role_name}-" : null
|
||||
description = var.iam_role_description
|
||||
path = var.iam_role_path
|
||||
|
||||
assume_role_policy = data.aws_iam_policy_document.assume_role[0].json
|
||||
force_detach_policies = var.iam_role_force_detach_policies
|
||||
max_session_duration = var.iam_role_max_session_duration
|
||||
permissions_boundary = var.iam_role_permissions_boundary
|
||||
|
||||
tags = merge(var.tags, var.iam_role_tags)
|
||||
}
|
||||
|
||||
data "aws_iam_policy_document" "this" {
|
||||
count = var.create_proxy && var.create_iam_role ? 1 : 0
|
||||
|
||||
statement {
|
||||
sid = "DecryptSecrets"
|
||||
effect = "Allow"
|
||||
actions = ["kms:Decrypt"]
|
||||
resources = distinct([for secret in var.secrets : secret.kms_key_id])
|
||||
condition {
|
||||
test = "StringEquals"
|
||||
variable = "kms:ViaService"
|
||||
|
||||
values = [
|
||||
"secretsmanager.${data.aws_region.current.name}.amazonaws.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
statement {
|
||||
sid = "ListSecrets"
|
||||
effect = "Allow"
|
||||
actions = [
|
||||
"secretsmanager:GetRandomPassword",
|
||||
"secretsmanager:ListSecrets",
|
||||
]
|
||||
resources = ["*"]
|
||||
}
|
||||
|
||||
statement {
|
||||
sid = "GetSecrets"
|
||||
effect = "Allow"
|
||||
actions = [
|
||||
"secretsmanager:GetResourcePolicy",
|
||||
"secretsmanager:GetSecretValue",
|
||||
"secretsmanager:DescribeSecret",
|
||||
"secretsmanager:ListSecretVersionIds",
|
||||
]
|
||||
|
||||
resources = distinct([for secret in var.secrets : secret.arn])
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "this" {
|
||||
count = var.create_proxy && var.create_iam_role && var.create_iam_policy ? 1 : 0
|
||||
|
||||
name = var.use_policy_name_prefix ? null : local.policy_name
|
||||
name_prefix = var.use_policy_name_prefix ? "${local.policy_name}-" : null
|
||||
policy = data.aws_iam_policy_document.this[0].json
|
||||
role = aws_iam_role.this[0].id
|
||||
}
|
||||
73
outputs.tf
Normal file
73
outputs.tf
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# RDS Proxy
|
||||
output "proxy_id" {
|
||||
description = "The ID for the proxy"
|
||||
value = element(concat(aws_db_proxy.this.*.id, [""]), 0)
|
||||
}
|
||||
|
||||
output "proxy_arn" {
|
||||
description = "The Amazon Resource Name (ARN) for the proxy"
|
||||
value = element(concat(aws_db_proxy.this.*.arn, [""]), 0)
|
||||
}
|
||||
|
||||
output "proxy_endpoint" {
|
||||
description = "The endpoint that you can use to connect to the proxy"
|
||||
value = element(concat(aws_db_proxy.this.*.endpoint, [""]), 0)
|
||||
}
|
||||
|
||||
# Proxy 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)
|
||||
}
|
||||
|
||||
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.*.id, [""]), 0)
|
||||
}
|
||||
|
||||
output "proxy_default_target_group_name" {
|
||||
description = "The name of the default target group"
|
||||
value = element(concat(aws_db_proxy_default_target_group.this.*.id, [""]), 0)
|
||||
}
|
||||
|
||||
# Proxy Target
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
# CloudWatch logs
|
||||
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)
|
||||
}
|
||||
263
variables.tf
Normal file
263
variables.tf
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
variable "tags" {
|
||||
description = "A map of tags to use on 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"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "auth" {
|
||||
description = "Configuration block(s) with authorization mechanisms to connect to the associated instances or clusters"
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "debug_logging" {
|
||||
description = "Whether the proxy includes detailed information about SQL statements in its logs"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "engine_family" {
|
||||
description = "The kind of database engine that the proxy will connect to. Valid values are `MYSQL` or `POSTGRESQL`"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "idle_client_timeout" {
|
||||
description = "The number of seconds that a connection to the proxy can be inactive before the proxy disconnects it"
|
||||
type = number
|
||||
default = 1800
|
||||
}
|
||||
|
||||
variable "require_tls" {
|
||||
description = "A Boolean parameter that specifies whether Transport Layer Security (TLS) encryption is required for connections to the proxy"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "role_arn" {
|
||||
description = "The Amazon Resource Name (ARN) of the IAM role that the proxy uses to access secrets in AWS Secrets Manager"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "vpc_security_group_ids" {
|
||||
description = "One or more VPC security group IDs to associate with the new proxy"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "vpc_subnet_ids" {
|
||||
description = "One or more VPC subnet IDs to associate with the new proxy"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "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 = {}
|
||||
}
|
||||
|
||||
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
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "init_query" {
|
||||
description = "One or more SQL statements for the proxy to run when opening each new database connection"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "max_connections_percent" {
|
||||
description = "The maximum size of the connection pool for each target in a target group"
|
||||
type = number
|
||||
default = 90
|
||||
}
|
||||
|
||||
variable "max_idle_connections_percent" {
|
||||
description = "Controls how actively the proxy closes idle database connections in the connection pool"
|
||||
type = number
|
||||
default = 50
|
||||
}
|
||||
|
||||
variable "session_pinning_filters" {
|
||||
description = "Each item in the list represents a class of SQL operations that normally cause all later statements in a session using a proxy to be pinned to the same underlying database connection"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
# Proxy Target
|
||||
variable "target_db_instance" {
|
||||
description = "Determines whether DB instance is targetted by proxy"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "db_instance_identifier" {
|
||||
description = "DB instance identifier"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "target_db_cluster" {
|
||||
description = "Determines whether DB cluster is targetted by proxy"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "db_cluster_identifier" {
|
||||
description = "DB cluster identifier"
|
||||
type = 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
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "log_group_retention_in_days" {
|
||||
description = "Specifies the number of days you want to retain log events in the log group"
|
||||
type = number
|
||||
default = 30
|
||||
}
|
||||
|
||||
variable "log_group_kms_key_id" {
|
||||
description = "The ARN of the KMS Key to use when encrypting log data"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "log_group_tags" {
|
||||
description = "A map of tags to apply to the CloudWatch log group"
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
# IAM Role
|
||||
variable "create_iam_role" {
|
||||
description = "Determines whether an IAM role is created"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "iam_role_name" {
|
||||
description = "The name of the role. If omitted, Terraform will assign a random, unique name"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "use_role_name_prefix" {
|
||||
description = "Whether to use unique name beginning with the specified `iam_role_name`"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "iam_role_description" {
|
||||
description = "The description of the role"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "iam_role_path" {
|
||||
description = "The path to the role"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "iam_role_force_detach_policies" {
|
||||
description = "Specifies to force detaching any policies the role has before destroying it"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "iam_role_max_session_duration" {
|
||||
description = "The maximum session duration (in seconds) that you want to set for the specified role"
|
||||
type = number
|
||||
default = 43200 # 12 hours
|
||||
}
|
||||
|
||||
variable "iam_role_permissions_boundary" {
|
||||
description = "The ARN of the policy that is used to set the permissions boundary for the role"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "iam_role_tags" {
|
||||
description = "A map of tags to apply to the IAM role"
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
# IAM Policy
|
||||
variable "create_iam_policy" {
|
||||
description = "Determines whether an IAM policy is created"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "iam_policy_name" {
|
||||
description = "The name of the role policy. If omitted, Terraform will assign a random, unique name"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "use_policy_name_prefix" {
|
||||
description = "Whether to use unique name beginning with the specified `iam_policy_name`"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "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"
|
||||
}
|
||||
7
versions.tf
Normal file
7
versions.tf
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
terraform {
|
||||
required_version = ">= 0.12.26"
|
||||
|
||||
required_providers {
|
||||
aws = ">= 3.9"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue