如何从账户 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 的路由

当 lambda 在 vpc 中时,无法从 lambda 运行 Fargate 任务

将 Lambda 函数分配给 serverless.yml 中的特定 VPC ID