使用和自动进行动态管道管理,以便在 Gitflow 环境中部署修补程序解决方案 AWS Service Catalog AWS CodePipeline - AWS 规范指引

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

使用和自动进行动态管道管理,以便在 Gitflow 环境中部署修补程序解决方案 AWS Service Catalog AWS CodePipeline

Balaji Vedagiri、Faisal Shahdad、Shanmugam Shanker 和 Vivek Thangamuthu,Amazon Web Services

Summary

注意

AWS CodeCommit 不再向新客户提供。的现有客户 AWS CodeCommit 可以继续照常使用该服务。了解详情

此模式适用于管理专门用于将修补程序解决方案安全地部署到生产环境的动态修补程序管道的情况。该解决方案是通过使用产品 AWS Service Catalog 组合和产品来实施和管理的。Amazon EventBridge 规则用于事件自动化。使用 Service Catalog 产品组合约束以及开发人员的 AWS Identity and Access Management (IAM)角色强制执行限制。只有一个 AWS Lambda 函数可以启动由 EventBridge 规则触发的 Service Catalog 产品。此模式专为采用特定 Gitflow 设置的环境而设计,详见附加信息

通常,部署修补程序是为了解决在实时环境(例如生产)中报告的关键问题或安全问题。修补程序应当仅直接部署到暂存和生产环境。暂存和生产管道广泛用于常规开发请求。这些管道不能用于部署修补程序,因为质量保证中有一些在研功能无法部署到生产中。为了发布修补程序,该模式描述了具有以下安全功能的动态、短暂的管道:

  • 自动创建-每当在存储库中创建修补程序分支时,都会自动创建修补程序管道。 AWS CodeCommit

  • 访问限制 - 开发人员无权在修补程序流程之外创建此管道。

  • 受控阶段 – 管道具有使用特殊访问令牌的受控阶段,确保拉取请求(PR)只能创建一次。

  • 审批阶段 – 审批阶段包括在该管道中,以获得相关干系人的必要审批。

  • 自动删除-每当仓库中的分支与 PR 合并后,只要删除 CodeCommit 存储库中的hotfix分支,就会自动删除该修补程序管道。

先决条件和限制

先决条件

  • 需要三个 AWS 账户 处于活动状态,如下所示:

    • 工具账户 - 用于持续集成和持续交付(CI/CD)设置。

    • 暂存账户 - 用于用户验收测试。

    • 生产账户 - 用于企业最终用户。

    • (可选)添加一个 AWS 账户 以充当 QA 帐户。如果您想要同时使用主管道设置(包括 QA)和修补程序管道解决方案进行测试,则需要此账户。

  • 具有可选条件的 AWS CloudFormation 堆栈,可根据需要使用主管道在 QA 账户中部署。通过创建和删除 hotfix 分支,仍然可以在没有主管道设置的情况下测试该模式。

  • 亚马逊简单存储服务 (Amazon S3) 存储桶,用于存储 CloudFormation 用于创建服务目录产品的模板。

  • 根据合规性要求为 CodeCommit 存储库创建 PR 批准规则(在创建存储库之后)。

  • 限制开发人员和团队负责人的 IAM 权限以禁止其执行 prcreation-lambda Lambda 函数,因为该函数仅应从管道中调用。

限制

  • 在部署阶段使用 CloudFormation 提供程序,使用 CloudFormation 更改集部署应用程序。如果要使用其他部署选项,请根据需要修改 CodePipeline 堆栈。

  • 此模式使用 AWS CodeBuild 和其他配置文件来部署示例微服务。如果您有不同的工作负载类型(例如,无服务器工作负载),则必须更新所有相关配置。

  • 这种模式将应用程序部署在单个 AWS 区域 (例如,美国东部(弗吉尼亚北部)us-east-1)中。 AWS 账户要跨多个区域进行部署,请更改命令和堆栈中的区域引用。

  • 有些 AWS 服务 并非全部可用 AWS 区域。有关区域可用性,请参阅按区域划分的 AWS 服务。有关特定端点,请参阅服务端点和配额,然后选择相应服务的链接。

架构

本节中的图表提供了创建生命周期事件和删除生命周期事件的工作流。

创建生命周期事件的工作流。

