系列导读: 上一篇我们搭建好了 S3 触发模式的 CI/CD 流水线。但实际使用中会遇到很多意想不到的问题——重复触发、权限不足、路径错误、部署失败…… 本篇盘点 8 个最常见的大坑,帮你少走弯路。


快速排障流程图

S3 触发模式排障流程图

当你遇到问题不知道怎么排查时,先看这张图 👆


坑 1:S3 上传不触发流水线

现象

aws s3 cp 上传 zip 文件后,CodePipeline 没有任何动静,等了 2 分钟也没反应。

原因

S3 存储桶未开启版本控制。 这是 90% 的新手都会遇到的问题

CodePipeline 的 S3 源动作有两种检测方式:

  • 轮询模式PollForSourceChanges: "true"):定期检测对象的新版本

  • 事件通知模式:通过 EventBridge 事件触发

两种模式都依赖版本控制。如果没有版本控制,上传同名称文件时 S3 只是覆盖原文件,没有新的版本 ID,CodePipeline 检测不到变化。

解决方案

# 检查版本控制状态
aws s3api get-bucket-versioning --bucket your-bucket-name

# 如果返回空对象 {} 或 Status=Suspended,说明版本控制没开启

# 开启版本控制
aws s3api put-bucket-versioning \
    --bucket your-bucket-name \
    --versioning-configuration Status=Enabled

# 确认已开启
aws s3api get-bucket-versioning --bucket your-bucket-name
# 应返回: {"Status": "Enabled"}

验证方法

开启版本控制后,重新上传一次,然后立即查看流水线状态:

# 上传
aws s3 cp mfmsapp-v1.zip s3://your-bucket/mfmsapp-v1.zip

# 检查流水线
aws codepipeline get-pipeline-state --name mfmsapp-pipeline \
    --query 'stageStates[].latestExecution.status' --output text

⚠️ 关键提醒: 如果你之前已经创建好了流水线,才想起来没开版本控制。你需要在 CodePipeline 中编辑流水线,把 Source 阶段的 PollForSourceChanges 重新设为 true,或者重新上传一次源文件来触发。


坑 2:CodeBuild 找不到 buildspec.yml

现象

Source 阶段成功(S3 已经上传了),但 Build 阶段失败,错误信息类似:

CLIENT_ERROR: open /codebuild/output/srcXXXXXXX/src/buildspec.yml: no such file or directory

原因

zip 包的目录结构不对。 这是第二大坑。

错误做法 ❌

# 在 v1 目录外执行
zip -r mfmsapp-v1.zip v1/

这样打包后的 zip 结构是:

v1/
├── main.go
├── go.mod
├── buildspec.yml    <-- 实际路径是 v1/buildspec.yml
└── appspec.yml

CodeBuild 把 zip 解压到 /codebuild/output/srcXXX/src/ 后,直接在根目录找 buildspec.yml,但实际文件在 v1/buildspec.yml,所以找不到。

正确做法 ✅

# 进入源码目录,在内部打包
cd v1/
zip -r ../mfmsapp-v1.zip .
cd ..
# 或者用 -j (junk paths) 忽略路径,只保留文件名

正确的 zip 结构:

mfmsapp-v1.zip
├── main.go
├── go.mod
├── buildspec.yml    <-- 根目录,CodeBuild 能找到!
├── appspec.yml
└── scripts/
    ├── start.sh
    ├── before_install.sh
    └── after_install.sh

验证 zip 结构

# 查看 zip 包内容
unzip -l mfmsapp-v1.zip

# 确认 buildspec.yml 在根目录(没有前缀路径)

坑 3:构建产物无法传递给 CodeDeploy

现象

CodeBuild 构建成功,但 CodeDeploy 阶段报错:

The input artifact of type CODEPIPELINE is missing

原因

CodeBuild 项目的 artifacts.type 不是 CODEPIPELINE

如果你在创建 CodeBuild 项目时把 artifacts.type 设成了 S3(或者用控制台时没注意),构建产物会写到 S3 桶而不是 CodePipeline 的内部存储。CodePipeline 拿不到产物,传给 CodeDeploy 的就是空的。

错误配置

{
    "artifacts": {
        "type": "S3",              // ❌ 错了!
        "location": "my-bucket"
    }
}

正确配置

{
    "artifacts": {
        "type": "CODEPIPELINE"     // ✅ 正确
    }
}

