Amazon-Web-Services

AWS 權限:拒絕對 S3 的 Lambda 訪問

  • February 18, 2019

我已經通過 AWS Cloud 9 創建了一個 Lambda Python 函式,但是在嘗試從 Lambda 函式寫入 S3 儲存桶時遇到了問題。當我在 Cloud 9 中進行測試時,Python 程式碼執行良好,並且可以完美地寫入 S3 儲存桶。當我將它推送到 Lambda 函式並執行時,我認為會出現錯誤。這讓我覺得 5 月 9 日用於執行應用程序的角色與 Lambda 函式執行時的角色之間存在不同的權限。

給出了以下錯誤,我正在尋找一些關於我可能遺漏的建議,在我描述設置的錯誤下方:

[ERROR] ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
Traceback (most recent call last):
 File "/var/task/index.py", line 22, in handler
   s3.Bucket(bucket_name).put_object(Key=s3_path, Body=encoded_string)
 File "/var/runtime/boto3/resources/factory.py", line 520, in do_action
   response = action(self, *args, **kwargs)
 File "/var/runtime/boto3/resources/action.py", line 83, in __call__
   response = getattr(parent.meta.client, operation_name)(**params)
 File "/var/runtime/botocore/client.py", line 320, in _api_call
   return self._make_api_call(operation_name, kwargs)
 File "/var/runtime/botocore/client.py", line 623, in _make_api_call
   raise error_class(parsed_response, operation_name)

我的程式碼如下:

   import json
   import datetime
   from botocore.vendored import requests
   import boto3


   def handler(event, context):
       print("Start:")
       response = requests.get('https://##########')

       data = response.json()

       for i in data:
           print (i)
           encoded_string = json.dumps(i).encode("utf-8")
           bucket_name = "data"
           file_name = str(i['id']) + ".txt"
           lambda_path = "/tmp/" + file_name
           s3_path = "testBucket/" + file_name
           s3 = boto3.resource("s3")
           s3.Bucket(bucket_name).put_object(Key=s3_path, Body=encoded_string)
...rest of code ...

具有必要權限的 .yml 文件如下:

AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::CodeStar

Parameters:
 ProjectId:
   Type: String
   Description: CodeStar projectId used to associate new resources to team members
 CodeDeployRole:
   Type: String
   Description: IAM role to allow AWS CodeDeploy to manage deployment of AWS Lambda functions
 Stage:
   Type: String
   Description: The name for a project pipeline stage, such as Staging or Prod, for which resources are provisioned and deployed.
   Default: ''

Globals:
 Function:
   AutoPublishAlias: live
   DeploymentPreference:
     Enabled: true
     Type: Canary10Percent5Minutes
     Role: !Ref CodeDeployRole

Resources:
 HelloWorld:
   Type: AWS::Serverless::Function
   Properties:
     Handler: index.handler
     Runtime: python3.7
     Timeout: 10
     Role:
       Fn::GetAtt:
       - LambdaExecutionRole
       - Arn
     Events:
       GetEvent:
         Type: Api
         Properties:
           Path: /
           Method: get
       PostEvent:
         Type: Api
         Properties:
           Path: /
           Method: post
 LambdaExecutionRole:
   Description: Creating service role in IAM for AWS Lambda
   Type: AWS::IAM::Role
   Properties:
     RoleName: !Sub 'CodeStar-${ProjectId}-Execution${Stage}'
     AssumeRolePolicyDocument:
       Statement:
       - Effect: Allow
         Principal:
           Service: [lambda.amazonaws.com]
         Action: sts:AssumeRole
     Path: /
     ManagedPolicyArns:
       -  arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
     PermissionsBoundary: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/CodeStar_${ProjectId}_PermissionsBoundary'

Lambda 函式執行的角色如下: IAM 角色

關於哪裡可能出錯的任何建議。我知道我需要提供正確的訪問權限,但我不確定我還需要在哪裡指定正確的訪問權限(我真的不想公開我的 S3 以便我的 Lambda 函式可以訪問它)。在 Lambda 中,它顯示 S3 已添加為函式角色可以訪問但仍收到上述錯誤的資源。

我相信解決方案應該像將您更改**LambdaExecutionRole**為這樣簡單:

LambdaExecutionRole:
 Description: Creating service role in IAM for AWS Lambda
 Type: AWS::IAM::Role
 Properties:
   RoleName: !Sub 'CodeStar-${ProjectId}-Execution${Stage}'
   AssumeRolePolicyDocument:
     Statement:
     - Effect: Allow
       Principal:
         Service: [lambda.amazonaws.com]
       Action: sts:AssumeRole
   Path: /
   ManagedPolicyArns:
   - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
   - arn:aws:iam::aws:policy/AmazonS3FullAccess         # <== Add
   # PermissionsBoundary: !Sub ...                      # <== Comment out

如果這可行,您可以嘗試將 S3 權限限制為特定儲存桶,但首先嘗試添加AmazonS3FullAccess策略並註釋掉PermissionsBoundary

希望有幫助:)

引用自:https://serverfault.com/questions/954355