Jenkins流水线中aws ecr wait image-scan-complete命令执行失败求助
Jenkins流水线中使用aws ecr wait image-scan-complete命令时触发ScanNotFoundException错误,报错信息如下:
Waiter ImageScanComplete failed: An error occurred (ScanNotFoundException): Image scan does not exist for the image with '{imageDigest:'IMAGE_DIGEST_HERE', imageTag:'test'}' in the repository with name 'testrepo' in the registry with id 'XXXXXXXXXXXXXX'
流水线负责构建Docker镜像并上传至ECR,后续需要等待扫描完成以将结果加入邮件正文。已尝试以下操作但未解决:
- 使用
imageTag替代imageDigest执行等待命令,仍报相同错误; - 在Jenkins所在Linux服务器上执行旧构建的对应命令,可正常运行;
- 确认AWS CLI已更新至最新v2版本。
流水线代码如下:
pipeline { agent any environment { AWS_CREDENTIALS = credentials('AWSCredentials') } stages { stage('Build Docker Image'){ steps{ dir("$CODE_CHECKOUT_FOLDER"){ sh 'sudo docker compose build --no-cache' } } } stage('Scan ECR Image'){ steps{ dir("$CODE_CHECKOUT_FOLDER"){ script{ withAWS(credentials:'AWSCredentials', region: 'us-west-2'){ //Grab the imageDigest of the latest image with the tag test def digest_image = sh( script: "aws ecr describe-images --repository-name testrepo --image-ids imageTag=test --query 'imageDetails[0].imageDigest'", returnStdout: true ).trim() // Wait for the image scan to complete sh "aws ecr wait image-scan-complete --repository-name testrepo --image-id imageDigest=$digest_image" def scan_findings = sh( script: "aws ecr describe-image-scan-findings --repository-name testrepo --image-id imageDigest=$digest_image", returnStdout: true ).trim() writeFile file: IMAGE_SCAN_FINDINGS, text: scan_findings } } } } } stage('Deploy to ECS'){ steps{ dir("$CODE_CHECKOUT_FOLDER"){ sh "sudo aws ecs update-service --region us-west-2 --cluster testrepo-dev-cluster --service testrepo-dev-service --force-new-deployment" } } } } post{ always{ cleanWs() echo "Cleaned up the workspace and finished executing pipeline!" } } }
确认ECR镜像扫描自动触发配置
进入AWS控制台ECR仓库页面,检查“扫描配置”是否设置为“推送时扫描”。如果是“手动扫描”,镜像上传后不会自动启动扫描,需在流水线中添加触发命令:aws ecr start-image-scan --repository-name testrepo --image-id imageDigest=$digest_image将该命令放在获取
digest_image之后、wait命令之前。修正镜像Digest的引号问题
使用aws ecr describe-images获取的imageDigest可能带有双引号,需通过--output text参数直接返回无引号的值:def digest_image = sh( script: "aws ecr describe-images --repository-name testrepo --image-ids imageTag=test --query 'imageDetails[0].imageDigest' --output text", returnStdout: true ).trim()验证IAM权限与凭证一致性
确认AWSCredentials对应的IAM用户拥有ecr:StartImageScan、ecr:DescribeImageScanFindings、ecr:WaitImageScanComplete权限;同时检查withAWS块中的凭证是否与本地测试时使用的凭证一致。添加扫描状态前置检查
在执行wait命令前先检查扫描状态,若未扫描或扫描失败则触发扫描:def scan_status = sh( script: "aws ecr describe-image-scan-findings --repository-name testrepo --image-id imageDigest=$digest_image --query 'imageScanStatus.status' --output text || echo 'UNSCANNED'", returnStdout: true ).trim() if (scan_status == 'FAILED' || scan_status == 'UNSCANNED') { sh "aws ecr start-image-scan --repository-name testrepo --image-id imageDigest=$digest_image" }移除sudo执行AWS命令
Deploy to ECS阶段的sudo aws可能导致环境变量(如AWS凭证)与withAWS块配置不一致,建议移除sudo,确保Jenkins用户拥有执行AWS命令的权限。
内容的提问来源于stack exchange,提问作者tt1997

