0

我试图实现一个用例,其中可以通过AWS CloudFormation模板跨L帐户调用Lambda函数。未能调用Lambda跨帐户创建Lambda支持的自定义资源

我在部署一个account B AWS CloudFormation堆栈,它有一个能调用,在account A定义lambda函数的自定义资源。 我在account A中创建了Lambda的交叉帐户角色,account B作为可信实体。此外,account B中的用户已附加了允许其承担此角色的策略。 不幸的是,堆栈创建失败了访问错误。

希望有任何帮助。这是我对B账户模板:

{ 
    "AWSTemplateFormatVersion": "2010-09-09", 
    "Resources": { 
    "GetNwInterfaces":{ 
     "Type": "Custom::GetNwInterfaces", 
     "Properties": { 
     "ServiceToken": "arn:aws:lambda:ap-northeast-2:XXXXXXXXXX:function:getini2", 
     "region": "us-west-2", 
     "uid" : "01100" 
     } 
    } 
    } 
} 
+0

你得到了什么确切的错误? 您可以分享其他模板(即正在使用的帐户A)吗? – Aditya

回答

0

有相应权限的创建账户A lambda函数,例如,使用此cloudformation模板:

Parameters: 
    OtherAccountId: 
    Type: String 

Resources: 
    TestFunction: 
    Type: AWS::Lambda::Function 
    Properties: 
     Runtime: python2.7 
     Handler: index.handler 
     Role: !GetAtt TestRole.Arn 
     Code: 
     ZipFile: !Sub | 
      from botocore.vendored import requests 
      import json 


      def send(event, context, responseStatus, responseData, physicalResourceId): 
       responseUrl = event['ResponseURL'] 

       print responseUrl 

       responseBody = {} 
       responseBody['Status'] = responseStatus 
       responseBody['Reason'] = 'See the details in CloudWatch Log Stream: ' + context.log_stream_name 
       responseBody['PhysicalResourceId'] = physicalResourceId or context.log_stream_name 
       responseBody['StackId'] = event['StackId'] 
       responseBody['RequestId'] = event['RequestId'] 
       responseBody['LogicalResourceId'] = event['LogicalResourceId'] 
       responseBody['Data'] = responseData 

       json_responseBody = json.dumps(responseBody) 

       print "Response body:\n" + json_responseBody 

       headers = { 
        'content-type' : '', 
        'content-length' : str(len(json_responseBody)) 
       } 

       try: 
        response = requests.put(responseUrl, 
              data=json_responseBody, 
              headers=headers) 
        print "Status code: " + response.reason 
       except Exception as e: 
        print "send(..) failed executing requests.put(..): " + str(e) 

      def handler(event, context): 
       print event 
       print context 

       responseData = {} 

       send(event, context, "SUCCESS", responseData, "CustomResourcePhysicalID") 

    CrossAccountPermission: 
    Type: AWS::Lambda::Permission 
    Properties: 
     Action: lambda:InvokeFunction 
     FunctionName: !Ref TestFunction 
     Principal: !Ref OtherAccountId 

    TestRole: 
    Type: AWS::IAM::Role 
    Properties: 
     AssumeRolePolicyDocument: 
     Version: 2012-10-17 
     Statement: 
      - 
      Effect: Allow 
      Principal: 
       Service: 
       - lambda.amazonaws.com 
      Action: 
       - sts:AssumeRole 
     Policies: 
     - PolicyName: AllowAccess 
      PolicyDocument: 
      Version: 2012-10-17 
      Statement: 
       - Effect: Allow 
       Action: 
        - "logs:*" 
       Resource: "arn:aws:logs:*:*:*" 

CrossAccountPermission记录这里最重要的一个,那么我们授予对帐户B的访问权限。

在帐户B中,使用以下模板对其进行测试:

Parameters: 
    LambdaArn: 
    Type: String 

Resources: 
    CustomResourceTest: 
    Type: Custom::Demo 
    Properties: 
     ServiceToken: !Ref LambdaArn 

这里还有一个额外的问题:在帐户B中运行cloudformation的用户/角色也需要执行Lambda函数的权限(如果您正在以不应该成为问题的管理员用户身份运行CF)无论如何,您将拥有资源*lambda:*权限。

+0

嗨Paulo,在这个练习中发现了一件有趣的事情。除了帐户A中的交叉账户访问角色以及完全的lambda访问权限和来自账户B的角色假设权限之外,我们还需要直接添加对lambda函数的另一层访问权限,该权限是从CLI调用的,它使整个工作起作用--- aws lambda add-permission --function-name test_lambda --region us-east-1 --statement-id id-123 --action“lambda:InvokeFunction”--principal 1234567890 – schaganti