Skip to content

Commit

Permalink
feat(proxy): rds proxy submodule (#24)
Browse files Browse the repository at this point in the history
* feat(proxy): rds proxy submodule

* feat(proxy): get secrets policy
  • Loading branch information
Young-ook authored Dec 18, 2021
1 parent 2ae0d2a commit 0a03d75
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 0 deletions.
17 changes: 17 additions & 0 deletions modules/proxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Amazon RDS Proxy
By using [Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html), you can allow your applications to pool and share database connections to improve their ability to scale. RDS Proxy makes applications more resilient to database failures by automatically connecting to a standby DB instance while preserving application connections. By using RDS Proxy, you can also enforce AWS Identity and Access Management (IAM) authentication for databases, and securely store credentials in AWS Secrets Manager.

## Quickstart
### Setup
```hcl
module "proxy" {
source = "Young-ook/aurora/aws//modules/proxy"
name = var.name
}
```

Run terraform:
```
terraform init
terraform apply
```
15 changes: 15 additions & 0 deletions modules/proxy/default.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
### default values

locals {
default_proxy_config = {
debug_logging = false
engine_family = "MYSQL" # allowed values: MYSQL | POSTGRESQL
idle_client_timeout = 1800
require_tls = true
target_role = "READ_WRITE" # allowed values: READ_WRITE | READ_ONLY
}
default_auth_config = {
auth_scheme = "SECRETS"
iam_auth = "DISABLED"
}
}
17 changes: 17 additions & 0 deletions modules/proxy/labels.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
resource "random_string" "uid" {
length = 12
upper = false
lower = true
number = false
special = false
}

locals {
service = "rdsproxy"
uid = join("-", [local.service, random_string.uid.result])
name = var.name == null || var.name == "" ? local.uid : var.name
default-tags = merge(
{ "terraform.io" = "managed" },
{ "Name" = local.name },
)
}
111 changes: 111 additions & 0 deletions modules/proxy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
## rds proxy

# parameters
locals {
security_groups = var.security_groups == [] ? null : var.security_groups
debug_logging = lookup(var.proxy_config, "debug_logging", local.default_proxy_config.debug_logging)
engine_family = lookup(var.proxy_config, "engine_family", local.default_proxy_config.engine_family)
idle_client_timeout = lookup(var.proxy_config, "idle_client_timeout", local.default_proxy_config.idle_client_timeout)
require_tls = lookup(var.proxy_config, "require_tls", local.default_proxy_config.require_tls)
target_role = lookup(var.proxy_config, "target_role", local.default_proxy_config.target_role)
auth = lookup(var.proxy_config, "auth", local.default_auth_config)
cluster_id = lookup(var.proxy_config, "cluster_id", null)
db_id = lookup(var.proxy_config, "db_id", null)
user_name = lookup(var.auth_config, "user_name") # required
user_password = lookup(var.auth_config, "user_password") # required
}

# security/secret
resource "aws_secretsmanager_secret" "password" {
name = join("-", [local.user_name, local.name])
tags = var.tags
#policy = var.policy
}

resource "aws_secretsmanager_secret_version" "password" {
secret_id = aws_secretsmanager_secret.password.id
secret_string = local.user_password
}

# aws partition and region (global, gov, china)
module "aws" {
source = "Young-ook/spinnaker/aws//modules/aws-partitions"
}

# security/policy
resource "aws_iam_role" "proxy" {
name = local.name
tags = merge(local.default-tags, var.tags)
assume_role_policy = jsonencode({
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = [format("rds.%s", module.aws.partition.dns_suffix)]
}
}]
Version = "2012-10-17"
})
}

resource "aws_iam_role_policy" "get-secret" {
role = aws_iam_role.proxy.id
policy = jsonencode({
Statement = [{
Action = [
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:ListSecretVersionIds",
]
Effect = "Allow"
Resource = [aws_secretsmanager_secret.password.arn]
}, {
Action = [
"secretsmanager:GetRandomPassword",
"secretsmanager:ListSecrets",
]
Effect = "Allow"
Resource = ["*"]
}]
Version = "2012-10-17"
})
}

# proxy
resource "aws_db_proxy" "proxy" {
name = local.name
tags = merge(local.default-tags, var.tags)
debug_logging = local.debug_logging
engine_family = local.engine_family
idle_client_timeout = local.idle_client_timeout
require_tls = local.require_tls
role_arn = aws_iam_role.proxy.arn
vpc_subnet_ids = var.subnets
vpc_security_group_ids = local.security_groups

auth {
description = lookup(local.auth, "description", null)
auth_scheme = lookup(local.auth, "auth_scheme", null)
secret_arn = lookup(local.auth, "secret_arn", aws_secretsmanager_secret.password.arn)
iam_auth = lookup(local.auth, "iam_auth", null)
}
}

resource "aws_db_proxy_default_target_group" "proxy" {
db_proxy_name = aws_db_proxy.proxy.name
connection_pool_config {
connection_borrow_timeout = 120
init_query = "SET x=1, y=2"
max_connections_percent = 100
max_idle_connections_percent = 50
session_pinning_filters = ["EXCLUDE_VARIABLE_SETS"]
}
}

resource "aws_db_proxy_target" "proxy" {
db_instance_identifier = local.db_id
db_cluster_identifier = local.cluster_id
db_proxy_name = aws_db_proxy.proxy.name
target_group_name = aws_db_proxy_default_target_group.proxy.name
}
6 changes: 6 additions & 0 deletions modules/proxy/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# output variables

output "proxy" {
description = "Attributes of the generated rds proxy"
value = aws_db_proxy.proxy
}
37 changes: 37 additions & 0 deletions modules/proxy/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
### network
variable "subnets" {
description = "The subnet IDs for rds"
type = list(string)
default = []
}

### security
variable "security_groups" {
description = "The security group IDs for rds"
type = list(string)
default = []
}

variable "auth_config" {
description = "Authentication configuration"
default = {}
}

### db proxy
variable "proxy_config" {
description = "RDS proxy configuration"
default = {}
}

### description
variable "name" {
description = "The logical name of the module instance"
type = string
}

### tags
variable "tags" {
description = "The key-value maps for tagging"
type = map(string)
default = {}
}

0 comments on commit 0a03d75

Please sign in to comment.