使用 Step Functions 和 Lambda 代理函数在 AWS 账户上启动 CodeBuild 项目 - AWS Prescriptive Guidance

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 Step Functions 和 Lambda 代理函数在 AWS 账户上启动 CodeBuild 项目

由 Richard Milner-Watts (AWS) 和 Amit Anjarlekar (AWS) 创作

代码库:跨账户 CodeBuild 代理

环境:生产

技术: DevOps;管理和治理;运营;无服务器

AWS 服务:AWS CodeBuild;AWS Lambda;AWS Step Functions;AWS X-Ray;AWS CloudFormation

Summary

此模式演示了如何使用 AWS Step Functions 和 AWS Lambda 代理函数跨多个 AWS 账户异步启动 AWS CodeBuild 项目。你可以使用模式的示例 Step Functions 状态机来测试你的 CodeBuild 项目是否成功。

CodeBuild 帮助您在完全托管的运行时环境中使用 AWS 命令行界面 (AWS CLI) Line Interface 启动操作任务。您可以通过覆盖环境变量来更改 CodeBuild 项目在运行时的行为。此外,您还可以使用 CodeBuild 来管理工作流程。有关更多信息,请参阅 AWS Workshop 网站上的服务目录工具和在 AWS 数据库博客上使用 AWS 在 Amazon RDS for PostgreSQL 中安排作业,并在 CodeBuild AWS 数据库博客上使用 EventBridge亚马逊安排作业。

先决条件和限制

先决条件

  • 两个活跃的 AWS 账户:一个用于通过 Step Functions 调用 Lambda 代理函数的源账户和一个用于构建远程示例项目的目标账户 CodeBuild

限制

  • 此模式不能用于在账户之间复制构件

架构

下图显示此模式构建的架构。

跨多个 AWS 账户启动 CodeBuild 项目的架构图

图表显示了以下工作流:

  1. Step Functions 状态机解析提供的输入映射,并为您定义的每个账户、区域和项目调用 Lambda 代理函数 (codebuild-proxy-lambda)。

  2. Lambda 代理函数使用 AWS Security Token Service (AWS STScodebuild-proxy-role) 来担任 IAM 代理角色 (),该角色与目标账户中的 IAM 策略 (codebuild-proxy-policy) 关联。

  3. 使用代入的角色,Lambda 函数启动 CodeBuild 项目并返回 CodeBuild 任务 ID。Step Functions 状态机循环并轮询 CodeBuild 作业,直到收到成功或失败状态。

状态机逻辑如下图所示。

Step Functions 状态机的工作流程

技术堆栈

  • AWS CloudFormation

  • CodeBuild

  • IAM

  • Lambda

  • Step Functions

  • X-Ray

工具

  • AWS CloudFormation 可帮助您设置 AWS 资源,快速一致地配置这些资源,并在 AWS 账户和区域的整个生命周期中对其进行管理。

  • AWS CloudFormation Designer 提供了一个集成的 JSON 和 YAML 编辑器,可帮助您查看和编辑 CloudFormation 模板。

  • AWS CodeBuild 是一项完全托管的构建服务,可帮助您编译源代码、运行单元测试和生成可随时部署的项目。

  • AWS Identity and Access Management(AWS IAM)通过控制验证和授权使用您 AWS 资源的用户,帮助您安全地管理对您 AWS 资源的访问。

  • AWS Lambda 是一项计算服务,可帮助您运行代码,而无需预置或管理服务器。它仅在需要时运行您的代码,并且能自动扩展,因此您只需为使用的计算时间付费。

  • AWS Step Functions 是一项无服务器编排服务,可让您搭配使用 AWS Lambda 函数和其他 Amazon Web Services 来构建业务关键型应用程序。

  • AWS X-Ray – 帮助您收集您的应用程序所服务的请求的相关数据,并提供用于查看、筛选和获取数据洞察力的工具,以确定问题和发现优化机会。

代码

此模式的示例代码可在 GitHub跨账户 CodeBuild 代理存储库中找到。此模式使用 AWS Lambda Powertools for Python 库来提供日志和跟踪功能。有关此库及其实用程序的更多信息,请参阅 Powertools for AWS Lambda (Python)

最佳实践

  1. 调整 Step Function 状态机中的等待时间值,以最大限度地减少对作业状态的轮询请求。使用 CodeBuild 项目的预期执行时间。

  2. 在 Step Functions 中调整地图的MaxConcurrency属性以控制可以并行运行的 CodeBuild 项目数量。

  3. 如有必要,请查看示例代码是否已准备就绪。考虑解决方案可能记录哪些数据,以及默认的 Amazon CloudWatch 加密是否足够。

操作说明

任务描述所需技能

记录 Amazon Web Services account ID。

需要使用 Amazon Web Services account ID 才能设置跨账户访问权限。

记录您的源账户和目标账户的 Amazon Web Services account ID。有关更多信息,请参阅 IAM 文档中的 查找您 Amazon Web Services account ID

AWS DevOps

下载 AWS CloudFormation 模板。

  1. GitHub 存储库中下载此模式的 sample_target_codebuild_template.yaml AWS CloudFormation 模板。

  2. GitHub 存储库中下载此模式的 codebuild_lambda_proxy_template.yaml AWS CloudFormation 模板。

注意:在 AWS CloudFormation 模板中,<SourceAccountId>是源账户的 AWS 账户 ID,<TargetAccountId>也是目标账户的 AWS 账户 ID。

AWS DevOps

