AWS Lambda S3.getObject 抛出 "Access Denied",但仅当 运行 在本地

AWS Lambda S3.getObject throws "Access Denied", but only when running locally

我正在使用 AWS Lambdaserverless 框架构建一个使用 S3 存储文件的服务。
lambda 函数 ("hello") 在部署到云时完美运行(它有一个 http 端点,我从浏览器调用它)。
相反,在本地调用时 (serverless invoke local --function hello) 我收到“访问被拒绝”错误:

{
    "errorMessage": "error getting object from S3: AccessDenied: Access Denied",
    "errorType": "Error",
    "stackTrace": [
        "Error: error getting object from S3: AccessDenied: Access Denied",
        "    at module.exports.hello (/....js:24:9)",
        "    at processTicksAndRejections (internal/process/task_queues.js:93:5)"
    ]
}

这是我的简化函数:

'use strict';

const aws = require("aws-sdk");
const s3 = new aws.S3({ region: "eu-west-1" });
const bucket = "my-bucket-dev";
const key = "ads.json";

module.exports.hello = async (event) => {
  let obj = null;
  try {
    return await s3.getObject({ Bucket: bucket, Key: key }).promise();
  } catch(err) {
    throw new Error(`error getting object from S3: ${err}`);
  }
  return {
    statusCode: 200,
    body: JSON.stringify({
        message: `Hello function executed successfully!`,
        obj,
        input: event,
      },
      null,
      2
    ),
  };
}

这是我的serveless.yml(相关部分):

service: my-service
frameworkVersion: '2'  
provider:
  name: aws
  runtime: nodejs12.x
  profile: serverless
  lambdaHashingVersion: 20201221
  apiGateway:
    shouldStartNameWithService: true
  stage: ${opt:stage, "dev"}
  region: eu-west-1
  iam:
    role:
      statements:
        - Effect: "Allow"
          Action:
            - "s3:ListBucket"
          Resource: { "Fn::Join": [ "", [ "arn:aws:s3:::", "my-service-dev" ] ] }
        - Effect: "Allow"
          Action:
            - "s3:GetObject"
            - "s3:PutObject"
            - "s3:DeleteObject"
          Resource: { "Fn::Join": [ "", [ "arn:aws:s3:::", "my-service-dev", "/*" ] ] }
functions:
  hello:
    handler: index.hello
    events:
      - http:
          method: get
          path: hello
      - s3: my-bucket-dev

我确实在某处读到 IAM 角色声明对于本地和云执行是不同的,但如果它是正确的,我有点困惑...
有人可以澄清一下吗?
我应该如何更正我的 serverless.yml 以避免本地调用错误?

引用 invoke-local 的文档:

When you use serverless invoke local, the situation is quite different: the role isn't available (the function is executed on your local machine), so unless you set a different user directly in the code (or via a key pair of environment variables), the AWS SDK will use the default profile specified inside your AWS credential configuration file.

因此,对于本地调用,要么在 ~/.aws/credentials 中适当配置本地 AWS 凭证,要么提供它们 via environment variables