如何从账户 A 中的 Lambda(VPC 中的 Lambda)调用账户 B 中的 AWS Lambda 函数(VPC 中的这个 Lambda)
Posted
技术标签:
【中文标题】如何从账户 A 中的 Lambda(VPC 中的 Lambda)调用账户 B 中的 AWS Lambda 函数(VPC 中的这个 Lambda)【英文标题】:How to invoke AWS Lambda function in account B (this Lambda in VPC) from Lambda in account A (Lambda in VPC) 【发布时间】:2020-09-27 01:41:20 【问题描述】:我做了什么:
-
我在这些帐户之间创建了 VPC 对等连接
互联网网关也连接到每个 VPC
还配置了路由表(以允许来自双方的流量)
案例一:
当这 2 个 VPC 在同一个账户中时,我成功地测试了从另一个 Lambda 函数(在 VPC A 中)调用 Lambda 函数(在 VPC B 中)。
但是,当我在另一个账户(账户 B)中创建类似的 VPC(作为 VPC B)时,我收到以下错误:
"errorMessage": "调用 Invoke 操作时发生错误 (AccessDeniedException):用户:arn:aws:sts::Account-A:assumed-role/role-for-vpc-peering-test/lambda1_in_vpc 不是授权执行:lambda:InvokeFunction on resource:arn:aws:lambda:us-east-1:Account-B:function:lambda-vpc
我的足迹:
我在账户 B 中为账户 A 创建了一个跨账户 IAM 角色,具有以下权限:
然后我为账户 A 中使用 Lambda 的角色添加了内联策略:
仅向上述角色添加策略:
"Version": "2012-10-17",
"Statement":
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::Account B:role/role-for-Account-A"
所以我的问题是我是否应该做任何其他事情来从账户 A 中的 Lambda 调用账户 B 中的 Lambda?
我认为我在跨账户角色中缺少一些东西 (access denied error
)。
lambda-A 码:
导入 json 导入boto3
client = boto3.client('lambda')
def lambda_handler(事件,上下文): inputForInvoker = 'CustomerId': '123', 'Amount': 50
response = client.invoke(
FunctionName='arn:aws:lambda:us-east-1:AccountB-id:function:lambda-vpc-peering',
InvocationType='RequestResponse', # Event
Payload=json.dumps(inputForInvoker)
)
responseJson = json.load(response['Payload'])
print('\n')
print(responseJson)
print('\n')
有什么建议吗?
假设账户 b 中的角色是:具有以下策略:1. AWSLambdaBasicExecutionRole 2.信任政策:
"Version": "2012-10-17",
"Statement": [
"Effect": "Allow",
"Principal":
"AWS": "arn:aws:iam::Account-id-A:role/role-for-vpc-peering-test"
,
"Action": "sts:AssumeRole"
]
.
执行角色 - 附加此内联策略:
"Version": "2012-10-17",
"Statement":
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::Account-b-id:role/role-for-7691-4701-2358"
并用下面提到的代码更新了我的 lambda 函数。
但仍然出现同样的错误
现在 lambdas 不在 vpc 中。
【问题讨论】:
A 中的 lambda 代码是什么?您必须承担 B 中的角色,例如使用sts.assume_role(...)
boto3 通话。
是的,我在账户 b 中创建了跨账户角色,仅用于账户 A
我会回答的,因为我不想在评论中粘贴代码。
【参考方案1】:
以下 AWS 博客中列出了在账户 A 中担任角色以在账户 B 中执行某些操作(例如在 B 中调用 lambda 函数)所需的一般步骤:
How can I configure a Lambda function to assume a role from another AWS account?需要注意的重要一点是账户 A 中的 lambda 函数必须承担账户 B 中的角色。可承担角色必须允许函数 A 的执行角色调用 B 中的函数。
我根据上面链接中的示例修改了帐户 A 中的 lambda 代码。
需要关注的关键要素是:
sts = boto3.client('sts') account_b = sts.assume_role(...) account_b_client = boto3.client(...)假设您的所有角色都已正确设置,您的代码应该看起来像打击。显然,您必须完全根据自己的需要对其进行调整,但它应该让您大致了解在帐户 A 的 lambda 中应该做什么。
import json
import boto3
client = boto3.client('lambda')
sts = boto3.client('sts')
def lambda_handler(event, context):
inputForInvoker = 'CustomerId': '123', 'Amount': 50
account_b = sts.assume_role(
RoleArn="<arn-of-assumbale-role-in-acccount-b>",
RoleSessionName="cross_acct_lambda"
)
ACCESS_KEY = account_b['Credentials']['AccessKeyId']
SECRET_KEY = account_b['Credentials']['SecretAccessKey']
SESSION_TOKEN = account_b['Credentials']['SessionToken']
# create service client using the assumed role credentials
# from account B
account_b_client = boto3.client(
'lambda',
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
aws_session_token=SESSION_TOKEN)
response = account_b_client.invoke(FunctionName='arn:aws:lambda:us-east-1:AccountB-id:function:lambda-vpc-peering', InvocationType='RequestResponse')
responseJson = json.load(response['Payload'])
print('\n') print(responseJson) print('\n')
附言
我在这些帐户之间创建了 VPC 对等连接
这是不需要的。 从函数 A 调用函数 B 无论如何都会通过 Internet。因此,如果您不将对等连接用于其他任何用途,则它不会用于 lambda。
【讨论】:
嘿,Marcin,你能看看这个,我仍然面临同样的访问被拒绝错误(我最后提到了更新的东西) @MaldannaGk 角色可能不正确。您能否在问题中添加以下名称:Acc A 中函数的执行角色、Acc B 中函数的执行角色以及 Acc A 中的 lambda 承担的 B 中的跨账户角色?以上是关于如何从账户 A 中的 Lambda(VPC 中的 Lambda)调用账户 B 中的 AWS Lambda 函数(VPC 中的这个 Lambda)的主要内容,如果未能解决你的问题,请参考以下文章
手动将 ENI 从子网分离后,VPC 中的 Lambda 不会创建新的 ENI
允许 VPC 中的 Lambda 访问同一 VPC 中的 Elasticsearch 域
如何将 VPC 和安全组分配给 AWS CDK 中的 Lambda?
AWS - 从公共 API 网关到 VPC 内 lambda 的路由