8

I am trying to send email from Lambda to SES.

When I run Lambda in NO VPC mode then email is successfully sent.

But when I assign my VPC it doesn't work.

AWS has VPC endpoint to connect to S3. It same available for SES? Or it is not possible to do so?

Lajpat
  • 591
  • 5
  • 19
  • I've used SNS (which has VPC endpoint) to publish to a topic that triggers a lambda outside the VPC. You can send a SES json from your VPC lambda and let your lambda outside sends the mail in a reaction of a topic. – Vinicius Lima Jul 16 '18 at 14:04
  • Thanks Vinicius. But this isn't the option I would prefer. FYI couldn't implement this as NAT is expensive for such a small requirement. – Lajpat Jul 23 '18 at 05:23

4 Answers4

2

VPC Endpoint is only available for S3 currently, there is plans to roll it out to other services already in flight but not available yet.

As Mentioned the VPC your lambda attaches to must have a route to the internet to connect to SES, the security groups must also allow the traffic to the secure SMTP port.

Brent
  • 1,324
  • 1
  • 15
  • 22
  • PrivateLink is available for SES as of Apr. 2020, but I haven't been able to get it to work. [announcement](https://aws.amazon.com/blogs/aws/new-amazon-simple-email-service-ses-for-vpc-endpoints/) – Carl G Aug 03 '20 at 03:10
  • 1
    Neither have I using the SES endpoint :( I attempted to connect a lambda to a serverless RDS, which has to be on a VPC - that worked. I attempted ot send an email from lambda - that did not. Set up SES endpoint and SMPT creds - smpt worked from local, but failed on the lambda via the ses endpoint. Support was not helpful. – PaulG Nov 03 '21 at 11:03
2

In 2020 this is now possible by creating a VPC endpoint for SES (for the security group part just enable all traffic with the source being the security group the lambda belongs to).

However, as far as I can tell you cannot send mail using the SES API, you have to use SMTP. I set up my lambda as follows:

"use strict";
const nodemailer = require("nodemailer");
const transporter = nodemailer.createTransport({
    host: "email-smtp.YOURREGION.amazonaws.com",
    port: 465,
    secure: true,
    auth: {
      user: process.env.USER,
      pass: process.env.PASS,
    },
});

const SENDER = 'no-reply@domain.com';
const RECEIVER = 'to@domain.com';

const response = {
    "statusCode": 200,
    "headers": { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*'},
    "body": "{\"result\": \"Success.\"}"
};

const errResponse = {
    "statusCode": 500,
    "headers": {'Access-Control-Allow-Origin': '*'},
    "body": "{\"result\": \"Failed.\"}"
};

exports.handler = function (event, context, callback) {
    transporter.sendMail({
        from: SENDER,
        to: RECEIVER,
        subject: "Hello ✔",
        text: "Hello world?", // plain text body
        html: "<b>Hello world?</b>", // html body
    }, function(error, info) {
        if (error) {
            console.log(error);
            callback(errResponse, null);
        } else {
            console.log('Email sent: ' + info);
            callback(null, response);
        }
    });
};
jdnz
  • 932
  • 1
  • 7
  • 18
0

It seems that the Lambda doesn't have Internet access. I'd confirm the Lambda subnet is associated with a route table that has a route to the internet (the SES endpoint is on the public internet) — 0.0.0.0 should point to a NAT gateway (or equivalent to outbound route to the internet).

Hugo Lopes Tavares
  • 28,528
  • 5
  • 47
  • 45
  • so since aws hasnt provided with ses endpoint just like it did for s3, then i have to create nat gateway even though lambda is launched in public vpc with security group outbound set for internet? – Lajpat Apr 28 '17 at 05:14
0

The easiest solution for me in a similar situation was to use SNS to invoke another lambda that is not inside a VPC to call the SES service. You can create an endpoint for SNS and connect it to the VPC.

Gilad S
  • 1,753
  • 1
  • 13
  • 14