我将采用模块化的方法跨多个地区(法律和法律)部署APIgateway和相关的lambda。二级供应商)。假设每个var变量都被赋值:
primary-gateway:
module "test_api" {
source = "./modules/api-gateway"
name = "test-api"
description = "primary API"
vpc_id = var.vpc_id #vpc in primary region
region = var.region
stage_name = ""
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "execute-api:/*",
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": ["${data.aws_vpc_endpoint.execute_api_endpoint.id}"]
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "execute-api:/*"
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "lambda:InvokeFunction",
"Resource": ["${module.test_lambda.lambda_arn}"]
}
]
}
EOF
}
data "aws_vpc_endpoint" "execute_api_endpoint" {
vpc_id = var.vpc_id
service_name = "com.amazonaws.${var.region}.execute-api"
}
# --------------Endpoint and Authorization ------------------
module "post_endpoint" {
source = "./modules/api-gateway-endpoint"
rest_api_id = module.test_api.api_id
root_resource_id = module.test_api.root_resource_id
path = "test"
invoke_arn = module.test_lambda.invoke_arn
lambda_name = module.test_lambda.function_name
execution_arn = module.test_api.execution_arn
http_method = "POST"
authorizer_id = aws_api_gateway_authorizer.gateway-authorizer.id
}
resource "aws_api_gateway_authorizer" "gateway-authorizer" {
name = "test-gateway-authorizer"
rest_api_id = module.test_api.api_id
authorizer_uri = module.lambda_api_gateway_authorizer.invoke_arn
authorizer_credentials = aws_iam_role.authorizer_invocation_role.arn
identity_source = "method.request.header.X-SF_AD_OIDC_TOKEN"
type = "REQUEST"
}
module "lambda_api_gateway_authorizer" {
source = "./modules/lambda"
function_name = "azureAuthorizer"
policy_document_json = data.aws_iam_policy_document.lambda_api_gateway_authorizer.json
account = var.account
region = var.region
subnet_ids = local.private_subnets
security_group_ids = [local.https_outbound_sg_id]
kms_key_arn = var.kms_key_id
permissions_boundary = var.permissions_boundary
}
data "aws_iam_policy_document" "lambda_api_gateway_authorizer" {
statement {
actions = "*"
resources = ["arn:aws:logs:${var.region}:${var.account}:log-group:/aws/lambda/*:*"]
}
statement {
actions = ["kms:Decrypt", "kms:Encrypt", "kms:GenerateDataKey"]
resources = [var.kms_key_id]
}
statement {
actions = [
"ec2:DescribeInstances",
"ec2:CreateNetworkInterface",
"ec2:AttachNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface",
]
resources = ["*"]
}
}
resource "aws_iam_role" "authorizer_invocation_role" {
name = "test-api-gateway-auth-invocation"
path = "/"
permissions_boundary = var.permissions_boundary
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
# --------------Stages and Deployment ------------------
resource "aws_api_gateway_deployment" "test_api" {
depends_on = [module.post_endpoint.endpoint_integration]
rest_api_id = module.test_api.api_id
triggers = {
redeployment = sha1(join(
"",
[
file("api-test-endpoint.tf") #endpoints are declared in this file
]
))
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_api_gateway_stage" "stage" {
deployment_id = aws_api_gateway_deployment.test_api.id
rest_api_id = module.test_api.api_id
stage_name = "sandbox"
access_log_settings {
destination_arn = module.test_api.api_logs_arn
format = "{ "requestId":"$context.requestId", "ip": "$context.identity.sourceIp", "caller":"$context.identity.caller", "user":"$context.identity.user", "requestTime":"$context.requestTime", "httpMethod":"$context.httpMethod", "resourcePath":"$context.resourcePath", "status":"$context.status", "protocol":"$context.protocol", "responseLength":"$context.responseLength" }"
}
}
resource "aws_api_gateway_method_settings" "test_api" {
rest_api_id = module.test_api.api_id
stage_name = aws_api_gateway_stage.stage.stage_name
method_path = "*/*"
}
module "test_lambda" {
source = "./modules/lambda"
function_name = "testAPILambda"
policy_document_json = data.aws_iam_policy_document.test_policy.json
tags = local.common_tags
workspace = terraform.workspace
account = var.account
region = var.region
subnet_ids = local.private_subnets
security_group_ids = [local.https_outbound_sg_id]
kms_key_arn = var.kms_key_id
permissions_boundary = var.permissions_boundary
}
secondary-gateway:
module "test_secondary" {
source = "./modules/api-gateway"
name = "test-api"
description = "Secondary API"
vpc_id = var.secondary_vpc_id
region = var.secondary_region
stage_name = ""
providers = { aws = aws.secondary }
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "execute-api:/*",
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": ["${data.aws_vpc_endpoint.execute_api_endpoint_secondary.id}"]
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "execute-api:/*"
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "lambda:InvokeFunction",
"Resource": ["${module.test_lambda_secondary.lambda_arn}"]
}
]
}
EOF
}
data "aws_vpc_endpoint" "execute_api_endpoint_secondary" {
vpc_id = var.secondary_vpc_id
service_name = "com.amazonaws.${var.secondary_region}.execute-api"
provider = aws.secondary
}
# --------------Endpoint and Authorization ------------------
module "test_endpoint_secondary" {
source = "./modules/api-gateway-endpoint"
rest_api_id = module.test_api_secondary.api_id
root_resource_id = module.test_api_secondary.root_resource_id
path = "test"
invoke_arn = module.test_lambda_secondary.invoke_arn
lambda_name = module.test_lambda_secondary.function_name
execution_arn = module.test_api_secondary.execution_arn
http_method = "POST"
authorizer_id = aws_api_gateway_authorizer.gateway-authorizer-secondary.id
}
resource "aws_api_gateway_authorizer" "gateway-authorizer-secondary" {
name = "test-gateway-authorizer-secondary"
rest_api_id = module.test_api_secondary.api_id
authorizer_uri = module.lambda_api_gateway_authorizer_secondary.invoke_arn
authorizer_credentials = aws_iam_role.authorizer_invocation_role.arn
identity_source = "method.request.header.X-SF_AD_OIDC_TOKEN"
type = "REQUEST"
}
resource "aws_iam_role_policy" "authorizer_invocation_policy_secondary" {
name = "test-api-gateway-auth-invocation-policy-secondary"
role = aws_iam_role.authorizer_invocation_role.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "lambda:InvokeFunction",
"Effect": "Allow",
"Resource": "${module.lambda_api_gateway_authorizer_secondary.lambda_arn}"
}
]
}
EOF
}
module "lambda_api_gateway_authorizer_secondary" {
source = "./modules/lambda"
function_name = "azureAuthorizer"
policy_document_json = data.aws_iam_policy_document.lambda_api_gateway_authorizer_secondary.json
account = var.account
region = var.secondary_region
providers = { aws = aws.secondary }
subnet_ids = local.secondary_private_subnets
security_group_ids = [local.https_outbound_sg_id_secondary]
kms_key_arn = var.kms_secondary_key_id
permissions_boundary = var.permissions_boundary
}
data "aws_iam_policy_document" "lambda_api_gateway_authorizer_secondary" {
statement {
actions = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams",
"logs:PutSubscriptionFilter"
]
resources = ["arn:aws:logs:${var.secondary_region}:${var.account}:log-group:/aws/lambda/*:*"]
}
statement {
actions = ["kms:Decrypt", "kms:Encrypt", "kms:GenerateDataKey"]
resources = [var.kms_secondary_key_id]
}
statement {
actions = [
"ec2:DescribeInstances",
"ec2:CreateNetworkInterface",
"ec2:AttachNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface",
]
resources = ["*"]
}
}
# --------------Stages and Deployment ------------------
resource "aws_api_gateway_deployment" "test_secondary" {
depends_on = [module.test_endpoint_secondary.endpoint_integration]
rest_api_id = module.test_secondary.api_id
triggers = {
redeployment = sha1(join(
"",
[
file("api-test-endpoint.tf")
]
))
}
lifecycle {
create_before_destroy = true
}
provider = aws.secondary
}
resource "aws_api_gateway_stage" "stage_secondary" {
deployment_id = aws_api_gateway_deployment.test_secondary.id
rest_api_id = module.test_secondary.api_id
stage_name = "sandbox"
access_log_settings {
destination_arn = module.test_secondary.api_logs_arn
format = "{ "requestId":"$context.requestId", "ip": "$context.identity.sourceIp", "caller":"$context.identity.caller", "user":"$context.identity.user", "requestTime":"$context.requestTime", "httpMethod":"$context.httpMethod", "resourcePath":"$context.resourcePath", "status":"$context.status", "protocol":"$context.protocol", "responseLength":"$context.responseLength" }"
}
provider = aws.secondary
}
resource "aws_api_gateway_method_settings" "test_secondary" {
rest_api_id = module.test_secondary.api_id
stage_name = aws_api_gateway_stage.stage_secondary.stage_name
method_path = "*/*"
provider = aws.secondary
}
resource "aws_lambda_permission" "test_permission_secondary" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = module.test_lambda_secondary.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${module.test_api_secondary.execution_arn}/*/*/*"
provider = aws.secondary
}
module "test_lambda_secondary" {
source = "./modules/lambda"
function_name = "testAPILambda-secondary"
policy_document_json = data.aws_iam_policy_document.test_policy_secondary.json
workspace = terraform.workspace
account = var.account
region = var.secondary_region
providers = { aws = aws.secondary }
subnet_ids = local.secondary_private_subnets
security_group_ids = [local.https_outbound_sg_id_secondary]
kms_key_arn = var.kms_secondary_key_id
permissions_boundary = var.permissions_boundary
}
这些几乎是相同的,除了第二个提供者是为该地区。
我得到这个错误:
创建API网关错误:AccessDeniedException: on modules API - Gateway main。在资源"aws_api_gateway_rest_api"中的第1行;"api_gateway"1: resource "aws_api_gateway_rest_api"api_gateway"{
和这个错误只有添加辅助资源后显示。
两个资源都引用了这个块模板:
resource "aws_api_gateway_rest_api" "api_gateway" {
name = var.name
description = var.description
endpoint_configuration {
types = ["PRIVATE"]
}
policy = var.policy
}
# ------------- API Cloudwatch Logs --------------
resource "aws_cloudwatch_log_group" "api_logs" {
name = "test-apigateway-${aws_api_gateway_rest_api.api_gateway.id}-access-logs"
retention_in_days = 14
}
对于在哪里可以找到这个错误或查看什么,任何帮助都是感激的。
已采取的步骤:
- 已添加提供商= aws。次要到次要模块
- aws_lambda_permission的扩展权限
- 检查vpc id是否正确
- 编辑lambda策略以扩大权限
我不确定我是否理解正确,但在我看来,您正在尝试在不同区域创建VPC接口端点到API网关。如果是,则不支持。从文档:
仅在同一区域内支持端点。不能在VPC和不同区域的服务之间创建端点。