Error decoding JSON: json: cannot unmarshal bool into Go struct field of type string
Hello!
The mesh-task submodule intakes a variable called log_configuration, to customize/configure logs for an ECS task built by this module. The variable is added to the merged container_definitions object for the generated ecs_task_definition resource.
Variable definition: https://github.com/hashicorp/terraform-aws-consul-ecs/blob/354c2157db4144ce254218025da5bb88edf66f00/modules/mesh-task/variables.tf#L120-L124
Appended value: https://github.com/hashicorp/terraform-aws-consul-ecs/blob/354c2157db4144ce254218025da5bb88edf66f00/modules/mesh-task/main.tf#L189
The AWS Developer guide includes an options block for logConfiguration that includes a setting for awslogs-create-group with values of true/false, to determine whether the task definition creates the Cloudwatch logs group, or references the defined values instead. Snippet below:
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html
"options": {
"awslogs-group": "firelens-container",
"awslogs-region": "us-west-2",
"awslogs-create-group": "true",
"awslogs-stream-prefix": "firelens"
In my code, I have created a mesh-task:
variable "awslogs_create_group" {
type = bool
default = true
}
# Object to add to log_configuration's "options" sub-block.
locals {
logs_options = {
. . .
awslogs-create-group = var.awslogs_create_group
. . .
}
}
module "mesh_task" {
. . .
log_configuration = {
logDriver = "awslogs"
options = local.logs_options
}
. . .
}
This module invocation returns a go struct error during terraform plan
Error: ECS Task Definition container_definitions is invalid: Error decoding JSON: json: cannot unmarshal bool into Go struct field LogConfiguration.LogConfiguration.Options of type string
│ with module..module.mesh_task["task"].aws_ecs_task_definition.this,
│ on .terraform/modules//modules/mesh-task/main.tf line 180, in resource "aws_ecs_task_definition" "this":
│ 180: container_definitions = jsonencode(
│ 181: flatten(
│ 182: concat(
│ 183: local.container_defs_with_depends_on,
│ 184: [
. . .
│ 220: logConfiguration = var.log_configuration
Changing awslogs-create-group's value from bool(true), to string(true) (Or, true -> "true") fixes this error to let the task definition create the cloudwatch group.
Looking at the log_configuration declaration, it seems like there isn't type checking or validation on the variable. There are validations for other variables: For example, the upstreams variable in variables.tf
Could it make sense to create an object definition for log_configuration, with a validation? Example below (Note: This is a rough suggestion, using existing validations in the module as reference)
variable "log_configuration" {
type = object({
logDriver = string
options = object({
awslogs-group = string
awslogs-region = string
awslogs-stream-prefix = string
awslogs-create-group = string
})
})
validation {
error_message = "awslogs-create-group must be a string 'true'"
condition = allfalse(flatten([
for log_var in var.log_configuration : [
type(can(lookup(log_var.options, "awslogs-create-group"), string))
]
]))
}
}
I couldn't find information on the available task definition values to configure in the mesh-task module, and relied on the ecs_task_definition resource, and this module's variables file to understand how to build the ECS task definition. Since some of the larger variables (log_configuration, container_definitions, volumes) are set to a type of any, it required some context switching to fully understand what was needed to get the mesh-task created, in addition to this specific error.
Thank you! 😺
i am also facing the same issue can anyone help here ? @webdog Did you get any solution yet ?
Hi @sumitpurandare, the fix would need to come from the repository maintainers. As far as I can tell, the work isn't prioritized. My suggestion would be to fork the repository and run the module from your fork, in order to add the object validations I recommended. Hope this helps!