Skip to content

Commit 99c1108

Browse files
authored
feat: Added wrappers for for_each/terragrunt (#53)
1 parent 50764f3 commit 99c1108

File tree

6 files changed

+191
-1
lines changed

6 files changed

+191
-1
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
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.80.0
3+
rev: v1.81.2
44
hooks:
55
- id: terraform_fmt
6+
- id: terraform_wrapper_module_for_each
67
- id: terraform_validate
78
- id: terraform_docs
89
args:

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/appsync/aws//wrappers"
16+
# Alternative source:
17+
# source = "git::[email protected]:terraform-aws-modules/terraform-aws-appsync.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/appsync/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/main.tf

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
module "wrapper" {
2+
source = "../"
3+
4+
for_each = var.items
5+
6+
create_graphql_api = try(each.value.create_graphql_api, var.defaults.create_graphql_api, true)
7+
logging_enabled = try(each.value.logging_enabled, var.defaults.logging_enabled, false)
8+
domain_name_association_enabled = try(each.value.domain_name_association_enabled, var.defaults.domain_name_association_enabled, false)
9+
caching_enabled = try(each.value.caching_enabled, var.defaults.caching_enabled, false)
10+
xray_enabled = try(each.value.xray_enabled, var.defaults.xray_enabled, false)
11+
name = try(each.value.name, var.defaults.name, "")
12+
schema = try(each.value.schema, var.defaults.schema, "")
13+
visibility = try(each.value.visibility, var.defaults.visibility, null)
14+
authentication_type = try(each.value.authentication_type, var.defaults.authentication_type, "API_KEY")
15+
create_logs_role = try(each.value.create_logs_role, var.defaults.create_logs_role, true)
16+
logs_role_name = try(each.value.logs_role_name, var.defaults.logs_role_name, null)
17+
log_cloudwatch_logs_role_arn = try(each.value.log_cloudwatch_logs_role_arn, var.defaults.log_cloudwatch_logs_role_arn, null)
18+
log_field_log_level = try(each.value.log_field_log_level, var.defaults.log_field_log_level, null)
19+
log_exclude_verbose_content = try(each.value.log_exclude_verbose_content, var.defaults.log_exclude_verbose_content, false)
20+
lambda_authorizer_config = try(each.value.lambda_authorizer_config, var.defaults.lambda_authorizer_config, {})
21+
openid_connect_config = try(each.value.openid_connect_config, var.defaults.openid_connect_config, {})
22+
user_pool_config = try(each.value.user_pool_config, var.defaults.user_pool_config, {})
23+
additional_authentication_provider = try(each.value.additional_authentication_provider, var.defaults.additional_authentication_provider, {})
24+
graphql_api_tags = try(each.value.graphql_api_tags, var.defaults.graphql_api_tags, {})
25+
logs_role_tags = try(each.value.logs_role_tags, var.defaults.logs_role_tags, {})
26+
tags = try(each.value.tags, var.defaults.tags, {})
27+
domain_name = try(each.value.domain_name, var.defaults.domain_name, "")
28+
domain_name_description = try(each.value.domain_name_description, var.defaults.domain_name_description, null)
29+
certificate_arn = try(each.value.certificate_arn, var.defaults.certificate_arn, "")
30+
caching_behavior = try(each.value.caching_behavior, var.defaults.caching_behavior, "FULL_REQUEST_CACHING")
31+
cache_type = try(each.value.cache_type, var.defaults.cache_type, "SMALL")
32+
cache_ttl = try(each.value.cache_ttl, var.defaults.cache_ttl, 1)
33+
cache_at_rest_encryption_enabled = try(each.value.cache_at_rest_encryption_enabled, var.defaults.cache_at_rest_encryption_enabled, false)
34+
cache_transit_encryption_enabled = try(each.value.cache_transit_encryption_enabled, var.defaults.cache_transit_encryption_enabled, false)
35+
api_keys = try(each.value.api_keys, var.defaults.api_keys, {})
36+
lambda_allowed_actions = try(each.value.lambda_allowed_actions, var.defaults.lambda_allowed_actions, ["lambda:invokeFunction"])
37+
dynamodb_allowed_actions = try(each.value.dynamodb_allowed_actions, var.defaults.dynamodb_allowed_actions, ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:DeleteItem", "dynamodb:UpdateItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem"])
38+
elasticsearch_allowed_actions = try(each.value.elasticsearch_allowed_actions, var.defaults.elasticsearch_allowed_actions, ["es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut"])
39+
iam_permissions_boundary = try(each.value.iam_permissions_boundary, var.defaults.iam_permissions_boundary, null)
40+
direct_lambda_request_template = try(each.value.direct_lambda_request_template, var.defaults.direct_lambda_request_template, <<-EOF
41+
{
42+
"version" : "2017-02-28",
43+
"operation": "Invoke",
44+
"payload": {
45+
"arguments": $util.toJson($ctx.arguments),
46+
"identity": $util.toJson($ctx.identity),
47+
"source": $util.toJson($ctx.source),
48+
"request": $util.toJson($ctx.request),
49+
"prev": $util.toJson($ctx.prev),
50+
"info": {
51+
"selectionSetList": $util.toJson($ctx.info.selectionSetList),
52+
"selectionSetGraphQL": $util.toJson($ctx.info.selectionSetGraphQL),
53+
"parentTypeName": $util.toJson($ctx.info.parentTypeName),
54+
"fieldName": $util.toJson($ctx.info.fieldName),
55+
"variables": $util.toJson($ctx.info.variables)
56+
},
57+
"stash": $util.toJson($ctx.stash)
58+
}
59+
}
60+
EOF
61+
)
62+
direct_lambda_response_template = try(each.value.direct_lambda_response_template, var.defaults.direct_lambda_response_template, <<-EOF
63+
$util.toJson($ctx.result)
64+
EOF
65+
)
66+
resolver_caching_ttl = try(each.value.resolver_caching_ttl, var.defaults.resolver_caching_ttl, 60)
67+
datasources = try(each.value.datasources, var.defaults.datasources, {})
68+
resolvers = try(each.value.resolvers, var.defaults.resolvers, {})
69+
functions = try(each.value.functions, var.defaults.functions, {})
70+
}

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 = true # At least one sensitive module output (appsync_api_key_key) found (requires Terraform 0.14+)
5+
}

wrappers/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/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+
}

0 commit comments

Comments
 (0)