You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS CodeBuild推送镜像至ECR时出现未知用户权限错误

问题描述

我的CodeBuild无法执行构建脚本将Docker镜像推送至ECR,本地环境可正常运行,但CodeBuild中报错。错误信息如下:

denied: User: arn:aws:iam::311791021927:user/ServerlessAccount is not authorized to perform: ecr:InitiateLayerUpload on resource: arn:aws:ecr:***:014498627014:repository/squared-www because no resource-based policy allows the ecr:InitiateLayerUpload action

问题在于,用户311791021927并不存在于我的IAM或任何位置,以下是我的buildspec.yml:

version: 0.2

env:
  secrets-manager:
    DOMAIN: "squared-envs:DOMAIN"
    EMAIL_USERNAME: "squared-envs:EMAIL_USERNAME"
    EMAIL_PASSWORD: "squared-envs:EMAIL_PASSWORD"
    AWS_ACCESS_KEY_ID: "squared-envs:AWS_ACCESS_KEY_ID"
    AWS_SECRET_ACCESS_KEY: "squared-envs:AWS_SECRET_ACCESS_KEY"
    AWS_S3_BUCKET: "squared-envs:AWS_S3_BUCKET"
    AWE_REGION: "squared-envs:AWE_REGION"
    CLIENT_ID: "squared-envs:CLIENT_ID"
    HOOKDECK_AUTH_TOKEN: "squared-envs:HOOKDECK_AUTH_TOKEN"
    JWT_SECRECT: "squared-envs:JWT_SECRECT"
    KINDE_CLIENT_ID: "squared-envs:KINDE_CLIENT_ID"
    KINDE_CLIENT_SECRET: "squared-envs:KINDE_CLIENT_SECRET"
    KINDE_ISSUER_URL: "squared-envs:KINDE_ISSUER_URL"
    KINDE_POST_LOGIN_REDIRECT_URL: "squared-envs:KINDE_POST_LOGIN_REDIRECT_URL"
    KINDE_POST_LOGOUT_REDIRECT_URL: "squared-envs:KINDE_POST_LOGOUT_REDIRECT_URL"
    KINDE_SITE_URL: "squared-envs:KINDE_SITE_URL"
    MONGO_URL: "squared-envs:MONGO_URL"
    NEXTAUTH_SECRET: "squared-envs:NEXTAUTH_SECRET"
    NEXT_PUBLIC_CLIENT_ID: "squared-envs:NEXT_PUBLIC_CLIENT_ID"
    NEXT_PUBLIC_CONFIRM_URL: "squared-envs:NEXT_PUBLIC_CONFIRM_URL"
    NEXT_PUBLIC_GITHUB_CLIENT_SECRET: "squared-envs:NEXT_PUBLIC_GITHUB_CLIENT_SECRET"
    NEXT_PUBLIC_SERVER: "squared-envs:NEXT_PUBLIC_SERVER"
    NEXT_PUBLIC_URL: "squared-envs:NEXT_PUBLIC_URL"
    NODE_ENV: "squared-envs:NODE_ENV"
    PORT: "squared-envs:PORT"
    SEED_PASSWORD: "squared-envs:SEED_PASSWORD"
    GOOGLE_CLIENT_ID: "squared-envs:GOOGLE_CLIENT_ID"
    GOOGLE_CLIENT_SECRET: "squared-envs:GOOGLE_CLIENT_SECRET"
    GITHUB_CLIENT_ID: "squared-envs:GITHUB_CLIENT_ID"
    GITHUB_CLIENT_SECRET: "squared-envs:GITHUB_CLIENT_SECRET"

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password --region $ECR_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY_URI
      - echo Creating .env file...
      - echo "DOMAIN=$DOMAIN" >> .env
      - echo "EMAIL_USERNAME=$EMAIL_USERNAME" >> .env
      - echo "EMAIL_PASSWORD=$EMAIL_PASSWORD" >> .env
      - echo "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> .env
      - echo "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> .env
      - echo "AWS_S3_BUCKET=$AWS_S3_BUCKET" >> .env
      - echo "AWE_REGION=$AWE_REGION" >> .env
      - echo "CLIENT_ID=$CLIENT_ID" >> .env
      - echo "HOOKDECK_AUTH_TOKEN=$HOOKDECK_AUTH_TOKEN" >> .env
      - echo "JWT_SECRECT=$JWT_SECRECT" >> .env
      - echo "KINDE_CLIENT_ID=$KINDE_CLIENT_ID" >> .env
      - echo "KINDE_CLIENT_SECRET=$KINDE_CLIENT_SECRET" >> .env
      - echo "KINDE_ISSUER_URL=$KINDE_ISSUER_URL" >> .env
      - echo "KINDE_POST_LOGIN_REDIRECT_URL=$KINDE_POST_LOGIN_REDIRECT_URL" >> .env
      - echo "KINDE_POST_LOGOUT_REDIRECT_URL=$KINDE_POST_LOGOUT_REDIRECT_URL" >> .env
      - echo "KINDE_SITE_URL=$KINDE_SITE_URL" >> .env
      - echo "MONGO_URL=$MONGO_URL" >> .env
      - echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET" >> .env
      - echo "NEXT_PUBLIC_CLIENT_ID=$NEXT_PUBLIC_CLIENT_ID" >> .env
      - echo "NEXT_PUBLIC_CONFIRM_URL=$NEXT_PUBLIC_CONFIRM_URL" >> .env
      - echo "NEXT_PUBLIC_GITHUB_CLIENT_SECRET=$NEXT_PUBLIC_GITHUB_CLIENT_SECRET" >> .env
      - echo "NEXT_PUBLIC_SERVER=$NEXT_PUBLIC_SERVER" >> .env
      - echo "NEXT_PUBLIC_URL=$NEXT_PUBLIC_URL" >> .env
      - echo "NODE_ENV=$NODE_ENV" >> .env
      - echo "PORT=$PORT" >> .env
      - echo "SEED_PASSWORD=$SEED_PASSWORD" >> .env
      - echo Building Docker images...
      - DOCKER_BUILDKIT=1 docker-compose build --progress=plain

  build:
    commands:
      - echo Tagging Docker images...
      - docker tag squared-www:latest $ECR_REGISTRY_URI/squared-www:latest
      - docker tag squared-web:latest $ECR_REGISTRY_URI/squared-web:latest
      - docker tag squared-api:latest $ECR_REGISTRY_URI/squared-api:latest
      - docker tag squared-nginx:latest $ECR_REGISTRY_URI/squared-nginx:latest

  post_build:
    commands:
      - echo Pushing Docker images to Amazon ECR...
      - docker push $ECR_REGISTRY_URI/squared-www:latest
      - docker push $ECR_REGISTRY_URI/squared-web:latest
      - docker push $ECR_REGISTRY_URI/squared-api:latest
      - docker push $ECR_REGISTRY_URI/squared-nginx:latest