上面创建生命周期事件的图表显示了以下内容:

  1. 开发人员在 CodeCommit 存储库中创建一个hotfix-*分支来开发与 hotfix 相关的解决方案。

  2. hotfix-*支创建事件是通过 EventBridge 规则捕获的。事件详细信息包括存储库名称和分支名称。

  3. 该 EventBridge 规则调用该函数。 AWS Lambda hotfix-lambda-function该 EventBridge 规则将事件信息作为输入传递给 Lambda 函数。

  4. Lambda 函数处理输入以检索存储库名称和分支名称。它使用从处理的输入中检索到的值启动 Service Catalog 产品。

  5. Service Catalog 产品包括将解决方案部署到预发布和生产环境的管道设置。管道块包括源、构建和部署阶段。此外,还有一个手动批准阶段,可以促进生产环境的部署。

  6. 源阶段从第一步中创建的存储库和 hotfix-* 分支检索代码。该代码通过用于存放构件的 Amazon S3 存储桶传递到构建阶段。在构建阶段,将创建一个容器映像,其中包含在 hotfix-* 分支中开发并推送到 Amazon Elastic Container Registry(Amazon ECR)中的修补程序。

  7. 预发布环境的部署阶段使用包含此修补程序的最新容器映像更新 Amazon Elastic Container Service(Amazon ECS)。此修补程序是通过创建和执行 CloudFormation 更改集来部署的。

  8. 在 Stage 环境中成功部署后调用 prcreation-lambda Lambda 函数。此 Lambda 函数创建从 hotfix-* 分支到存储库 developmain 分支的 PR。Lambda 函数可确保 hotfix-* 分支中开发的修复程序被回溯并包含在后续部署中。

  9. 手动批准阶段有助于确保必要的利益相关者审核该修复并批准在生产环境中部署。

  10. 生产环境的部署阶段使用包含此修补程序的最新容器映像更新 Amazon ECS。此修补程序是通过创建和执行 CloudFormation 更改集来部署的。

删除生命周期事件的工作流。

上面删除生命周期事件的图表显示了以下内容:

  1. 成功将修补程序部署到生产环境后,开发人员会删除该 hotfix-* 分支。

  2. hotfix-*支删除事件是通过 EventBridge 规则捕获的。事件详细信息包括存储库名称和分支名称。

  3. 该 EventBridge 规则调用 Lambda 函数。该 EventBridge 规则将事件信息作为输入传递给 Lambda 函数。

  4. Lambda 函数处理输入以检索存储库名称和分支名称。Lambda 函数根据传递的输入确定相应的 Service Catalog 产品,然后终止该产品。

  5. Service Catalog 预调配的产品终止会删除之前在该产品中创建的管道和相关资源。

自动化和扩展

  • 该模式包括一个 EventBridge 规则和一个 Lambda 函数,它们可以并行处理多个修补程序分支创建请求。Lambda 函数为匹配的事件规则预调配 Service Catalog 产品。

  • 管道设置通过使用提供版本控制功能的 Service Catalog 产品来处理。该解决方案还可以自动扩展,以并行处理同一应用程序的多个修补程序开发。

  • prcreation-lambda 函数可确保通过自动创建拉取请求,将这些修补程序更改合并回 maindevelop 分支中。这种方法对于确保 maindevelop 分支及时同步所有修复内容并避免潜在的代码回归至关重要。此过程通过确保所有长期存在的分支获得了最新的修复程序,有助于保持分支之间的一致性,并防止代码回归。

工具

AWS 服务

其他工具

代码存储库

此模式的代码可在 d GitHub ynamic_hotfix_ codepipeline 存储库中找到。

最佳实践

查看并调整您环境中的 IAM 角色和服务控制策略(SCP),以确保它们适当地限制访问。这对于防止任何可能覆盖此模式中包含的安全措施的行为至关重要。遵循最低权限原则,并授予执行任务所需的最低权限。有关详情,请参阅 IAM 文档中的授予最低权限安全最佳实践

操作说明

Task说明所需技能

克隆存储库。

要将示例存储库克隆到工作地点的新目录中,请运行以下命令:

git clone git@github.com:aws-samples/dynamic_hotfix_codepipeline.git
AWS DevOps

导出用于 CloudFormation 堆栈部署的环境变量。

定义以下环境变量,这些变量将在此模式的后面用作 CloudFormation 堆栈的输入。

  • ApplicationName – 此变量用于命名为应用程序创建的资源,以便于跟踪这些资源。使用以下命令,将 Applicationname 替换为实际应用程序名称:

    export ApplicationName=<Applicationname>
  • BucketStartName – 此变量用于命名 Amazon S3 存储桶。S3 存储桶名称在所有存储桶中必须是全局唯一的 AWS 账户。使用以下命令,将您的 S3 存储桶的 BucketName 替换为唯一名称:

