s3:PutObject 访问被 CodeBuild 拒绝

如何解决s3:PutObject 访问被 CodeBuild 拒绝

我正在尝试创建一个简单的 s3 托管网站,并且为了构建/部署对 s3 存储桶的更改,我想将 CodePipeline 与 CodeBuild 步骤一起使用。当 CodeBuild 创建生产工件时,我会这样做

aws s3 cp --recursive --acl public-read ./dist s3://my-hosting-bucket

然后它会将我需要的所有东西放入我的托管存储桶中。问题是当我运行这个命令时,我收到以下错误

upload Failed: dist/js/chunk-vendors.e598c2a4.js.map to s3://<my-bucket-name>/js/chunk-vendors.e598c2a4.js.map An error occurred (AccessDenied) when calling the PutObject operation: Access Denied Completed 831.9 KiB/977.4 KiB (0 Bytes/s) with 9 file(s) remaining

如果我复制/粘贴此命令并在本地与我的用户一起运行,它会毫无问题地上传文件。我已经创建了正确的角色并尝试添加一个存储桶策略,它允许角色写入存储桶,但没有任何效果

CodePipelineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action: 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
      Policies:
        - PolicyName: "PipelineAccess"
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Action: 
                - 's3:Getobject'
                - 's3:GetobjectVersion'
                - 's3:GetBucketVersioning'
                - 's3:PutObject'
                Effect: Allow
                Resource:
                  - !GetAtt ArtifactBucket.Arn
                  - !Join ['',[!GetAtt ArtifactBucket.Arn,"/*"]]
              - Action:
                - 'codebuild:BatchGetBuilds'
                - 'codebuild:StartBuild'
                Effect: Allow
                Resource: '*'
              - Action:
                - 'codecommit:GetRepository'
                - 'codecommit:ListRepositories'
                - 'codecommit:GetBranch'
                - 'codecommit:GetCommit'
                - 'codecommit:UploadArchive'
                - 'codecommit:GetUploadArchiveStatus'
                Effect: Allow
                Resource: !ImportValue RepoArn

Codebuildrole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action: ['sts:AssumeRole']
            Effect: Allow
            Principal:
              Service: [codebuild.amazonaws.com]
      Path: /
      Policies:
        - PolicyName: "CodeBuildAccess"
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: 
                  - 's3:Getobject'
                  - 's3:GetobjectVersion'
                  - 's3:GetBucketVersioning'
                  - 's3:PutObject'
                Resource:
                  - !GetAtt ArtifactBucket.Arn
                  - !Join ['',"/*"]]
              - Effect: Allow
                Action:
                  - 's3:Getobject'
                  - 's3:GetobjectVersion'
                  - 's3:GetBucketVersioning'
                  - 's3:PutObject'
                Resource:
                  - !GetAtt DeployBucket.Arn
                  - !Join ['',[!GetAtt DeployBucket.Arn,"/*"]]
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                  - 'cloudfront:CreateInvalidation'
                Resource:
                  - "*"

CodeBuild:
    Type: "AWS::CodeBuild::Project"
    Properties:
      Name: !Sub ${AWS::StackName}-CodeBuild
      ServiceRole: !Ref Codebuildrole 
      Artifacts:
        Type: CODEPIPELINE
        Name: '/'
        Location: !Ref DeployBucket
        Path: 'dist/'
      Source:
        Type: CODEPIPELINE
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Type: LINUX_CONTAINER
        Image: "aws/codebuild/standard:5.0"
      Source:
        Type: CODEPIPELINE
        BuildSpec: !Sub |
          version: 0.2
          phases:
            pre_build:
              commands:
                - echo Installing source NPM dependencies...
                - npm install
            build:
              commands:
                - echo Build starting on `date`
                - npm install -g @vue/cli
                - npm run build
            post_build:
              commands:
                - aws s3 cp --recursive --acl public-read ./dist s3://${DeployBucket}/ --region us-east-2
          artifacts:
            files:
              - '**/*'
            base-directory: build

Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      ArtifactStore:
        Location: !Ref 'ArtifactBucket'
        Type: S3
      RoleArn: !GetAtt CodePipelineRole.Arn
      Name: !Ref 'PipelineName'
      Stages:
        - Name: Source
          Actions:
            - Name: CheckoutSource
              ActionTypeId:
                Category: Source
                Owner: AWS
                Version: 1
                Provider: CodeCommit
              Configuration:
                PollForSourceChanges: true
                RepositoryName: !ImportValue Repo
                BranchName: master
              OutputArtifacts:
                - Name: App
              Runorder: 1
        - Name: Build
          Actions:
            -
              Name: BuildAction
              ActionTypeId:
                Category: Build
                Owner: AWS
                Version: 1
                Provider: CodeBuild
              InputArtifacts:
                -
                  Name: App
              OutputArtifacts:
                -
                  Name: MyAppBuild
              Configuration:
                ProjectName: !Ref CodeBuild

这里也是存储桶策略

{
    "Version": "2012-10-17","Id": "Policy1624203","Statement": [
        {
            "Sid": "Stmt162424558","Effect": "Allow","Principal": {
                "AWS": [
                    "arn:aws:iam::<account id>:role/Pipeline-CodePipelineRole-4MZ4YYUIGCBT","arn:aws:iam::<account id>:role/Pipeline-Codebuildrole-1SOSJXEILREIB"
                ]
            },"Action": "s3:PutObject","Resource": "arn:aws:s3:::<deploy bucket>/*"
        }
    ]
}

这是我的代码构建角色

{
    "Version": "2012-10-17","Statement": [
        {
            "Action": [
                "s3:Getobject","s3:GetobjectVersion","s3:GetBucketVersioning","s3:PutObject"
            ],"Resource": [
                "arn:aws:s3:::<Artifact bucket>","arn:aws:s3:::<Artifact bucket>/*"
            ],"Effect": "Allow"
        },{
            "Action": [
                "s3:Getobject","Resource": [
                "arn:aws:s3:::<deploy bucket>","arn:aws:s3:::<deploy bucket>/*"
            ],{
            "Action": [
                "logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents","cloudfront:CreateInvalidation"
            ],"Resource": [
                "*"
            ],"Effect": "Allow"
        }
    ]
}

似乎我已经给了我可能的所有权限以将其上传到 s3,所以不确定我哪里出错了

Update

我尝试根据@StefanN 的评论更新存储桶策略,但没有奏效。这是新的存储桶策略

{
    "Version": "2012-10-17","Id": "Policy1624202574423","Statement": [
        {
            "Sid": "Stmt1624202534558","Effect": "Deny","Principal": "*","Resource": [
                "<bucket arn>/*","<bucket arn>"
            ],"Condition": {
                "StringNotLike": {
                    "aws:userId": "<role id>:*"
                }
            }
        }
    ]
}

解决方法

事实证明,因为我正在使用 CLI 命令设置公共读取 ACL,所以我还需要添加该权限。这是我的最终存储桶 ACL

{
    "Version": "2012-10-17","Id": "Policy1624611947939","Statement": [
        {
            "Sid": "Stmt1624611923175","Effect": "Allow","Principal": {
                "AWS": "arn:aws:iam::<account id>:role/Pipeline-CodeBuildRole-1SOSJXEILREIB"
            },"Action": [
                "s3:PutObject","s3:PutObjectAcl"
            ],"Resource": [
                "arn:aws:s3:::<bucket>/*","arn:aws:s3:::<bucket>"
            ]
        }
    ]
}

现在一切正常。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?