Skip to content

Commit b34450e

Browse files
authored
feat: Add Terragrunt wrappers (#607)
feat: Add wrappers
1 parent 22b02b3 commit b34450e

36 files changed

+1159
-2
lines changed

.pre-commit-config.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
repos:
22
- repo: https://github.com/antonbabenko/pre-commit-terraform
3-
rev: v1.96.1
3+
rev: v1.100.1
44
hooks:
55
- id: terraform_fmt
6+
- id: terraform_wrapper_module_for_each
67
- id: terraform_docs
78
args:
89
- '--args=--lockfile=false'
@@ -23,7 +24,7 @@ repos:
2324
- '--args=--only=terraform_workspace_remote'
2425
- id: terraform_validate
2526
- repo: https://github.com/pre-commit/pre-commit-hooks
26-
rev: v5.0.0
27+
rev: v6.0.0
2728
hooks:
2829
- id: check-merge-conflict
2930
- id: end-of-file-fixer

wrappers/README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Wrapper for the root module
2+
3+
The configuration in this directory contains an implementation of a single module wrapper pattern, which allows managing several copies of a module in places where using the native Terraform 0.13+ `for_each` feature is not feasible (e.g., with Terragrunt).
4+
5+
You may want to use a single Terragrunt configuration file to manage multiple resources without duplicating `terragrunt.hcl` files for each copy of the same module.
6+
7+
This wrapper does not implement any extra functionality.
8+
9+
## Usage with Terragrunt
10+
11+
`terragrunt.hcl`:
12+
13+
```hcl
14+
terraform {
15+
source = "tfr:///terraform-aws-modules/rds/aws//wrappers"
16+
# Alternative source:
17+
# source = "git::[email protected]:terraform-aws-modules/terraform-aws-rds.git//wrappers?ref=master"
18+
}
19+
20+
inputs = {
21+
defaults = { # Default values
22+
create = true
23+
tags = {
24+
Terraform = "true"
25+
Environment = "dev"
26+
}
27+
}
28+
29+
items = {
30+
my-item = {
31+
# omitted... can be any argument supported by the module
32+
}
33+
my-second-item = {
34+
# omitted... can be any argument supported by the module
35+
}
36+
# omitted...
37+
}
38+
}
39+
```
40+
41+
## Usage with Terraform
42+
43+
```hcl
44+
module "wrapper" {
45+
source = "terraform-aws-modules/rds/aws//wrappers"
46+
47+
defaults = { # Default values
48+
create = true
49+
tags = {
50+
Terraform = "true"
51+
Environment = "dev"
52+
}
53+
}
54+
55+
items = {
56+
my-item = {
57+
# omitted... can be any argument supported by the module
58+
}
59+
my-second-item = {
60+
# omitted... can be any argument supported by the module
61+
}
62+
# omitted...
63+
}
64+
}
65+
```
66+
67+
## Example: Manage multiple S3 buckets in one Terragrunt layer
68+
69+
`eu-west-1/s3-buckets/terragrunt.hcl`:
70+
71+
```hcl
72+
terraform {
73+
source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers"
74+
# Alternative source:
75+
# source = "git::[email protected]:terraform-aws-modules/terraform-aws-s3-bucket.git//wrappers?ref=master"
76+
}
77+
78+
inputs = {
79+
defaults = {
80+
force_destroy = true
81+
82+
attach_elb_log_delivery_policy = true
83+
attach_lb_log_delivery_policy = true
84+
attach_deny_insecure_transport_policy = true
85+
attach_require_latest_tls_policy = true
86+
}
87+
88+
items = {
89+
bucket1 = {
90+
bucket = "my-random-bucket-1"
91+
}
92+
bucket2 = {
93+
bucket = "my-random-bucket-2"
94+
tags = {
95+
Secure = "probably"
96+
}
97+
}
98+
}
99+
}
100+
```

wrappers/db_instance/README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Wrapper for module: `modules/db_instance`
2+
3+
The configuration in this directory contains an implementation of a single module wrapper pattern, which allows managing several copies of a module in places where using the native Terraform 0.13+ `for_each` feature is not feasible (e.g., with Terragrunt).
4+
5+
You may want to use a single Terragrunt configuration file to manage multiple resources without duplicating `terragrunt.hcl` files for each copy of the same module.
6+
7+
This wrapper does not implement any extra functionality.
8+
9+
## Usage with Terragrunt
10+
11+
`terragrunt.hcl`:
12+
13+
```hcl
14+
terraform {
15+
source = "tfr:///terraform-aws-modules/rds/aws//wrappers/db_instance"
16+
# Alternative source:
17+
# source = "git::[email protected]:terraform-aws-modules/terraform-aws-rds.git//wrappers/db_instance?ref=master"
18+
}
19+
20+
inputs = {
21+
defaults = { # Default values
22+
create = true
23+
tags = {
24+
Terraform = "true"
25+
Environment = "dev"
26+
}
27+
}
28+
29+
items = {
30+
my-item = {
31+
# omitted... can be any argument supported by the module
32+
}
33+
my-second-item = {
34+
# omitted... can be any argument supported by the module
35+
}
36+
# omitted...
37+
}
38+
}
39+
```
40+
41+
## Usage with Terraform
42+
43+
```hcl
44+
module "wrapper" {
45+
source = "terraform-aws-modules/rds/aws//wrappers/db_instance"
46+
47+
defaults = { # Default values
48+
create = true
49+
tags = {
50+
Terraform = "true"
51+
Environment = "dev"
52+
}
53+
}
54+
55+
items = {
56+
my-item = {
57+
# omitted... can be any argument supported by the module
58+
}
59+
my-second-item = {
60+
# omitted... can be any argument supported by the module
61+
}
62+
# omitted...
63+
}
64+
}
65+
```
66+
67+
## Example: Manage multiple S3 buckets in one Terragrunt layer
68+
69+
`eu-west-1/s3-buckets/terragrunt.hcl`:
70+
71+
```hcl
72+
terraform {
73+
source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers"
74+
# Alternative source:
75+
# source = "git::[email protected]:terraform-aws-modules/terraform-aws-s3-bucket.git//wrappers?ref=master"
76+
}
77+
78+
inputs = {
79+
defaults = {
80+
force_destroy = true
81+
82+
attach_elb_log_delivery_policy = true
83+
attach_lb_log_delivery_policy = true
84+
attach_deny_insecure_transport_policy = true
85+
attach_require_latest_tls_policy = true
86+
}
87+
88+
items = {
89+
bucket1 = {
90+
bucket = "my-random-bucket-1"
91+
}
92+
bucket2 = {
93+
bucket = "my-random-bucket-2"
94+
tags = {
95+
Secure = "probably"
96+
}
97+
}
98+
}
99+
}
100+
```

wrappers/db_instance/main.tf

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
module "wrapper" {
2+
source = "../../modules/db_instance"
3+
4+
for_each = var.items
5+
6+
allocated_storage = try(each.value.allocated_storage, var.defaults.allocated_storage, null)
7+
allow_major_version_upgrade = try(each.value.allow_major_version_upgrade, var.defaults.allow_major_version_upgrade, false)
8+
apply_immediately = try(each.value.apply_immediately, var.defaults.apply_immediately, false)
9+
auto_minor_version_upgrade = try(each.value.auto_minor_version_upgrade, var.defaults.auto_minor_version_upgrade, true)
10+
availability_zone = try(each.value.availability_zone, var.defaults.availability_zone, null)
11+
backup_retention_period = try(each.value.backup_retention_period, var.defaults.backup_retention_period, null)
12+
backup_window = try(each.value.backup_window, var.defaults.backup_window, null)
13+
blue_green_update = try(each.value.blue_green_update, var.defaults.blue_green_update, {})
14+
ca_cert_identifier = try(each.value.ca_cert_identifier, var.defaults.ca_cert_identifier, null)
15+
character_set_name = try(each.value.character_set_name, var.defaults.character_set_name, null)
16+
cloudwatch_log_group_class = try(each.value.cloudwatch_log_group_class, var.defaults.cloudwatch_log_group_class, null)
17+
cloudwatch_log_group_kms_key_id = try(each.value.cloudwatch_log_group_kms_key_id, var.defaults.cloudwatch_log_group_kms_key_id, null)
18+
cloudwatch_log_group_retention_in_days = try(each.value.cloudwatch_log_group_retention_in_days, var.defaults.cloudwatch_log_group_retention_in_days, 7)
19+
cloudwatch_log_group_skip_destroy = try(each.value.cloudwatch_log_group_skip_destroy, var.defaults.cloudwatch_log_group_skip_destroy, null)
20+
cloudwatch_log_group_tags = try(each.value.cloudwatch_log_group_tags, var.defaults.cloudwatch_log_group_tags, {})
21+
copy_tags_to_snapshot = try(each.value.copy_tags_to_snapshot, var.defaults.copy_tags_to_snapshot, false)
22+
create = try(each.value.create, var.defaults.create, true)
23+
create_cloudwatch_log_group = try(each.value.create_cloudwatch_log_group, var.defaults.create_cloudwatch_log_group, false)
24+
create_monitoring_role = try(each.value.create_monitoring_role, var.defaults.create_monitoring_role, false)
25+
custom_iam_instance_profile = try(each.value.custom_iam_instance_profile, var.defaults.custom_iam_instance_profile, null)
26+
database_insights_mode = try(each.value.database_insights_mode, var.defaults.database_insights_mode, null)
27+
db_instance_tags = try(each.value.db_instance_tags, var.defaults.db_instance_tags, {})
28+
db_name = try(each.value.db_name, var.defaults.db_name, null)
29+
db_subnet_group_name = try(each.value.db_subnet_group_name, var.defaults.db_subnet_group_name, null)
30+
dedicated_log_volume = try(each.value.dedicated_log_volume, var.defaults.dedicated_log_volume, false)
31+
delete_automated_backups = try(each.value.delete_automated_backups, var.defaults.delete_automated_backups, true)
32+
deletion_protection = try(each.value.deletion_protection, var.defaults.deletion_protection, false)
33+
domain = try(each.value.domain, var.defaults.domain, null)
34+
domain_auth_secret_arn = try(each.value.domain_auth_secret_arn, var.defaults.domain_auth_secret_arn, null)
35+
domain_dns_ips = try(each.value.domain_dns_ips, var.defaults.domain_dns_ips, null)
36+
domain_fqdn = try(each.value.domain_fqdn, var.defaults.domain_fqdn, null)
37+
domain_iam_role_name = try(each.value.domain_iam_role_name, var.defaults.domain_iam_role_name, null)
38+
domain_ou = try(each.value.domain_ou, var.defaults.domain_ou, null)
39+
enabled_cloudwatch_logs_exports = try(each.value.enabled_cloudwatch_logs_exports, var.defaults.enabled_cloudwatch_logs_exports, [])
40+
engine = try(each.value.engine, var.defaults.engine, null)
41+
engine_lifecycle_support = try(each.value.engine_lifecycle_support, var.defaults.engine_lifecycle_support, null)
42+
engine_version = try(each.value.engine_version, var.defaults.engine_version, null)
43+
final_snapshot_identifier_prefix = try(each.value.final_snapshot_identifier_prefix, var.defaults.final_snapshot_identifier_prefix, "final")
44+
iam_database_authentication_enabled = try(each.value.iam_database_authentication_enabled, var.defaults.iam_database_authentication_enabled, false)
45+
identifier = try(each.value.identifier, var.defaults.identifier)
46+
instance_class = try(each.value.instance_class, var.defaults.instance_class, null)
47+
iops = try(each.value.iops, var.defaults.iops, null)
48+
kms_key_id = try(each.value.kms_key_id, var.defaults.kms_key_id, null)
49+
license_model = try(each.value.license_model, var.defaults.license_model, null)
50+
maintenance_window = try(each.value.maintenance_window, var.defaults.maintenance_window, null)
51+
manage_master_user_password = try(each.value.manage_master_user_password, var.defaults.manage_master_user_password, true)
52+
manage_master_user_password_rotation = try(each.value.manage_master_user_password_rotation, var.defaults.manage_master_user_password_rotation, false)
53+
master_user_password_rotate_immediately = try(each.value.master_user_password_rotate_immediately, var.defaults.master_user_password_rotate_immediately, null)
54+
master_user_password_rotation_automatically_after_days = try(each.value.master_user_password_rotation_automatically_after_days, var.defaults.master_user_password_rotation_automatically_after_days, null)
55+
master_user_password_rotation_duration = try(each.value.master_user_password_rotation_duration, var.defaults.master_user_password_rotation_duration, null)
56+
master_user_password_rotation_schedule_expression = try(each.value.master_user_password_rotation_schedule_expression, var.defaults.master_user_password_rotation_schedule_expression, null)
57+
master_user_secret_kms_key_id = try(each.value.master_user_secret_kms_key_id, var.defaults.master_user_secret_kms_key_id, null)
58+
max_allocated_storage = try(each.value.max_allocated_storage, var.defaults.max_allocated_storage, 0)
59+
monitoring_interval = try(each.value.monitoring_interval, var.defaults.monitoring_interval, 0)
60+
monitoring_role_arn = try(each.value.monitoring_role_arn, var.defaults.monitoring_role_arn, null)
61+
monitoring_role_description = try(each.value.monitoring_role_description, var.defaults.monitoring_role_description, null)
62+
monitoring_role_name = try(each.value.monitoring_role_name, var.defaults.monitoring_role_name, "rds-monitoring-role")
63+
monitoring_role_permissions_boundary = try(each.value.monitoring_role_permissions_boundary, var.defaults.monitoring_role_permissions_boundary, null)
64+
monitoring_role_use_name_prefix = try(each.value.monitoring_role_use_name_prefix, var.defaults.monitoring_role_use_name_prefix, false)
65+
multi_az = try(each.value.multi_az, var.defaults.multi_az, false)
66+
nchar_character_set_name = try(each.value.nchar_character_set_name, var.defaults.nchar_character_set_name, null)
67+
network_type = try(each.value.network_type, var.defaults.network_type, null)
68+
option_group_name = try(each.value.option_group_name, var.defaults.option_group_name, null)
69+
parameter_group_name = try(each.value.parameter_group_name, var.defaults.parameter_group_name, null)
70+
password = try(each.value.password, var.defaults.password, null)
71+
performance_insights_enabled = try(each.value.performance_insights_enabled, var.defaults.performance_insights_enabled, false)
72+
performance_insights_kms_key_id = try(each.value.performance_insights_kms_key_id, var.defaults.performance_insights_kms_key_id, null)
73+
performance_insights_retention_period = try(each.value.performance_insights_retention_period, var.defaults.performance_insights_retention_period, 7)
74+
port = try(each.value.port, var.defaults.port, null)
75+
publicly_accessible = try(each.value.publicly_accessible, var.defaults.publicly_accessible, false)
76+
replica_mode = try(each.value.replica_mode, var.defaults.replica_mode, null)
77+
replicate_source_db = try(each.value.replicate_source_db, var.defaults.replicate_source_db, null)
78+
restore_to_point_in_time = try(each.value.restore_to_point_in_time, var.defaults.restore_to_point_in_time, null)
79+
s3_import = try(each.value.s3_import, var.defaults.s3_import, null)
80+
skip_final_snapshot = try(each.value.skip_final_snapshot, var.defaults.skip_final_snapshot, false)
81+
snapshot_identifier = try(each.value.snapshot_identifier, var.defaults.snapshot_identifier, null)
82+
storage_encrypted = try(each.value.storage_encrypted, var.defaults.storage_encrypted, true)
83+
storage_throughput = try(each.value.storage_throughput, var.defaults.storage_throughput, null)
84+
storage_type = try(each.value.storage_type, var.defaults.storage_type, null)
85+
tags = try(each.value.tags, var.defaults.tags, {})
86+
timeouts = try(each.value.timeouts, var.defaults.timeouts, {})
87+
timezone = try(each.value.timezone, var.defaults.timezone, null)
88+
upgrade_storage_config = try(each.value.upgrade_storage_config, var.defaults.upgrade_storage_config, null)
89+
use_identifier_prefix = try(each.value.use_identifier_prefix, var.defaults.use_identifier_prefix, false)
90+
username = try(each.value.username, var.defaults.username, null)
91+
vpc_security_group_ids = try(each.value.vpc_security_group_ids, var.defaults.vpc_security_group_ids, [])
92+
}

wrappers/db_instance/outputs.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
output "wrapper" {
2+
description = "Map of outputs of a wrapper."
3+
value = module.wrapper
4+
sensitive = true # At least one sensitive module output (db_instance_username) found (requires Terraform 0.14+)
5+
}

wrappers/db_instance/variables.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
variable "defaults" {
2+
description = "Map of default values which will be used for each item."
3+
type = any
4+
default = {}
5+
}
6+
7+
variable "items" {
8+
description = "Maps of items to create a wrapper from. Values are passed through to the module."
9+
type = any
10+
default = {}
11+
}

wrappers/db_instance/versions.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 5.92"
8+
}
9+
10+
random = {
11+
source = "hashicorp/random"
12+
version = ">= 3.1"
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)