artifacts:
  files:
    - '**/*'

cache:
  paths:
    - '/var/lib/docker'
    - '/root/.cache/buildkit'

从服务器日志可见,所有环境变量均已正确设置,可排除该因素。我无法理解的是,这个未知用户是如何产生的?为何无法在IAM中编辑其权限(因为它并不存在)。

问题分析与解决方案

核心原因

你的buildspec.yml中通过Secrets Manager注入了AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY环境变量,这会直接覆盖CodeBuild默认使用的服务角色身份。Docker推送镜像时,实际使用的是这组密钥对应的外部IAM账号(即错误信息中的311791021927账号),而该账号没有当前ECR仓库的访问权限。本地运行正常是因为你使用的是自己有权限的本地AWS凭证,和CodeBuild里的身份完全不同。

解决步骤

方案1:使用CodeBuild默认服务角色(优先推荐)

  1. 从buildspec.yml的env.secrets-manager配置中,移除AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY这两项,让CodeBuild使用默认的服务角色执行操作。
  2. 给CodeBuild的服务角色添加ECR相关权限:
    编辑该角色的IAM策略,添加以下内容:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "ecr:GetAuthorizationToken",
            "ecr:InitiateLayerUpload",
            "ecr:UploadLayerPart",
            "ecr:CompleteLayerUpload",
            "ecr:BatchCheckLayerAvailability",
            "ecr:PutImage"
          ],
          "Resource": "arn:aws:ecr:***:014498627014:repository/squared-www"
        }
      ]
    }
    
    如果需要推送多个ECR仓库,可将资源ARN改为arn:aws:ecr:***:014498627014:repository/*以覆盖所有仓库。

方案2:必须使用外部账号密钥时

  1. 登录到密钥对应的311791021927账号,确认ServerlessAccount用户存在,并给该用户添加ECR相关操作权限。
  2. 在当前ECR仓库的资源策略中,添加允许外部账号用户访问的规则:
    {
      "Version": "2008-10-17",
      "Statement": [
        {
          "Sid": "AllowExternalAccountPush",
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::311791021927:user/ServerlessAccount"
          },
          "Action": [
            "ecr:InitiateLayerUpload",
            "ecr:UploadLayerPart",
            "ecr:CompleteLayerUpload",
            "ecr:PutImage"
          ]
        }
      ]
    }
    

内容的提问来源于stack exchange,提问作者Jacob Sanderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 03:29:54