Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specifying a request template for a aws_api_gateway_integration in terraform

In the Terraform documentation for AWS_API_GATEWAY_INTEGRATION, the following parameters are supported:

  • rest_api_id
  • resource_id
  • http_method
  • type
  • uri
  • integration_http_method

They give this example:

resource "aws_api_gateway_integration" "MyDemoIntegration" {
  rest_api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
  resource_id = "${aws_api_gateway_resource.MyDemoResource.id}"
  http_method = "${aws_api_gateway_method.MyDemoMethod.http_method}"
  type = "MOCK"
}

But I would like to specify a mapping template (as well as a Lambda integration), as you can with the UI:

enter image description here

However I see no way of doing that with Terraform. Is is possible ?

Note: What I am currently doing is applying the rest of the configuration (lambda, s3, iam etc...), and then adding mapping template manually afterwards (as well as the integration type of lambda).

But then every time I terraform apply to apply some other config (eg: s3), Terraform reverts back the mapping template and the integration type.

The "reverting" plan looks like this:

~ aws_api_gateway_integration.post_hit_integration
    request_templates.#:                "1" => "0"
    request_templates.application/json: "{\n  \"body\" : $input.json('$'),\n  \"headers\": {\n    #foreach($param in $input.params().header.keySet())\n    \"$param\": \"$util.escapeJavaScript($input.params().header.get($param))\" #if($foreach.hasNext),#end\n    \n    #end  \n  },\n  \"stage\" : \"$context.stage\"\n}" => ""
    uri:                                "arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:000000000000:function:create_hit/invocations" => ""
like image 937
Benjamin Crouzier Avatar asked Mar 29 '16 15:03

Benjamin Crouzier


2 Answers

Based on this issue, here is a config that works:

(You have to use the params uri, type, integration_http_method and request_templates)

# API
resource "aws_api_gateway_rest_api" "my_api" {
  name = "my_api"
  description = "My Api for adding pets"
}

# Resource
resource "aws_api_gateway_resource" "pets_resource" {
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  parent_id = "${aws_api_gateway_rest_api.my_api.root_resource_id}"
  path_part = "pets"
}

# Method
resource "aws_api_gateway_method" "post_pet_method" {
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id = "${aws_api_gateway_resource.pets_resource.id}"
  http_method = "POST"
  authorization = "NONE"
}

# Integration
resource "aws_api_gateway_integration" "post_pet_integration" {
  rest_api_id = "${aws_api_gateway_rest_api.my_api.id}"
  resource_id = "${aws_api_gateway_resource.pets_resource.id}"
  http_method = "${aws_api_gateway_method.post_pet_method.http_method}"
  uri = "arn:aws:apigateway:${var.region}:lambda:path/2015-03-31/functions/${aws_lambda_function.create_pet.arn}/invocations"
  type = "AWS"                           # Documentation not clear
  integration_http_method = "POST"       # Not documented
  request_templates = {                  # Not documented
    "application/json" = "${file("api_gateway_body_mapping.template")}"
  }
}

And contents of api_gateway_body_mapping.template:

{
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end  
  },
  "stage" : "$context.stage"
}
like image 70
Benjamin Crouzier Avatar answered Sep 18 '22 12:09

Benjamin Crouzier


If you want to have it inline rather than in a separate template you can do:

request_templates = {                  
  "application/json" =  <<REQUEST_TEMPLATE
  {
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end  
  },
  "stage" : "$context.stage"
  }
  REQUEST_TEMPLATE
}
like image 23
phill.tomlinson Avatar answered Sep 17 '22 12:09

phill.tomlinson