Azure DevOps中Checkov指定目录扫描及PR分支增量扫描问题
解决Checkov在Azure DevOps流水线中的两个问题
问题1:无法指定ARM模板扫描路径
当前docker命令挂载了整个代码目录到容器的/scripts,如果你的ARM模板集中在某个子目录(比如arm-templates/),需要调整--directory参数为具体的子路径,同时确保路径映射正确。另外,也可以用--file参数精准指定单个或多个文件,避免扫描整个仓库。
修改后的bash步骤示例:
docker run \ --volume $(pwd):/scripts bridgecrew/checkov \ --directory /scripts/arm-templates \ # 替换为你的目标子目录 --output junitxml \ --soft-fail > $(pwd)/CheckovReport.xml
如果要扫描特定文件:
docker run \ --volume $(pwd):/scripts bridgecrew/checkov \ --file /scripts/arm-templates/vm-template.json \ --file /scripts/arm-templates/storage-template.json \ --output junitxml \ --soft-fail > $(pwd)/CheckovReport.xml
问题2:PR评审时仅扫描分支变更的文件
要实现只扫描PR中提交的文件,需要以下步骤:
- 启用PR触发器:在流水线开头添加PR触发配置,只在PR打开或更新时运行:
pr: branches: include: - master # 替换为你的目标主分支 paths: include: - '*.json' # 只监控ARM模板文件变更
- 获取PR变更的文件列表:添加bash步骤,用
git diff命令获取当前分支与目标分支的差异文件,过滤出ARM模板(.json):
# 获取变更的ARM模板文件,保存到临时文件 git diff --name-only origin/master...HEAD | grep -E '\.json$' > changed_arm_files.txt # 如果没有变更文件,创建空报告避免后续任务失败 if [ ! -s changed_arm_files.txt ]; then echo '<?xml version="1.0" encoding="UTF-8"?><testsuite name="Checkov" tests="0" failures="0" errors="0" skipped="0"></testsuite>' > $(pwd)/CheckovReport.xml exit 0 fi
- 修改Checkov命令,仅扫描变更文件:读取临时文件中的路径,传递给Checkov的
--file参数,注意要把本地路径转换为容器内的/scripts/前缀:
# 生成Checkov的--file参数列表 FILE_ARGS=$(cat changed_arm_files.txt | awk '{print "--file /scripts/"$0}' | tr '\n' ' ') # 运行Checkov扫描变更文件 docker run \ --volume $(pwd):/scripts bridgecrew/checkov \ $FILE_ARGS \ --output junitxml \ --soft-fail > $(pwd)/CheckovReport.xml
- 完整流水线示例:
trigger: none pr: branches: include: - master paths: include: - '*.json' pool: vmImage: ubuntu-latest stages: - stage: 'runCheckov' displayName: 'Checkov - Scan ARM files' jobs: - job: 'RunCheckov' displayName: 'Checkov solution' steps: - bash: | docker pull bridgecrew/checkov displayName: 'Pull bridgecrew/checkov image' - bash: | # 获取变更的ARM模板文件 git diff --name-only origin/master...HEAD | grep -E '\.json$' > changed_arm_files.txt # 处理无变更的情况 if [ ! -s changed_arm_files.txt ]; then echo '<?xml version="1.0" encoding="UTF-8"?><testsuite name="Checkov" tests="0" failures="0" errors="0" skipped="0"></testsuite>' > $(pwd)/CheckovReport.xml exit 0 fi displayName: 'Get changed ARM files' - bash: | FILE_ARGS=$(cat changed_arm_files.txt | awk '{print "--file /scripts/"$0}' | tr '\n' ' ') docker run \ --volume $(pwd):/scripts bridgecrew/checkov \ $FILE_ARGS \ --output junitxml \ --soft-fail > $(pwd)/CheckovReport.xml displayName: 'Run checkov on changed files' - task: PublishTestResults@2 inputs: testRunTitle: 'Checkov run results' failTaskOnFailedTests: false testResultsFormat: 'JUnit' testResultsFiles: 'CheckovReport.xml' searchFolder: '$(System.DefaultWorkingDirectory)' mergeTestResults: false publishRunAttachments: true displayName: 'Publish Test results'
关键说明
- 对于问题1,确保
--directory或--file参数使用容器内的路径(基于挂载的/scripts),而非本地路径。 - 对于问题2,
git diff origin/master...HEAD会获取当前分支相对于目标主分支的所有变更文件,过滤.json确保只处理ARM模板;如果没有变更文件,直接生成空的JUnit报告,避免流水线失败。
内容的提问来源于stack exchange,提问作者NewUser
相关产品推荐
相关产品推荐