修复方法

# 更新 CodeBuild 项目
aws codebuild update-project \
    --name mfmsapp-build \
    --artifacts type=CODEPIPELINE

⚠️ 关键提醒: 当 CodeBuild 作为 CodePipeline 的一个阶段时,必须使用 type: CODEPIPELINE。只有独立使用的 CodeBuild 项目才用 type: S3


坑 4:S3 重复触发导致构建爆炸

现象

上传一次 zip 文件,CodePipeline 却触发了多次运行。更严重的是,如果流水线本身会上传产物到同一个桶,就会形成无限循环

原因

当你同时启用了两种触发方式

  1. PollForSourceChanges: "true"(轮询)

  2. S3 事件通知 → EventBridge → CodePipeline

两个触发器同时起作用,一次上传 → 两个事件 → 两次执行。

解决方案

方案 A:只用轮询(推荐,简单)

{
    "configuration": {
        "S3Bucket": "your-bucket",
        "S3ObjectKey": "mfmsapp-v1.zip",
        "PollForSourceChanges": "true"    // 只用这一个
    }
}

不需要额外配置 S3 事件通知。CodePipeline V2 管道默认轮询间隔约 1 分钟。

方案 B:只用事件通知(实时触发)

{
    "configuration": {
        "S3Bucket": "your-bucket",
        "S3ObjectKey": "mfmsapp-v1.zip",
        "PollForSourceChanges": "false"   // 关掉轮询
    }
}

同时配置 EventBridge:

aws events put-rule \
    --name "CodePipelineS3Trigger" \
    --event-pattern '{
        "source": ["aws.s3"],
        "detail-type": ["Object Created"],
        "detail": {
            "bucket": {
                "name": ["your-bucket"]
            },
            "object": {
                "key": ["mfmsapp-v1.zip"]
            }
        }
    }' \
    --state ENABLED

🚫 不要用方案 C:两种同时启用

{
    "PollForSourceChanges": "true"  // 同时还有 EventBridge 规则
}

这就是重复触发的罪魁祸首!

验证是否重复触发

# 查看流水线执行历史
aws codepipeline list-pipeline-executions \
    --pipeline-name mfmsapp-pipeline \
    --max-results 5

# 如果一次上传对应多个执行记录,说明重复触发了

坑 5:CodeDeploy Agent 未运行

现象

Build 阶段成功后,Deploy 阶段一直卡着或者直接失败,错误:

The deployment timed out while waiting for instances to report healthy status.

原因

EC2 实例上的 CodeDeploy Agent 没有启动,原因可能是:

  • 实例重启后没有设置自启动

  • agent 崩溃

  • 根本没有安装

解决方案

# 通过 SSM 或 SSH 连接到 EC2,运行以下命令

# 1. 检查 agent 状态
sudo systemctl status codedeploy-agent

# 2. 如果没安装,安装 agent(Amazon Linux 2023)
sudo dnf update -y
sudo dnf install -y ruby
sudo dnf install -y wget
wget -P /tmp https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
chmod +x /tmp/install
sudo /tmp/install auto

# 3. 启动并设置开机自启
sudo systemctl start codedeploy-agent
sudo systemctl enable codedeploy-agent
sudo systemctl status codedeploy-agent

自动确保 agent 运行

在 EC2 的 用户数据(User Data) 中加入安装脚本:

#!/bin/bash
# 确保 CodeDeploy Agent 运行
dnf update -y
dnf install -y ruby wget
wget -P /tmp https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
chmod +x /tmp/install
/tmp/install auto
systemctl start codedeploy-agent
systemctl enable codedeploy-agent

坑 6:appspec.yml 路径映射错误

现象

CodeDeploy 开始部署,但文件没有正确复制到目标目录。

原因

buildspec.yml 的 artifacts 路径和 appspec.yml 的 source 路径不匹配。

这是最容易被忽视的坑。CodeDeploy 的 source 路径是相对于构建产物根目录的。

错误配置

# buildspec.yml
artifacts:
  files:
    - '**/*'              # 所有文件
  base-directory: build   # 相对于 build 目录
  discard-paths: yes

# appspec.yml
files:
  - source: ./mfmsapp     # ❌ 多了 ./ 前缀
    destination: /opt/mfmsapp

正确配置

# buildspec.yml
artifacts:
  files:
    - mfmsapp
    - appspec.yml
    - scripts/start.sh
  discard-paths: yes

