无法通过 Lambda 中的 VPC 端点访问 S3
Can not access S3 via VPC endpoint in Lambda
我的 VPC 中有一个 Lambda 函数,我想访问 S3 存储桶。
我认为我已经正确设置了 S3 VPC 端点,因为我在与 Lambda 函数相同的子网和安全组中创建了一个 EC2 实例。当我在 EC2 实例上 运行 Lambda 函数代码 的副本时,它可以正确显示 S3 文件内容。
但是当我 运行 Lambda 中的代码时,它失败了。所以,我想知道 “运行 in EC2”和“运行 in Lambda”有什么区别? 为什么我 运行 它在 Lambda 中?
这是我的 Lambda 函数代码:
import boto3
s3 = boto3.client('s3', region_name='ap-northeast-1')
def lambda_handler(event, context):
bucket = '*xxxxxx*'
key = 's3-upload.json'
try:
response = s3.get_object(Bucket=bucket, Key=key)
print('--------------------------------------')
print(response)
print('--------------------------------------')
body = response['Body'].read()
print(body)
print('--------------------------------------')
print("CONTENT TYPE: " + response['ContentType'])
except Exception as e:
print('Error getting object.')
print(e)
raise e
即使它们在同一个 VPC 中,EC2 和 Lambda 在 AWS 中仍然是不同的环境。能够 运行 你的代码在一个而不是另一个意味着你的代码很好并且可以工作,所以它可能是 AWS 的配置问题。
您检查过 lambda 使用的 service/execution 角色了吗?
您需要确保它所使用的 IAM 角色被允许具有正确的 S3 访问级别。
这份关于 lambda 执行角色的文档可能会提供一个有用的起点:https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role
像这样的 IAM 策略会为您使用的任何执行角色提供对所有 S3 存储桶的只读访问权限,并且恰好是 AWS 托管策略之一。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "*"
}
]
}
如果您想允许 AWS Lambda 访问 Amazon S3,请使用以下方法之一:
- 不要将函数关联到 VPC。然后自动访问。
如果该函数附加到 VPC 中的 public 子网,请将 弹性 IP 关联到出现在VPC(不推荐)
- 如果函数附加到 VPC 中的私有子网,请在 public 子网中启动 NAT 网关 并更新路由表。流量将通过 NAT 网关流向互联网。
- 在 VPC 中添加一个 Amazon S3 VPC 端点 并更新路由表。流量将流经该网关而不是 Internet 网关。
谢谢大家!我找到原因了。
我的 Lambda 有两个子网,private_sn_1 和 private_sn_2,
private_sn_1 已正确设置 vpc 端点路由 table,
但是 private_sn_2 设置了错误的路线 table,
我的 ec2 在 private_sn_1 中创建,因此它可以访问 vpc 端点。
正常情况下,Lambda 会在 private_sn_1 或 private_sn_2,
中随机 运行
但在我的情况下它总是 运行 在 private_sn_2(我不知道为什么),
所以当我修复 private_sn_2 路线时 table,
一切正常。
除了上述所有内容之外,VPC 端点策略也可能是禁止的,不允许流量 to/from S3 通过。确保使用 "Full access" 策略允许流量通过端点。
编辑:这里是相关的文档:
Your policy must contain a Principal element. For gateway endpoints
only, you cannot limit the principal to a specific IAM role or user.
Specify "*" to grant access to all IAM roles and users. Additionally,
for gateway endpoints only, if you specify the principal in the format
"AWS":"AWS-account-ID" or "AWS":"arn:aws:iam::AWS-account-ID:root",
access is granted to the AWS account root user only, and not all IAM
users and roles for the account.
因此,为了使 S3 端点正常工作,您需要在一般情况下将“*”指定为主体
我的 VPC 中有一个 Lambda 函数,我想访问 S3 存储桶。
我认为我已经正确设置了 S3 VPC 端点,因为我在与 Lambda 函数相同的子网和安全组中创建了一个 EC2 实例。当我在 EC2 实例上 运行 Lambda 函数代码 的副本时,它可以正确显示 S3 文件内容。
但是当我 运行 Lambda 中的代码时,它失败了。所以,我想知道 “运行 in EC2”和“运行 in Lambda”有什么区别? 为什么我 运行 它在 Lambda 中?
这是我的 Lambda 函数代码:
import boto3
s3 = boto3.client('s3', region_name='ap-northeast-1')
def lambda_handler(event, context):
bucket = '*xxxxxx*'
key = 's3-upload.json'
try:
response = s3.get_object(Bucket=bucket, Key=key)
print('--------------------------------------')
print(response)
print('--------------------------------------')
body = response['Body'].read()
print(body)
print('--------------------------------------')
print("CONTENT TYPE: " + response['ContentType'])
except Exception as e:
print('Error getting object.')
print(e)
raise e
即使它们在同一个 VPC 中,EC2 和 Lambda 在 AWS 中仍然是不同的环境。能够 运行 你的代码在一个而不是另一个意味着你的代码很好并且可以工作,所以它可能是 AWS 的配置问题。
您检查过 lambda 使用的 service/execution 角色了吗?
您需要确保它所使用的 IAM 角色被允许具有正确的 S3 访问级别。
这份关于 lambda 执行角色的文档可能会提供一个有用的起点:https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role
像这样的 IAM 策略会为您使用的任何执行角色提供对所有 S3 存储桶的只读访问权限,并且恰好是 AWS 托管策略之一。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "*"
}
]
}
如果您想允许 AWS Lambda 访问 Amazon S3,请使用以下方法之一:
- 不要将函数关联到 VPC。然后自动访问。
如果该函数附加到 VPC 中的 public 子网,请将 弹性 IP 关联到出现在VPC(不推荐)- 如果函数附加到 VPC 中的私有子网,请在 public 子网中启动 NAT 网关 并更新路由表。流量将通过 NAT 网关流向互联网。
- 在 VPC 中添加一个 Amazon S3 VPC 端点 并更新路由表。流量将流经该网关而不是 Internet 网关。
谢谢大家!我找到原因了。
我的 Lambda 有两个子网,private_sn_1 和 private_sn_2,
private_sn_1 已正确设置 vpc 端点路由 table,
但是 private_sn_2 设置了错误的路线 table,
我的 ec2 在 private_sn_1 中创建,因此它可以访问 vpc 端点。
正常情况下,Lambda 会在 private_sn_1 或 private_sn_2,
中随机 运行但在我的情况下它总是 运行 在 private_sn_2(我不知道为什么),
所以当我修复 private_sn_2 路线时 table,
一切正常。
除了上述所有内容之外,VPC 端点策略也可能是禁止的,不允许流量 to/from S3 通过。确保使用 "Full access" 策略允许流量通过端点。
编辑:这里是相关的文档:
Your policy must contain a Principal element. For gateway endpoints only, you cannot limit the principal to a specific IAM role or user. Specify "*" to grant access to all IAM roles and users. Additionally, for gateway endpoints only, if you specify the principal in the format "AWS":"AWS-account-ID" or "AWS":"arn:aws:iam::AWS-account-ID:root", access is granted to the AWS account root user only, and not all IAM users and roles for the account.
因此,为了使 S3 端点正常工作,您需要在一般情况下将“*”指定为主体