Terraform API网关多区域部署:Access Denied



我将采用模块化的方法跨多个地区(法律和法律)部署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和不同区域的服务之间创建端点。

相关内容

  • 没有找到相关文章

最新更新