export BucketStartName=<BucketName>
  • 账号和区域-这些变量存储不同环境和部署区域的账 AWS 账户 号。使用以下命令,将占位符(例如prodaccountnumberregion)替换为实际 AWS 账户 数字和正在 AWS 区域 使用的数字。

    注意

    QAAccount 为可选项。如果要使用 QAAccount,请使用主管道堆栈的参数对其进行设置。

export ProdAccount=<prodaccountnumber> export StageAccount=<stage/preprodaccountnumber> export QAAccount=<qaccountnumber> export ToolsAccount=<toolsaccountnumber> export DepRegion=<region>
AWS DevOps
Task说明所需技能

在工具账户 CI/CD 中创建所需的资源。

要在工具账户中部署 CloudFormation 堆栈,请使用以下命令。(如果您不使用 QA 账户进行设置,请删除该 QAAccount 参数。)

#InToolsAccount aws cloudformation deploy \ --template-file pre-requisites/pre-reqs.yaml \ --stack-name prereqs \ --parameter-overrides BucketStartName=${BucketStartName} \ ApplicationName=${ApplicationName} ProdAccount=${ProdAccount} \ StageAccount=${StageAccount} ToolsAccount=${ToolsAccount} \ QAAccount=${QAAccount} \ --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM --region ${DepRegion}

记下 CodeCommit 存储库和 Amazon ECR 从前面的堆栈中创建的资源。在接下来的步骤中,设置管道的 main 分支需要用到这些参数。

AWS DevOps

在工作负载帐户 CI/CD 中创建所需的资源。

  1. 要将 CloudFormation 模板打包到每个工作负载帐户(阶段、生产和可选 QA)中,请使用以下命令。在以下命令中,将 S3bucketpackage 替换为要在打包时使用的 Amazon S3 存储桶名称。

    #InStageAccount aws cloudformation package \ --template-file pre-requisites/infrastack.yaml \ --s3-bucket <S3bucketpackage> \ --s3-prefix infraStack \ --region ${DepRegion} \ --output-template-file pre-requisites/infrastructure_stage.template #InProdAccount aws cloudformation package \ --template-file pre-requisites/infrastack.yaml \ --s3-bucket <S3bucketpackage> \ --s3-prefix infraStack \ --region ${DepRegion} \ --output-template-file pre-requisites/infrastructure_prod.template
  2. 要在每个工作负载帐户中部署 CloudFormation 模板,请使用以下命令:

    #InStageAccount aws cloudformation deploy --stack-name inframainstack \ --parameter-overrides ApplicationName=${ApplicationName} ToolsAccount=${ToolsAccount} DepRegion=${DepRegion} \ --template-file pre-requisites/infrastructure_stage.template --region ${DepRegion} --capabilities CAPABILITY_NAMED_IAM #InProdAccount aws cloudformation deploy --stack-name inframainstack \ --parameter-overrides ApplicationName=${ApplicationName} ToolsAccount=${ToolsAccount} DepRegion=${DepRegion} \ --template-file pre-requisites/infrastructure_prod.template --region ${DepRegion} --capabilities CAPABILITY_NAMED_IAM
AWS DevOps

更新 S3 构件存储桶策略以允许工作负载账户访问。

要更新工具帐户中的 CloudFormation 堆栈先决条件,请使用以下命令为阶段和生产工作负载帐户添加所有必需的权限。(如果您不使用该 QAAccount 参数进行设置,请将其删除。)

#InToolsAccount aws cloudformation deploy \ --template-file pre-requisites/pre-reqs.yaml \ --stack-name prereqs \ --parameter-overrides BucketStartName=${BucketStartName} \ ApplicationName=${ApplicationName} ProdAccount=${ProdAccount} \ StageAccount=${StageAccount} ToolsAccount=${ToolsAccount} \ QAAccount=${QAAccount} PutPolicy=true \ --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM --region ${DepRegion}
AWS DevOps
Task说明所需技能

设置 Service Catalog 产品组合和产品。

