迁移轮询管道以使用基于事件的更改检测 - Amazon CodePipeline
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

迁移轮询管道以使用基于事件的更改检测

Amazon CodePipeline 支持完整、 end-to-end 持续的交付,包括在发生代码更改时启动您的管道。在发生代码更改后,有两种支持的方法来启动管道:基于事件的更改检测和轮询。建议对管道使用基于事件的更改检测。

使用此处包含的过程,迁移(更新)轮询管道以对管道使用基于事件的更改检测方法。

推荐的管道基于事件的变更检测方法由管道来源决定,例如 CodeCommit。例如,在这种情况下,轮询管道需要使用 EventBridge迁移到基于事件的变更检测。

如何迁移轮询管道

要迁移轮询管道,请确定您的轮询管道,然后确定建议的基于事件的更改检测方法:

  • 使用查看账户中的轮询管道中的步骤来确定轮询管道。

  • 在此表中,找到您的管道源类型,然后选择具有要用于迁移轮询管道的实施的过程。每个部分都包含多种迁移方法,例如使用 CLI 或 Amazon CloudFormation。

如何将管道迁移至建议的更改检测方法
管道源 建议的基于事件的检测方法 迁移过程
Amazon CodeCommit EventBridge (推荐)。 请参阅 使用 CodeCommit 来源迁移轮询管道
Amazon S3 EventBridge 并启用存储桶以接收事件通知(推荐)。 请参阅 迁移为事件启用了 S3 源的轮询管道
Amazon S3 EventBridge 还有一条 Amazon CloudTrail 小径。 请参阅 使用 S3 源和 CloudTrail 跟踪迁移轮询管道
GitHub 第 1 版 连接(建议) 请参阅 将 GitHub 版本 1 源操作的轮询管道迁移到连接
GitHub 第 1 版 Webhook 请参阅 将 GitHub 版本 1 源操作的轮询管道迁移到 webhook
重要

对于适用的管道操作配置更新(例如具有 GitHub版本 1 操作的管道),您必须在源操作的配置中将该PollForSourceChanges参数显式设置为 false,以停止管道轮询。因此,可能会错误地将管道配置为基于事件的变更检测轮询,例如配置 EventBridge 规则并省略参数。PollForSourceChanges这将导致重复的管道执行,并且会将管道计入轮询管道总数限制,默认情况下,该值远低于基于事件的管道。有关更多信息,请参阅 中的配额 Amazon CodePipeline

查看账户中的轮询管道

首先,使用以下脚本之一来确定账户中的哪些管道配置为使用轮询。这些是迁移到基于事件的更改检测的管道。

查看账户中的轮询管道(脚本)

按照以下步骤使用脚本来确定账户中使用轮询的管道。

  1. 打开终端窗口,然后执行以下操作之一:

    • 运行以下命令创建名为 PollingPipelinesExtractor.sh 的新脚本。

      vi PollingPipelinesExtractor.sh
    • 要使用 python 脚本,请运行以下命令创建一个名为 PollingPipelinesExtractor.py 的新 python 脚本。

      vi PollingPipelinesExtractor.py
  2. 将以下代码复制并粘贴到PollingPipelinesExtractor脚本中。请执行以下操作之一:

    • 将以下代码复制并粘贴到 PollingPipelinesExtractor.sh 脚本中。

      #!/bin/bash set +x POLLING_PIPELINES=() LAST_EXECUTED_DATES=() NEXT_TOKEN=null HAS_NEXT_TOKEN=true if [[ $# -eq 0 ]] ; then echo 'Please provide region name' exit 0 fi REGION=$1 while [ "$HAS_NEXT_TOKEN" != "false" ]; do if [ "$NEXT_TOKEN" != "null" ]; then LIST_PIPELINES_RESPONSE=$(aws codepipeline list-pipelines --region $REGION --next-token $NEXT_TOKEN) else LIST_PIPELINES_RESPONSE=$(aws codepipeline list-pipelines --region $REGION) fi LIST_PIPELINES=$(jq -r '.pipelines[].name' <<< "$LIST_PIPELINES_RESPONSE") NEXT_TOKEN=$(jq -r '.nextToken' <<< "$LIST_PIPELINES_RESPONSE") if [ "$NEXT_TOKEN" == "null" ]; then HAS_NEXT_TOKEN=false fi for pipline_name in $LIST_PIPELINES do PIPELINE=$(aws codepipeline get-pipeline --name $pipline_name --region $REGION) HAS_POLLABLE_ACTIONS=$(jq '.pipeline.stages[].actions[] | select(.actionTypeId.category == "Source") | select(.actionTypeId.owner == ("ThirdParty","AWS")) | select(.actionTypeId.provider == ("GitHub","S3","CodeCommit")) | select(.configuration.PollForSourceChanges == ("true",null))' <<< "$PIPELINE") if [ ! -z "$HAS_POLLABLE_ACTIONS" ]; then POLLING_PIPELINES+=("$pipline_name") PIPELINE_EXECUTIONS=$(aws codepipeline list-pipeline-executions --pipeline-name $pipline_name --region $REGION) LAST_EXECUTION=$(jq -r '.pipelineExecutionSummaries[0]' <<< "$PIPELINE_EXECUTIONS") if [ "$LAST_EXECUTION" != "null" ]; then LAST_EXECUTED_TIMESTAMP=$(jq -r '.startTime' <<< "$LAST_EXECUTION") LAST_EXECUTED_DATE="$(date -r ${LAST_EXECUTED_TIMESTAMP%.*})" else LAST_EXECUTED_DATE="Not executed in last year" fi LAST_EXECUTED_DATES+=("$LAST_EXECUTED_DATE") fi done done fileName=$REGION-$(date +%s) printf "| %-30s | %-30s |\n" "Polling Pipeline Name" "Last Executed Time" printf "| %-30s | %-30s |\n" "_____________________" "__________________" for i in "${!POLLING_PIPELINES[@]}"; do printf "| %-30s | %-30s |\n" "${POLLING_PIPELINES[i]}" "${LAST_EXECUTED_DATES[i]}" printf "${POLLING_PIPELINES[i]}," >> $fileName.csv done printf "\nSaving Polling Pipeline Names to file $fileName.csv."
    • 将以下代码复制并粘贴到 PollingPipelinesExtractor.py 脚本中。

      import boto3 import sys import time import math hasNextToken = True nextToken = "" pollablePipelines = [] lastExecutedTimes = [] if len(sys.argv) == 1: raise Exception("Please provide region name.") session = boto3.Session(profile_name='default', region_name=sys.argv[1]) codepipeline = session.client('codepipeline') def is_pollable_action(action): actionTypeId = action['actionTypeId'] configuration = action['configuration'] return actionTypeId['owner'] in {"AWS", "ThirdParty"} and actionTypeId['provider'] in {"GitHub", "CodeCommit", "S3"} and ('PollForSourceChanges' not in configuration or configuration['PollForSourceChanges'] == 'true') def has_pollable_actions(pipeline): hasPollableAction = False pipelineDefinition = codepipeline.get_pipeline(name=pipeline['name'])['pipeline'] for action in pipelineDefinition['stages'][0]['actions']: hasPollableAction = is_pollable_action(action) if hasPollableAction: break return hasPollableAction def get_last_executed_time(pipelineName): pipelineExecutions=codepipeline.list_pipeline_executions(pipelineName=pipelineName)['pipelineExecutionSummaries'] if pipelineExecutions: return pipelineExecutions[0]['startTime'].strftime("%A %m/%d/%Y, %H:%M:%S") else: return "Not executed in last year" while hasNextToken: if nextToken=="": list_pipelines_response = codepipeline.list_pipelines() else: list_pipelines_response = codepipeline.list_pipelines(nextToken=nextToken) if 'nextToken' in list_pipelines_response: nextToken = list_pipelines_response['nextToken'] else: hasNextToken= False for pipeline in list_pipelines_response['pipelines']: if has_pollable_actions(pipeline): pollablePipelines.append(pipeline['name']) lastExecutedTimes.append(get_last_executed_time(pipeline['name'])) fileName="{region}-{timeNow}.csv".format(region=sys.argv[1],timeNow=math.trunc(time.time())) file = open(fileName, 'w') print ("{:<30} {:<30} {:<30}".format('Polling Pipeline Name', '|','Last Executed Time')) print ("{:<30} {:<30} {:<30}".format('_____________________', '|','__________________')) for i in range(len(pollablePipelines)): print("{:<30} {:<30} {:<30}".format(pollablePipelines[i], '|', lastExecutedTimes[i])) file.write("{pipeline},".format(pipeline=pollablePipelines[i])) file.close() print("\nSaving Polling Pipeline Names to file {fileName}".format(fileName=fileName))
  3. 对于每个具有管道的区域,必须为此区域运行脚本。要运行脚本,请执行以下操作之一:

    • 运行以下命令运行名为 PollingPipelinesExtractor.sh 的脚本。在此示例中,区域为 us-west-2。

      ./PollingPipelinesExtractor.sh us-west-2
    • 对于 python 脚本,运行以下命令以运行名为 PollingPipelinesExtractor.py 的 python 脚本。在此示例中,区域为 us-west-2。

      python3 PollingPipelinesExtractor.py us-west-2

    在脚本的以下示例输出中,区域 us-west-2 返回了轮询管道列表,并显示了每个管道的上次执行时间。

    % ./pollingPipelineExtractor.sh us-west-2 | Polling Pipeline Name | Last Executed Time | | _____________________ | __________________ | | myCodeBuildPipeline | Wed Mar 8 09:35:49 PST 2023 | | myCodeCommitPipeline | Mon Apr 24 22:32:32 PDT 2023 | | TestPipeline | Not executed in last year | Saving list of polling pipeline names to us-west-2-1682496174.csv...%

    分析脚本输出,并针对列表中的每个管道,更新轮询源以使用建议的基于事件的更改检测方法。

    注意

    轮询管道由管道操作配置中的 PollForSourceChanges 参数决定。如果管道源配置省略了PollForSourceChanges参数,则 CodePipeline默认会轮询存储库以查看源代码更改。如果包括 PollForSourceChanges 并将其设置为 true,则此行为相同。有关更多信息,请参阅管道源操作的配置参数,例如Amazon S3 源操作中的 Amazon S3 源操作配置参数。

    请注意,此脚本还会生成一个包含账户中轮询管道列表的 .csv 文件,并将此 .csv 文件保存到当前工作文件夹。

使用 CodeCommit 来源迁移轮询管道

您可以迁移轮询管道 EventBridge 以用于检测 CodeCommit源存储库或 Amazon S3 源存储桶中的更改。

CodeCommit--对于带有 CodeCommit 源的管道,请修改管道,以便自动进行更改检测 EventBridge。从以下方法中进行选择以实施迁移:

迁移轮询管道(CodeCommit 或 Amazon S3 源代码)(控制台)

您可以使用 CodePipeline 控制台更新管道, EventBridge 以用于检测 CodeCommit 源存储库或 Amazon S3 源存储桶中的更改。

注意

当您使用控制台编辑包含 CodeCommit 源存储库或 Amazon S3 源存储桶的管道时,将为您创建规则和 IAM 角色。如果您使用编辑管道,则必须自己创建 EventBridge 规则和 IAM 角色。 Amazon CLI 有关更多信息,请参阅 CodeCommit 源操作和 EventBridge

使用以下步骤可编辑正在使用定期检查的管道。如果要创建管道,请参阅在中创建管道 CodePipeline

