1

I am creating some AWS Config rules using Terraform version 0.14.5. I am defining the resources using the for_each method shown below. I am getting an error stating my JSON is invalid. I have used tools such as JSONlint to validate my JSON, but I am still facing this issue. Below is how I defined my resource, variable, potential output, and error I am facing. Any insight would be helpful.

Resource

resource "aws_config_config_rule" "managed_rules" {
  for_each         = var.managed_rules
  name             = each.value.name
  description      = each.value.description
  input_parameters = jsonencode(each.value.input_parameters)

  source {
    owner             = each.value.owner
    source_identifier = each.value.source_identifier
  }

  depends_on = [aws_config_configuration_recorder.config_recorder]
}

Variable

variable "managed_rules" {


type = map(object({
    name              = string
    description       = string
    owner             = string
    source_identifier = string
    input_parameters  = string
  }))
  default = {
    "1" = {
      name              = "account-part-of-organizations"
      description       = "Rule checks whether AWS account is part of AWS Organizations. The rule is NON_COMPLIANT if the AWS account is not part of AWS Organizations or AWS Organizations master account ID does not match rule parameter MasterAccountId."
      owner             = "AWS"
      source_identifier = "ACCOUNT_PART_OF_ORGANIZATIONS"
      input_parameters  = <<EOL
      {
        "MaximumExecutionFrequency": "TwentyFour_Hours"
      }
EOL
    }
  }
}

Potential output

Terraform will perform the following actions:

# aws_config_config_rule.managed_rules["1"] will be updated in-place
  ~ resource "aws_config_config_rule" "managed_rules" {
        id               = "account-part-of-organizations"
      + input_parameters = "\"      {\\n        \\\"MaximumExecutionFrequency\\\": \\\"TwentyFour_Hours\\\"\\n      }\\n\""
        name             = "account-part-of-organizations"
        tags             = {}
        # (4 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

Error

Error: Error creating AWSConfig rule: Failed to create AWSConfig rule: 
InvalidParameterValueException: Invalid json "      {\n        \"MaximumExecutionFrequency\": \"TwentyFour_Hours\"\n      }\n" passed in the inputParameters field.
Dave Michaels
  • 847
  • 1
  • 19
  • 51

1 Answers1

1

In your managed_rules variable, the input_parameters attribute is a string. When you jsonencode the input_parameters attribute of the aws_config_config_rule resource, you are encoding a value that is already a string.

I was able to resolve the issue by changing your managed_rules variable to the following:

variable "managed_rules" {


  type = map(object({
    name              = string
    description       = string
    owner             = string
    source_identifier = string
    input_parameters  = map(any)
  }))
  default = {
    "1" = {
      name              = "account-part-of-organizations"
      description       = "Rule checks whether AWS account is part of AWS Organizations. The rule is NON_COMPLIANT if the AWS account is not part of AWS Organizations or AWS Organizations master account ID does not match rule parameter MasterAccountId."
      owner             = "AWS"
      source_identifier = "ACCOUNT_PART_OF_ORGANIZATIONS"
      input_parameters = {
        "MaximumExecutionFrequency" : "TwentyFour_Hours"
      }
    }
  }
}

Notice that I changed the type of input_parameters from string to map(any).

Now when you invoke jsonencode on the input_parameters attribute of the the aws_config_config_rule resource, it will encode the map of strings to a JSON-encoded string.

jasonwalsh
  • 756
  • 5
  • 9
  • Note that the `map(string)` type will only work for a single-level maps, i.e. you can't pass anything complex into it (or any value types other than `string`, such as `number`). `map(any)` might work better. – Jordan Jul 15 '21 at 22:06
  • Thanks @Jordan. Updated my answer to use `map(any)`. – jasonwalsh Jul 15 '21 at 22:09