简体   繁体   中英

ClientError: An error occurred (AccessDenied) when calling the SendEmail operation:

I want to use lambda to send automated emails whenever a file hits a specific region of an s3-bucket. When I place the file in the bucket at the given location and it attempts to run I receive the following error in cloudwatch logs:

[ERROR] ClientError: An error occurred (AccessDenied) when calling the SendEmail operation: User `arn:aws:sts::123456789012:assumed-role/my-bot-role-abcdefg/my-bot' is not authorized to perform `ses:SendEmail' on resource `arn:aws:ses:eu-west-1:123456789012:identity/my_address@gmail.com'
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 44, in lambda_handler
    Message = message   )
  File "/var/runtime/botocore/client.py", line 316, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 626, in _make_api_call
    raise error_class(parsed_response, operation_name)

I have written the following permissions into the json policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Action": [
                "ses:SendEmail"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:ses:eu-west-1:123456789012:identity/*"
        }
    ]
}

The basis of the code I am using within the lambda handle before I plan to modify it for specific purposes is not my own:

import json
import boto3

email_defaults = {
    "port" : 465,  # For SSL
    "smtp_server" : "smtp.gmail.com",
    "sender_email" : "my_sender_address@gmail.com", #replace as needed in testing
    "receiver_email" : "my_reciever_address@gmail.co.uk" #replace as needed in testing
    }

def lambda_handler(event, context):

    for i in event["Records"]:
        action = i["eventName"]
        ip = i["requestParameters"]["sourceIPAddress"]
        bucket_name = i["s3"]["bucket"]["name"]
        object = i["s3"]["object"]["key"]

    client = boto3.client("ses")

    subject = str(action) + 'Event from ' + bucket_name
    body = """
        <br>
        This email is to notify you regarding {} event.
        The object {} has been uploaded.
        Source IP: {}
    """.format(action, object, ip)

    message = {"Subject": {"Data": subject}, "Body": {"Html": {"Data": body}}}

    response = client.send_email(   Source = email_defaults["sender_email"], 
                                    Destination = {"ToAddresses": [email_defaults["receiver_email"]]}, 
                                    Message = message   )

    return "Hello world"

Any guidance on anything I may have overlooked would be appreciated, but I'm quite stumped currently.

you have to add the policy that enables the email sending to your role.

in the console, go to your IAM serviceIAM服务

then, on the left side choose roles:

选择角色

select your role: 选择角色

then add inline policy内联政策

选择 SES 作为服务,然后选择所有 SES 操作和所有资源(如果需要,您可以减少此权限)

then review and save. and done! you're ready to send emails via lambda

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM