skip to Main Content

I’m working on a terraform script which integrates API Gateway to DynamoDB using HTTPS/POST request. The basic objective is to insert the records that are passed in the API request body in the DynamoDB table.
I’m using aws_api_gateway_integration to define the integration and there I’m passing the request template which should include two attributes(BusinessUnitId and Frequency).My script looks like this –

resource aws_api_gateway_integration schedule_post_integration {
  rest_api_id             = aws_api_gateway_rest_api.schedule.id
  resource_id             = aws_api_gateway_resource.schedule_resource.id
  http_method             = aws_api_gateway_method.schedule_post_method.http_method
  type                    = "AWS"
  integration_http_method = "POST"
  uri                     = "arn:aws:apigateway:${var.target_region}:dynamodb:action/PutItem"
  credentials             = aws_iam_role.schedule_api_dynamodb_role.arn
  request_templates       = {
    "application/json" = EOF
    {
        "TableName" : "${var.environment_id}-AccountService-NotesToDatalakeSchedule",
        "Item" : {
            "BusinessUnitId" : {
                "N" : "$input.path('$.BusinessUnitId')"
            },
            "Frequency" : {
                "N" : "$input.path('$.Frequency')"
            }
        }
    }
  }
}

I couldn’t find a proper syntax indicating how the Item should be passed in the request_templates. During deployment it throws the error –

2022-09-12T11:51:22.6623262Z ##[error][1m[31mError: [0m[0m[1mMissing attribute value[0m
2022-09-12T11:51:22.6626316Z ##[error][0m  on api-gateway.tf line 47, in resource "aws_api_gateway_integration" "schedule_post_integration":
2022-09-12T11:51:22.6628770Z ##[error]  35:   request_templates       = {
2022-09-12T11:51:22.6630845Z ##[error]  36:     "application/json" = EOF
2022-09-12T11:51:22.6632935Z ##[error]  37:     {
2022-09-12T11:51:22.6636136Z ##[error]  38:         "TableName" : "${var.environment_id}-AccountService-NotesToDatalakeSchedule",
2022-09-12T11:51:22.6638305Z ##[error]  39:         "Item" : {
2022-09-12T11:51:22.6642274Z ##[error]  40:             "BusinessUnitId" : {
2022-09-12T11:51:22.6645424Z ##[error]  41:                 "N" : "$input.path('$.BusinessUnitId')"
2022-09-12T11:51:22.6647529Z ##[error]  42:             },
2022-09-12T11:51:22.6649461Z ##[error]  43:             "Frequency" : {
2022-09-12T11:51:22.6651639Z ##[error]  44:                 "N" : "$input.path('$.Frequency')"
2022-09-12T11:51:22.6653642Z ##[error]  45:             }
2022-09-12T11:51:22.6655505Z ##[error]  46:         }
2022-09-12T11:51:22.6657282Z ##[error]  47:     }
2022-09-12T11:51:22.6659045Z ##[error]  48:   }
2022-09-12T11:51:22.6661277Z ##[error]Expected an attribute value, introduced by an equals sign ("=").

Can someone help me identifying the issue here?

2

Answers


  1. It looks like you are trying to use HCL Template Expressions, but you forgot two key things:

    1. A template expression starts with << MARKER, you chose EOF as marker but forgot the <<
    2. You forgot the marker "on a line by itself".

    Fixed version:

    resource aws_api_gateway_integration schedule_post_integration {
      rest_api_id             = aws_api_gateway_rest_api.schedule.id
      resource_id             = aws_api_gateway_resource.schedule_resource.id
      http_method             = aws_api_gateway_method.schedule_post_method.http_method
      type                    = "AWS"
      integration_http_method = "POST"
      uri                     = "arn:aws:apigateway:${var.target_region}:dynamodb:action/PutItem"
      credentials             = aws_iam_role.schedule_api_dynamodb_role.arn
      request_templates       = {
        "application/json" = << EOF
        {
            "TableName" : "${var.environment_id}-AccountService-NotesToDatalakeSchedule",
            "Item" : {
                "BusinessUnitId" : {
                    "N" : "$input.path('$.BusinessUnitId')"
                },
                "Frequency" : {
                    "N" : "$input.path('$.Frequency')"
                }
            }
        }
    EOF
      }
    }
    
    Login or Signup to reply.
  2. Although the other existing answer is correct about how to use multi-line template expressions, it’s typically better to produce JSON strings using the jsonencode function instead of using string templating, because then the result is always guaranteed to be valid JSON without any need for you to account for quoting, escaping, and correct placement of commas.

    For example:

      request_templates = {
        "application/json" = jsonencode({
          "TableName" = "${var.environment_id}-AccountService-NotesToDatalakeSchedule"
          "Item" = {
            "BusinessUnitId" = {
              "N" = "$input.path('$.BusinessUnitId')"
            }
            "Frequency" = {
              "N" = "$input.path('$.Frequency')"
            }
          }
        })
      }
    

    The argument to jsonencode here is a Terraform expression constructing an object value. The jsonencode documentation describes how the function translates Terraform values into corresponding JSON data types, and per that table the example above should generate an equivalent JSON data structure to the template you were trying to write in your question.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search