使用 Terraform 部署 API 网关和 Lambda 集成

Deploying API Gateway and Lambda Integration using Terraform

我正在尝试使用 Terraform 创建 Lambda 函数。没有权限问题。

Plan: 7 to add, 0 to change, 0 to destroy.
aws_api_gateway_rest_api.test-rest-api: Creating...
aws_iam_role.test-lambda-role: Creating...
aws_lambda_function.test-lambda: Creating...
aws_api_gateway_rest_api.test-rest-api: Creation complete after 0s [id=13hnx8sw80]
aws_api_gateway_resource.resource: Creating...
aws_iam_role.test-lambda-role: Creation complete after 1s [id=testroleLambda]
aws_api_gateway_resource.resource: Creation complete after 2s [id=yd8iyo]
aws_api_gateway_method.method: Creating...
aws_api_gateway_method.method: Creation complete after 0s [id=agm-13hnx8sw80-yd8iyo-GET]
╷
│ Error: error creating Lambda Function (1): ValidationException:
│       status code: 400, request id: f769fb69-dbfe-4b8d-8321-e87c01eaffd9
│
│   with aws_lambda_function.test-lambda,
│   on main.tf line 41, in resource "aws_lambda_function" "test-lambda":
│   41:         resource "aws_lambda_function" "test-lambda" {

我试过调试,它有相同的信息。没有太多。

export TF_LOG=TRACE terraform apply 2>&1 | tee apply.txt

根据此 git 页面,这是一个已知错误。 https://github.com/hashicorp/terraform-provider-aws/issues/13709 有人解决了吗? 我在 linux_amd64

上使用 Terraform v1.1.5
    # Lambda
resource "aws_lambda_permission" "test-lambda" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.test-lambda.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn = "arn:aws:execute-api:${var.region_name}:${var.accountId}:${aws_api_gateway_rest_api.test-rest-api.id}
}

resource "aws_lambda_function" "test-lambda" {
  filename      = "test-lambda.zip"
  function_name = "test-lambda"
  role = aws_iam_role.test-lambda-role.arn
  handler       = "test-lambda.lambda_handler"
  runtime       = "python3.8"
}

resource "aws_iam_role" "test-lambda-role" {
  name = "roleLambda"

  assume_role_policy = <<-POLICY
{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Principal": {
          "Service": "lambda.amazonaws.com"
        },
        "Effect": "Allow",
        "Sid": ""
      }
    ]
  }
  POLICY
}

我能够成功创建 lambda 函数和 IAM 角色资源;

# YOUR PROVIDER IS LIKELY DIFFERENT THAN MINE
provider "aws" {
region = "us-east-1"
access_key = "AAAABBBBCCCC"
secret_key = "DDDDDEEEFFFGGGGHHH"
allowed_account_ids = ["YOUR-AWS-ACCOUNT-ID"]
}

# I USE TERRAFORM CLOUD FOR BACKEND STATE FILE MGMT
# THIS IS LIKELY NOT RELEVANT TO YOU
terraform {
  backend "remote" {
    hostname    = "app.terraform.io"
    organization = "MYORG"

    workspaces {
      name = "testing"
    }
  }
}

#resource "aws_lambda_permission" "test-lambda" {
#  statement_id  = "AllowExecutionFromAPIGateway"
#  action        = "lambda:InvokeFunction"
#  function_name = aws_lambda_function.test-lambda.function_name
#  principal     = "apigateway.amazonaws.com"
#  source_arn = join("",["arn:aws:execute-api:",var.region_name,var.accountId,aws_api_gateway_rest_api.test-rest-api.id])
#}

resource "aws_lambda_function" "test-lambda" {
  filename      = "test-lambda.zip"
  function_name = "test-lambda"
  role = aws_iam_role.test-lambda-role.arn
  handler       = "test-lambda.lambda_handler"
  runtime       = "python3.8"
}

resource "aws_iam_role" "general" {
    name = "YOUR-ROLE-NAME"
    description = "YOUR-ROLE-DESCRIPTION"
    //managed_policy_arns = var.managed_policy_arns
    assume_role_policy = file("${path.module}/assume-role-policy.json")
    //tags = var.tags
}

resource "aws_iam_policy" "general" {
    name = "YOUR-POLICY-NAME"
    description = "YOUR-POLICY-DESCRIPTION"
    policy = file("${path.module}/role-policy.json")
}

resource "aws_iam_role_policy_attachment" "general" {
    role = aws_iam_role.general.name
    policy_arn = aws_iam_policy.general.arn
}

// CONTENTS OF POLICY ./assume-role-policy.json used in aws_iam_role resource:
{
    "Version": "2012-10-17",
    "Statement": [{
        "Action": "sts:AssumeRole",
        "Principal": {
            "Service": [
                "lambda.amazonaws.com",
                "apigateway.amazonaws.com"
            ]
        },
        "Effect": "Allow",
        "Sid": ""
    }]
}

// CONTENTS OF ROLE ./role-policy.json used in aws_iam_policy resource:
{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Action": [
            "ec2:*",
            "events:*",
            "cloudwatch:*",
            "logs:*",
            "ssm:*",
            "kms:*",
            "sns:*",
            "iam:GetPolicy",
            "iam:GetPolicyVersion",
            "iam:GetRole",
            "s3:*",
            "servicediscovery:*"
        ],
        "Resource": "*"
    },
    {
        "Effect": "Allow",
        "Action": "iam:CreateServiceLinkedRole",
        "Resource": "arn:aws:iam::*:role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents*",
        "Condition": {
            "StringLike": {
                "iam:AWSServiceName": "events.amazonaws.com"
            }
        }
    }]
}

您能否尝试仅创建那些 lambda 和 IAM 资源并查看是否仍然出现相同的错误?这表明 lambda 权限资源或权限引用的 API 网关资源存在问题。 我仍然会仔细检查您的提供商是否正确设置了正确的区域和 aws 帐户 ID。只是为了排除这种可能性。我更新了我的答案以展示我通常如何使用 lambda 管理 IAM 权限。您可以根据自己需要的权限进行相应的修改。