Having a hard time trying to make this work.
I'm trying to use the generate block to add a for_each and run the module multiple times depending on how much entries I have in the variable s3, but having lots of trouble making it right.
This are the important parts of the terragrunt.hcl file
locals {
s3 = {
"companies-data-service" = {
enable_cloudfront = true
cloudfront_allowed_paths = ["logos/*"]
cors_rules = {
"local" = {
methods = ["POST", "HEAD", "PUT", "GET"]
origins = ["http://localhost:*", "https://*.test.io"]
}
}
}
}
}
generate "cdn" {
path = "cdn.tf"
if_exists = "overwrite"
contents = <<EOF
module "cdn" {
source = "git::git@github.com:my-org/terraform-modules.git//s3?ref=v0.0.21"
for_each = { for $${k}, $${v} in "${local.s3}" : $${k} => $${v} }
name = "${local.s3}" != {} ? $${each.value} : ""
environment = "${local.parent.inputs.core_env_name}"
cors_rules = try($${each.value.cors_rules}, {})
enable_cloudfront = try($${each.value.enable_cloudfront}, false)
enable_versioning = try($${each.value.enable_versioning}, false)
cloudfront_allowed_paths = try($${each.value.cloudfront_allowed_paths}, [])
acm_certificate_arn = "${dependency.acm.outputs.acm_certificate_arn}"
aliases = ["$${each.key}-static.test.com"]
enable_lifecycle_rules = try($${each.value.enable_lifecycle_rules}, false)
s3_lifecycle_rules = try($${each.value.lifecycle_rules}, [])
bucket_policies = try($${each.value.bucket_policies}, {})
}
EOF
}
Having these errors
local.s3 as object with 1 attribute "companies-data-service"
ERRO[0010] .
ERRO[0010] Cannot include the given value in a string template: string required.
ERRO[0010] Error: Invalid template interpolation value
Also tried the local.s3 variable like this:
s3 = {
companies = {
name = "companies"
enable_cloudfront = true
cloudfront_allowed_paths = ["logos/*"]
cors_rules = {
"local" = {
methods = ["POST", "HEAD", "PUT", "GET"]
origins = ["http://localhost:*", "https://*.test.io"]
}
}
},
companies2 = {
name = "companies-2"
enable_cloudfront = true
cloudfront_allowed_paths = ["logos/*"]
cors_rules = {
"local" = {
methods = ["POST", "HEAD", "PUT", "GET"]
origins = ["http://localhost:*", "https://*.test.io"]
}
}
}
}
And block generate like this:
generate "cdn" {
path = "cdn.tf"
if_exists = "overwrite"
contents = <<EOF
module "cdn" {
source = "git::git@github.com:my-org/terraform-modules.git//s3?ref=v0.0.21"
for_each = "${local.s3}"
name = $${each.value.name}
environment = "${local.parent.inputs.core_env_name}"
cors_rules = try($${each.value.cors_rules}, {})
enable_cloudfront = try($${each.value.enable_cloudfront}, false)
enable_versioning = try($${each.value.enable_versioning}, false)
cloudfront_allowed_paths = try($${each.value.cloudfront_allowed_paths}, [])
acm_certificate_arn = "${dependency.acm.outputs.acm_certificate_arn}"
aliases = ["$${each.value.name}-static.test.com"]
enable_lifecycle_rules = try($${each.value.enable_lifecycle_rules}, false)
s3_lifecycle_rules = try($${each.value.lifecycle_rules}, [])
bucket_policies = try($${each.value.bucket_policies}, {})
}
EOF
}
To validate my changes I tried to pass the locals inside the generate block like pure terraform code, that way it works.
generate "cdn" {
path = "cdn.tf"
if_exists = "overwrite"
contents = <<EOF
locals {
s3 = {
companies = {
name = "companies"
enable_cloudfront = true
cloudfront_allowed_paths = ["logos/*"]
cors_rules = {
"local" = {
methods = ["POST", "HEAD", "PUT", "GET"]
origins = ["http://localhost:*", "https://*.test.io"]
}
}
},
companies2 = {
name = "companies-2"
enable_cloudfront = true
cloudfront_allowed_paths = ["logos/*"]
cors_rules = {
"local" = {
methods = ["POST", "HEAD", "PUT", "GET"]
origins = ["http://localhost:*", "https://*.test.io"]
}
}
}
}
}
module "cdn" {
source = "git::git@github.com:my-org/terraform-modules.git//s3?ref=v0.0.21"
for_each = local.s3
name = each.value.name
environment = "${local.parent.inputs.core_env_name}"
cors_rules = try(each.value.cors_rules, {})
enable_cloudfront = try(each.value.enable_cloudfront, false)
enable_versioning = try(each.value.enable_versioning, false)
cloudfront_allowed_paths = try(each.value.cloudfront_allowed_paths, [])
acm_certificate_arn = "${dependency.acm.outputs.acm_certificate_arn}"
aliases = ["$${each.value.name}-static.test.com"]
enable_lifecycle_rules = try(each.value.enable_lifecycle_rules, false)
s3_lifecycle_rules = try(each.value.lifecycle_rules, [])
bucket_policies = try(each.value.bucket_policies, {})
}
EOF
}
```
So the issue is clearly with how terragrunt is passing the variable to the generate block, but I don't what is happening because terragrunt don't output anything I can use to debug that variable.
Any help will be much appreciated
This is a terragrunt file, therefore locals
is consumed inside terragrunt, and you cannot pass it to terraform. Terragrunt only generates the tf files and execute the terraform command. you need to pass the locals
to terraform and you can use
inputs = {
s3 = local.s3
}
generate "vars" {
path = "vars.tf"
if_exists = "overwrite"
contents = <<EOF
variable "s3" {
type = object({})
}
EOF
}
and then the cdn
block can be written in
generate "cdn" {
path = "cdn.tf"
if_exists = "overwrite"
contents = <<EOF
module "cdn" {
source = "git::git@github.com:my-org/terraform-modules.git//s3?ref=v0.0.21"
for_each = { for k, v in s3 : k => v }
name = s3 != {} ? each.value : ""
environment = "${local.parent.inputs.core_env_name}"
cors_rules = try(each.value.cors_rules, {})
enable_cloudfront = try(each.value.enable_cloudfront, false)
enable_versioning = try(each.value.enable_versioning, false)
cloudfront_allowed_paths = try(each.value.cloudfront_allowed_paths, [])
acm_certificate_arn = "${dependency.acm.outputs.acm_certificate_arn}"
aliases = ["$${each.key}-static.test.com"]
enable_lifecycle_rules = try(each.value.enable_lifecycle_rules, false)
s3_lifecycle_rules = try(each.value.lifecycle_rules, [])
bucket_policies = try(each.value.bucket_policies, {})
}
EOF
}
I have replaced "${dependency.acm.outputs.acm_certificate_arn}"
and "${local.parent.inputs.core_env_name}"
with static values (I didn't have the values) and source = "vancluever/module/null"
, and it worked.