Шлюз AWS API и функция Lambda, развернутые через terraform - Ошибка выполнения из-за ошибки конфигурации: неверные разрешения для функции Lambda

Я развертываю шлюз API и функцию Lambda вместе через Terraform, и функция Lambda предназначена для запуска через шлюз API. После успешного развертывания ресурсов я тестирую шлюз API и получаю ответ:

{"message": "Внутренняя ошибка сервера" } .

Фактические журналы шлюза API говорят:

Выполнение не выполнено из-за ошибки конфигурации: недопустимые разрешения для функции Lambda

Я могу получить действительную функциональность api-lambda, перейдя в раздел запросов интеграции шлюза API, повторно выбрав мою существующую функцию и "сохранив" ее снова с помощью небольшой галочки, но это нарушает автоматизацию, и я хочу, чтобы это работало без необходимость делать этот шаг вручную каждый раз. Не уверен, что это ошибка в Terraform/AWS или я что-то не так делаю. (Найден кто-то, задающий тот же вопрос, но использующий SAM, но не получивший ответ: сбой выполнения из-за ошибки конфигурации: недопустимые разрешения для функции Lambda)

Моя текущая настройка заключается в развертывании API через файл swagger json, и Lambda Invoke ARN используется в качестве URI в разделе интеграции этого файла. Я попытался переключить это между жестко закодированным ARN и переменной безрезультатно. Я также попытался включить ресурсы aws_api_gateway_deployment и aws_api_gateway_integration, но я подумал, что, если я уже использую файл swagger, его использование может конфликтовать с тем, что файл swagger уже создает.

Мой main.tf для моего модуля api_gateway выглядит так:

resource "aws_api_gateway_rest_api" "post_session" {
    name = "${var.api_gateway_name}"
    body = "${data.template_file.post-session.rendered}"

    endpoint_configuration {
        types = ["PRIVATE"]
    }
}

data "template_file" "post-session" {
    template = "${file("../source/aapt-ual-post-session-v1-swagger-apigateway.json")}"

    vars {
        session_init_arn = "${var.session_init_function_arn}"
    }
}

Мой соответствующий раздел файла swagger выглядит так:

"x-amazon-apigateway-integration": {
      "uri": "${session_init_arn}",
      "responses": {
        "default": {
          "statusCode": "200"
        }
      },
      "requestTemplates": {
        "application/json":  ....

И моя секция триггера lambda_permission / api_gateway моего модуля Lambda выглядит так:

resource "aws_lambda_permission" "post_session_trigger" {
     statement_id  = "Allow_My_Post_Session_Invoke"
     action        = "lambda:InvokeFunction"
     function_name = "${aws_lambda_function.init_function.function_name}"
     principal     = "apigateway.amazonaws.com"
     source_arn = "arn:aws:execute-api:us-east-1:${var.account_id}:${var.post_session_id}/v1/POST/aa/ual/session"

}

Дайте мне знать, если у вас есть предложения, спасибо!

1 ответ

Решение

В соответствии с предложением Denis Weerasiri я проверил права доступа Lambda после повторного выбора имени функции Lambda в разделе интеграции шлюза API и добавил еще одну политику. Мне нужно было изменить v1 на * в source_arn в ресурсе функции Lambda. Таким образом, новый триггер API-шлюза в моем модуле Lambda выглядит следующим образом:

resource "aws_lambda_permission" "post_session_trigger" {
     statement_id  = "Allow_My_Post_Session_Invoke"
     action        = "lambda:InvokeFunction"
     function_name = "${aws_lambda_function.init_function.function_name}"
     principal     = "apigateway.amazonaws.com"
     source_arn = "arn:aws:execute-api:us-east-1:${var.account_id}:${var.post_session_id}/*/POST/aa/ual/session"}

У меня была аналогичная проблема, и я использовал Terraform. Ему нужна политика с "POST" в ней. По какой-то причине политика /*/ (подстановочный знак) не сработала?

Вот политика и пример terraform, которые я использовал для решения проблемы.

Большое спасибо всем выше.

Вот как выглядела моя политика JSON в отношении лямбда-функций и терраформа:

    {
      "Version": "2012-10-17",
      "Id": "default",
      "Statement": [
        {
          "Sid": "AllowAPIGatewayInvoke",
          "Effect": "Allow",
          "Principal": {
            "Service": "apigateway.amazonaws.com"
          },
          "Action": "lambda:InvokeFunction",
          "Resource": "arn:aws:lambda:us-east-1:999999999999:function:MY-APP",
          "Condition": {
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:execute-api:us-east-1:999999999999:d85kyq3jx3/test/*/MY-APP"
            }
          }
        },
        {
          "Sid": "e841fc76-c755-43b5-bd2c-53edf052cb3e",
          "Effect": "Allow",
          "Principal": {
            "Service": "apigateway.amazonaws.com"
          },
          "Action": "lambda:InvokeFunction",
          "Resource": "arn:aws:lambda:us-east-1:999999999999:function:MY-APP",
          "Condition": {
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:execute-api:us-east-1:999999999999:d85kyq3jx3/*/POST/MY-APP"
            }
          }
        }
      ]
    }

    add in a terraform like this:


    //************************************************
    // allows you to read in the ARN and parse out needed info, like region, and account
    //************************************************
    data "aws_arn" "api_gw_deployment_arn" {
        arn = aws_api_gateway_deployment.MY-APP_deployment.execution_arn 
    }

    //************************************************
    // Add in this to support API GW testing in AWS Console.
    //************************************************
    resource "aws_lambda_permission" "apigw-post" {
        statement_id  = "AllowAPIGatewayInvokePOST"
        action        = "lambda:InvokeFunction"
        //function_name = aws_lambda_function.lambda-MY-APP.arn
        function_name = module.lambda.function_name
        principal     = "apigateway.amazonaws.com"

        // "arn:aws:execute-api:us-east-1:473097069755:708lig5xuc/dev/POST1/cloudability-church-ws"
        source_arn = "arn:aws:execute-api:${data.aws_arn.api_gw_deployment_arn.region}:${data.aws_arn.api_gw_deployment_arn.account}:${aws_api_gateway_deployment.MY-APP_deployment.rest_api_id}/*/POST/${var.api_gateway_root_path}"
    }
Другие вопросы по тегам