GitLab流水线部署Elastic Beanstalk报错:无法从S3下载(Bad Request)
通过GitLab流水线部署应用到AWS Elastic Beanstalk时,调用CreateApplicationVersion操作报错InvalidParameterCombination,提示“Unable to download from S3 location. Reason: Bad Request”。
错误截图:
相关配置文件
gitlab.ci.yml
stages: - build - package - test - deploy variables: APP_VERSION: $CI_PIPELINE_IID build website: stage: build image: node:20-alpine script: - yarn install - yarn build - echo $APP_VERSION > dist/version.html artifacts: paths: - dist build docker image: stage: package image: docker:26.1.2 services: - docker:26.1.2-dind script: - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin - docker build -t $CI_REGISTRY_IMAGE -t $CI_REGISTRY_IMAGE:$APP_VERSION . - docker image ls - docker push --all-tags $CI_REGISTRY_IMAGE test docker image: stage: test image: curlimages/curl services: - name: $CI_REGISTRY_IMAGE:$APP_VERSION alias: website script: - curl http://website/version.html | grep $APP_VERSION deploy production: stage: deploy variables: APP_NAME: clean-city-dashboard APP_ENV_NAME: clean-city-dashboard-env environment: production image: name: amazon/aws-cli:2.15.38 entrypoint: [""] script: - aws --version - yum install -y gettext - export DEPLOY_TOKEN=$(echo $GITLAB_DEPLOY_TOKEN | tr -d "\n" | base64) - envsubst < config/Dockerrun.aws.json > Dockerrun.aws.json - envsubst < config/auth.json > auth.json - cat Dockerrun.aws.json - cat auth.json - aws s3 cp Dockerrun.aws.json s3://$AWS_S3_BUCKET/Dockerrun.aws.json - aws s3 cp auth.json s3://$AWS_S3_BUCKET/auth.json - aws elasticbeanstalk create-application-version --application-name "$APP_NAME" --version-label $APP_VERSION --source-bundle S3Bucket=$AWS_S3_BUCKET,S3Key=Dockerrun.aws.json - aws elasticbeanstalk update-environment --application-name "$APP_NAME" --version-label $APP_VERSION --environment-name $APP_ENV_NAME
Dockerrun.aws.json
{ "AWSEBDockerrunVersion": "1", "Image": { "Name": "$CI_REGISTRY_IMAGE:$APP_VERSION" }, "Authentication": { "Bucket": "$AWS_S3_BUCKET", "Key": "auth.json" }, "Ports": [ { "ContainerPort": 80 } ] }
auth.json
{ "auths": { "$CI_REGISTRY": { "auth": "$DEPLOY_TOKEN" } } }
这个错误核心是Elastic Beanstalk无法从指定S3路径下载文件,按以下步骤排查修复:
验证S3对象权限:确保Elastic Beanstalk的服务角色(
aws-elasticbeanstalk-ec2-role和aws-elasticbeanstalk-service-role)拥有目标S3桶的s3:GetObject权限。可通过IAM控制台给角色附加如下策略:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*" } ] }同时检查S3桶的ACL和桶策略,确保没有拒绝Elastic Beanstalk的访问。
确认S3路径正确性:检查
$AWS_S3_BUCKET变量是否拼写正确、无多余空格;确认Dockerrun.aws.json的上传路径与create-application-version命令中的S3Key完全一致。可手动执行aws s3 cp s3://$AWS_S3_BUCKET/Dockerrun.aws.json ./test.json验证是否能正常下载。检查认证文件有效性:查看GitLab流水线中
cat auth.json的输出,确认$CI_REGISTRY和$DEPLOY_TOKEN已被正确替换。注意Docker的auth字段需要是username:password格式的base64编码,若GITLAB_DEPLOY_TOKEN不是该格式,修改deploy阶段的脚本:export DEPLOY_TOKEN=$(echo "${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}" | tr -d "\n" | base64)核对区域一致性:确保Elastic Beanstalk环境所在区域与S3桶区域一致,若跨区域需确认桶策略允许跨区域访问,且服务角色有对应权限。
内容的提问来源于stack exchange,提问作者Mike

