在 CodePipeline 中创建和添加自定义操作
AWS CodePipeline 包括一些帮助您配置构建、测试和部署资源以实现自动化发布过程的操作。如果您的发布过程包括默认操作中不包含的活动,例如内部开发的构建过程或测试套件,则可以为此目的创建自定义操作,并将其包含在管道中。您可以使用 AWS CLI 在与 AWS 账户关联的管道中创建自定义操作。
您可以为以下 AWS CodePipeline 操作类别创建自定义操作:
-
用于构建或转换项目的自定义构建操作
-
用于将项目部署到一个或多个服务器、网站或存储库的自定义部署操作
-
用于配置和运行自动化测试的自定义测试操作
-
用于运行函数的自定义调用操作
当您创建自定义操作时,还必须创建一个作业辅助角色,它将轮询 CodePipeline 以获取该自定义操作的作业请求,执行该作业,并将状态结果返回给 CodePipeline。该作业辅助角色可以位于任何计算机或资源上,只要它有权访问 CodePipeline 的公有端点即可。要轻松管理访问权限和安全性,请考虑在 Amazon EC2 实例上托管您的作业辅助角色。
下图展示了包含自定义构建操作的管道的概要视图:
当管道包含作为阶段一部分的自定义操作时,该管道将创建一个作业请求。自定义作业辅助角色会检测到该请求并执行该作业(在本示例中,是使用第三方构建软件的自定义流程)。操作完成后,作业辅助角色会返回成功结果或失败结果。如果收到成功结果,管道将向下一个操作提供修订及其构件。如果返回失败结果,管道不会向管道中的下一个操作提供修订。
注意
这些说明假设您已经完成了开始使用 CodePipeline中的步骤。
创建自定义操作
使用 AWS CLI 创建自定义操作
-
打开文本编辑器,为您的自定义操作创建一个 JSON 文件,其中包括操作类别、操作提供程序以及您的自定义操作所需的任何设置。例如,要创建一个只需一个属性的自定义生成操作,您的 JSON 文件可能类似下面这样:
{ "category": "Build", "provider": "My-Build-Provider-Name", "version": "1", "settings": { "entityUrlTemplate": "https://my-build-instance/job/{Config:ProjectName}/", "executionUrlTemplate": "https://my-build-instance/job/{Config:ProjectName}/lastSuccessfulBuild/{ExternalExecutionId}/" }, "configurationProperties": [{ "name": "ProjectName", "required": true, "key": true, "secret": false, "queryable": false, "description": "The name of the build project must be provided when this action is added to the pipeline.", "type": "String" }], "inputArtifactDetails": { "maximumCount":integer, "minimumCount":integer}, "outputArtifactDetails": { "maximumCount":integer, "minimumCount":integer}, "tags": [{ "key": "Project", "value": "ProjectA" }] }此示例通过在自定义操作上包含
Project标签键和ProjectA值来为自定义操作添加标记。有关标记 CodePipeline 中资源的更多信息,请参阅为资源添加标签。JSON 文件中有两个属性:
entityUrlTemplate和executionUrlTemplate。只要配置属性是必需的且不为私有,您就可以遵照以下格式在 URL 模板内引用自定义操作的配置属性中的名称:{Config:。例如,在以上示例中,name}entityUrlTemplate值是指配置属性ProjectName。-
entityUrlTemplate:用于提供操作服务提供方相关信息的静态链接。在示例中,构建系统包含一个指向每个构建项目的静态链接。链接格式可能不同,具体取决于您的构建提供程序(或者如果您创建的是其他操作类型,比如测试,则取决于其他服务提供方)。您必须提供此链接格式,以便在添加自定义操作时,用户可以选择此链接来打开浏览器,从而打开您的网站上提供生成项目 (或测试环境) 具体细节的页面。 -
executionUrlTemplate:将会使用有关当前或最新运行的操作进行更新的动态链接。当您的自定义作业辅助角色更新作业的状态(例如成功、失败或正在进行)时,它还将提供一个externalExecutionId用于完成此链接。此链接可用于提供有关操作运行的详细信息。
例如,当您查看管道中的操作时,您将看到以下两个链接:
此静态链接在您添加自定义操作时显示,指向 entityUrlTemplate中您在创建自定义操作时指定的地址。
此动态链接在每次操作运行后更新,指向 executionUrlTemplate中您在创建自定义操作时指定的地址。有关这些链接类型以及
RevisionURLTemplate和ThirdPartyURL的更多信息,请参阅 CodePipeline API 参考中的 ActionTypeSettings 和 CreateCustomActionType。有关操作结构要求以及如何创建操作的更多信息,请参阅 CodePipeline 管道结构参考。 -
-
保存 JSON 文件,并为其提供一个方便记忆的名称(例如,
MyCustomAction.json)。 -
在您安装了 AWS CLI 的计算机上打开终端会话 (Linux、OS X、Unix) 或命令提示符 (Windows)。
-
使用 AWS CLI 运行 aws codepipeline create-custom-action-type 命令,并指定您刚创建的 JSON 文件的名称。
例如,要创建一个构建自定义操作:
重要
务必在文件名前包含
file://。此命令中需要该项。aws codepipeline create-custom-action-type --cli-input-json file://MyCustomAction.json -
该命令将返回您创建的自定义操作的整个结构以及为您添加的
JobList操作配置属性。在管道中添加自定义操作时,您可以使用JobList来指定您可以在提供程序的哪些项目中轮询作业。如果您不配置此操作,则您的自定义作业辅助角色轮询作业时将会返回所有可用作业。例如,上述命令可能会返回类似以下的结构:
{ "actionType": { "inputArtifactDetails": { "maximumCount": 1, "minimumCount": 1 }, "actionConfigurationProperties": [ { "secret": false, "required": true, "name": "ProjectName", "key": true, "description": "The name of the build project must be provided when this action is added to the pipeline." } ], "outputArtifactDetails": { "maximumCount": 0, "minimumCount": 0 }, "id": { "category": "Build", "owner": "Custom", "version": "1", "provider": "My-Build-Provider-Name" }, "settings": { "entityUrlTemplate": "https://my-build-instance/job/{Config:ProjectName}/", "executionUrlTemplate": "https://my-build-instance/job/mybuildjob/lastSuccessfulBuild/{ExternalExecutionId}/" } } }注意
作为 create-custom-action-type 命令输出的一部分,
id部分包括"owner": "Custom"。CodePipeline 会自动分配Custom以作为自定义操作类型的拥有者。使用 create-custom-action-type 命令或 update-pipeline 命令时,无法分配或更改此值。
为自定义操作创建作业辅助角色
自定义操作需要一个作业辅助角色来轮询 CodePipeline 以获取该自定义操作的作业请求,执行该作业,并将状态结果返回给 CodePipeline。作业辅助角色可以位于任何计算机或资源上,只要它能够访问 CodePipeline 的公有端点即可。
有许多方法可以设计您的作业辅助角色。以下各节针对为 CodePipeline 开发自定义作业辅助角色提供了一些实用的指导。
为作业辅助角色选择和配置权限管理策略
要在 CodePipeline 中为您的自定义操作开发自定义作业辅助角色,您需要一个关于用户和权限管理集成的策略。
最简单的策略是通过创建具有 IAM 实例角色的 Amazon EC2 实例,为您的自定义作业辅助角色添加所需的基础设施,从而允许您轻松纵向扩展集成所需的资源。您可以使用与 AWS 的内置集成来简化您的自定义作业辅助角色与 CodePipeline 之间的交互。
设置 Amazon EC2 实例
-
了解更多有关 Amazon EC2 的信息,并确定其是否为适合您的集成的正确选择。有关信息,请参阅 Amazon EC2 – 虚拟服务器托管
。 -
开始创建您的 Amazon EC2 实例。有关信息,请参阅开始使用 Amazon EC2 Linux 实例。
另一个需要考虑的策略是使用 IAM 的身份联合验证来集成您的现有身份提供程序系统和资源。如果您已经拥有企业身份提供程序,或已经配置为支持使用网络身份提供程序的用户,则此策略特别有用。身份联合验证允许您授予对 AWS 资源(包括 CodePipeline)的安全访问权限,而不必创建或管理 IAM 用户。您可以利用针对密码安全性要求和凭证轮换的功能和策略。您可以使用示例应用程序作为自己设计的模板。
若要设置身份联合验证
-
了解有关 IAM 身份联合验证的更多信息。有关信息,请参阅管理联合身份验证
。 -
查看授予临时访问权限的情形中的示例,以确定最适合您的自定义操作需求的临时访问情形。
-
查看与您的基础设施相关的联合身份验证代码示例,例如:
-
开始配置联合身份验证。有关信息,请参阅 IAM 用户指南 中的身份提供程序和联合身份验证。
创建以下内容之一,以便在运行自定义操作和作业辅助工具时在您的AWS 账户下使用。
如果用户需要在 AWS 管理控制台之外与 AWS 交互,则需要编程式访问权限。授予编程式访问权限的方法取决于访问 AWS 的用户类型。
要向用户授予编程式访问权限,请选择以下选项之一。
| 哪个用户需要编程式访问权限? | 目的 | 方式 |
|---|---|---|
|
人力身份 (在 IAM Identity Center 中管理的用户) |
使用临时凭证签署向 AWS CLI、AWS SDK 或 AWS API 发出的编程请求。 |
按照您希望使用的界面的说明进行操作。
|
| IAM | 使用临时凭证签署向 AWS CLI、AWS SDK 或 AWS API 发出的编程请求。 | 按照《IAM 用户指南》中将临时凭证用于 AWS 资源中的说明进行操作。 |
| IAM | (不推荐使用) 使用长期凭证签署向 AWS CLI、AWS SDK 或 AWS API 发出的编程请求。 |
按照您希望使用的界面的说明进行操作。
|
以下是一个您为了与自定义作业辅助角色一起使用而可能会创建的示例策略。此策略仅作为示例,按原样提供。
注意
考虑使用 AWSCodePipelineCustomActionAccess 托管式策略。
为自定义操作开发作业辅助角色
选择权限管理策略后,您应该考虑自己的作业辅助角色将如何与 CodePipeline 进行交互。以下概要图表显示了构建过程的自定义操作和作业辅助角色的工作流。
-
作业辅助角色使用
PollForJobs来轮询 CodePipeline 以获取作业。 -
当源阶段中的变更(例如,开发者提交更改)触发管道时,自动发布过程就会开始。该过程将持续执行,一直到配置自定义操作的阶段为止。到达您在此阶段中的操作时,CodePipeline 会将作业排队。如果您的作业辅助角色再次调用
PollForJobs以获取状态,则会显示此作业。从PollForJobs中获取作业详细信息并将其传回给您的作业辅助角色。 -
作业辅助角色调用
AcknowledgeJob以向 CodePipeline 发送作业确认。CodePipeline 返回一个确认,指示作业辅助角色应继续处理该作业 (InProgress),或者,如果有多个作业辅助角色轮询作业,而另一个作业辅助角色已经认领该作业,则会返回InvalidNonceException错误响应。收到InProgress确认后,CodePipeline 会等待返回结果。 -
作业辅助角色对修订启动您的自定义操作,然后您的操作将开始执行。与任何其他操作一样,您的自定义操作也会将结果返回给作业辅助角色。在构建自定义操作的示例中,操作从 Amazon S3 桶中提取项目,对其进行构建,然后将成功构建的构件推送回 Amazon S3 桶。
-
当操作正在运行时,作业辅助角色可以使用延续令牌(由作业辅助角色生成的作业状态的序列化,例如 JSON 格式的构建标识符或一个 Amazon S3 对象键),以及将用于填充
executionUrlTemplate中的链接的ExternalExecutionId信息来调用PutJobSuccessResult。这将使用一个有效链接来更新管道的控制台视图,该链接提供正在进行中的操作的具体细节。虽然不是必需的,但它是最佳实践,因为它使用户能够在自定义操作运行时查看其状态。调用
PutJobSuccessResult后,作业即视为完成。CodePipeline 中会创建一个包括延续令牌的新作业。如果您的作业辅助角色再次调用PollForJobs,则会显示此作业。此新任务可用于检查操作的状态,然后返回延续令牌,或者在操作完成后不返回延续令牌。注意
如果您的作业辅助角色执行自定义操作的所有工作,则应考虑将作业辅助角色处理过程分为至少两个步骤。第一步是为您的操作建立详细信息页面。创建详细信息页面后,您可以将作业辅助角色的状态序列化,并将其作为延续令牌返回,同时遵守大小限制(请参阅 AWS CodePipeline 中的限额)。例如,您可以将操作的状态写入用作延续令牌的字符串中。作业辅助角色处理过程的第二步(以及后续步骤)将执行操作的实际工作。最后一步是向 CodePipeline 返回成功或失败结果,最后一步中没有延续令牌。
有关使用延续令牌的更多信息,请参阅 CodePipeline API 参考中的
PutJobSuccessResult规范。 -
自定义操作完成后,作业辅助角色通过调用两个 API 之一,将自定义操作的结果返回给 CodePipeline:
-
PutJobSuccessResult,不带延续令牌,表示自定义操作已成功运行 -
PutJobFailureResult,表示自定义操作未成功运行
根据结果,管道将继续执行下一个操作(成功),或者停止(失败)。
-
自定义作业辅助角色架构和示例
在制定概要工作流后,您可以创建作业辅助角色。尽管自定义操作的细节最终将决定作业辅助角色需要什么,但自定义操作的大多数作业辅助角色都包括以下功能:
-
使用
PollForJobs向 CodePipeline 轮询作业。 -
使用
AcknowledgeJob、PutJobSuccessResult和PutJobFailureResult确认作业,并将结果返回到 CodePipeline。 -
从管道的 Amazon S3 桶中检索构件和/或将构件放入桶。要从 Amazon S3 桶下载构件,您必须创建一个使用签名版本 4 (Sig V4) 签名的 Amazon S3 客户端。Sig V4 是 AWS KMS 所必需的。
要将构件上传到 Amazon S3 桶,您还必须另外配置 Amazon S3
PutObject请求以使用加密。目前仅支持使用 AWS Key Management Service (AWS KMS) 进行加密。AWS KMS 使用 AWS KMS keys。为了解使用 AWS 托管式密钥 还是客户管理的密钥来上传构件,您的作业辅助角色必须查看作业数据并检查加密密钥属性。如果设置了该属性,则在配置 AWS KMS 时应使用该客户管理的密钥 ID。如果密钥属性为空,则使用 AWS 托管式密钥。除非另有配置,否则 CodePipeline 使用 AWS 托管式密钥。有关演示如何在 Java 或 .NET 中创建 AWS KMS 参数的示例,请参阅使用 AWS SDK 在 Amazon S3 中指定 AWS Key Management Service。有关适用于 CodePipeline 的 Amazon S3 桶的更多信息,请参阅 CodePipeline 概念。
GitHub 上提供了一个更复杂的自定义作业辅助角色示例。此示例是一个开源示例,按原样提供。
-
CodePipeline 的作业辅助角色示例
:从 GitHub 存储库下载示例。
向管道添加自定义操作
在拥有作业辅助角色后,您可以通过以下方法将自定义操作添加到管道中:创建一个新管道并在使用创建管道向导时选择该管道,编辑现有管道并添加自定义操作,或者使用 AWS CLI、SDK 或 API。
注意
您可以在“Create Pipeline (创建管道)”向导中创建一个包含自定义操作(如果自定义操作是生成或部署操作)的管道。如果您的自定义操作位于测试类别中,则您必须通过编辑现有管道来添加它。
向现有管道添加自定义操作 (CLI)
您可以使用 AWS CLI 将自定义操作添加到现有管道。
-
打开终端会话(Linux、macOS 或 Unix)或命令提示符 (Windows),然后运行 get-pipeline 命令,将要编辑的管道结构复制到 JSON 文件中。例如,对于名为
MyFirstPipeline的管道,可以键入以下命令:aws codepipeline get-pipeline --nameMyFirstPipeline>pipeline.json该命令不会返回任何结果,但您创建的文件将出现在您运行命令所在的目录中。
-
在任何文本编辑器中打开 JSON 文件,修改文件结构,以便将您的自定义操作添加到一个现有阶段中。
注意
如果您希望您的操作与此阶段中的另一操作并行运行,请确保为其分配与另一操作相同的
runOrder值。例如,要修改管道结构,以添加一个名为 Build 的阶段并将一个生成自定义操作添加到该阶段中,您可以将 JSON 修改为在部署阶段之前添加 Build 阶段,如下所示:
, { "name": "MyBuildStage", "actions": [ { "inputArtifacts": [ { "name": "MyApp" } ], "name": "MyBuildCustomAction", "actionTypeId": { "category": "Build", "owner": "Custom", "version": "1", "provider": "My-Build-Provider-Name" }, "outputArtifacts": [ { "name": "MyBuiltApp" } ], "configuration": { "ProjectName": "MyBuildProject" }, "runOrder": 1 } ] }, { "name": "Staging", "actions": [ { "inputArtifacts": [ { "name": "MyBuiltApp" } ], "name": "Deploy-CodeDeploy-Application", "actionTypeId": { "category": "Deploy", "owner": "AWS", "version": "1", "provider": "CodeDeploy" }, "outputArtifacts": [], "configuration": { "ApplicationName": "CodePipelineDemoApplication", "DeploymentGroupName": "CodePipelineDemoFleet" }, "runOrder": 1 } ] }] } -
要应用更改,请运行 update-pipeline 命令并指定一个管道 JSON 文件,类似于以下内容:
重要
务必在文件名前包含
file://。此命令中需要该项。aws codepipeline update-pipeline --cli-input-json file://pipeline.json该命令会返回编辑后的管道的整个结构。
-
打开 CodePipeline 控制台,并选择刚才编辑的管道的名称。
管道将显示您的更改。当您下一次更改源位置时,管道会通过管道修订后的结构运行该修订。