跨账号CodePipeline调用Lambda遇JobNotFoundException及结果返回问题
Hey there! Great question—yes, you absolutely can return putJobSuccess/putJobFailure results from a cross-account Lambda to your CodePipeline in Account A. The missing JobID issue you're facing happens because the Lambda in Account B doesn't have access to Account A's native CodePipeline job context by default. Let's walk through how to fix this step by step:
1. 显式传递JobID给跨账号Lambda
在Account A的CodePipeline中配置调用Account B Lambda的阶段时,需要把JobID作为参数传递过去:
- 进入CodePipeline阶段的动作配置页面
- 在User Parameters字段中输入
#{codepipeline.jobId},这样当前Job的ID会被注入到发送给Account B Lambda的事件中
2. 给Account B的Lambda添加权限
Account B的Lambda需要明确的IAM权限,才能调用Account A CodePipeline的成功/失败API。给Lambda的执行角色添加如下策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codepipeline:PutJobSuccessResult", "codepipeline:PutJobFailureResult" ], "Resource": "arn:aws:codepipeline:<A账号区域>:<A账号ID>:<Pipeline名称>" } ] }
记得替换占位符为你Account A的实际区域、账号ID和流水线名称。
3. 修改Lambda代码使用传递的JobID
在Account B的Lambda代码中,从传入事件中提取JobID,然后显式调用CodePipeline API返回结果。这里是Python的示例:
import boto3 def lambda_handler(event, context): # 从UserParameters中提取传递的JobID job_id = event['CodePipeline.job']['data']['actionConfiguration']['configuration']['UserParameters'] # 初始化CodePipeline客户端(指定Account A的区域) codepipeline_client = boto3.client('codepipeline', region_name='<A账号区域>') try: # 执行你的核心业务逻辑 print("跨账号任务执行成功!") # 向Account A的CodePipeline发送成功结果 codepipeline_client.put_job_success_result( jobId=job_id, executionDetails={ 'summary': '跨账号任务已完成,无异常' } ) except Exception as e: # 发送失败结果 codepipeline_client.put_job_failure_result( jobId=job_id, failureDetails={ 'message': f"任务失败:{str(e)}", 'type': 'JobFailed' } ) # 重新抛出异常用于日志记录 raise e
额外关键注意事项
- Account A的CodePipeline权限:确保Account A的CodePipeline执行角色有调用Account B Lambda的权限,需要给该角色添加
lambda:InvokeFunction动作,目标为Account B Lambda的ARN。 - Lambda资源策略:Account B的Lambda还需要配置资源策略,允许Account A的CodePipeline角色调用它,示例如下:
{ "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "AllowAccountACodePipelineInvoke", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<A账号ID>:role<CodePipeline执行角色名称>" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:<B账号区域>:<B账号ID>:function:<Lambda名称>" } ] }
按照这些步骤配置后,跨账号Lambda就能正确向Account A的CodePipeline返回任务状态了。
内容的提问来源于stack exchange,提问作者charsidrogo

