LaVOZs

The World’s Largest Online Community for Developers

'; amazon web services - How do I resolve the error: "Argument names must not be quoted" in Terraform? - LavOzs.Com

I am running Terraform 0.12.24 locally

I am trying to deploy an API Gateway integration with Lambda

I am trying to enable AWS API GW CORS with Terraform.

I have the following resource for the OPTIONS method response:

resource "aws_api_gateway_method_response" "options_200" {
    rest_api_id   = aws_api_gateway_rest_api.scout-approve-api-gateway.id
    resource_id   = aws_api_gateway_resource.proxy.id
    http_method   = aws_api_gateway_method.options_method.http_method
    status_code   = "200"

    response_models {
      "application/json" = "Empty"
    }

    response_parameters {
        "method.response.header.Access-Control-Allow-Headers" = true,
        "method.response.header.Access-Control-Allow-Methods" = true,
        "method.response.header.Access-Control-Allow-Origin" = true
    }
    depends_on = [aws_api_gateway_method.options_method]
}

And I am getting:

Error: Invalid argument name

  on main.tf line 48, in resource "aws_api_gateway_method_response" "options_200":
  48:       "application/json" = "Empty"

Argument names must not be quoted.

What gives?

This is actually the parser misunderstanding where the error is. It is actually complaining that it's trying to read the response_models and response_parameters as blocks instead of attributes. There's further discussion of this in the 0.12 documentation.

The main difference between a map attribute and a nested block is that a map attribute will usually have user-defined keys, like we see in the tags example above, while a nested block always has a fixed set of supported arguments defined by the resource type schema, which Terraform will validate.

In 0.11 you could interchangeably get away with using the block syntax (just curly braces such as response_parameters { ... }) for attributes but in 0.12 it is stricter around types so this is no longer possible. The code in the Medium post you linked to as a working example is 0.11 code and isn't valid in 0.12. If you look closely at the GitHub code you also linked you can see that it uses the attribute syntax instead of the block syntax so is valid.

Switching to using the attribute syntax by adding an = will make this work as expected:

resource "aws_api_gateway_method_response" "options_200" {
  rest_api_id = aws_api_gateway_rest_api.scout-approve-api-gateway.id
  resource_id = aws_api_gateway_resource.proxy.id
  http_method = aws_api_gateway_method.options_method.http_method
  status_code = "200"

  response_models = {
    "application/json" = "Empty"
  }

  response_parameters = {
    "method.response.header.Access-Control-Allow-Headers" = true,
    "method.response.header.Access-Control-Allow-Methods" = true,
    "method.response.header.Access-Control-Allow-Origin"  = true
  }

  depends_on = [aws_api_gateway_method.options_method]
}
Related
Fail to enable CORS for API Gateway functions
CORS issue with AWS API Gateway
How to assign tags on an AWS API Gateway deployment stage using Terraform
AWS API Gateway Access-Control-Allow-Origin
Sharing resources between Terraform workspaces
AWS API Gateway and Lambda function deployed through terraform — Execution failed due to configuration error: Invalid permissions on Lambda function
Get endpoint from API Gateway for an AWS lambda in terraform
Error creating API Gateway Domain Name by terraform