使用 Terraform 从 VPC 中的 Lambda 访问 S3
Access S3 from Lambda within VPC using Terraform
我有一个 Lambda
resource "aws_lambda_function" "api" {
function_name = "ApiController"
timeout = 10
s3_bucket = "mn-lambda"
s3_key = "mn/v1.0.0/sketch-avatar-api-1.0.0-all.jar"
handler = "io.micronaut.function.aws.proxy.MicronautLambdaHandler"
runtime = "java11"
memory_size = 1024
role = aws_iam_role.api_lambda.arn
vpc_config {
security_group_ids = [aws_security_group.lambda.id]
subnet_ids = [for subnet in aws_subnet.private: subnet.id]
}
}
在 VPC 内
resource "aws_vpc" "vpc" {
cidr_block = var.vpc_cidr_block
enable_dns_support = true
enable_dns_hostnames = true
}
我创建了一个 aws_vpc_endpoint 因为我读到这是我的 VPC 访问 S3 所需要的
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.vpc.id
service_name = "com.amazonaws.${var.region}.s3"
}
我创建并附加了允许访问 S3 的策略
resource "aws_iam_role_policy_attachment" "s3" {
role = aws_iam_role.api_lambda.name
policy_arn = aws_iam_policy.s3.arn
}
resource "aws_iam_policy" "s3" {
policy = data.aws_iam_policy_document.s3.json
}
data "aws_iam_policy_document" "s3" {
statement {
effect = "Allow"
resources = ["*"]
actions = [
"s3:*",
]
}
}
可能值得注意的是,我尝试访问的存储桶是使用 aws cli 创建的,但位于同一区域。所以不使用 terraform。
问题是当我尝试从 S3 读取文件时我的 Lambda 超时。
可以找到完整的项目 here 如果有人想看一看。
您正在创建 com.amazonaws.${var.region}.s3
,即 gateway VPC endpoint , which shouldn't be confused with interface VPC endpoints。
两者的主要区别之一是网关类型需要与路由tables关联。因此,您应该使用 route_table_ids 将您的 S3 网关与子网的路由 table 相关联。
例如,使用默认主 VPC 路由 table:
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.vpc.id
service_name = "com.amazonaws.${var.region}.s3"
route_table_ids = [aws_vpc.vpc.main_route_table_id]
}
或者,您也可以使用 aws_vpc_endpoint_route_table_association 来完成。
我有一个 Lambda
resource "aws_lambda_function" "api" {
function_name = "ApiController"
timeout = 10
s3_bucket = "mn-lambda"
s3_key = "mn/v1.0.0/sketch-avatar-api-1.0.0-all.jar"
handler = "io.micronaut.function.aws.proxy.MicronautLambdaHandler"
runtime = "java11"
memory_size = 1024
role = aws_iam_role.api_lambda.arn
vpc_config {
security_group_ids = [aws_security_group.lambda.id]
subnet_ids = [for subnet in aws_subnet.private: subnet.id]
}
}
在 VPC 内
resource "aws_vpc" "vpc" {
cidr_block = var.vpc_cidr_block
enable_dns_support = true
enable_dns_hostnames = true
}
我创建了一个 aws_vpc_endpoint 因为我读到这是我的 VPC 访问 S3 所需要的
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.vpc.id
service_name = "com.amazonaws.${var.region}.s3"
}
我创建并附加了允许访问 S3 的策略
resource "aws_iam_role_policy_attachment" "s3" {
role = aws_iam_role.api_lambda.name
policy_arn = aws_iam_policy.s3.arn
}
resource "aws_iam_policy" "s3" {
policy = data.aws_iam_policy_document.s3.json
}
data "aws_iam_policy_document" "s3" {
statement {
effect = "Allow"
resources = ["*"]
actions = [
"s3:*",
]
}
}
可能值得注意的是,我尝试访问的存储桶是使用 aws cli 创建的,但位于同一区域。所以不使用 terraform。
问题是当我尝试从 S3 读取文件时我的 Lambda 超时。
可以找到完整的项目 here 如果有人想看一看。
您正在创建 com.amazonaws.${var.region}.s3
,即 gateway VPC endpoint , which shouldn't be confused with interface VPC endpoints。
两者的主要区别之一是网关类型需要与路由tables关联。因此,您应该使用 route_table_ids 将您的 S3 网关与子网的路由 table 相关联。
例如,使用默认主 VPC 路由 table:
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.vpc.id
service_name = "com.amazonaws.${var.region}.s3"
route_table_ids = [aws_vpc.vpc.main_route_table_id]
}
或者,您也可以使用 aws_vpc_endpoint_route_table_association 来完成。