# appspec.yml
files:
  - source: mfmsapp       # ✅ 文件名精确匹配
    destination: /opt/mfmsapp
  - source: scripts/start.sh
    destination: /opt/mfmsapp/scripts

💡 关键规则: source 路径不能以 / 开头,是相对于构建产物根目录的相对路径。


坑 7:IAM 权限不足但报错信息不明确

现象

CodePipeline 运行失败,但错误信息只有一行:

Execution failed: The action failed because the service role does not have sufficient permissions.

没有告诉你具体缺少什么权限。

解决方案

快速修复(学习阶段)

直接附加托管策略:

# CodePipeline 角色
aws iam attach-role-policy \
    --role-name AWSCodePipelineServiceRole \
    --policy-arn arn:aws:iam::aws:policy/AWSCodePipelineServiceRole

# CodeBuild 角色
aws iam attach-role-policy \
    --role-name AWSCodeBuildServiceRole \
    --policy-arn arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess

# CodeDeploy 角色
aws iam attach-role-policy \
    --role-name AWSCodeDeployRole \
    --policy-arn arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole

生产环境:最小权限

生产环境不要直接用托管策略。按实际需要的权限自定义:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "S3Access",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::your-bucket/*"
        },
        {
            "Sid": "CodeBuild",
            "Effect": "Allow",
            "Action": [
                "codebuild:StartBuild",
                "codebuild:BatchGetBuilds"
            ],
            "Resource": "arn:aws:codebuild:region:account:project/mfmsapp-build"
        },
        {
            "Sid": "CodeDeploy",
            "Effect": "Allow",
            "Action": [
                "codedeploy:CreateDeployment",
                "codedeploy:GetDeployment"
            ],
            "Resource": "arn:aws:codedeploy:region:account:*"
        }
    ]
}

坑 8:多 Region 资源不匹配

现象

CodePipeline 在 ap-northeast-1,但 S3 桶在 us-east-1,构建一直失败。

原因

CodePipeline 的所有服务必须在同一个 Region。

  • S3 源桶必须与 Pipeline 同 Region

  • CodeBuild 项目必须与 Pipeline 同 Region

  • CodeDeploy 必须在同 Region

解决方案

创建资源时确保 Region 一致:

# 统一设置变量
export AWS_REGION="ap-northeast-1"

# 所有命令都带 --region 参数(或设置环境变量)
aws s3api create-bucket \
    --bucket my-bucket \
    --region $AWS_REGION

aws codebuild create-project \
    --name mfmsapp-build \
    --region $AWS_REGION \
    # ... 其他参数

排障速查表

症状

检查项

命令

上传不触发

版本控制

aws s3api get-bucket-versioning

找不到 buildspec

zip 目录结构

unzip -l file.zip

产物传递失败

artifacts type

aws codebuild batch-get-projects

重复触发

事件源数量

确认只有 PollForSourceChanges EventBridge,不能同时

部署超时

Agent 状态

systemctl status codedeploy-agent

文件未复制

appspec source

确认不以 / 开头

权限错误

IAM 策略

附加托管策略快速排除

Region 不匹配

所有资源

aws configure get region


完整排障清单

遇到问题时,按顺序检查:

  1. S3 版本控制已开启?aws s3api get-bucket-versioning

  2. zip 包根目录有 buildspec.yml?unzip -l file.zip | head

  3. CodeBuild artifacts.type = CODEPIPELINE? → 检查项目配置

  4. 没有同时配置轮询和事件? → 只选一种触发方式

  5. CodeDeploy Agent 正在运行?systemctl status codedeploy-agent

  6. appspec source 不以 / 开头? → 检查路径

  7. IAM 角色有足够的权限? → 附加托管策略测试

  8. 所有资源在同一个 Region? → 检查 AWS_REGION


下一篇预告

第 04 篇:CodeCommit 触发模式 —— 从零搭建完整 CI/CD 流水线

上一篇用的是 S3 上传触发,每次还得手动 zip。第 04 篇我们升级玩法,用 CodeCommit Git 仓库作为代码源,实现每次 git push 自动触发构建部署,完全不需要手动上传。


本文档内容基于 2026 年 4 月 AWS 官方文档整理。AWS 服务可能随时更新,如遇差异请以 AWS 官方文档 为准。