Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
korenyoni committed Dec 26, 2021
1 parent 159faa7 commit f2bf4c1
Show file tree
Hide file tree
Showing 12 changed files with 568 additions and 25 deletions.
4 changes: 3 additions & 1 deletion examples/complete/fixtures.us-east-2.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ availability_zones = ["us-east-2a", "us-east-2b"]

namespace = "eg"

environment = "ue2"

stage = "test"

name = "rds-test"
name = "rds"

deletion_protection = false

Expand Down
103 changes: 100 additions & 3 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ provider "aws" {

module "vpc" {
source = "cloudposse/vpc/aws"
version = "0.21.1"
version = "0.28.1"

cidr_block = "172.16.0.0/16"

Expand All @@ -13,7 +13,7 @@ module "vpc" {

module "subnets" {
source = "cloudposse/dynamic-subnets/aws"
version = "0.38.0"
version = "0.39.8"

availability_zones = var.availability_zones
vpc_id = module.vpc.vpc_id
Expand All @@ -37,6 +37,7 @@ module "rds_instance" {
storage_encrypted = var.storage_encrypted
engine = var.engine
engine_version = var.engine_version
major_engine_version = var.major_engine_version
instance_class = var.instance_class
db_parameter_group = var.db_parameter_group
publicly_accessible = var.publicly_accessible
Expand All @@ -46,8 +47,11 @@ module "rds_instance" {
apply_immediately = var.apply_immediately
availability_zone = var.availability_zone
db_subnet_group_name = var.db_subnet_group_name
role_associations = local.s3_integration_enabled ? {
S3_INTEGRATION = module.role.arn
} : {}

db_parameter = [
db_parameter = local.s3_integration_enabled ? [] : [ # the S3 integration test relies on MySQL
{
name = "myisam_sort_buffer_size"
value = "1048576"
Expand All @@ -62,3 +66,96 @@ module "rds_instance" {

context = module.this.context
}

# The remainder of this configuration has to do with creating an S3 integration.
# This is to test var.role_associations.
# See: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance_role_association
# and https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/oracle-s3-integration.html
locals {
s3_integration_enabled = module.this.enabled && var.s3_integration_enabled
s3_integration_actions = [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject"
]
# Workaround for principal ARN in S3 Bucket policy not being known until apply
s3_integration_bucket_arn = "arn:${join("", data.aws_partition.current.*.partition)}:s3:::${module.this.id}"
s3_integration_role_arn = "arn:${join("", data.aws_partition.current.*.partition)}:iam::${join("", data.aws_caller_identity.current.*.account_id)}:role/${module.this.id}"
}

data "aws_caller_identity" "current" {
count = local.s3_integration_enabled ? 1 : 0
}

data "aws_partition" "current" {
count = local.s3_integration_enabled ? 1 : 0
}

data "aws_iam_policy_document" "bucket_policy" {
count = local.s3_integration_enabled ? 1 : 0

statement {
sid = "AllowIntegrationRoleS3Access"

actions = local.s3_integration_actions

resources = [
local.s3_integration_bucket_arn,
"${local.s3_integration_bucket_arn}/*"
]
effect = "Allow"

principals {
identifiers = [local.s3_integration_role_arn]
type = "AWS"
}
}
}

module "s3_bucket" {
source = "cloudposse/s3-bucket/aws"
version = "0.44.1"

enabled = local.s3_integration_enabled

acl = "private"
policy = join("", data.aws_iam_policy_document.bucket_policy.*.json)

context = module.this.context
}

data "aws_iam_policy_document" "role_policy" {
count = local.s3_integration_enabled ? 1 : 0

statement {
sid = "AllowS3Access"

actions = local.s3_integration_actions

resources = [
local.s3_integration_bucket_arn,
"${local.s3_integration_bucket_arn}/*"
]
effect = "Allow"
}
}

module "role" {
source = "cloudposse/iam-role/aws"
version = "0.14.0"

enabled = local.s3_integration_enabled

policy_description = "Allow RDS Access to S3 (S3_INTEGRATION)."
role_description = "Allow IAM Role assumed by RDS to perform S3 Actions (S3_INTEGRATION)."

principals = {
Service = ["rds.amazonaws.com"]
}

policy_documents = [
join("", data.aws_iam_policy_document.role_policy.*.json)
]

context = module.this.context
}
5 changes: 5 additions & 0 deletions examples/complete/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,8 @@ output "private_subnet_cidrs" {
output "vpc_cidr" {
value = module.vpc.vpc_cidr_block
}

output "role_associations" {
value = module.rds_instance.role_associations
description = "Map of RDS Role Associations for the DB instance."
}
45 changes: 45 additions & 0 deletions examples/complete/s3-integration.us-east-2.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
region = "us-east-2"

availability_zones = ["us-east-2a", "us-east-2b"]

namespace = "eg"

environment = "ue2"

stage = "test"

name = "rds-s3-integration"

deletion_protection = false

database_name = "testdb"

database_user = "oraadmin"

database_password = "admin_password"

database_port = 1521

multi_az = false

storage_type = "standard"

storage_encrypted = false

allocated_storage = 20

engine = "oracle-ee"

engine_version = "12.1.0.2.v25"

major_engine_version = "12.1"

instance_class = "db.t3.small"

db_parameter_group = "oracle-ee-12.1"

publicly_accessible = false

apply_immediately = true

s3_integration_enabled = true
6 changes: 6 additions & 0 deletions examples/complete/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,9 @@ variable "apply_immediately" {
type = bool
description = "Specifies whether any database modifications are applied immediately, or during the next maintenance window"
}

variable "s3_integration_enabled" {
type = bool
description = "Whether to enable or disable the RDS integration test for S3_INTEGRATION."
default = false
}
32 changes: 23 additions & 9 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ module "final_snapshot_label" {
}

locals {
enabled = module.this.enabled

computed_major_engine_version = var.engine == "postgres" ? join(".", slice(split(".", var.engine_version), 0, 1)) : join(".", slice(split(".", var.engine_version), 0, 2))
major_engine_version = var.major_engine_version == "" ? local.computed_major_engine_version : var.major_engine_version

Expand All @@ -20,7 +22,11 @@ locals {
}

resource "aws_db_instance" "default" {
count = module.this.enabled ? 1 : 0
#bridgecrew:skip=BC_AWS_LOGGING_28:RDS enhanced monitoring is configurable via var.monitoring_interval and var.monitoring_role_arn
#bridgecrew:skip=BC_AWS_GENERAL_73:Multi AZ is configurable via var.multi_az
#bridgecrew:skip=BC_AWS_IAM_60:RDS logs are configurable via var.enabled_cloudwatch_logs_exports
#bridgecrew:skip=BC_AWS_GENERAL_46:RDS backup policies are configurable via var.backup_retention_period
count = local.enabled ? 1 : 0

identifier = module.this.id
name = var.database_name
Expand Down Expand Up @@ -92,7 +98,7 @@ resource "aws_db_instance" "default" {
}

resource "aws_db_parameter_group" "default" {
count = length(var.parameter_group_name) == 0 && module.this.enabled ? 1 : 0
count = length(var.parameter_group_name) == 0 && local.enabled ? 1 : 0

name_prefix = "${module.this.id}${module.this.delimiter}"
family = var.db_parameter_group
Expand All @@ -113,7 +119,7 @@ resource "aws_db_parameter_group" "default" {
}

resource "aws_db_option_group" "default" {
count = length(var.option_group_name) == 0 && module.this.enabled ? 1 : 0
count = length(var.option_group_name) == 0 && local.enabled ? 1 : 0

name_prefix = "${module.this.id}${module.this.delimiter}"
engine_name = var.engine
Expand Down Expand Up @@ -144,16 +150,24 @@ resource "aws_db_option_group" "default" {
}
}

resource "aws_db_instance_role_association" "default" {
for_each = local.enabled ? var.role_associations : {}

db_instance_identifier = join("", aws_db_instance.default.*.id)
feature_name = each.key
role_arn = each.value
}

resource "aws_db_subnet_group" "default" {
count = module.this.enabled && local.subnet_ids_provided && ! local.db_subnet_group_name_provided ? 1 : 0
count = local.enabled && local.subnet_ids_provided && ! local.db_subnet_group_name_provided ? 1 : 0

name = module.this.id
subnet_ids = var.subnet_ids
tags = module.this.tags
}

resource "aws_security_group" "default" {
count = module.this.enabled ? 1 : 0
count = local.enabled ? 1 : 0

name = module.this.id
description = "Allow inbound traffic from the security groups"
Expand All @@ -162,7 +176,7 @@ resource "aws_security_group" "default" {
}

resource "aws_security_group_rule" "ingress_security_groups" {
count = module.this.enabled ? length(var.security_group_ids) : 0
count = local.enabled ? length(var.security_group_ids) : 0

description = "Allow inbound traffic from existing Security Groups"
type = "ingress"
Expand All @@ -174,7 +188,7 @@ resource "aws_security_group_rule" "ingress_security_groups" {
}

resource "aws_security_group_rule" "ingress_cidr_blocks" {
count = module.this.enabled && length(var.allowed_cidr_blocks) > 0 ? 1 : 0
count = local.enabled && length(var.allowed_cidr_blocks) > 0 ? 1 : 0

description = "Allow inbound traffic from CIDR blocks"
type = "ingress"
Expand All @@ -186,7 +200,7 @@ resource "aws_security_group_rule" "ingress_cidr_blocks" {
}

resource "aws_security_group_rule" "egress" {
count = module.this.enabled ? 1 : 0
count = local.enabled ? 1 : 0
description = "Allow all egress traffic"
type = "egress"
from_port = 0
Expand All @@ -200,7 +214,7 @@ module "dns_host_name" {
source = "cloudposse/route53-cluster-hostname/aws"
version = "0.12.2"

enabled = length(var.dns_zone_id) > 0 && module.this.enabled
enabled = length(var.dns_zone_id) > 0 && local.enabled
dns_name = var.host_name
zone_id = var.dns_zone_id
records = coalescelist(aws_db_instance.default.*.address, [""])
Expand Down
11 changes: 11 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,14 @@ output "resource_id" {
value = join("", aws_db_instance.default.*.resource_id)
description = "The RDS Resource ID of this instance."
}

output "role_associations" {
value = local.enabled ? { for k, v in var.role_associations :
k => {
id = aws_db_instance_role_association.default[k].id
role_arn = aws_db_instance_role_association.default[k].role_arn
feature_name = aws_db_instance_role_association.default[k].feature_name
}
} : {}
description = "Map of RDS Role Associations for the DB instance."
}
4 changes: 3 additions & 1 deletion test/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ init:
## Run tests
test: init
go mod download
go test -v -timeout 60m -run TestExamplesComplete
#go test -v -timeout 60m -run TestExamplesComplete
#go test -v -timeout 60m
go test -timeout 60m

## Run tests in docker container
docker/test:
Expand Down
Loading

0 comments on commit f2bf4c1

Please sign in to comment.