【问题标题】:Attach bucket policy to bucket generated by serverless将存储桶策略附加到无服务器生成的存储桶
【发布时间】:2019-01-16 01:46:33
【问题描述】:

我正在尝试使用无服务器创建一个 S3 存储桶,它可以工作,但是为了操作其中的文件,我需要一个存储桶策略。我很难理解在何处以及如何添加使用第一次无服务器部署时创建的生成的 S3bucket 名称的策略

##serverless.yml##

service: vcc-nametags-api

# Use the serverless-webpack plugin to transpile ES6
plugins:
  - serverless-webpack
  - serverless-offline
  - serverless-ding

# serverless-webpack configuration
# Enable auto-packing of external modules
custom:
  # Our stage is based on what is passed in when running serverless
  # commands. Or fallsback to what we have set in the provider section.
  stage: ${opt:stage, self:provider.stage}
  # Set our DynamoDB throughput for prod and all other non-prod stages.
  # Load our webpack config
  webpack:
    webpackConfig: ./webpack.config.js
    includeModules: true
  environment: ${file(env.yml):${self:custom.stage}, file(env.yml):default}

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: us-east-1

  # These environment variables are made available to our functions
  # under process.env.
  environment:
    S3DBBucketName:
      Ref: NametagsDatabaseBucket

functions:
  # Defines an HTTP API endpoint that calls the main function in create.js
  # - path: url path is /tags
  # - method: POST request
  # - cors: enabled CORS (Cross-Origin Resource Sharing) for browser cross
  #     domain api call
  # - authorizer: authenticate using the AWS IAM role
  create:
    handler: create.main
    events:
      - http:
          path: tags
          method: post
          cors: true

  get:
    # Defines an HTTP API endpoint that calls the main function in get.js
    # - path: url path is /tags/{id}
    # - method: GET request
    handler: get.main
    events:
      - http:
          path: tags/{id}
          method: get
          cors: true

  list:
    # Defines an HTTP API endpoint that calls the main function in list.js
    # - path: url path is /tags
    # - method: GET request
    handler: list.main
    events:
      - http:
          path: tags
          method: get
          cors: true

  update:
    # Defines an HTTP API endpoint that calls the main function in update.js
    # - path: url path is /tags/{id}
    # - method: PUT request
    handler: update.main
    events:
      - http:
          path: tags/{id}
          method: put
          cors: true

  delete:
    # Defines an HTTP API endpoint that calls the main function in delete.js
    # - path: url path is /tags/{id}
    # - method: DELETE request
    handler: delete.main
    events:
      - http:
          path: tags/{id}
          method: delete
          cors: true
# Create our resources with separate CloudFormation templates
resources:
  # S3DB
  - ${file(resources/s3-database.yml)}

##s3-database.yml##

Resources:
  NametagsDatabaseBucket:
    Type: AWS::S3::Bucket
    Properties:
      # Set the CORS policy
      CorsConfiguration:
        CorsRules:
          -
            AllowedOrigins:
              - '*'
            AllowedHeaders:
              - '*'
            AllowedMethods:
              - GET
              - PUT
              - POST
              - DELETE
              - HEAD
            MaxAge: 3000
  NametagsDatabaseBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket:
        Ref: NametagsDatabaseBucket
      PolicyDocument:
        Statement:
          - Sid: PublicReadGetObject
            Effect: Allow
            Principal: "*"
            Action:
            - "s3:DeleteObject"
            - "s3:GetObject"
            - "s3:ListBucket"
            - "s3:PutObject"
            Resource:
              Fn::Join: [
                "", [
                  "arn:aws:s3:::",
                  {
                    "Ref": "NametagsDatabaseBucket"
                  },
                  "/*"
                ]
              ]

# Print out the name of the bucket that is created
Outputs:
  NametagsDatabaseBucketName:
    Value:
      Ref: NametagsDatabaseBucket

我尝试了在 Internet 上找到的各种组合,并将其添加到 serverless.yml 文件中的 iamroles 属性中,但我似乎无法得到任何工作

【问题讨论】:

    标签: amazon-web-services amazon-s3 serverless-framework


    【解决方案1】:

    资源引用名称似乎很重要,我一直不得不在资源名称中使用存储桶的名称。例如,带有 www.example.com 的存储桶需要引用名称 S3BucketWwwexamplecom

    但是我也注意到您的示例中缺少 BucketName 元素。

    这是来自具有存储桶策略的静态网站的工作示例:

    resources:
      Resources:
        S3BucketWwwexamplecom:
          Type: AWS::S3::Bucket
          DeletionPolicy: Delete
          Properties:
            BucketName: ${self:custom.s3WwwBucket}
            CorsConfiguration:
              CorsRules:
                - AllowedMethods:
                    - PUT
                    - GET
                    - POST
                    - HEAD
                  AllowedOrigins:
                    - "https://${self:custom.myDomain}"
                  AllowedHeaders:
                    - "*"
            AccessControl: PublicRead
            WebsiteConfiguration:
              IndexDocument: index.html
        BucketPolicyWwwexamplecom:
          Type: 'AWS::S3::BucketPolicy'
          Properties:
            PolicyDocument:
              Statement:
                - Sid: PublicReadForGetBucketObjects
                  Effect: Allow
                  Principal: '*'
                  Action:
                    - 's3:GetObject'
                  Resource: arn:aws:s3:::${self:custom.s3WwwBucket}/*
            Bucket:
              Ref: S3BucketWwwexamplecom
    

    【讨论】:

      【解决方案2】:

      由于您使用 lambda 进行上传,您应该为您的 Lambda 创建一个 IAM 角色和一个仅具有操作所需权限的 IAM 策略。您可以通过在云形成中使用以下摘录来完成此操作:

      AWSTemplateFormatVersion: '2010-09-09'
      Description: My Template
      Resources:    
        LambdaRole:
          Type: AWS::IAM::Role
          Properties:
            AssumeRolePolicyDocument:
              Version: '2012-10-17'
              Statement:
              - Effect: Allow
                Principal:
                  Service: lambda.amazonaws.com
                Action: sts:AssumeRole
            RoleName: !Sub ${AWS::StackName}-LambdaRole
      
        S3Policy:
          Type: AWS::IAM::Policy
          Properties:
            PolicyName: S3_Writer
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
              - Effect: Allow
                Action:
                  - s3:*
                Resource: !Sub
                  - arn:aws:s3:::${BucketName}/*
                  - BucketName: !Ref NametagsDatabaseBucket
            Roles:
              - !Ref TaskRole
      Outputs:
        LambdaRole:
          Value: !Sub "${LambdaRole.Arn}"
          Export:
            Name: !Sub ${AWS::StackName}-LambdaRole
      

      然后在你的 serverless.yml 中只引用使用这样的东西创建的任务角色来引用执行角色:

      service: vcc-nametags-api
      
      provider:
        role: ${cf:${env:YOUR_STACK_ENV, 'YOUR_STACK_NAME'}.LambdaRole}
      

      我们在几个项目中都有这样的设置,我希望它对你有用。

      【讨论】:

        猜你喜欢
        • 2019-05-15
        • 2020-11-05
        • 2021-12-07
        • 2021-01-19
        • 1970-01-01
        • 2013-06-20
        • 2023-03-31
        • 2011-09-10
        • 1970-01-01
        相关资源
        最近更新 更多