Thursday, 12 December 2024

Send emails using Amazon SES with an IAM role

Allowing a Laravel application, running on an EC2 instance in a public subnet, to send emails using Amazon SES with an IAM role:

1. Prerequisites and Overvie

Before configuring your application, ensure that:

  • SES Setup:
    You have verified your sending domain or email address in Amazon SES. If your account is still in the SES sandbox, you need to verify every recipient email address as well. Once moved out of the sandbox by requesting production access, you can send to any email address.

  • Region Selection:
    SES is a regional service. Make sure you use the same region for SES and the IAM role policies. Also, ensure that your .env and mail configuration files in Laravel reflect the correct region.

2. Create and Attach an IAM Role with SES Permissions

Instead of manually providing AWS credentials in .env, you can rely on an IAM role attached to the EC2 instance. The AWS SDK in Laravel will automatically retrieve temporary credentials from the instance metadata:

  1. Create the IAM Role:

    • Open the IAM console in AWS.
    • Click Roles > Create role.
    • Select AWS service and choose EC2 as the use case.
    • Click Next: Permissions.
    • Attach a policy that allows sending emails via SES. For testing, you can use AmazonSESFullAccess (not recommended for production), or create a more restrictive policy like:
      json
      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ses:SendEmail", "ses:SendRawEmail" ], "Resource": "*" } ] }
    • Complete the role creation.
  2. Attach the Role to Your EC2 Instance:

    • Go to the EC2 console and select your running instance.
    • Choose Actions > Security > Modify IAM Role.
    • Select the IAM role you just created and attach it.

After this step, the EC2 instance will have permission to send emails through SES without requiring access keys in the application’s code.

3. Configure Laravel to Use SES

Laravel uses config/mail.php and .env for mail configurations. The SES mailer is built into Laravel’s core mail system (for Laravel versions 5.7+):

  1. .env Configuration: In your .env, specify SES as your mail driver and the AWS region:

    env
    MAIL_MAILER=ses AWS_DEFAULT_REGION=us-east-1 # or your chosen region AWS_SES_REGION=us-east-1 # match the region where your SES is set up # Leave these blank since the IAM role will provide credentials: AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY=

    Note: The AWS_SES_REGION should correspond to the region where your SES service (domain/email verification) is set up.

  2. config/mail.php: The default configuration for the SES mailer in config/mail.php might look like this:

    php
    'mailers' => [ 'ses' => [ 'transport' => 'ses', 'region' => env('AWS_SES_REGION', 'us-east-1'), ], // other mailers... ],

    The AWS SDK will automatically fetch credentials from the EC2 instance metadata since the IAM role is attached. You do not need to hardcode any keys.

4. Network and Security Considerations

  • Since the EC2 instance is in a public subnet with an Internet Gateway, it likely already has outbound internet access.
  • Ensure the instance’s Security Group allows outbound HTTPS (port 443) traffic. SES endpoints are accessed over HTTPS.
  • No need for a VPC endpoint if you are fine with public internet access. If you prefer private connectivity and do not want public internet traffic, you would consider adding a VPC endpoint. However, in a public subnet scenario, this is usually unnecessary.

5. Test the Configuration

After setting everything up, test sending an email from your Laravel application:

php
use Illuminate\Support\Facades\Mail; Mail::raw('This is a test email sent via SES', function ($message) { $message->to('recipient@example.com') ->subject('Test SES Email'); });
  • Check the logs at storage/logs/laravel.log if the email is not delivered.
  • If in the SES sandbox, ensure you verify both the sender and recipient addresses.
  • If you see errors related to Unverified email address or MessageRejected, verify that SES is configured correctly and that the email/domain is verified.

6. Common Troubleshooting Tips

  • Permissions: Make sure the IAM role has the correct SES permissions. Check IAM > Roles to confirm the attached policies.
  • Region Mismatch: Ensure the AWS_SES_REGION and the region where you verified your domain in SES match.
  • Sandbox vs. Production: If still in the SES sandbox, you must verify recipient emails. To lift sandbox restrictions, request production access from the AWS SES console.
  • Logging and Debugging:
    Check laravel.log for detailed error messages.
    You can also SSH into the instance and use the AWS CLI to test SES sending (if CLI is installed and configured to use the IAM role):
    bash
    aws ses send-email \ --from sender@verifieddomain.com \ --destination "ToAddresses=recipient@example.com" \ --message "Subject={Data=Test},Body={Text={Data=Test message}}"
    If this works, then the issue might be within the Laravel configuration. If this fails, the problem is at the IAM or SES level.

Summary

  • Assign an IAM role with SES permissions to your EC2 instance.
  • Configure Laravel’s .env and config/mail.php to use SES.
  • Ensure that SES domain/email verification and region alignment are correct.
  • Check networking to confirm outbound HTTPS is allowed.
  • Test sending emails and troubleshoot as necessary.

Thank you

No comments:

Post a Comment

Publish npm package

  Để publish   pav-kit  lên NPM, bạn hãy làm theo các bước dưới đây. Tôi đã tạo thêm file  index.js  để đảm bảo gói tin hợp lệ. Bước 1: Tạo ...