编辑管道源阶段
  1. 登录 Amazon Web Services Management Console 并打开 CodePipeline 控制台,网址为 http://console.aws.amazon.com/codesuite/codepipeline/home

    将显示与您的 Amazon 账户关联的所有管道的名称。

  2. Name 中,选择您要编辑的管道的名称。这将打开管道的详细视图,包括管道每个阶段中每个操作的状态。

  3. 在管道详细信息页中,选择编辑

  4. Edit stage (编辑阶段) 中,选择源操作上的编辑图标。

  5. 展开 “更改检测选项”,然后选择 “使用 CloudWatch 事件”,以便在发生更改时自动启动我的管道(推荐)

    将出现一条消息,显示要为此管道创建的 EventBridge 规则。选择更新

    如果您更新的是具有 Amazon S3 源的管道,将显示以下消息。选择更新

  6. 编辑完您的管道后,请选择 Save pipeline changes 以返回到摘要页面。

    一条消息显示要为您的管道创建的 EventBridge 规则的名称。选择 保存并继续

  7. 要测试您的操作,请使用发布更改,将更改提交 Amazon CLI 到管道源阶段中指定的源。

迁移轮询管道(CodeCommit 来源)(CLI)

按照以下步骤编辑正在使用轮询(定期检查)的管道,以使用 EventBridge 规则启动管道。如果要创建管道,请参阅在中创建管道 CodePipeline

要使用构建事件驱动的管道 CodeCommit,请编辑管道的PollForSourceChanges参数,然后创建以下资源:

  • EventBridge 事件

  • IAM 角色,以允许该事件启动您的管道

编辑管道的 PollForSourceChanges参数
重要

使用此方法创建管道时,如果 PollForSourceChanges 参数未明确设置为 false,则默认为 true。添加基于事件的更改检测时,必须将参数添加到输出并将其设置为 false 以禁用轮询。否则,您的管道将针对单个源更改启动两次。有关更多信息,请参阅 PollForSourceChanges 参数的默认设置

  1. 运行 get-pipeline 命令以将管道结构复制到 JSON 文件中。例如,对于名为 MyFirstPipeline 的管道,运行以下命令:

    aws codepipeline get-pipeline --name MyFirstPipeline >pipeline.json

    该命令不会返回任何结果,但您创建的文件将出现在您运行命令所在的目录中。

  2. 在任何纯文本编辑器中打开 JSON 文件并通过将 PollForSourceChanges 参数更改为 false 来编辑源阶段,如此示例中所示。

    我为何做出此更改? 将此参数更改为 false 将关闭定期检查,因此您只能使用基于事件的更改检测。

    "configuration": { "PollForSourceChanges": "false", "BranchName": "main", "RepositoryName": "MyTestRepo" },
  3. 如果您要使用通过 get-pipeline 命令检索到的管道结构,请删除 JSON 文件中的 metadata 行。否则,update-pipeline 命令无法使用它。删除 "metadata": { } 行以及 "created""pipelineARN""updated" 字段。

    例如,从结构中删除以下各行:

    "metadata": { "pipelineArn": "arn:aws:codepipeline:region:account-ID:pipeline-name", "created": "date", "updated": "date" },

    保存该文件。

  4. 要应用更改,请运行 update-pipeline 命令,指定管道 JSON 文件:

    重要

    务必在文件名前包含 file://。此命令中需要该项。

    aws codepipeline update-pipeline --cli-input-json file://pipeline.json

    该命令会返回编辑后的管道的整个结构。

    注意

    update-pipeline 命令会停止管道。如果在运行 update-pipeline 命令时正在通过管道运行修订,则该运行会被停止。您必须手动启动管道,通过升级后的管道运行此修订。使用 start-pipeline-execution 命令手动启动您的管道。

创建以事件源 CodeCommit 为目标的 EventBridge 规则 CodePipeline
  1. 添加用于调 EventBridge CodePipeline 用规则的权限。有关更多信息,请参阅使用适用于 Amazon EventBridge 的基于资源的政策。

    1. 使用以下示例创建允许 EventBridge 担任服务角色的信任策略。将信任策略命名为 trustpolicyforEB.json

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
    2. 使用以下命令创建 Role-for-MyRule 角色并附加信任策略。

      aws iam create-role --role-name Role-for-MyRule --assume-role-policy-document file://trustpolicyforEB.json
    3. 为名为 MyFirstPipeline 的管道创建权限策略 JSON,如此示例中所示。将权限策略命名为 permissionspolicyforEB.json

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codepipeline:StartPipelineExecution" ], "Resource": [ "arn:aws:codepipeline:us-west-2:80398EXAMPLE:MyFirstPipeline" ] } ] }
    4. 使用以下命令将 CodePipeline-Permissions-Policy-for-EB 权限策略附加到 Role-for-MyRule 角色。

      我为何做出此更改? 将此策略添加到角色会为创建权限 EventBridge。

      aws iam put-role-policy --role-name Role-for-MyRule --policy-name CodePipeline-Permissions-Policy-For-EB --policy-document file://permissionspolicyforEB.json
  2. 调用 put-rule 命令并包含 --name--event-pattern--role-arn 参数。

    我为何做出此更改? 此命令将允许 Amazon CloudFormation 创建事件。

    以下示例命令创建一个名为 MyCodeCommitRepoRule 的规则。

    aws events put-rule --name "MyCodeCommitRepoRule" --event-pattern "{\"source\":[\"aws.codecommit\"],\"detail-type\":[\"CodeCommit Repository State Change\"],\"resources\":[\"repository-ARN\"],\"detail\":{\"referenceType\":[\"branch\"],\"referenceName\":[\"main\"]}}" --role-arn "arn:aws:iam::ACCOUNT_ID:role/Role-for-MyRule"
  3. 要添加 CodePipeline 为目标,请调用put-targets命令并添加以下参数:

    • --rule 参数与您使用 put-rule 创建的 rule_name 结合使用。

    • --targets 参数与目标列表中该目标的列表 Id 以及目标管道的 ARN 结合使用。

    以下示例命令为名为 MyCodeCommitRepoRule 的规则指定此内容,目标 Id 由数字 1 组成,这指示此内容位于规则的目标列表中,而这是目标 1。示例命令还为管道指定一个示例 ARN。管道在存储库中发生更改时启动。

    aws events put-targets --rule MyCodeCommitRepoRule --targets Id=1,Arn=arn:aws:codepipeline:us-west-2:80398EXAMPLE:TestPipeline

迁移轮询管道(CodeCommit 来源)(Amazon CloudFormation 模板)

要使用构建事件驱动的管道 Amazon CodeCommit,请编辑管道的PollForSourceChanges参数,然后将以下资源添加到模板中:

  • 一条 EventBridge 规则

  • 您的 EventBridge 规则的 IAM 角色

如果您 Amazon CloudFormation 使用创建和管理管道,则您的模板将包含以下内容。

注意

源阶段中的 Configuration 属性称为 PollForSourceChanges。如果该属性未包含在您的模板中,PollForSourceChanges 在默认情况下将设置为 true