创建并部署 AWS CloudFormation 堆栈。

  1. 登录您的源账户的 AWS 管理控制台,打开 AWS CloudFormation 控制台,然后选择 Stacks

  2. 选择创建堆栈,然后选择使用新资源(标准)

  3. 对于 Template source(模板来源),选择 Upload a template file(上载模板文件)。

  4. 对于上传模板文件,选择文件,然后选择您下载的codebuild_lambda_proxy_template.yaml文件。选择下一步

  5. 对于 堆栈名称,输入堆栈名称 (例如codebuild-lambda-proxy)。

  6. crossAccountTargetRoleArn参数替换成您的 <TargetAccountId>(例如,<arn:aws:iam::123456789012:role/proxy-lambda-codebuild-role>)。注意:您无需更新 targetCodeBuildProject参数的默认值。

  7. 选择下一步,接受默认堆栈创建选项,然后选择下一步

  8. 选中 “我确认 AWS CloudFormation 可能会使用自定义名称创建 IAM 资源” 复选框,然后选择 “创建堆栈”。

注意:在目标账户中创建任何资源之前,您必须为代理 Lambda 函数创建 AWS CloudFormation 堆栈。当您在目标账户中创建信任策略时,IAM 角色会从角色名称转换至内部标识符。所以 IAM 角色必须已经存在。

AWS DevOps

确认代理函数和状态机已创建。

  1. 等待 AWS CloudFormation 堆栈达到 CREATE_COMPLETE 状态。这应该需要不到 1 分钟的时间。

  2. 打开 AWS Lambda 控制台,选择函数,然后查找lambda-proxy-ProxyLambda-<GUID>函数。

  3. 打开 AWS Step Functions 控制台,选择状态机,然后查找 sample-crossaccount-codebuild-state-machine状态机。

AWS DevOps
任务描述所需技能

创建并部署 AWS CloudFormation 堆栈。

  1. 登录目标账户的 AWS 管理控制台,打开 AWS CloudFormation 控制台,然后选择 Stacks

  2. 选择创建堆栈,然后选择使用新资源(标准)

  3. 对于 Template source(模板来源),选择 Upload a template file(上载模板文件)。

  4. 对于上传模板文件,选择选择文件,然后选择sample_target_codebuild_template.yaml文件。选择下一步

  5. 对于堆栈名称,请为堆栈输入名称(例如,sample-codebuild-stack)。

  6. crossAccountSourceRoleArn参数替换成您的 <SourceAccountId>(例如,<arn:aws:iam::123456789012:role/codebuild-proxy-lambda-role>)。

  7. 选择下一步,接受默认堆栈创建选项,然后选择下一步

  8. 选中 “我确认 AWS CloudFormation 可能会使用自定义名称创建 IAM 资源” 复选框,然后选择 “创建堆栈”。

AWS DevOps

验证示例 CodeBuild 项目的创建。

  1. 等待 AWS CloudFormation 堆栈达到 CREATE_COMPLETE 状态。这应该需要不到 1 分钟的时间。

  2. 打开 A WS CodeBuild 控制台,然后找到该sample-codebuild-project项目。

AWS DevOps
任务描述所需技能

启动状态机。

  1. 登录您的源账户的 Amazon Web Services Management Console,打开 AWS Step Functions 控制台,选择状态机

  2. 选择 sample-crossaccount-codebuild-state-machine状态机,然后选择开始执行

  3. 输入编辑器中,输入以下 JSON,然后<TargetAccountID>替换为包含该 CodeBuild 项目的账户的 AWS 账户 ID。

    { "crossAccountTargetRoleArns": [ { "arn": "arn:aws:iam::<TargetAccountID>:role/proxy-lambda-codebuild-role", "region": "eu-west-1", "codeBuildProject": "sample-codebuild-project", "SampleValue1": "Value1", "SampleValue2": "Value2" } ] }

    注意:键值对作为环境变量从源账户中的函数传递到目标账户中的 CodeBuild 项目。

  4. 选择启动执行

  5. 在状态机页面的详细信息选项卡,检查执行状态是否设置为成功。这可以确认您的状态机正运行。注意:状态机可能需要大约 30 秒才能达到 成功状态。

  6. 要查看状态机中某个 步骤的输出和输入,请在执行事件历史记录 部分中展开该步骤。例如,展开 Lambda- CodeBuild 代理-启动步骤。输出包括有关被覆盖的环境变量、原始有效载荷和 CodeBuild 作业 ID 的详细信息。

AWS DevOps

验证环境变量。

  1. 使用您的目标账户登录 Amazon Web Services Management Console。

  2. 打开 AWS CodeBuild 控制台,展开 “建”,然后选择 “构建项目”。

  3. 选择sample-codebuild-project项目,然后选择 “查看详细信息”。

  4. 在 “生成历史记录” 选项卡上,选择项目的最新版本,然后选择 “查看日志”。

  5. 在日志输出中,验证打印至 STDOUT 的环境变量是否与 Step Functions 示例状态机中的环境变量相匹配。

AWS DevOps

故障排除

问题解决方案

Step Functions 的执行时间比预期的要长。

在 Step Function 状态机中调整地图的MaxConcurrency属性,以控制可以并行运行多少 CodeBuild 项目。

CodeBuild 任务的执行时间比预期的要长。

  1. 调整 Step Functions 状态机中的等待时间值,以最大限度地减少对作业状态的轮询请求。使用 CodeBuild 项目的预期执行时间。

  2. 考虑使用的工具 CodeBuild 是否合适。例如,初始化 CodeBuild 任务所需的时间可能比 AWS Lambda 长得多。如果需要高吞吐量和快速完成时间,可以考虑将业务逻辑迁移到 AWS Lambda 并使用扇出架构。