Skip to content

Commit

Permalink
feat: Added wrappers for for_each/terragrunt (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
antonbabenko authored Aug 10, 2023
1 parent 50764f3 commit 99c1108
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.80.0
rev: v1.81.2
hooks:
- id: terraform_fmt
- id: terraform_wrapper_module_for_each
- id: terraform_validate
- id: terraform_docs
args:
Expand Down
100 changes: 100 additions & 0 deletions wrappers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Wrapper for the root module

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).

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.

This wrapper does not implement any extra functionality.

## Usage with Terragrunt

`terragrunt.hcl`:

```hcl
terraform {
source = "tfr:///terraform-aws-modules/appsync/aws//wrappers"
# Alternative source:
# source = "git::git@github.com:terraform-aws-modules/terraform-aws-appsync.git//wrappers?ref=master"
}
inputs = {
defaults = { # Default values
create = true
tags = {
Terraform = "true"
Environment = "dev"
}
}
items = {
my-item = {
# omitted... can be any argument supported by the module
}
my-second-item = {
# omitted... can be any argument supported by the module
}
# omitted...
}
}
```

## Usage with Terraform

```hcl
module "wrapper" {
source = "terraform-aws-modules/appsync/aws//wrappers"
defaults = { # Default values
create = true
tags = {
Terraform = "true"
Environment = "dev"
}
}
items = {
my-item = {
# omitted... can be any argument supported by the module
}
my-second-item = {
# omitted... can be any argument supported by the module
}
# omitted...
}
}
```

## Example: Manage multiple S3 buckets in one Terragrunt layer

`eu-west-1/s3-buckets/terragrunt.hcl`:

