Указание шаблона запроса для aws_api_gateway_integration в terraform

В документации Terraform для AWS_API_GATEWAY_INTEGRATION поддерживаются следующие параметры:

  • rest_api_id
  • resource_id
  • http_method
  • типа
  • URI
  • integration_http_method

Они приводят этот пример:

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"
}

Но я хотел бы указать шаблон сопоставления (а также интеграцию лямбда), как вы можете с пользовательским интерфейсом:

введите описание изображения здесь

Однако я не вижу никакого способа сделать это с Terraform. Возможно ли?

Примечание. То, что я сейчас делаю, - это apply остальная конфигурация (lambda, s3, iam и т.д.), а затем добавление шаблона сопоставления вручную после этого (а также тип интеграции лямбда).

Но тогда каждый раз, когда я terraform apply применяет другую конфигурацию (например: s3), Terraform возвращает шаблон отображения и тип интеграции.

План "возврата" выглядит следующим образом:

~ 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" => ""

Ответ 1

Основываясь на этой проблеме, вот конфигурация, которая работает:

(Вы должны использовать параметры uri, type, integration_http_method и 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")}"
  }
}

И содержимое 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"
}

Ответ 2

Если вы используете функцию Lambda в качестве конечной точки, тип интеграции будет "AWS".

Вот документация AWS, которая объясняет создание интеграции Lambda.

Вот сообщение GitHub, в котором показано, как это можно сделать с помощью Terraform.

Надеюсь, что это поможет! Дайте нам знать, если у вас есть какие-либо вопросы.

Ответ 3

Если вы хотите иметь его встроенный, а не отдельный шаблон, вы можете сделать:

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
}

Ответ 4

У меня была похожая проблема, я не мог добавить шаблоны Mapping, так как мой тип интеграции был "AWS_PROXY". Я изменил его на "AWS", и это сработало.

Terraform не будет учитывать шаблоны сопоставления, если тип интеграции "AWS_PROXY"

Вы можете узнать больше о типах интеграции здесь.