要设置 Service Catalog 产品组合和产品,请执行以下操作:

  1. 将模板 pipeline-main.yamlpipeline-hotfix.yaml 从目录中的存储库上传到您要部署 CodePipeline 到的区域中的现有 Amazon S3 存储桶 Bucketname () 中 ()。DepRegion

    #InToolsAccount aws s3 cp ./codepipeline/pipeline-main.yaml s3://<Bucketname>/pipeline-main.yaml aws s3 cp ./codepipeline/pipeline-hotfix.yaml s3://<Bucketname>/pipeline-hotfix.yaml
  2. 设置用于管理 mainhotfix 分支管道的 Service Catalog 产品组合和产品。记下来自以下堆栈 MainProductIdMainProductArtifactIdOutputs 部分的详细信息。在 main 分支的管道设置过程中,后续步骤中需要这些信息。

    #InToolsAccount aws cloudformation deploy \ --template-file pre-requisites/servicecatalogsetup.yaml \ --stack-name servicecatalogsetup \ --parameter-overrides TemplateBucket=<Bucketname> \ --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM --region ${DepRegion}
  3. 为 IAM 角色提供访问权限,该角色将工具账户中的资源部署到 Service Catalog 产品组合的主管道组合。使用此产品组合通过 main 分支部署应用程序。有关如何提供访问权限的更多信息,请参阅 Service Catalog 文档中的向用户授予访问权限

AWS DevOps

设置 Lambda 函数。

此解决方案使用以下 Lambda 函数来管理修补程序工作流:

  • hotfix-lambda-function 在创建 hotfix 分支时处理 Service Catalog 产品预调配。

  • hotfix 分支被删除时 hotfix-cleanup-lambda-function 管理产品终止。

  • prcreation-lambda 创建从 hotfix 分支到 developmain 分支的拉取请求。

要使 Lambda 函数能够在通过关联 EventBridge 规则创建或删除hotfix 分支时预置和终止 Service Catalog 产品,请使用以下步骤:

  1. 要为 Lambda 函数创建 IAM 角色和权限,请使用以下命令部署堆栈: CloudFormation

    #InToolsAccount aws cloudformation deploy \ --template-file pre-requisites/lambdasetup.yaml \ --stack-name prsclambdasetup \ --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM --region ${DepRegion}
  2. 部署堆栈后,使用 AWS 管理控制台 授予对 Service Catalog 产品组合修补程序管道组合的 hotfix-lambda-execution-role 访问权限。此访问权限允许 Lambda 函数启动或终止修补程序分支的 Service Catalog 产品。

AWS DevOps
Task说明所需技能

main 分支设置管道。

要为主分支设置管道,请在工具账户中运行以下命令。将 MainProductIdMainProductArtifactId 的参数替换为 servicecatalogsetup 堆栈输出中的值。

#InToolsAccount aws servicecatalog provision-product \ --product-id <MainProductId> \ --provisioning-artifact-id <MainProductArtifactId> \ --provisioned-product-name "${ApplicationName}-main-pipeline" \ --provisioning-parameters Key=CodeCommitRepoName,Value="${ApplicationName}-repository" Key=ECRRepository,Value="${ApplicationName}-app" \ --region=${DepRegion}
AWS DevOps

使用 main 分支部署应用程序。

  1. 要克隆在先决条件中创建的 CodeCommit 存储库,请使用命令。git clone有关更多信息,请参阅如 CodeCommit 文档中所述, CodeCommit 通过克隆存储库来连接存储库。

  2. 将存储库的可用 repotemplates 目录中的所有应用程序文件复制到本地存储库克隆版本(${ApplicationName}-repository)中。修改以下文件以更新 ToolsAccount ID。在每个文件中,找到 RegistryAccountid 参数并将其值设置为您的 ToolsAccount ID。将更改提交到 CodeCommit 存储库,然后将文件推送到maindevelop分支。

  3. 要验证应用程序部署,请使用监控 CodePipeline 执行情况 AWS 管理控制台。部署完成后,在 Stage 环境中使用应用程序负载均衡器 FQDN 访问应用程序。确认应用程序按预期方式工作。

  4. 要批准部署到生产环境,请使用 CodePipeline 控制台查找应用程序的管道。找到 ApprovalToStart 阶段。审核更改,如果满意,则手动批准以继续进行生产部署。

AWS DevOps
Task说明所需技能

创建 hotfix-* 分支并提交更改。

要为 hotfix-* 分支创建管道并将修补程序部署到工作负载账户,请执行以下操作:

  1. 使用以关键字 hotfix 开头的名称创建分支。例如,此模式使用 CodeCommit 应用程序存储库中的hotfix-check1分支 (${ApplicationName}-repository)。有关更详细的步骤,请参阅 CodeCommit 文档中的 Connect 到 AWS CodeCommit 存储库和基本 Git 命令

  2. 验证是否已成功地为 hotfix-check1 分支动态预调配了 Service Catalog 产品 Hotfix CICD Pipeline。预配置的产品名称以此修补程序分支名称和应用程序 CodeCommit 存储库名称命名。

  3. index.html 文件中提交一些小改动,然后将其推送到 CodeCommit 存储库。

  4. 验证在舞台环境中 CodePipeline 执行是否成功。要在生产环境中部署,请在中提供手动批准 CodePipeline。

  5. 使用应用程序负载均衡器完全限定域名(FQDN)确认更改在应用程序主页中可见。FQDN 可在 inframainstack-ALBStack-*Outputs 部分中找到。

