Skip to content

Commit fe70a60

Browse files
committed
feat: Add Terragrunt wrapper support
1 parent d4323ea commit fe70a60

21 files changed

+579
-1
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ repos:
33
rev: v1.81.0
44
hooks:
55
- id: terraform_fmt
6-
- id: terraform_validate
6+
- id: terraform_wrapper_module_for_each
77
- id: terraform_docs
88
args:
99
- '--args=--lockfile=false'
@@ -22,6 +22,7 @@ repos:
2222
- '--args=--only=terraform_required_providers'
2323
- '--args=--only=terraform_standard_module_structure'
2424
- '--args=--only=terraform_workspace_remote'
25+
- id: terraform_validate
2526
- repo: https://github.com/pre-commit/pre-commit-hooks
2627
rev: v4.4.0
2728
hooks:

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/network-firewall/aws//wrappers"
16+
# Alternative source:
17+
# source = "git::git@github.com:terraform-aws-modules/terraform-aws-network-firewall.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/network-firewall/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::git@github.com: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/firewall/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/firewall`
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/network-firewall/aws//wrappers/firewall"
16+
# Alternative source:
17+
# source = "git::git@github.com:terraform-aws-modules/terraform-aws-network-firewall.git//wrappers/firewall?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/network-firewall/aws//wrappers/firewall"
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::git@github.com: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/firewall/main.tf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module "wrapper" {
2+
source = "../../modules/firewall"
3+
4+
for_each = var.items
5+
6+
create = try(each.value.create, var.defaults.create, true)
7+
tags = try(each.value.tags, var.defaults.tags, {})
8+
delete_protection = try(each.value.delete_protection, var.defaults.delete_protection, true)
9+
description = try(each.value.description, var.defaults.description, "")
10+
encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, {})
11+
firewall_policy_arn = try(each.value.firewall_policy_arn, var.defaults.firewall_policy_arn, "")
12+
firewall_policy_change_protection = try(each.value.firewall_policy_change_protection, var.defaults.firewall_policy_change_protection, null)
13+
name = try(each.value.name, var.defaults.name, "")
14+
subnet_change_protection = try(each.value.subnet_change_protection, var.defaults.subnet_change_protection, true)
15+
subnet_mapping = try(each.value.subnet_mapping, var.defaults.subnet_mapping, {})
16+
vpc_id = try(each.value.vpc_id, var.defaults.vpc_id, "")
17+
create_logging_configuration = try(each.value.create_logging_configuration, var.defaults.create_logging_configuration, false)
18+
logging_configuration_destination_config = try(each.value.logging_configuration_destination_config, var.defaults.logging_configuration_destination_config, [])
19+
}

wrappers/firewall/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 = false # No sensitive module output found
5+
}

wrappers/firewall/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/firewall/versions.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
terraform {
2+
required_version = ">= 0.13.1"
3+
}

wrappers/main.tf

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module "wrapper" {
2+
source = "../"
3+
4+
for_each = var.items
5+
6+
create = try(each.value.create, var.defaults.create, true)
7+
tags = try(each.value.tags, var.defaults.tags, {})
8+
delete_protection = try(each.value.delete_protection, var.defaults.delete_protection, true)
9+
description = try(each.value.description, var.defaults.description, "")
10+
encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, {})
11+
firewall_policy_arn = try(each.value.firewall_policy_arn, var.defaults.firewall_policy_arn, "")
12+
firewall_policy_change_protection = try(each.value.firewall_policy_change_protection, var.defaults.firewall_policy_change_protection, null)
13+
name = try(each.value.name, var.defaults.name, "")
14+
subnet_change_protection = try(each.value.subnet_change_protection, var.defaults.subnet_change_protection, true)
15+
subnet_mapping = try(each.value.subnet_mapping, var.defaults.subnet_mapping, {})
16+
vpc_id = try(each.value.vpc_id, var.defaults.vpc_id, "")
17+
create_logging_configuration = try(each.value.create_logging_configuration, var.defaults.create_logging_configuration, false)
18+
logging_configuration_destination_config = try(each.value.logging_configuration_destination_config, var.defaults.logging_configuration_destination_config, [])
19+
create_policy = try(each.value.create_policy, var.defaults.create_policy, true)
20+
policy_description = try(each.value.policy_description, var.defaults.policy_description, null)
21+
policy_encryption_configuration = try(each.value.policy_encryption_configuration, var.defaults.policy_encryption_configuration, {})
22+
policy_stateful_default_actions = try(each.value.policy_stateful_default_actions, var.defaults.policy_stateful_default_actions, [])
23+
policy_stateful_engine_options = try(each.value.policy_stateful_engine_options, var.defaults.policy_stateful_engine_options, {})
24+
policy_stateful_rule_group_reference = try(each.value.policy_stateful_rule_group_reference, var.defaults.policy_stateful_rule_group_reference, {})
25+
policy_stateless_custom_action = try(each.value.policy_stateless_custom_action, var.defaults.policy_stateless_custom_action, {})
26+
policy_stateless_default_actions = try(each.value.policy_stateless_default_actions, var.defaults.policy_stateless_default_actions, ["aws:pass"])
27+
policy_stateless_fragment_default_actions = try(each.value.policy_stateless_fragment_default_actions, var.defaults.policy_stateless_fragment_default_actions, ["aws:pass"])
28+
policy_stateless_rule_group_reference = try(each.value.policy_stateless_rule_group_reference, var.defaults.policy_stateless_rule_group_reference, {})
29+
policy_name = try(each.value.policy_name, var.defaults.policy_name, "")
30+
policy_tags = try(each.value.policy_tags, var.defaults.policy_tags, {})
31+
create_policy_resource_policy = try(each.value.create_policy_resource_policy, var.defaults.create_policy_resource_policy, false)
32+
policy_resource_policy_actions = try(each.value.policy_resource_policy_actions, var.defaults.policy_resource_policy_actions, [])
33+
policy_resource_policy_principals = try(each.value.policy_resource_policy_principals, var.defaults.policy_resource_policy_principals, [])
34+
policy_attach_resource_policy = try(each.value.policy_attach_resource_policy, var.defaults.policy_attach_resource_policy, false)
35+
policy_resource_policy = try(each.value.policy_resource_policy, var.defaults.policy_resource_policy, "")
36+
policy_ram_resource_associations = try(each.value.policy_ram_resource_associations, var.defaults.policy_ram_resource_associations, {})
37+
}

wrappers/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 = false # No sensitive module output found
5+
}

0 commit comments

Comments
 (0)