YAML
Resources: AppPipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: codecommit-polling-pipeline RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit OutputArtifacts: - Name: SourceOutput Configuration: BranchName: !Ref BranchName RepositoryName: !Ref RepositoryName PollForSourceChanges: true RunOrder: 1
JSON
"Stages": [ { "Name": "Source", "Actions": [{ "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "AWS", "Version": 1, "Provider": "CodeCommit" }, "OutputArtifacts": [{ "Name": "SourceOutput" }], "Configuration": { "BranchName": { "Ref": "BranchName" }, "RepositoryName": { "Ref": "RepositoryName" }, "PollForSourceChanges": true }, "RunOrder": 1 }] },
更新您的管道 Amazon CloudFormation 模板并创建 EventBridge 规则
  1. 在模板下的模板中Resources,使用AWS::IAM::Role Amazon CloudFormation 资源配置允许您的事件启动管道的 IAM 角色。此条目将创建一个使用两个策略的角色:

    • 第一个策略允许代入角色。

    • 第二个策略提供启动管道所需的权限。

    我为何做出此更改? 添加AWS::IAM::Role资源可以 Amazon CloudFormation 为创建权限 EventBridge。此资源已添加到您的 Amazon CloudFormation 堆栈中。

    YAML
    EventRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: eb-pipeline-execution PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: codepipeline:StartPipelineExecution Resource: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ]
    JSON
    "EventRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "events.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "eb-pipeline-execution", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "codepipeline:StartPipelineExecution", "Resource": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ...
  2. 在模板的下方Resources,使用AWS::Events::Rule Amazon CloudFormation 资源添加 EventBridge 规则。此事件模式会创建一个事件,以监控向存储库推送更改的操作。当 EventBridge 检测到存储库状态更改时,将在目标管道StartPipelineExecution上调用该规则。

    我为何做出此更改? 添加AWS::Events::Rule资源 Amazon CloudFormation 即可创建事件。此资源已添加到您的 Amazon CloudFormation 堆栈中。

    YAML
    EventRule: Type: AWS::Events::Rule Properties: EventPattern: source: - aws.codecommit detail-type: - 'CodeCommit Repository State Change' resources: - !Join [ '', [ 'arn:aws:codecommit:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref RepositoryName ] ] detail: event: - referenceCreated - referenceUpdated referenceType: - branch referenceName: - main Targets: - Arn: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] RoleArn: !GetAtt EventRole.Arn Id: codepipeline-AppPipeline
    JSON
    "EventRule": { "Type": "AWS::Events::Rule", "Properties": { "EventPattern": { "source": [ "aws.codecommit" ], "detail-type": [ "CodeCommit Repository State Change" ], "resources": [ { "Fn::Join": [ "", [ "arn:aws:codecommit:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "RepositoryName" } ] ] } ], "detail": { "event": [ "referenceCreated", "referenceUpdated" ], "referenceType": [ "branch" ], "referenceName": [ "main" ] } }, "Targets": [ { "Arn": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] }, "RoleArn": { "Fn::GetAtt": [ "EventRole", "Arn" ] }, "Id": "codepipeline-AppPipeline" } ] } },
  3. 将更新后的模板保存到本地计算机,然后打开 Amazon CloudFormation 控制台。

  4. 选择堆栈,然后选择为当前堆栈创建更改集

  5. 上传模板,然后查看 Amazon CloudFormation中列出的更改。这些是要对堆栈进行的更改。您应在列表中看到新资源。

  6. 选择执行

编辑管道的 PollForSourceChanges参数
重要

许多情况下,当您创建管道时,PollForSourceChanges 参数默认为 true。添加基于事件的更改检测时,必须将参数添加到输出并将其设置为 false 以禁用轮询。否则,您的管道将针对单个源更改启动两次。有关更多信息,请参阅 PollForSourceChanges 参数的默认设置

  • 在模板中,将 PollForSourceChanges 更改为 false。如果您未在管道定义中包含 PollForSourceChanges,请添加它并将它设置为 false

    我为何做出此更改? 将此参数更改为 false 将关闭定期检查,因此您只能使用基于事件的更改检测。

    YAML
    Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit OutputArtifacts: - Name: SourceOutput Configuration: BranchName: !Ref BranchName RepositoryName: !Ref RepositoryName PollForSourceChanges: false RunOrder: 1
    JSON
    { "Name": "Source", "Actions": [ { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "AWS", "Version": 1, "Provider": "CodeCommit" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "BranchName": { "Ref": "BranchName" }, "RepositoryName": { "Ref": "RepositoryName" }, "PollForSourceChanges": false }, "RunOrder": 1 } ] },

当您使用创建这些资源时 Amazon CloudFormation,系统会在创建或更新存储库中的文件时触发您的管道。下面是最终模板代码段:

YAML
Resources: EventRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: eb-pipeline-execution PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: codepipeline:StartPipelineExecution Resource: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] EventRule: Type: AWS::Events::Rule Properties: EventPattern: source: - aws.codecommit detail-type: - 'CodeCommit Repository State Change' resources: - !Join [ '', [ 'arn:aws:codecommit:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref RepositoryName ] ] detail: event: - referenceCreated - referenceUpdated referenceType: - branch referenceName: - main Targets: - Arn: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] RoleArn: !GetAtt EventRole.Arn Id: codepipeline-AppPipeline AppPipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: codecommit-events-pipeline RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit OutputArtifacts: - Name: SourceOutput Configuration: BranchName: !Ref BranchName RepositoryName: !Ref RepositoryName PollForSourceChanges: false RunOrder: 1 ...
JSON
"Resources": { ... "EventRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "events.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "eb-pipeline-execution", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "codepipeline:StartPipelineExecution", "Resource": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] } } ] } } ] } }, "EventRule": { "Type": "AWS::Events::Rule", "Properties": { "EventPattern": { "source": [ "aws.codecommit" ], "detail-type": [ "CodeCommit Repository State Change" ], "resources": [ { "Fn::Join": [ "", [ "arn:aws:codecommit:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "RepositoryName" } ] ] } ], "detail": { "event": [ "referenceCreated", "referenceUpdated" ], "referenceType": [ "branch" ], "referenceName": [ "main" ] } }, "Targets": [ { "Arn": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] }, "RoleArn": { "Fn::GetAtt": [ "EventRole", "Arn" ] }, "Id": "codepipeline-AppPipeline" } ] } }, "AppPipeline": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { "Name": "codecommit-events-pipeline", "RoleArn": { "Fn::GetAtt": [ "CodePipelineServiceRole", "Arn" ] }, "Stages": [ { "Name": "Source", "Actions": [ { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "AWS", "Version": 1, "Provider": "CodeCommit" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "BranchName": { "Ref": "BranchName" }, "RepositoryName": { "Ref": "RepositoryName" }, "PollForSourceChanges": false }, "RunOrder": 1 } ] }, ...

迁移为事件启用了 S3 源的轮询管道

对于具有 Amazon S3 源的管道,请修改管道,以便通过 EventBridge 启用事件通知的源存储桶自动进行更改检测。如果您正在使用 CLI 或 Amazon CloudFormation 迁移管道,则推荐使用此方法。

注意

这包括使用启用了事件通知功能的存储桶,在这种存储桶中,您无需创建单独的 CloudTrail 跟踪。如果您使用的是控制台,则会为您设置事件规则和 CloudTrail 跟踪。有关这些步骤,请参阅使用 S3 源和 CloudTrail 跟踪迁移轮询管道

迁移为事件启用了 S3 源的轮询管道 (CLI)

按照以下步骤编辑正在使用轮询(定期检查)的管道, EventBridge 改为使用事件。如果要创建管道,请参阅在中创建管道 CodePipeline

要构建具有 Amazon S3 源的事件驱动管道,您应编辑管道的 PollForSourceChanges 参数,然后创建以下资源:

  • EventBridge 事件规则

  • 允许 EventBridge 事件启动管道的 IAM 角色

创建以 Amazon S3 作为事件源和 CodePipeline 目标的 EventBridge 规则并应用权限策略
  1. 授 EventBridge 予使用调 CodePipeline 用规则的权限。有关更多信息,请参阅使用适用于 Amazon EventBridge 的基于资源的政策。

    1. 使用以下示例创建允许 EventBridge担任服务角色的信任策略。将它命名为 trustpolicyforEB.json

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
    2. 使用以下命令创建 Role-for-MyRule 角色并附加信任策略。

      我为何做出此更改? 将此信任策略添加到角色会为创建权限 EventBridge。

      aws iam create-role --role-name Role-for-MyRule --assume-role-policy-document file://trustpolicyforEB.json
    3. 为名为 MyFirstPipeline 的管道创建权限策略 JSON,如此处所示。将权限策略命名为 permissionspolicyforEB.json

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codepipeline:StartPipelineExecution" ], "Resource": [ "arn:aws:codepipeline:us-west-2:80398EXAMPLE:MyFirstPipeline" ] } ] }
    4. 使用以下命令将新的 CodePipeline-Permissions-Policy-for-EB 权限策略附加到您创建的 Role-for-MyRule 角色。

      aws iam put-role-policy --role-name Role-for-MyRule --policy-name CodePipeline-Permissions-Policy-For-EB --policy-document file://permissionspolicyforEB.json
  2. 调用 put-rule 命令并包含 --name--event-pattern--role-arn 参数。

    以下示例命令创建名为 EnabledS3SourceRule 的规则。

    aws events put-rule --name "EnabledS3SourceRule" --event-pattern "{\"source\":[\"aws.s3\"],\"detail-type\":[\"Object Created\"],\"detail\":{\"bucket\":{\"name\":[\"my-bucket\"]}}}" --role-arn "arn:aws:iam::ACCOUNT_ID:role/Role-for-MyRule"
  3. 要添加 CodePipeline 为目标,请调用put-targets命令并添加--rule--targets参数。

    以下示例命令为名为 EnabledS3SourceRule 的规则指定此内容,目标 Id 由数字 1 组成,这指示此内容位于规则的目标列表中,而这是目标 1。此命令还为管道指定一个示例 ARN。管道在存储库中发生更改时启动。

    aws events put-targets --rule EnabledS3SourceRule --targets Id=codepipeline-AppPipeline,Arn=arn:aws:codepipeline:us-west-2:80398EXAMPLE:TestPipeline
编辑管道的 PollForSourceChanges参数
重要

使用此方法创建管道时,如果 PollForSourceChanges 参数未明确设置为 false,则默认为 true。添加基于事件的更改检测时,必须将参数添加到输出并将其设置为 false 以禁用轮询。否则,您的管道将针对单个源更改启动两次。有关更多信息,请参阅 PollForSourceChanges 参数的默认设置

  1. 运行 get-pipeline 命令以将管道结构复制到 JSON 文件中。例如,对于名为 MyFirstPipeline 的管道,运行以下命令:

    aws codepipeline get-pipeline --name MyFirstPipeline >pipeline.json

    该命令不会返回任何结果,但您创建的文件将出现在您运行命令所在的目录中。

  2. 在任何纯文本编辑器中打开 JSON 文件并通过将名为 storage-bucket 的存储桶的 PollForSourceChanges 参数更改为 false 来编辑源阶段,如此示例中所示。

    我为何做出此更改? 将此参数设置为 false 将关闭定期检查,因此您只能使用基于事件的更改检测。

    "configuration": { "S3Bucket": "storage-bucket", "PollForSourceChanges": "false", "S3ObjectKey": "index.zip" },
  3. 如果您要使用通过 get-pipeline 命令检索到的管道结构,则必须删除 JSON 文件中的 metadata 行。否则,update-pipeline 命令无法使用它。删除 "metadata": { } 行以及 "created""pipelineARN""updated" 字段。

    例如,从结构中删除以下各行:

    "metadata": { "pipelineArn": "arn:aws:codepipeline:region:account-ID:pipeline-name", "created": "date", "updated": "date" },

    保存该文件。

  4. 要应用更改,请运行 update-pipeline 命令,指定管道 JSON 文件:

    重要

    务必在文件名前包含 file://。此命令中需要该项。

    aws codepipeline update-pipeline --cli-input-json file://pipeline.json

    该命令会返回编辑后的管道的整个结构。

    注意

    update-pipeline 命令会停止管道。如果在运行 update-pipeline 命令时正在通过管道运行修订,则该运行会被停止。您必须手动启动管道,通过升级后的管道运行此修订。使用 start-pipeline-execution 命令手动启动您的管道。

在为事件启用 S3 源的情况下迁移轮询管道(Amazon CloudFormation 模板)

此过程适用于源桶启用了事件的管道。

使用以下步骤,将具有 Amazon S3 源的管道从轮询编辑为基于事件的更改检测。

要构建具有 Amazon S3 的事件驱动管道,您应编辑管道的 PollForSourceChanges 参数,然后将以下资源添加到您的模板:

  • EventBridge 规则和 IAM 角色以允许此事件启动您的管道。

如果您 Amazon CloudFormation 使用创建和管理管道,则您的模板将包含以下内容。

注意

源阶段中的 Configuration 属性称为 PollForSourceChanges。如果您的模板未包含该属性,PollForSourceChanges 在默认情况下将设置为 true

YAML
AppPipeline: Type: AWS::CodePipeline::Pipeline Properties: RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: S3 OutputArtifacts: - Name: SourceOutput Configuration: S3Bucket: !Ref SourceBucket S3ObjectKey: !Ref S3SourceObjectKey PollForSourceChanges: true RunOrder: 1 ...
JSON
"AppPipeline": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { "RoleArn": { "Fn::GetAtt": ["CodePipelineServiceRole", "Arn"] }, "Stages": [ { "Name": "Source", "Actions": [ { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "AWS", "Version": 1, "Provider": "S3" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "S3Bucket": { "Ref": "SourceBucket" }, "S3ObjectKey": { "Ref": "SourceObjectKey" }, "PollForSourceChanges": true }, "RunOrder": 1 } ] }, ...
创建以 Amazon S3 作为事件源和 CodePipeline 目标的 EventBridge 规则并应用权限策略
  1. 在模板下的模板中Resources,使用AWS::IAM::Role Amazon CloudFormation 资源配置允许您的事件启动管道的 IAM 角色。此条目将创建一个使用两个策略的角色:

    • 第一个策略允许代入角色。

    • 第二个策略提供启动管道所需的权限。

    我为何做出此更改? 添加AWS::IAM::Role资源可以 Amazon CloudFormation 为创建权限 EventBridge。此资源已添加到您的 Amazon CloudFormation 堆栈中。

    YAML
    EventRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: eb-pipeline-execution PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: codepipeline:StartPipelineExecution Resource: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] ...
    JSON
    "EventRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "events.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "eb-pipeline-execution", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "codepipeline:StartPipelineExecution", "Resource": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] ...
  2. 使用AWS::Events::Rule Amazon CloudFormation 资源添加 EventBridge 规则。此事件模式会创建一个事件,以监控 Amazon S3 源桶中对象的创建或删除。此外,还包括您管道的目标。创建对象后,此规则将在您的目标管道上调用 StartPipelineExecution

    我为何做出此更改? 添加AWS::Events::Rule资源 Amazon CloudFormation 即可创建事件。此资源已添加到您的 Amazon CloudFormation 堆栈中。

    YAML
    EventRule: Type: AWS::Events::Rule Properties: EventBusName: default EventPattern: source: - aws.s3 detail-type: - Object Created detail: bucket: name: - !Ref SourceBucket Name: EnabledS3SourceRule State: ENABLED Targets: - Arn: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] RoleArn: !GetAtt EventRole.Arn Id: codepipeline-AppPipeline ...
    JSON
    "EventRule": { "Type": "AWS::Events::Rule", "Properties": { "EventBusName": "default", "EventPattern": { "source": [ "aws.s3" ], "detail-type": [ "Object Created" ], "detail": { "bucket": { "name": [ "s3-pipeline-source-fra-bucket" ] } } }, "Name": "EnabledS3SourceRule", "State": "ENABLED", "Targets": [ { "Arn": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] }, "RoleArn": { "Fn::GetAtt": [ "EventRole", "Arn" ] }, "Id": "codepipeline-AppPipeline" } ] } } }, ...
  3. 将更新的模板保存到本地计算机,并打开 Amazon CloudFormation 控制台。

  4. 选择堆栈,然后选择为当前堆栈创建更改集

  5. 上传更新的模板,然后查看 Amazon CloudFormation中所列的更改。以下是将对堆栈进行的更改。您应在列表中看到新资源。

  6. 选择执行

编辑管道的 PollForSourceChanges参数
重要

使用此方法创建管道时,如果 PollForSourceChanges 参数未明确设置为 false,则默认为 true。添加基于事件的更改检测时,必须将参数添加到输出并将其设置为 false 以禁用轮询。否则,您的管道将针对单个源更改启动两次。有关更多信息,请参阅 PollForSourceChanges 参数的默认设置

  • 在模板中,将 PollForSourceChanges 更改为 false。如果您未在管道定义中包含 PollForSourceChanges,请添加它并将它设置为 false

    我为何做出此更改?PollForSourceChanges 更改为 false 将关闭定期检查,因此您只能使用基于事件的更改检测。

    YAML
    Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: S3 OutputArtifacts: - Name: SourceOutput Configuration: S3Bucket: !Ref SourceBucket S3ObjectKey: !Ref SourceObjectKey PollForSourceChanges: false RunOrder: 1
    JSON
    { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "AWS", "Version": 1, "Provider": "S3" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "S3Bucket": { "Ref": "SourceBucket" }, "S3ObjectKey": { "Ref": "SourceObjectKey" }, "PollForSourceChanges": false }, "RunOrder": 1 }

当您使用 Amazon CloudFormation 创建这些资源时,系统会在创建或更新存储库中的文件时触发您的管道。

注意

请勿在此处停止。尽管您的管道已创建,但您必须为 Amazon S3 管道创建第二个 Amazon CloudFormation 模板。如果您不创建第二个模板,您的管道不会有任何更改检测功能。

YAML
Parameters: SourceObjectKey: Description: 'S3 source artifact' Type: String Default: SampleApp_Linux.zip ApplicationName: Description: 'CodeDeploy application name' Type: String Default: DemoApplication BetaFleet: Description: 'Fleet configured in CodeDeploy' Type: String Default: DemoFleet Resources: SourceBucket: Type: AWS::S3::Bucket Properties: NotificationConfiguration: EventBridgeConfiguration: EventBridgeEnabled: true VersioningConfiguration: Status: Enabled CodePipelineArtifactStoreBucket: Type: AWS::S3::Bucket CodePipelineArtifactStoreBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref CodePipelineArtifactStoreBucket PolicyDocument: Version: 2012-10-17 Statement: - Sid: DenyUnEncryptedObjectUploads Effect: Deny Principal: '*' Action: s3:PutObject Resource: !Join [ '', [ !GetAtt CodePipelineArtifactStoreBucket.Arn, '/*' ] ] Condition: StringNotEquals: s3:x-amz-server-side-encryption: aws:kms - Sid: DenyInsecureConnections Effect: Deny Principal: '*' Action: s3:* Resource: !Sub ${CodePipelineArtifactStoreBucket.Arn}/* Condition: Bool: aws:SecureTransport: false CodePipelineServiceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - codepipeline.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: AWS-CodePipeline-Service-3 PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - codecommit:CancelUploadArchive - codecommit:GetBranch - codecommit:GetCommit - codecommit:GetUploadArchiveStatus - codecommit:UploadArchive Resource: 'resource_ARN' - Effect: Allow Action: - codedeploy:CreateDeployment - codedeploy:GetApplicationRevision - codedeploy:GetDeployment - codedeploy:GetDeploymentConfig - codedeploy:RegisterApplicationRevision Resource: 'resource_ARN' - Effect: Allow Action: - codebuild:BatchGetBuilds - codebuild:StartBuild Resource: 'resource_ARN' - Effect: Allow Action: - devicefarm:ListProjects - devicefarm:ListDevicePools - devicefarm:GetRun - devicefarm:GetUpload - devicefarm:CreateUpload - devicefarm:ScheduleRun Resource: 'resource_ARN' - Effect: Allow Action: - lambda:InvokeFunction - lambda:ListFunctions Resource: 'resource_ARN' - Effect: Allow Action: - iam:PassRole Resource: 'resource_ARN' - Effect: Allow Action: - elasticbeanstalk:* - ec2:* - elasticloadbalancing:* - autoscaling:* - cloudwatch:* - s3:* - sns:* - cloudformation:* - rds:* - sqs:* - ecs:* Resource: 'resource_ARN' AppPipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: s3-events-pipeline RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: S3 OutputArtifacts: - Name: SourceOutput Configuration: S3Bucket: !Ref SourceBucket S3ObjectKey: !Ref SourceObjectKey PollForSourceChanges: false RunOrder: 1 - Name: Beta Actions: - Name: BetaAction InputArtifacts: - Name: SourceOutput ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CodeDeploy Configuration: ApplicationName: !Ref ApplicationName DeploymentGroupName: !Ref BetaFleet RunOrder: 1 ArtifactStore: Type: S3 Location: !Ref CodePipelineArtifactStoreBucket EventRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: eb-pipeline-execution PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: codepipeline:StartPipelineExecution Resource: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] EventRule: Type: AWS::Events::Rule Properties: EventBusName: default EventPattern: source: - aws.s3 detail-type: - Object Created detail: bucket: name: - !Ref SourceBucket Name: EnabledS3SourceRule State: ENABLED Targets: - Arn: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] RoleArn: !GetAtt EventRole.Arn Id: codepipeline-AppPipeline
JSON
{ "Parameters": { "SourceObjectKey": { "Description": "S3 source artifact", "Type": "String", "Default": "SampleApp_Linux.zip" }, "ApplicationName": { "Description": "CodeDeploy application name", "Type": "String", "Default": "DemoApplication" }, "BetaFleet": { "Description": "Fleet configured in CodeDeploy", "Type": "String", "Default": "DemoFleet" } }, "Resources": { "SourceBucket": { "Type": "AWS::S3::Bucket", "Properties": { "NotificationConfiguration": { "EventBridgeConfiguration": { "EventBridgeEnabled": true } }, "VersioningConfiguration": { "Status": "Enabled" } } }, "CodePipelineArtifactStoreBucket": { "Type": "AWS::S3::Bucket" }, "CodePipelineArtifactStoreBucketPolicy": { "Type": "AWS::S3::BucketPolicy", "Properties": { "Bucket": { "Ref": "CodePipelineArtifactStoreBucket" }, "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyUnEncryptedObjectUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": { "Fn::Join": [ "", [ { "Fn::GetAtt": [ "CodePipelineArtifactStoreBucket", "Arn" ] }, "/*" ] ] }, "Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "aws:kms" } } }, { "Sid": "DenyInsecureConnections", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": { "Fn::Join": [ "", [ { "Fn::GetAtt": [ "CodePipelineArtifactStoreBucket", "Arn" ] }, "/*" ] ] }, "Condition": { "Bool": { "aws:SecureTransport": false } } } ] } } }, "CodePipelineServiceRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "codepipeline.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "AWS-CodePipeline-Service-3", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codecommit:CancelUploadArchive", "codecommit:GetBranch", "codecommit:GetCommit", "codecommit:GetUploadArchiveStatus", "codecommit:UploadArchive" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "codedeploy:CreateDeployment", "codedeploy:GetApplicationRevision", "codedeploy:GetDeployment", "codedeploy:GetDeploymentConfig", "codedeploy:RegisterApplicationRevision" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "codebuild:BatchGetBuilds", "codebuild:StartBuild" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "devicefarm:ListProjects", "devicefarm:ListDevicePools", "devicefarm:GetRun", "devicefarm:GetUpload", "devicefarm:CreateUpload", "devicefarm:ScheduleRun" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "lambda:InvokeFunction", "lambda:ListFunctions" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "elasticbeanstalk:*", "ec2:*", "elasticloadbalancing:*", "autoscaling:*", "cloudwatch:*", "s3:*", "sns:*", "cloudformation:*", "rds:*", "sqs:*", "ecs:*" ], "Resource": "resource_ARN" } ] } } ] } }, "AppPipeline": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { "Name": "s3-events-pipeline", "RoleArn": { "Fn::GetAtt": [ "CodePipelineServiceRole", "Arn" ] }, "Stages": [ { "Name": "Source", "Actions": [ { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "AWS", "Version": 1, "Provider": "S3" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "S3Bucket": { "Ref": "SourceBucket" }, "S3ObjectKey": { "Ref": "SourceObjectKey" }, "PollForSourceChanges": false }, "RunOrder": 1 } ] }, { "Name": "Beta", "Actions": [ { "Name": "BetaAction", "InputArtifacts": [ { "Name": "SourceOutput" } ], "ActionTypeId": { "Category": "Deploy", "Owner": "AWS", "Version": 1, "Provider": "CodeDeploy" }, "Configuration": { "ApplicationName": { "Ref": "ApplicationName" }, "DeploymentGroupName": { "Ref": "BetaFleet" } }, "RunOrder": 1 } ] } ], "ArtifactStore": { "Type": "S3", "Location": { "Ref": "CodePipelineArtifactStoreBucket" } } } }, "EventRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "events.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "eb-pipeline-execution", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "codepipeline:StartPipelineExecution", "Resource": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] } } ] } } ] } }, "EventRule": { "Type": "AWS::Events::Rule", "Properties": { "EventBusName": "default", "EventPattern": { "source": [ "aws.s3" ], "detail-type": [ "Object Created" ], "detail": { "bucket": { "name": [ { "Ref": "SourceBucket" } ] } } }, "Name": "EnabledS3SourceRule", "State": "ENABLED", "Targets": [ { "Arn": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] }, "RoleArn": { "Fn::GetAtt": [ "EventRole", "Arn" ] }, "Id": "codepipeline-AppPipeline" } ] } } } } }

使用 S3 源和 CloudTrail 跟踪迁移轮询管道

对于具有 Amazon S3 源的管道,请修改管道,以便通过自动进行更改检测 EventBridge。从以下方法中进行选择以实施迁移:

使用 S3 源和跟 CloudTrail 踪 (CLI) 迁移轮询管道

按照以下步骤编辑正在使用轮询(定期检查)的管道, EventBridge 改为使用事件。如果要创建管道,请参阅在中创建管道 CodePipeline

要构建具有 Amazon S3 源的事件驱动管道,您应编辑管道的 PollForSourceChanges 参数,然后创建以下资源:

  • Amazon CloudTrail Amazon S3 可用于记录事件的跟踪、存储桶和存储桶策略。

  • EventBridge 事件

  • 允许 EventBridge 事件启动管道的 IAM 角色

创建 Amazon CloudTrail 跟踪并启用日志记录

要使用创建跟踪,请调用create-trail命令,指定: Amazon CLI

  • 跟踪名称。

  • 已将 Amazon CloudTrail的存储桶策略应用于的存储桶。

有关更多信息,请参阅使用Amazon 命令行界面创建跟踪

  1. 调用 create-trail 命令并包含 --name--s3-bucket-name 参数。

    我为何做出此更改? 这将为您的 S3 源存储桶创建所需的 CloudTrail跟踪。

    以下示例命令使用 --name--s3-bucket-name 创建一个名为 my-trail 的跟踪和一个名为 myBucket 的存储桶。

    aws cloudtrail create-trail --name my-trail --s3-bucket-name myBucket
  2. 调用 start-logging 命令并包含 --name 参数。

    我为何做出此更改? 此命令启动您的源存储桶的 CloudTrail 日志记录并将事件发送到 EventBridge。

    例如:

    以下命令使用 --name 启动针对名为 my-trail 的跟踪的日志记录。

    aws cloudtrail start-logging --name my-trail
  3. 调用 put-event-selectors 命令并包含 --trail-name--event-selectors 参数。使用事件选择器指定您希望您的跟踪记录源存储桶的数据事件并将事件发送到 EventBridge 规则。

    我为何做出此更改? 此命令筛选事件。

    例如:

    以下示例命令使用 --trail-name--event-selectors 指定源存储桶的数据事件以及名为 myBucket/myFolder 的前缀。

    aws cloudtrail put-event-selectors --trail-name my-trail --event-selectors '[{ "ReadWriteType": "WriteOnly", "IncludeManagementEvents":false, "DataResources": [{ "Type": "AWS::S3::Object", "Values": ["arn:aws:s3:::myBucket/myFolder/file.zip"] }] }]'
创建以 Amazon S3 作为事件源和 CodePipeline 目标的 EventBridge 规则并应用权限策略
  1. 授 EventBridge 予使用调 CodePipeline 用规则的权限。有关更多信息,请参阅使用适用于 Amazon EventBridge 的基于资源的政策。

    1. 使用以下示例创建允许 EventBridge 担任服务角色的信任策略。将它命名为 trustpolicyforEB.json

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
    2. 使用以下命令创建 Role-for-MyRule 角色并附加信任策略。

      我为何做出此更改? 将此信任策略添加到角色会为创建权限 EventBridge。

      aws iam create-role --role-name Role-for-MyRule --assume-role-policy-document file://trustpolicyforEB.json
    3. 为名为 MyFirstPipeline 的管道创建权限策略 JSON,如此处所示。将权限策略命名为 permissionspolicyforEB.json

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codepipeline:StartPipelineExecution" ], "Resource": [ "arn:aws:codepipeline:us-west-2:80398EXAMPLE:MyFirstPipeline" ] } ] }
    4. 使用以下命令将新的 CodePipeline-Permissions-Policy-for-EB 权限策略附加到您创建的 Role-for-MyRule 角色。

      aws iam put-role-policy --role-name Role-for-MyRule --policy-name CodePipeline-Permissions-Policy-For-EB --policy-document file://permissionspolicyforEB.json
  2. 调用 put-rule 命令并包含 --name--event-pattern--role-arn 参数。

    以下示例命令创建名为 MyS3SourceRule 的规则。

    aws events put-rule --name "MyS3SourceRule" --event-pattern "{\"source\":[\"aws.s3\"],\"detail-type\":[\"AWS API Call via CloudTrail\"],\"detail\":{\"eventSource\":[\"s3.amazonaws.com\"],\"eventName\":[\"CopyObject\",\"PutObject\",\"CompleteMultipartUpload\"],\"requestParameters\":{\"bucketName\":[\"my-bucket\"],\"key\":[\"my-key\"]}}} --role-arn "arn:aws:iam::ACCOUNT_ID:role/Role-for-MyRule"
  3. 要添加 CodePipeline 为目标,请调用put-targets命令并添加--rule--targets参数。

    以下示例命令为名为 MyS3SourceRule 的规则指定此内容,目标 Id 由数字 1 组成,这指示此内容位于规则的目标列表中,而这是目标 1。此命令还为管道指定一个示例 ARN。管道在存储库中发生更改时启动。

    aws events put-targets --rule MyS3SourceRule --targets Id=1,Arn=arn:aws:codepipeline:us-west-2:80398EXAMPLE:TestPipeline
编辑管道的 PollForSourceChanges参数
重要

使用此方法创建管道时,如果 PollForSourceChanges 参数未明确设置为 false,则默认为 true。添加基于事件的更改检测时,必须将参数添加到输出并将其设置为 false 以禁用轮询。否则,您的管道将针对单个源更改启动两次。有关更多信息,请参阅 PollForSourceChanges 参数的默认设置

  1. 运行 get-pipeline 命令以将管道结构复制到 JSON 文件中。例如,对于名为 MyFirstPipeline 的管道,运行以下命令:

    aws codepipeline get-pipeline --name MyFirstPipeline >pipeline.json

    该命令不会返回任何结果,但您创建的文件将出现在您运行命令所在的目录中。

  2. 在任何纯文本编辑器中打开 JSON 文件并通过将名为 storage-bucket 的存储桶的 PollForSourceChanges 参数更改为 false 来编辑源阶段,如此示例中所示。

    我为何做出此更改? 将此参数设置为 false 将关闭定期检查,因此您只能使用基于事件的更改检测。

    "configuration": { "S3Bucket": "storage-bucket", "PollForSourceChanges": "false", "S3ObjectKey": "index.zip" },
  3. 如果您要使用通过 get-pipeline 命令检索到的管道结构,则必须删除 JSON 文件中的 metadata 行。否则,update-pipeline 命令无法使用它。删除 "metadata": { } 行以及 "created""pipelineARN""updated" 字段。

    例如,从结构中删除以下各行:

    "metadata": { "pipelineArn": "arn:aws:codepipeline:region:account-ID:pipeline-name", "created": "date", "updated": "date" },

    保存该文件。

  4. 要应用更改,请运行 update-pipeline 命令,指定管道 JSON 文件:

    重要

    务必在文件名前包含 file://。此命令中需要该项。

    aws codepipeline update-pipeline --cli-input-json file://pipeline.json

    该命令会返回编辑后的管道的整个结构。

    注意

    update-pipeline 命令会停止管道。如果在运行 update-pipeline 命令时正在通过管道运行修订,则该运行会被停止。您必须手动启动管道,通过升级后的管道运行此修订。使用 start-pipeline-execution 命令手动启动您的管道。

使用 S3 源和 CloudTrail 跟踪(Amazon CloudFormation 模板)迁移轮询管道

使用以下步骤,将具有 Amazon S3 源的管道从轮询编辑为基于事件的更改检测。

要构建具有 Amazon S3 的事件驱动管道,您应编辑管道的 PollForSourceChanges 参数,然后将以下资源添加到您的模板:

  • EventBridge 要求必须记录所有 Amazon S3 事件。必须创建 Amazon CloudTrail 跟踪、桶和桶策略,以便 Amazon S3 用于记录发生的事件。有关更多信息,请参阅记录数据事件以用于跟踪记录管理事件以用于跟踪

  • EventBridge 规则和 IAM 角色以允许此事件启动我们的管道。

如果您 Amazon CloudFormation 使用创建和管理管道,则您的模板将包含以下内容。

注意

源阶段中的 Configuration 属性称为 PollForSourceChanges。如果您的模板未包含该属性,PollForSourceChanges 在默认情况下将设置为 true

YAML
AppPipeline: Type: AWS::CodePipeline::Pipeline Properties: RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: S3 OutputArtifacts: - Name: SourceOutput Configuration: S3Bucket: !Ref SourceBucket S3ObjectKey: !Ref S3SourceObjectKey PollForSourceChanges: true RunOrder: 1 ...
JSON
"AppPipeline": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { "RoleArn": { "Fn::GetAtt": ["CodePipelineServiceRole", "Arn"] }, "Stages": [ { "Name": "Source", "Actions": [ { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "AWS", "Version": 1, "Provider": "S3" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "S3Bucket": { "Ref": "SourceBucket" }, "S3ObjectKey": { "Ref": "SourceObjectKey" }, "PollForSourceChanges": true }, "RunOrder": 1 } ] }, ...
创建以 Amazon S3 作为事件源和 CodePipeline 目标的 EventBridge 规则并应用权限策略
  1. 在模板下的模板中Resources,使用AWS::IAM::Role Amazon CloudFormation 资源配置允许您的事件启动管道的 IAM 角色。此条目将创建一个使用两个策略的角色:

    • 第一个策略允许代入角色。

    • 第二个策略提供启动管道所需的权限。

    我为何做出此更改? 添加AWS::IAM::Role资源可以 Amazon CloudFormation 为创建权限 EventBridge。此资源已添加到您的 Amazon CloudFormation 堆栈中。

    YAML
    EventRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: eb-pipeline-execution PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: codepipeline:StartPipelineExecution Resource: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] ...
    JSON
    "EventRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "events.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "eb-pipeline-execution", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "codepipeline:StartPipelineExecution", "Resource": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] ...
  2. 使用AWS::Events::Rule Amazon CloudFormation 资源添加 EventBridge 规则。此事件模式会创建一个事件,以监控 Amazon S3 源桶上的 CopyObjectPutObjectCompleteMultipartUpload。此外,还包括您管道的目标。当发生 CopyObjectPutObjectCompleteMultipartUpload 时,此规则将对目标管道调用 StartPipelineExecution

    我为何做出此更改? 添加AWS::Events::Rule资源 Amazon CloudFormation 即可创建事件。此资源已添加到您的 Amazon CloudFormation 堆栈中。

    YAML
    EventRule: Type: AWS::Events::Rule Properties: EventPattern: source: - aws.s3 detail-type: - 'AWS API Call via CloudTrail' detail: eventSource: - s3.amazonaws.com eventName: - CopyObject - PutObject - CompleteMultipartUpload requestParameters: bucketName: - !Ref SourceBucket key: - !Ref SourceObjectKey Targets: - Arn: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] RoleArn: !GetAtt EventRole.Arn Id: codepipeline-AppPipeline ...
    JSON
    "EventRule": { "Type": "AWS::Events::Rule", "Properties": { "EventPattern": { "source": [ "aws.s3" ], "detail-type": [ "AWS API Call via CloudTrail" ], "detail": { "eventSource": [ "s3.amazonaws.com" ], "eventName": [ "CopyObject", "PutObject", "CompleteMultipartUpload" ], "requestParameters": { "bucketName": [ { "Ref": "SourceBucket" } ], "key": [ { "Ref": "SourceObjectKey" } ] } } }, "Targets": [ { "Arn": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] }, "RoleArn": { "Fn::GetAtt": [ "EventRole", "Arn" ] }, "Id": "codepipeline-AppPipeline" } ] } } }, ...
  3. 将此代码段添加到第一个模板,以允许跨堆栈功能:

    YAML
    Outputs: SourceBucketARN: Description: "S3 bucket ARN that Cloudtrail will use" Value: !GetAtt SourceBucket.Arn Export: Name: SourceBucketARN
    JSON
    "Outputs" : { "SourceBucketARN" : { "Description" : "S3 bucket ARN that Cloudtrail will use", "Value" : { "Fn::GetAtt": ["SourceBucket", "Arn"] }, "Export" : { "Name" : "SourceBucketARN" } } ...
  4. 将更新后的模板保存到本地计算机上,然后打开 Amazon CloudFormation 控制台。

  5. 选择堆栈,然后选择为当前堆栈创建更改集

  6. 上传更新的模板,然后查看 Amazon CloudFormation中所列的更改。以下是将对堆栈进行的更改。您应在列表中看到新资源。

  7. 选择执行

编辑管道的 PollForSourceChanges参数
重要

使用此方法创建管道时,如果 PollForSourceChanges 参数未明确设置为 false,则默认为 true。添加基于事件的更改检测时,必须将参数添加到输出并将其设置为 false 以禁用轮询。否则,您的管道将针对单个源更改启动两次。有关更多信息,请参阅 PollForSourceChanges 参数的默认设置

  • 在模板中,将 PollForSourceChanges 更改为 false。如果您未在管道定义中包含 PollForSourceChanges,请添加它并将它设置为 false

    我为何做出此更改?PollForSourceChanges 更改为 false 将关闭定期检查,因此您只能使用基于事件的更改检测。

    YAML
    Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: S3 OutputArtifacts: - Name: SourceOutput Configuration: S3Bucket: !Ref SourceBucket S3ObjectKey: !Ref SourceObjectKey PollForSourceChanges: false RunOrder: 1
    JSON
    { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "AWS", "Version": 1, "Provider": "S3" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "S3Bucket": { "Ref": "SourceBucket" }, "S3ObjectKey": { "Ref": "SourceObjectKey" }, "PollForSourceChanges": false }, "RunOrder": 1 }
为您的 Amazon S3 管道 CloudTrail 资源创建第二个模板
  • 在单独的模板中Resources,使用AWS::S3::BucketAWS::S3::BucketPolicy、和AWS::CloudTrail::Trail Amazon CloudFormation 资源为其提供简单的存储桶定义和跟踪 CloudTrail。

    我为何做出此更改? 鉴于当前每个账户只能有五条 CloudTrail 跟踪,因此必须单独创建和管理跟踪。(参见中的限制 Amazon CloudTrail。) 但是,您可以在单个跟踪上包括许多 Amazon S3 桶,因此您可以创建跟踪一次,然后根据需要为其他管道添加 Amazon S3 桶。将以下内容粘贴到第二个示例模板文件中。

    YAML
    ################################################################################### # Prerequisites: # - S3 SourceBucket and SourceObjectKey must exist ################################################################################### Parameters: SourceObjectKey: Description: 'S3 source artifact' Type: String Default: SampleApp_Linux.zip Resources: AWSCloudTrailBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref AWSCloudTrailBucket PolicyDocument: Version: 2012-10-17 Statement: - Sid: AWSCloudTrailAclCheck Effect: Allow Principal: Service: - cloudtrail.amazonaws.com Action: s3:GetBucketAcl Resource: !GetAtt AWSCloudTrailBucket.Arn - Sid: AWSCloudTrailWrite Effect: Allow Principal: Service: - cloudtrail.amazonaws.com Action: s3:PutObject Resource: !Join [ '', [ !GetAtt AWSCloudTrailBucket.Arn, '/AWSLogs/', !Ref 'AWS::AccountId', '/*' ] ] Condition: StringEquals: s3:x-amz-acl: bucket-owner-full-control AWSCloudTrailBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain AwsCloudTrail: DependsOn: - AWSCloudTrailBucketPolicy Type: AWS::CloudTrail::Trail Properties: S3BucketName: !Ref AWSCloudTrailBucket EventSelectors: - DataResources: - Type: AWS::S3::Object Values: - !Join [ '', [ !ImportValue SourceBucketARN, '/', !Ref SourceObjectKey ] ] ReadWriteType: WriteOnly IncludeManagementEvents: false IncludeGlobalServiceEvents: true IsLogging: true IsMultiRegionTrail: true ...
    JSON
    { "Parameters": { "SourceObjectKey": { "Description": "S3 source artifact", "Type": "String", "Default": "SampleApp_Linux.zip" } }, "Resources": { "AWSCloudTrailBucket": { "Type": "AWS::S3::Bucket", "DeletionPolicy": "Retain" }, "AWSCloudTrailBucketPolicy": { "Type": "AWS::S3::BucketPolicy", "Properties": { "Bucket": { "Ref": "AWSCloudTrailBucket" }, "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "AWSCloudTrailAclCheck", "Effect": "Allow", "Principal": { "Service": [ "cloudtrail.amazonaws.com" ] }, "Action": "s3:GetBucketAcl", "Resource": { "Fn::GetAtt": [ "AWSCloudTrailBucket", "Arn" ] } }, { "Sid": "AWSCloudTrailWrite", "Effect": "Allow", "Principal": { "Service": [ "cloudtrail.amazonaws.com" ] }, "Action": "s3:PutObject", "Resource": { "Fn::Join": [ "", [ { "Fn::GetAtt": [ "AWSCloudTrailBucket", "Arn" ] }, "/AWSLogs/", { "Ref": "AWS::AccountId" }, "/*" ] ] }, "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } } } ] } } }, "AwsCloudTrail": { "DependsOn": [ "AWSCloudTrailBucketPolicy" ], "Type": "AWS::CloudTrail::Trail", "Properties": { "S3BucketName": { "Ref": "AWSCloudTrailBucket" }, "EventSelectors": [ { "DataResources": [ { "Type": "AWS::S3::Object", "Values": [ { "Fn::Join": [ "", [ { "Fn::ImportValue": "SourceBucketARN" }, "/", { "Ref": "SourceObjectKey" } ] ] } ] } ], "ReadWriteType": "WriteOnly", "IncludeManagementEvents": false } ], "IncludeGlobalServiceEvents": true, "IsLogging": true, "IsMultiRegionTrail": true } } } } ...

当您使用 Amazon CloudFormation 创建这些资源时,系统会在创建或更新存储库中的文件时触发您的管道。

注意

请勿在此处停止。尽管您的管道已创建,但您必须为 Amazon S3 管道创建第二个 Amazon CloudFormation 模板。如果您不创建第二个模板,您的管道不会有任何更改检测功能。

YAML
Resources: SourceBucket: Type: AWS::S3::Bucket Properties: VersioningConfiguration: Status: Enabled CodePipelineArtifactStoreBucket: Type: AWS::S3::Bucket CodePipelineArtifactStoreBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref CodePipelineArtifactStoreBucket PolicyDocument: Version: 2012-10-17 Statement: - Sid: DenyUnEncryptedObjectUploads Effect: Deny Principal: '*' Action: s3:PutObject Resource: !Join [ '', [ !GetAtt CodePipelineArtifactStoreBucket.Arn, '/*' ] ] Condition: StringNotEquals: s3:x-amz-server-side-encryption: aws:kms - Sid: DenyInsecureConnections Effect: Deny Principal: '*' Action: s3:* Resource: !Join [ '', [ !GetAtt CodePipelineArtifactStoreBucket.Arn, '/*' ] ] Condition: Bool: aws:SecureTransport: false CodePipelineServiceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - codepipeline.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: AWS-CodePipeline-Service-3 PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - codecommit:CancelUploadArchive - codecommit:GetBranch - codecommit:GetCommit - codecommit:GetUploadArchiveStatus - codecommit:UploadArchive Resource: 'resource_ARN' - Effect: Allow Action: - codedeploy:CreateDeployment - codedeploy:GetApplicationRevision - codedeploy:GetDeployment - codedeploy:GetDeploymentConfig - codedeploy:RegisterApplicationRevision Resource: 'resource_ARN' - Effect: Allow Action: - codebuild:BatchGetBuilds - codebuild:StartBuild Resource: 'resource_ARN' - Effect: Allow Action: - devicefarm:ListProjects - devicefarm:ListDevicePools - devicefarm:GetRun - devicefarm:GetUpload - devicefarm:CreateUpload - devicefarm:ScheduleRun Resource: 'resource_ARN' - Effect: Allow Action: - lambda:InvokeFunction - lambda:ListFunctions Resource: 'resource_ARN' - Effect: Allow Action: - iam:PassRole Resource: 'resource_ARN' - Effect: Allow Action: - elasticbeanstalk:* - ec2:* - elasticloadbalancing:* - autoscaling:* - cloudwatch:* - s3:* - sns:* - cloudformation:* - rds:* - sqs:* - ecs:* Resource: 'resource_ARN' AppPipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: s3-events-pipeline RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: S3 OutputArtifacts: - Name: SourceOutput Configuration: S3Bucket: !Ref SourceBucket S3ObjectKey: !Ref SourceObjectKey PollForSourceChanges: false RunOrder: 1 - Name: Beta Actions: - Name: BetaAction InputArtifacts: - Name: SourceOutput ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CodeDeploy Configuration: ApplicationName: !Ref ApplicationName DeploymentGroupName: !Ref BetaFleet RunOrder: 1 ArtifactStore: Type: S3 Location: !Ref CodePipelineArtifactStoreBucket EventRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: sts:AssumeRole Path: / Policies: - PolicyName: eb-pipeline-execution PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: codepipeline:StartPipelineExecution Resource: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] EventRule: Type: AWS::Events::Rule Properties: EventPattern: source: - aws.s3 detail-type: - 'AWS API Call via CloudTrail' detail: eventSource: - s3.amazonaws.com eventName: - PutObject - CompleteMultipartUpload resources: ARN: - !Join [ '', [ !GetAtt SourceBucket.Arn, '/', !Ref SourceObjectKey ] ] Targets: - Arn: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ] RoleArn: !GetAtt EventRole.Arn Id: codepipeline-AppPipeline Outputs: SourceBucketARN: Description: "S3 bucket ARN that Cloudtrail will use" Value: !GetAtt SourceBucket.Arn Export: Name: SourceBucketARN
JSON
"Resources": { "SourceBucket": { "Type": "AWS::S3::Bucket", "Properties": { "VersioningConfiguration": { "Status": "Enabled" } } }, "CodePipelineArtifactStoreBucket": { "Type": "AWS::S3::Bucket" }, "CodePipelineArtifactStoreBucketPolicy": { "Type": "AWS::S3::BucketPolicy", "Properties": { "Bucket": { "Ref": "CodePipelineArtifactStoreBucket" }, "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyUnEncryptedObjectUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": { "Fn::Join": [ "", [ { "Fn::GetAtt": [ "CodePipelineArtifactStoreBucket", "Arn" ] }, "/*" ] ] }, "Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "aws:kms" } } }, { "Sid": "DenyInsecureConnections", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": { "Fn::Join": [ "", [ { "Fn::GetAtt": [ "CodePipelineArtifactStoreBucket", "Arn" ] }, "/*" ] ] }, "Condition": { "Bool": { "aws:SecureTransport": false } } } ] } } }, "CodePipelineServiceRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "codepipeline.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "AWS-CodePipeline-Service-3", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codecommit:CancelUploadArchive", "codecommit:GetBranch", "codecommit:GetCommit", "codecommit:GetUploadArchiveStatus", "codecommit:UploadArchive" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "codedeploy:CreateDeployment", "codedeploy:GetApplicationRevision", "codedeploy:GetDeployment", "codedeploy:GetDeploymentConfig", "codedeploy:RegisterApplicationRevision" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "codebuild:BatchGetBuilds", "codebuild:StartBuild" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "devicefarm:ListProjects", "devicefarm:ListDevicePools", "devicefarm:GetRun", "devicefarm:GetUpload", "devicefarm:CreateUpload", "devicefarm:ScheduleRun" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "lambda:InvokeFunction", "lambda:ListFunctions" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": "resource_ARN" }, { "Effect": "Allow", "Action": [ "elasticbeanstalk:*", "ec2:*", "elasticloadbalancing:*", "autoscaling:*", "cloudwatch:*", "s3:*", "sns:*", "cloudformation:*", "rds:*", "sqs:*", "ecs:*" ], "Resource": "resource_ARN" } ] } } ] } }, "AppPipeline": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { "Name": "s3-events-pipeline", "RoleArn": { "Fn::GetAtt": [ "CodePipelineServiceRole", "Arn" ] }, "Stages": [ { "Name": "Source", "Actions": [ { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "AWS", "Version": 1, "Provider": "S3" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "S3Bucket": { "Ref": "SourceBucket" }, "S3ObjectKey": { "Ref": "SourceObjectKey" }, "PollForSourceChanges": false }, "RunOrder": 1 } ] }, { "Name": "Beta", "Actions": [ { "Name": "BetaAction", "InputArtifacts": [ { "Name": "SourceOutput" } ], "ActionTypeId": { "Category": "Deploy", "Owner": "AWS", "Version": 1, "Provider": "CodeDeploy" }, "Configuration": { "ApplicationName": { "Ref": "ApplicationName" }, "DeploymentGroupName": { "Ref": "BetaFleet" } }, "RunOrder": 1 } ] } ], "ArtifactStore": { "Type": "S3", "Location": { "Ref": "CodePipelineArtifactStoreBucket" } } } }, "EventRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "events.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "eb-pipeline-execution", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "codepipeline:StartPipelineExecution", "Resource": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] } } ] } } ] } }, "EventRule": { "Type": "AWS::Events::Rule", "Properties": { "EventPattern": { "source": [ "aws.s3" ], "detail-type": [ "AWS API Call via CloudTrail" ], "detail": { "eventSource": [ "s3.amazonaws.com" ], "eventName": [ "PutObject", "CompleteMultipartUpload" ], "resources": { "ARN": [ { "Fn::Join": [ "", [ { "Fn::GetAtt": [ "SourceBucket", "Arn" ] }, "/", { "Ref": "SourceObjectKey" } ] ] } ] } } }, "Targets": [ { "Arn": { "Fn::Join": [ "", [ "arn:aws:codepipeline:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":", { "Ref": "AppPipeline" } ] ] }, "RoleArn": { "Fn::GetAtt": [ "EventRole", "Arn" ] }, "Id": "codepipeline-AppPipeline" } ] } } }, "Outputs" : { "SourceBucketARN" : { "Description" : "S3 bucket ARN that Cloudtrail will use", "Value" : { "Fn::GetAtt": ["SourceBucket", "Arn"] }, "Export" : { "Name" : "SourceBucketARN" } } } } ...

将 GitHub 版本 1 源操作的轮询管道迁移到连接

您可以迁移 GitHub 版本 1 的源操作以使用外部存储库的连接。对于使用 GitHub版本 1 源操作的管道,这是推荐的变更检测方法。

对于具有 GitHub 版本 1 源操作的管道,我们建议将管道修改为使用 GitHub 版本 2 操作,以便自动进行更改检测 Amazon CodeConnections。有关使用连接的更多信息,请参阅GitHub 连接

创建与 GitHub (控制台)的连接

您可以使用控制台创建与的连接 GitHub。

步骤 1:替换版本 1 的 GitHub 操作

使用管道编辑页面将您的版本 1 GitHub 操作替换为版本 2 GitHub 操作。

替换您的版本 1 GitHub 操作
  1. 登录 CodePipeline 控制台。

  2. 选择管道,然后选择编辑。在源阶段中,选择编辑阶段。将显示一条消息,建议您更新操作。

  3. 操作提供者中,选择 GitHub (版本 2)

  4. 请执行以下操作之一:

    • 在 “连接” 下,如果您尚未创建与提供商的连接,请选择 “连接到” GitHub。继续步骤 2:创建与的连接 GitHub。

    • 连接下,如果您已创建到提供程序的连接,请选择该连接。继续执行步骤 3:保存连接的源操作。

步骤 2:创建与的连接 GitHub

选择创建连接后,将显示 “Connect t GitHub o” 页面。

要创建与的连接 GitHub
  1. “GitHub 连接设置” 下,您的连接名称显示在 “连接名称” 中。

    在 “GitHub 应用程序” 下,选择应用程序安装或选择 “安装新应用程序” 来创建一个。

    注意

    您可以为与特定提供程序的所有连接安装一个应用程序。如果您已经安装了该 GitHub 应用程序,请选择它并跳过此步骤。

  2. 如果 GitHub 显示的授权页面,请使用您的凭据登录,然后选择继续。

  3. 在应用程序安装页面上,一条消息显示该 AWS CodeStar 应用程序正在尝试连接到您的 GitHub 帐户。

    注意

    您只需为每个 GitHub 账户安装一次该应用程序。如果您之前已安装了应用程序,则可以选择配置,继续进入应用程序安装的修改页面,也可以使用后退按钮返回到控制台。

  4. 安装 AWS CodeStar 页面上,选择安装

  5. 在 “Connect t o GitHub” 页面上,将显示新安装的连接 ID。选择连接

第 3 步:保存您的 GitHub 源代码操作

编辑操作页面上完成更新以保存新的源操作。

保存您的 GitHub 源代码操作
  1. 存储库中,输入第三方存储库的名称。在分支中,输入您希望管道在其中检测源更改的分支。

    注意

    存储库中键入 owner-name/repository-name,如以下示例所示:

    my-account/my-repository
  2. 输出构件格式中,为构件选择格式。

  3. 输出构件中,可以保留此操作的输出对象的名称,例如 SourceArtifact。选择完成以关闭编辑操作页面。

  4. 选择完成以关闭阶段编辑页面。选择保存以关闭管道编辑页面。

创建与 GitHub (CLI) 的连接

您可以使用 Amazon Command Line Interface (Amazon CLI) 创建与的连接 GitHub。

为此,请使用 create-connection 命令。

重要

默认情况下,通过 Amazon CLI 或创建的连接 Amazon CloudFormation 处于PENDING状态。使用 CLI 或创建连接后 Amazon CloudFormation,使用控制台编辑连接以使其处于状态AVAILABLE

要创建与的连接 GitHub
  1. 打开终端(Linux、macOS 或 Unix)或命令提示符(Windows)。 Amazon CLI 使用运行create-connection命令,--connection-name为您的连接指定--provider-type和。在此示例中,第三方提供方名称为 GitHub,指定的连接名称为 MyConnection

    aws codeconnections create-connection --provider-type GitHub --connection-name MyConnection

    如果成功,该命令将返回类似以下内容的连接 ARN 信息。

    { "ConnectionArn": "arn:aws:codeconnections:us-west-2:account_id:connection/aEXAMPLE-8aad-4d5d-8878-dfcab0bc441f" }
  2. 使用控制台完成连接。

将 GitHub 版本 1 源操作的轮询管道迁移到 webhook

您可以将管道迁移到使用 webhook 来检测 GitHub 源存储库中的更改。这种向 webhook 的迁移仅适用于 GitHub 版本 1 的操作。

将轮询管道迁移到 webhook(GitHub 版本 1 源操作)(控制台)

您可以使用 CodePipeline 控制台更新管道,以便使用 webhook 来检测 CodeCommit 源存储库中的更改。

按照以下步骤编辑 EventBridge 改用轮询(定期检查)的管道。如果要创建管道,请参阅在中创建管道 CodePipeline

当您使用控制台时,您的管道的 PollForSourceChanges 参数将为您更改。 GitHub Webhook 已为您创建并注册。

编辑管道源阶段
  1. 登录 Amazon Web Services Management Console 并打开 CodePipeline 控制台,网址为 http://console.aws.amazon.com/codesuite/codepipeline/home

    将显示与您的 Amazon 账户关联的所有管道的名称。

  2. Name 中,选择您要编辑的管道的名称。这将打开管道的详细视图,包括管道每个阶段中每个操作的状态。

  3. 在管道详细信息页中,选择编辑

  4. Edit stage (编辑阶段) 中,选择源操作上的编辑图标。

  5. 展开 “更改检测选项”,然后选择 “使用 Amazon CloudWatch Events”,以便在发生更改时自动启动我的管道(推荐)

    屏幕上会显示一条消息,提示您 CodePipeline 创建一个 webhook GitHub 以检测源代码更改: Amazon CodePipeline 将为您创建 webhook。可以在以下选项中选择退出。选择更新。除了 webhook 之外,还 CodePipeline 会创建以下内容:

    • 随机生成并用于授权连接的密钥 GitHub。

    • Webhook URL,使用该区域的公有终端节点生成。

    CodePipeline 向注册 webhook。 GitHub这将订阅 URL 以接收存储库事件。

  6. 编辑完您的管道后,请选择 Save pipeline changes 以返回到摘要页面。

    将出现一条消息,显示要为您的管道创建的 Webhook 的名称。选择 保存并继续

  7. 要测试您的操作,请使用发布更改,将更改提交 Amazon CLI 到管道源阶段中指定的源。

将轮询管道迁移到 Webhook(GitHub 版本 1 源操作)(CLI)

执行以下步骤来编辑正在使用定期检查的管道,以改用 Webhook。如果要创建管道,请参阅在中创建管道 CodePipeline

要构建一个事件驱动的管道,您应编辑管道的 PollForSourceChanges 参数,然后手动创建以下资源:

  • GitHub webhook 和授权参数

创建和注册您的 Webhook
注意

使用 CLI 或 Amazon CloudFormation 创建管道并添加 webhook 时,必须禁用定期检查。要禁用定期检查,您必须明确添加该 PollForSourceChanges 参数并将其设置为 false,有关详细信息,请参阅下面的最终过程。否则,CLI 或 Amazon CloudFormation 管道的默认PollForSourceChanges值为默认为 true,并且不会显示在管道结构输出中。有关 PollForSourceChanges 默认值的更多信息,请参阅 PollForSourceChanges 参数的默认设置

  1. 在文本编辑器中,创建并保存您要创建的 Webhook 的 JSON 文件。为名为 my-webhook 的 Webhook 使用此示例文件:

    { "webhook": { "name": "my-webhook", "targetPipeline": "pipeline_name", "targetAction": "source_action_name", "filters": [{ "jsonPath": "$.ref", "matchEquals": "refs/heads/{Branch}" }], "authentication": "GITHUB_HMAC", "authenticationConfiguration": { "SecretToken": "secret" } } }
  2. 调用 put-webhook 命令并包含 --cli-input--region 参数。

    以下示例命令使用 webhook_json JSON 文件创建一个 Webhook。

    aws codepipeline put-webhook --cli-input-json file://webhook_json.json --region "eu-central-1"
  3. 在此示例中显示的输出中,返回了名为 my-webhook 的 Webhook 的 URL 和 ARN。

    { "webhook": { "url": "https://webhooks.domain.com/trigger111111111EXAMPLE11111111111111111", "definition": { "authenticationConfiguration": { "SecretToken": "secret" }, "name": "my-webhook", "authentication": "GITHUB_HMAC", "targetPipeline": "pipeline_name", "targetAction": "Source", "filters": [ { "jsonPath": "$.ref", "matchEquals": "refs/heads/{Branch}" } ] }, "arn": "arn:aws:codepipeline:eu-central-1:ACCOUNT_ID:webhook:my-webhook" }, "tags": [{ "key": "Project", "value": "ProjectA" }] }

    此示例通过为 Webhook 包含 Project 标签键和 ProjectA 值来为 Webhook 添加标记。有关在中为资源添加标签的更多信息 CodePipeline,请参阅标记资源

  4. 调用 register-webhook-with-third-party 命令并包含 --webhook-name 参数。

    以下示例命令注册名为 my-webhook 的 Webhook。

    aws codepipeline register-webhook-with-third-party --webhook-name my-webhook
编辑管道的 PollForSourceChanges参数
重要

使用此方法创建管道时,如果 PollForSourceChanges 参数未明确设置为 false,则默认为 true。添加基于事件的更改检测时,必须将参数添加到输出并将其设置为 false 以禁用轮询。否则,您的管道将针对单个源更改启动两次。有关更多信息,请参阅 PollForSourceChanges 参数的默认设置

  1. 运行 get-pipeline 命令以将管道结构复制到 JSON 文件中。例如,对于名为 MyFirstPipeline 的管道,可以键入以下命令:

    aws codepipeline get-pipeline --name MyFirstPipeline >pipeline.json

    该命令不会返回任何结果,但您创建的文件将出现在您运行命令所在的目录中。

  2. 在任何纯文本编辑器中打开 JSON 文件,并通过更改或添加 PollForSourceChanges 参数来编辑源阶段。在此示例中,对于名为 UserGitHubRepo 的存储库,该参数设置为 false

    我为何做出此更改? 更改此参数将关闭定期检查,因此您只能使用基于事件的更改检测。

    "configuration": { "Owner": "name", "Repo": "UserGitHubRepo", "PollForSourceChanges": "false", "Branch": "main", "OAuthToken": "****" },
  3. 如果您使用的是通过 get-pipeline 命令检索到的管道结构,则必须通过从文件中删除 metadata 行来编辑 JSON 文件中的结构。否则,update-pipeline 命令无法使用它。从 JSON 文件中的管道结构中删除 "metadata" 部分,包括:{ } 以及 "created""pipelineARN""updated" 字段。

    例如,从结构中删除以下各行:

    "metadata": { "pipelineArn": "arn:aws:codepipeline:region:account-ID:pipeline-name", "created": "date", "updated": "date" },

    保存该文件。

  4. 要应用更改,请运行 update-pipeline 命令并指定一个管道 JSON 文件,类似于以下内容:

    重要

    务必在文件名前包含 file://。此命令中需要该项。

    aws codepipeline update-pipeline --cli-input-json file://pipeline.json

    该命令会返回编辑后的管道的整个结构。

    注意

    update-pipeline 命令会停止管道。如果在运行 update-pipeline 命令时正在通过管道运行修订,则该运行会被停止。您必须手动启动管道,通过升级后的管道运行此修订。使用 start-pipeline-execution 命令手动启动您的管道。

更新推送事件的管道(GitHub 版本 1 源操作)(Amazon CloudFormation 模板)

按照以下步骤将您的管道(带有 GitHub 来源)从定期检查(轮询)更新为使用 webhook 的基于事件的变更检测。

要使用构建事件驱动的管道 Amazon CodeCommit,请编辑管道的PollForSourceChanges参数,然后向模板中添加 GitHub webhook 资源。

如果您 Amazon CloudFormation 使用创建和管理管道,则模板的内容如下所示。

注意

请注意源阶段中的 PollForSourceChanges 配置属性。如果您的模板未包含该属性,PollForSourceChanges 在默认情况下将设置为 true

YAML
Resources: AppPipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: github-polling-pipeline RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: ThirdParty Version: 1 Provider: GitHub OutputArtifacts: - Name: SourceOutput Configuration: Owner: !Ref GitHubOwner Repo: !Ref RepositoryName Branch: !Ref BranchName OAuthToken: {{resolve:secretsmanager:MyGitHubSecret:SecretString:token}} PollForSourceChanges: true RunOrder: 1 ...
JSON
"AppPipeline": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { "Name": "github-polling-pipeline", "RoleArn": { "Fn::GetAtt": [ "CodePipelineServiceRole", "Arn" ] }, "Stages": [ { "Name": "Source", "Actions": [ { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "ThirdParty", "Version": 1, "Provider": "GitHub" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "Owner": { "Ref": "GitHubOwner" }, "Repo": { "Ref": "RepositoryName" }, "Branch": { "Ref": "BranchName" }, "OAuthToken": "{{resolve:secretsmanager:MyGitHubSecret:SecretString:token}}", "PollForSourceChanges": true }, "RunOrder": 1 } ] }, ...
在模板中添加参数并创建 Webhook

我们强烈建议您使用 Amazon Secrets Manager 来存储您的证书。如果使用 Secrets Manager,则您必须已在 Secrets Manager 中配置并存储密钥参数。此示例使用对 Secrets Manager 的动态引用作为您的 webhook 的 GitHub凭证。有关更多信息,请参阅使用动态引用以指定模板值

重要

传递密钥参数时,请勿直接将值输入到模板中。该值以明文形式提供,因此是可读的。出于安全考虑,请勿在 Amazon CloudFormation 模板中使用纯文本来存储您的证书。

使用 CLI 或 Amazon CloudFormation 创建管道并添加 webhook 时,必须禁用定期检查。

注意

要禁用定期检查,您必须明确添加该 PollForSourceChanges 参数并将其设置为 false,有关详细信息,请参阅下面的最终过程。否则,CLI 或 Amazon CloudFormation 管道的默认PollForSourceChanges值为默认为 true,并且不会显示在管道结构输出中。有关 PollForSourceChanges 默认值的更多信息,请参阅 PollForSourceChanges 参数的默认设置

  1. 在模板中的 Resources 下,添加您的参数:

    YAML
    Parameters: GitHubOwner: Type: String ...
    JSON
    { "Parameters": { "BranchName": { "Description": "GitHub branch name", "Type": "String", "Default": "main" }, "GitHubOwner": { "Type": "String" }, ...
  2. 使用该AWS::CodePipeline::Webhook Amazon CloudFormation 资源添加 webhook。

    注意

    您指定的 TargetAction 必须与管道中定义的源操作的 Name 属性匹配。

    如果设置RegisterWithThirdPartytrue,请确保与关联的用户OAuthToken可以在中设置所需的范围 GitHub。令牌和 webhook 需要以下 GitHub 范围:

    • repo - 用于完全控制从公有和私有存储库读取项目并将项目提取到管道中的过程。

    • admin:repo_hook - 用于完全控制存储库挂钩。

    否则, GitHub 返回 404。有关返回的 404 的更多信息,请参阅https://help.github.com/articles/about-webhooks

    YAML
    AppPipelineWebhook: Type: AWS::CodePipeline::Webhook Properties: Authentication: GITHUB_HMAC AuthenticationConfiguration: SecretToken: {{resolve:secretsmanager:MyGitHubSecret:SecretString:token}} Filters: - JsonPath: "$.ref" MatchEquals: refs/heads/{Branch} TargetPipeline: !Ref AppPipeline TargetAction: SourceAction Name: AppPipelineWebhook TargetPipelineVersion: !GetAtt AppPipeline.Version RegisterWithThirdParty: true ...
    JSON
    "AppPipelineWebhook": { "Type": "AWS::CodePipeline::Webhook", "Properties": { "Authentication": "GITHUB_HMAC", "AuthenticationConfiguration": { "SecretToken": "{{resolve:secretsmanager:MyGitHubSecret:SecretString:token}}" }, "Filters": [{ "JsonPath": "$.ref", "MatchEquals": "refs/heads/{Branch}" }], "TargetPipeline": { "Ref": "AppPipeline" }, "TargetAction": "SourceAction", "Name": "AppPipelineWebhook", "TargetPipelineVersion": { "Fn::GetAtt": [ "AppPipeline", "Version" ] }, "RegisterWithThirdParty": true } }, ...
  3. 将更新的模板保存到本地计算机,然后打开 Amazon CloudFormation 控制台。

  4. 选择堆栈,然后选择为当前堆栈创建更改集

  5. 上传模板,然后查看 Amazon CloudFormation中列出的更改。这些是要对堆栈进行的更改。您应在列表中看到新资源。

  6. 选择执行

编辑管道的 PollForSourceChanges参数
重要

使用此方法创建管道时,如果 PollForSourceChanges 参数未明确设置为 false,则默认为 true。添加基于事件的更改检测时,必须将参数添加到输出并将其设置为 false 以禁用轮询。否则,您的管道将针对单个源更改启动两次。有关更多信息,请参阅 PollForSourceChanges 参数的默认设置

  • 在模板中,将 PollForSourceChanges 更改为 false。如果您未在管道定义中包含 PollForSourceChanges,请添加它并将它设置为 false。

    我为何做出此更改? 将此参数更改为 false 将关闭定期检查,因此您只能使用基于事件的更改检测。

    YAML
    Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: ThirdParty Version: 1 Provider: GitHub OutputArtifacts: - Name: SourceOutput Configuration: Owner: !Ref GitHubOwner Repo: !Ref RepositoryName Branch: !Ref BranchName OAuthToken: {{resolve:secretsmanager:MyGitHubSecret:SecretString:token}} PollForSourceChanges: false RunOrder: 1
    JSON
    { "Name": "Source", "Actions": [{ "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "ThirdParty", "Version": 1, "Provider": "GitHub" }, "OutputArtifacts": [{ "Name": "SourceOutput" }], "Configuration": { "Owner": { "Ref": "GitHubOwner" }, "Repo": { "Ref": "RepositoryName" }, "Branch": { "Ref": "BranchName" }, "OAuthToken": "{{resolve:secretsmanager:MyGitHubSecret:SecretString:token}}", PollForSourceChanges: false }, "RunOrder": 1 }]

使用创建这些资源时 Amazon CloudFormation,定义的 webhook 将在指定的 GitHub 存储库中创建。您的管道将在提交时触发。

YAML
Parameters: GitHubOwner: Type: String Resources: AppPipelineWebhook: Type: AWS::CodePipeline::Webhook Properties: Authentication: GITHUB_HMAC AuthenticationConfiguration: SecretToken: {{resolve:secretsmanager:MyGitHubSecret:SecretString:token}} Filters: - JsonPath: "$.ref" MatchEquals: refs/heads/{Branch} TargetPipeline: !Ref AppPipeline TargetAction: SourceAction Name: AppPipelineWebhook TargetPipelineVersion: !GetAtt AppPipeline.Version RegisterWithThirdParty: true AppPipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: github-events-pipeline RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: ThirdParty Version: 1 Provider: GitHub OutputArtifacts: - Name: SourceOutput Configuration: Owner: !Ref GitHubOwner Repo: !Ref RepositoryName Branch: !Ref BranchName OAuthToken: {{resolve:secretsmanager:MyGitHubSecret:SecretString:token}} PollForSourceChanges: false RunOrder: 1 ...
JSON
{ "Parameters": { "BranchName": { "Description": "GitHub branch name", "Type": "String", "Default": "main" }, "RepositoryName": { "Description": "GitHub repository name", "Type": "String", "Default": "test" }, "GitHubOwner": { "Type": "String" }, "ApplicationName": { "Description": "CodeDeploy application name", "Type": "String", "Default": "DemoApplication" }, "BetaFleet": { "Description": "Fleet configured in CodeDeploy", "Type": "String", "Default": "DemoFleet" } }, "Resources": { ... }, "AppPipelineWebhook": { "Type": "AWS::CodePipeline::Webhook", "Properties": { "Authentication": "GITHUB_HMAC", "AuthenticationConfiguration": { "SecretToken": { "{{resolve:secretsmanager:MyGitHubSecret:SecretString:token}}" } }, "Filters": [ { "JsonPath": "$.ref", "MatchEquals": "refs/heads/{Branch}" } ], "TargetPipeline": { "Ref": "AppPipeline" }, "TargetAction": "SourceAction", "Name": "AppPipelineWebhook", "TargetPipelineVersion": { "Fn::GetAtt": [ "AppPipeline", "Version" ] }, "RegisterWithThirdParty": true } }, "AppPipeline": { "Type": "AWS::CodePipeline::Pipeline", "Properties": { "Name": "github-events-pipeline", "RoleArn": { "Fn::GetAtt": [ "CodePipelineServiceRole", "Arn" ] }, "Stages": [ { "Name": "Source", "Actions": [ { "Name": "SourceAction", "ActionTypeId": { "Category": "Source", "Owner": "ThirdParty", "Version": 1, "Provider": "GitHub" }, "OutputArtifacts": [ { "Name": "SourceOutput" } ], "Configuration": { "Owner": { "Ref": "GitHubOwner" }, "Repo": { "Ref": "RepositoryName" }, "Branch": { "Ref": "BranchName" }, "OAuthToken": "{{resolve:secretsmanager:MyGitHubSecret:SecretString:token}}", "PollForSourceChanges": false }, "RunOrder": 1 ...