AWS DevOps

删除 hotfix-check1 分支。

要删除之前创建的 hotfix-check1 分支,请执行以下操作:

  1. 删除 CodeCommit 应用程序存储库中的hotfix-check1分支。

  2. 验证为 hotfix-check1 分支预调配的 Service Catalog 产品已成功终止。

AWS DevOps
Task说明所需技能

清理部署的资源。

要清理之前部署的先决条件,请执行以下操作:

  1. 要将 Amazon ECS 服务缩减到工作负载账户中的零副本,请使用以下命令:

    aws ecs update-service --cluster ${ApplicationName}-Cluster --service ${ApplicationName}-Service-stage --desired-count 0 --region ${DepRegion} aws ecs update-service --cluster ${ApplicationName}-Cluster --service ${ApplicationName}-Service-prod --desired-count 0 --region ${DepRegion}
  2. 终止为 main 分支预调配的 Service Catalog 产品。

  3. 清理在工具账户中的 Amazon S3 存储桶内创建的对象。删除注册表本身之前,请先删除 Amazon ECR 中的所有 Docker 映像。

  4. 在删除 Service Catalog 产品组合之前,请移除 Service Catalog 产品组合的已授予访问权限部分中的 IAM 角色。

  5. 删除部署在工具帐户和工作负载帐户中的 CloudFormation 堆栈。

##In Tools Account## aws cloudformation delete-stack --stack-name servicecatalogsetup --region ${DepRegion} aws cloudformation delete-stack --stack-name prlambdasetup --region ${DepRegion} aws cloudformation delete-stack --stack-name prereqs --region ${DepRegion}
##In Workload Accounts## aws cloudformation delete-stack --stack-name inframainstack --region ${DepRegion}

有关更多信息,请参阅 Service Catalog 文档中的删除预调配产品

AWS DevOps

问题排查

问题解决方案

您提交到 CodeCommit 存储库的更改尚未部署。

检查 CodeBuild 日志,查看 Docker 构建操作中是否存在错误。有关详情,请参阅 CodeBuild 文档

未预调配 Service Catalog 产品。

查看相关 CloudFormation 堆栈中是否存在失败的事件。有关详情,请参阅 CloudFormation 文档

相关资源

附加信息

此模式专为具有 Gitflow 设置的环境而设计,该设置用于流程中的 CI/CD 开发工作流程。这些管道遵循以下部署周期:从开发开始,依次经过质量保证(QA)、预发布和生产环境。该 CI/CD 设置包括两个 git 分支,它们对环境进行了促销部署,如下所示:

  • develop 分支部署到开发环境。

  • main 分支部署到 QA、预发布和生产环境。

在这种设置中,在积极开发新功能的同时,要比通常的部署周期更快地应用修补程序或安全补丁是一项挑战。需要专用的流程来处理修补程序或安全请求,从而确保实时环境保持正常运行和安全。

但是,在下面的情况中,您可以使用其他可用选项,而无需专门的部署流程:

  • 该 CI/CD 流程配备了功能和测试等自动化 end-to-end测试,无需手动测试,并可防止部署到生产的延迟。但是,如果自动化测试没有很好地集成到 CI/CD 流程中,那么对开发人员来说,向生产环境推送一个小修复程序可能会变得复杂而繁琐。这是因为 QA 环境中可能有新功能等待批准和签署。修补程序或安全补丁无法以简单的方式同时投入到生产环境。

  • 开发团队不断将新功能部署到生产环境,从而将修补程序或安全补丁集成到每个新功能的计划部署中。换句话说,生产环境的下一次功能更新包括两个组件:增加新功能和包含修补程序或安全补丁。但是,如果部署周期不连续,则 QA 环境中可能已有多个新功能正在等待批准。管理不同的版本并确保重新应用正确的更改会变得复杂且容易出错。

注意

如果您使用的是版本 2,并在hotfix分支上设置了适当的触发器,则仍然需要一个专门的流程来处理计划外的请求。 AWS CodePipeline 在版本 2 中,您可以为推送或拉取请求设置触发器。执行将排队或立即执行,具体取决于管道的先前状态。但是,通过专用管道,修复程序会立即应用于生产环境,从而确保紧急问题毫不拖延地得到解决。