Почему отклик метода шлюза API отличается при создании с помощью terraform? - PullRequest
0 голосов
/ 10 мая 2019

У меня есть следующий скрипт terraform, который создает API-шлюз, который передает запросы к лямбда-функции.

provider "aws" {

  access_key = "${var.access_key}"

  secret_key = "${var.secret_key}"
  # 
  region     = "${var.region}"

  version = "~> 2.6"
}

resource "aws_api_gateway_rest_api" "MyDemoAPI" {
  name        = "MyDemoAPI"
  description = "This is my API for demonstration purposes"
}

resource "aws_api_gateway_resource" "MyDemoResource" {
  rest_api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
  parent_id   = "${aws_api_gateway_rest_api.MyDemoAPI.root_resource_id}"
  path_part   = "mydemoresource"
}

resource "aws_api_gateway_method" "MyDemoMethod" {
  rest_api_id   = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
  resource_id   = "${aws_api_gateway_resource.MyDemoResource.id}"
  http_method   = "POST"
  authorization = "NONE"
}

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}"
  integration_http_method = "POST"
  type        = "AWS_PROXY"
  uri         = "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/${aws_lambda_function.test_lambda_function.arn}/invocations"
  content_handling = "CONVERT_TO_TEXT"
}

resource "aws_api_gateway_method_response" "200" {
  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}"
  status_code = "200"
  response_models {
     "application/json" = "Empty"
  }
}

resource "aws_lambda_function" "test_lambda_function" {
  filename         = "lambda.zip"
  description      = "test build api gateway and lambda function using terraform"
  function_name    = "test_lambda_function"
  role             = "arn:aws:iam::123456789123:role/my_labmda_role"
  handler          = "gateway.lambda_handler"
  runtime          = "python3.6"
  memory_size      = 128
  timeout          = 60
}

Раздел Method Response в ресурсах API-шлюза отображает Select an integration response..

enter image description here

Но если я создам тот же шлюз API с помощью консоли AWS, в разделе Method Response отобразится что-то другое:

enter image description here

Почему это происходит?

Ниже описано, как использовать консоль AWS для создания шлюза API:

  1. Выбрать Create Method под ресурсом.enter image description here

  2. Выберите POST метод.enter image description here

  3. Выберите нужные параметры.enter image description here

Сначала я попытался создать вышеуказанные ресурсы вручную, а затем выполнить terraform apply.Затем terraform говорит мне, что ничего не нужно менять.

terraform apply
aws_api_gateway_rest_api.MyDemoAPI: Refreshing state... (ID: 1qa34vs1k7)
aws_lambda_function.test_lambda_function: Refreshing state... (ID: test_lambda_function)
aws_api_gateway_resource.MyDemoResource: Refreshing state... (ID: 4xej81)
aws_api_gateway_method.MyDemoMethod: Refreshing state... (ID: agm-1qa34vs1k7-4xej81-POST)
aws_api_gateway_method_response.200: Refreshing state... (ID: agmr-1qa34vs1k7-4xej81-POST-200)
aws_api_gateway_integration.MyDemoIntegration: Refreshing state... (ID: agi-1qa34vs1k7-4xej81-POST)

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Это, кажется, означает, что построенная вручную структура такая же, как структура, созданная terraform.

1 Ответ

0 голосов
/ 10 мая 2019

Поскольку API Gateway является сложным компонентом AWS, и вы можете контролировать практически все, что находится на нем (практически каждая его часть управляется независимо, что дает вам большой контроль над тем, что вы создаете, но также усложняет работу с ним).

Посмотрите, что там написано "Выберите ответ интеграции", но, поскольку ваш код Terraform не создал его, он пуст.

Я столкнулся с этой же проблемой нескольконедель назад, и я нашел решение на GitHub от Terraform.Я думаю, что Terraform лучше документировать это, поскольку вы не первый, и вы не будете последним, кто задаст этот вопрос.Ну, по крайней мере, у нас есть это задокументировано в StackOverflow:)

Короче говоря, вам нужно добавить ресурс Terraform aws_api_gateway_integration_response в ваш API-шлюз.

resource "aws_api_gateway_integration_response" "MyDemoIntegrationResponse" {
   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}"
   status_code = "${aws_api_gateway_method_response.200.status_code}"

   response_templates = {
       "application/json" = ""
   } 
}

Если вы можететем не менее, я предлагаю вам использовать подходящую среду для привязки событий к вашим функциям Lambda (например, Serverless Framework или AWS SAM ), так как это очень многословно и подвержено ошибкам при их создании в Terraform..

Обычно я объединяю Terraform и Serverless Framework вместе: я использую Terraform для создания ресурсов инфраструктуры - даже если они не содержат сервера - таких как таблицы DynamoDB, очереди SQS, темы SNS и т. Д., А также Serverless Framework для созданияЛямбда-функции и соответствующие им события.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...