前置:需完成AWS之Gitlab增量配置
https://mp.csdn.net/mp_blog/creation/success/158067495
当你使用 CMake 构建系统 + 自建 SonarQube ,这是嵌入式/ C++ 项目的典型组合。下面我将为你量身定制一套 基于 AWS CodePipeline + CodeBuild 的 CI/CD 架构,实现:
- ✅ 单流水线(Single Pipeline)
- ✅ 并行执行:编译、单元测试、Cppcheck、SonarQube 扫描
- ✅ 安全访问内网 SonarQube(通过 VPC)
- ✅ 与 GitLab MR 深度集成(失败阻止合并)
🧩 一、整体架构图

🔑 关键设计:
- 所有 CodeBuild 项目运行在 VPC 内,可访问自建 SonarQube
- 编译产物通过 Pipeline Artifacts 共享
- 使用 CMake 标准构建流程
🛠 二、前置条件
1. 网络准备
- 自建 SonarQube 部署在 公司内网或 AWS VPC 内
- CodeBuild 需配置 VPC + 子网 + 安全组 ,允许访问 SonarQube 的
9000端口
2. 凭证准备
- GitLab Token(
read_repository) - SonarQube Token(用于扫描)
- 存入 AWS Secrets Manager
📁 三、项目目录结构(推荐)
your-project/
├── CMakeLists.txt
├── src/
│ └── *.cpp
├── tests/
│ └── test_main.cpp
├── buildspec/
│ ├── buildspec-build.yml
│ ├── buildspec-test.yml
│ ├── buildspec-cppcheck.yml
│ └── buildspec-sonar.yml
└── sonar-project.properties # SonarQube 配置
📝 四、Buildspec 文件详解
1. buildspec-build.yml ------ CMake 编译
version: 0.2
phases:
install:
runtime-versions:
python: 3.9
commands:
- yum install -y gcc gcc-c++ make cmake
pre_build:
commands:
- mkdir build && cd build
build:
commands:
- cmake .. -DCMAKE_BUILD_TYPE=Release
- make -j$(nproc)
artifacts:
files:
- 'build/**/*'
base-directory: 'build'
name: compiled-artifacts-$(date +%Y-%m-%d)
2. buildspec-test.yml ------ 单元测试(假设用 Google Test)
version: 0.2
phases:
install:
commands:
- yum install -y gcc-c++ make cmake
- # 假设测试框架已编译在 artifacts 中
pre_build:
commands:
- ls -R # 查看输入 artifacts
build:
commands:
- cd build
- ./tests/my_tests --gtest_output=xml:test-results.xml
reports:
test-results:
files:
- 'build/test-results.xml'
file-format: JUNITXML
💡 CodeBuild 原生支持 JUnit XML 报告,可在控制台查看测试结果。
3. buildspec-cppcheck.yml ------ 静态分析
version: 0.2
phases:
install:
commands:
- yum install -y cppcheck
build:
commands:
- cppcheck src/ --enable=all --suppress=missingIncludeSystem --error-exitcode=1 -i build/
# 不输出 artifacts,只关心 exit code
4. buildspec-sonar.yml ------ 自建 SonarQube 扫描
version: 0.2
env:
secrets-manager:
SONAR_TOKEN: "sonar-token-myproject" # ← 从 Secrets Manager 注入
phases:
install:
commands:
- yum install -y wget unzip
- wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip
- unzip sonar-scanner-cli-*.zip
build:
commands:
- ./sonar-scanner-*/bin/sonar-scanner \
-Dsonar.host.url=https://sonar.internal.yourcompany.com \
-Dsonar.login=$SONAR_TOKEN \
-Dsonar.projectKey=my-embedded-app \
-Dsonar.sources=src \
-Dsonar.cfamily.build-wrapper-output=bw-output \
-Dsonar.cfamily.threads=$(nproc)
# 注意:C/C++ 项目需配合 build-wrapper,见下文
⚠️ C/C++ 项目必须使用
build-wrapper!修改
buildspec-build.yml的 build 阶段:
- yum install -y wget - wget https://sonar.internal.yourcompany.com/static/cpp/build-wrapper-linux-x86.zip - unzip build-wrapper-linux-x86.zip - ./build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output make -j$(nproc)并将
bw-output/也加入 artifacts。
🌐 五、CodeBuild VPC 配置(访问自建 SonarQube)
在 CloudFormation 中为每个 CodeBuild Project 添加:
Environment:
Type: LINUX_CONTAINER
Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0
ComputeType: BUILD_GENERAL1_SMALL
VpcConfig:
VpcId: !Ref YourVPC
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
SecurityGroupIds:
- !Ref CodeBuildSG # 允许出站到 SonarQube:9000
🔒 安全组规则示例:
- Outbound: Allow TCP 9000 to SonarQube Server IP
🎯 六、CodePipeline 并行 Stage 配置(CloudFormation 片段)
Stages:
- Name: Source
Actions:
- Name: GitLabSource
ActionTypeId:
Category: Source
Owner: ThirdParty
Provider: GitLab
Version: '1'
Configuration:
ConnectionArn: !GetAtt GitLabConnection.ConnectionArn
FullRepositoryId: your-group/your-project
BranchName: main
OutputArtifacts:
- Name: SourceArtifact
- Name: Build
Actions:
- Name: CMakeBuild
ActionTypeId: { Category: Build, Owner: AWS, Provider: CodeBuild, Version: '1' }
InputArtifacts:
- Name: SourceArtifact
OutputArtifacts:
- Name: BuildArtifact
Configuration:
ProjectName: !Ref BuildProject
- Name: QualityGate
Actions:
- Name: UnitTest
RunOrder: 1
ActionTypeId: { Category: Build, Owner: AWS, Provider: CodeBuild, Version: '1' }
InputArtifacts:
- Name: BuildArtifact
Configuration:
ProjectName: !Ref TestProject
- Name: Cppcheck
RunOrder: 1
ActionTypeId: { Category: Build, Owner: AWS, Provider: CodeBuild, Version: '1' }
InputArtifacts:
- Name: SourceArtifact # 静态分析只需源码
Configuration:
ProjectName: !Ref CppcheckProject
- Name: SonarQube
RunOrder: 1
ActionTypeId: { Category: Build, Owner: AWS, Provider: CodeBuild, Version: '1' }
InputArtifacts:
- Name: BuildArtifact # 需要 bw-output
Configuration:
ProjectName: !Ref SonarProject
🔔 七、GitLab MR 状态反馈(Lambda + EventBridge)
复用前文提到的 Lambda 方案,但注意:
- 所有 4 个 CodeBuild 项目都触发 EventBridge
- Lambda 需判断是否 所有质量门禁都成功 才上报 ✅
- 或者:任一失败即上报 ❌
💡 简化方案:让 CodePipeline 整体状态作为 MR 状态(通过监听 Pipeline 状态变更而非单个 Build)。
✅ 八、最终效果
当开发者发起 MR:
- 自动触发 CodePipeline
- 并行执行 4 项检查(总时间 ≈ 最慢任务,非累加)
- 若 任一失败 :
- GitLab MR 页面显示 ❌
aws-codebuild failed - "Merge" 按钮禁用
- 点击可跳转到对应 CodeBuild 日志(如 Cppcheck 报错详情)
- GitLab MR 页面显示 ❌
- 全部成功 → ✅ 允许合并
📦 九、成本优化建议
| 优化点 | 说明 |
|---|---|
| 使用缓存 | cache: paths: ['/root/.ccache'] 加速 C++ 编译 |
| 选择合适实例 | BUILD_GENERAL1_SMALL 足够多数嵌入式项目 |
| 失败快速退出 | 编译失败 → 后续阶段不执行(CodePipeline 默认行为) |
🎁 附:你需要准备的清单
- 自建 SonarQube URL 和 Token
- GitLab Personal Access Token(
read_repository) - VPC / 子网 / 安全组(允许 CodeBuild 访问 SonarQube)
sonar-project.properties文件(可选,也可用 CLI 参数)- CMake 项目支持 out-of-source build(标准做法)