```hcl
terraform {
source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers"
# Alternative source:
# source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git//wrappers?ref=master"
}
inputs = {
defaults = {
force_destroy = true
attach_elb_log_delivery_policy = true
attach_lb_log_delivery_policy = true
attach_deny_insecure_transport_policy = true
attach_require_latest_tls_policy = true
}
items = {
bucket1 = {
bucket = "my-random-bucket-1"
}
bucket2 = {
bucket = "my-random-bucket-2"
tags = {
Secure = "probably"
}
}
}
}
```
70 changes: 70 additions & 0 deletions wrappers/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
module "wrapper" {
source = "../"

for_each = var.items

create_graphql_api = try(each.value.create_graphql_api, var.defaults.create_graphql_api, true)
logging_enabled = try(each.value.logging_enabled, var.defaults.logging_enabled, false)
domain_name_association_enabled = try(each.value.domain_name_association_enabled, var.defaults.domain_name_association_enabled, false)
caching_enabled = try(each.value.caching_enabled, var.defaults.caching_enabled, false)
xray_enabled = try(each.value.xray_enabled, var.defaults.xray_enabled, false)
name = try(each.value.name, var.defaults.name, "")
schema = try(each.value.schema, var.defaults.schema, "")
visibility = try(each.value.visibility, var.defaults.visibility, null)
authentication_type = try(each.value.authentication_type, var.defaults.authentication_type, "API_KEY")
create_logs_role = try(each.value.create_logs_role, var.defaults.create_logs_role, true)
logs_role_name = try(each.value.logs_role_name, var.defaults.logs_role_name, null)
log_cloudwatch_logs_role_arn = try(each.value.log_cloudwatch_logs_role_arn, var.defaults.log_cloudwatch_logs_role_arn, null)
log_field_log_level = try(each.value.log_field_log_level, var.defaults.log_field_log_level, null)
log_exclude_verbose_content = try(each.value.log_exclude_verbose_content, var.defaults.log_exclude_verbose_content, false)
lambda_authorizer_config = try(each.value.lambda_authorizer_config, var.defaults.lambda_authorizer_config, {})
openid_connect_config = try(each.value.openid_connect_config, var.defaults.openid_connect_config, {})
user_pool_config = try(each.value.user_pool_config, var.defaults.user_pool_config, {})
additional_authentication_provider = try(each.value.additional_authentication_provider, var.defaults.additional_authentication_provider, {})
graphql_api_tags = try(each.value.graphql_api_tags, var.defaults.graphql_api_tags, {})
logs_role_tags = try(each.value.logs_role_tags, var.defaults.logs_role_tags, {})
tags = try(each.value.tags, var.defaults.tags, {})
domain_name = try(each.value.domain_name, var.defaults.domain_name, "")
domain_name_description = try(each.value.domain_name_description, var.defaults.domain_name_description, null)
certificate_arn = try(each.value.certificate_arn, var.defaults.certificate_arn, "")
caching_behavior = try(each.value.caching_behavior, var.defaults.caching_behavior, "FULL_REQUEST_CACHING")
cache_type = try(each.value.cache_type, var.defaults.cache_type, "SMALL")
cache_ttl = try(each.value.cache_ttl, var.defaults.cache_ttl, 1)
cache_at_rest_encryption_enabled = try(each.value.cache_at_rest_encryption_enabled, var.defaults.cache_at_rest_encryption_enabled, false)
cache_transit_encryption_enabled = try(each.value.cache_transit_encryption_enabled, var.defaults.cache_transit_encryption_enabled, false)
api_keys = try(each.value.api_keys, var.defaults.api_keys, {})
lambda_allowed_actions = try(each.value.lambda_allowed_actions, var.defaults.lambda_allowed_actions, ["lambda:invokeFunction"])
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"])
elasticsearch_allowed_actions = try(each.value.elasticsearch_allowed_actions, var.defaults.elasticsearch_allowed_actions, ["es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut"])
iam_permissions_boundary = try(each.value.iam_permissions_boundary, var.defaults.iam_permissions_boundary, null)
direct_lambda_request_template = try(each.value.direct_lambda_request_template, var.defaults.direct_lambda_request_template, <<-EOF
{
"version" : "2017-02-28",
"operation": "Invoke",
"payload": {
"arguments": $util.toJson($ctx.arguments),
"identity": $util.toJson($ctx.identity),
"source": $util.toJson($ctx.source),
"request": $util.toJson($ctx.request),
"prev": $util.toJson($ctx.prev),
"info": {
"selectionSetList": $util.toJson($ctx.info.selectionSetList),
"selectionSetGraphQL": $util.toJson($ctx.info.selectionSetGraphQL),
"parentTypeName": $util.toJson($ctx.info.parentTypeName),
"fieldName": $util.toJson($ctx.info.fieldName),
"variables": $util.toJson($ctx.info.variables)
},
"stash": $util.toJson($ctx.stash)
}
}
EOF
)
direct_lambda_response_template = try(each.value.direct_lambda_response_template, var.defaults.direct_lambda_response_template, <<-EOF
$util.toJson($ctx.result)
EOF
)
resolver_caching_ttl = try(each.value.resolver_caching_ttl, var.defaults.resolver_caching_ttl, 60)
datasources = try(each.value.datasources, var.defaults.datasources, {})
resolvers = try(each.value.resolvers, var.defaults.resolvers, {})
functions = try(each.value.functions, var.defaults.functions, {})
}
5 changes: 5 additions & 0 deletions wrappers/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
output "wrapper" {
description = "Map of outputs of a wrapper."
value = module.wrapper
sensitive = true # At least one sensitive module output (appsync_api_key_key) found (requires Terraform 0.14+)
}
11 changes: 11 additions & 0 deletions wrappers/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
variable "defaults" {
description = "Map of default values which will be used for each item."
type = any
default = {}
}

variable "items" {
description = "Maps of items to create a wrapper from. Values are passed through to the module."
type = any
default = {}
}
3 changes: 3 additions & 0 deletions wrappers/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
terraform {
required_version = ">= 0.13.1"
}

0 comments on commit 99c1108

Please sign in to comment.