sst / ion

SST v3
https://sst.dev
MIT License
1.59k stars 203 forks source link

Email Component Does not Validate in AWS #846

Open claughinghouse opened 1 month ago

claughinghouse commented 1 month ago

When setting up the Email component AWS fails to validate the sender identity when there are ant DMARC overrides and DNS is on Cloudflare. If you run the example that works properly (or comment out the dmarc key, deploy, uncomment on the non working example) below first then add the custom DMARC settings in, there are no issues.

Example that works properly:

export const email = new sst.aws.Email("EmailSes", {
  sender: domain,
  dns: sst.cloudflare.dns(),
});

Example that fails after approx 30 minutes with an error in the AWS console:

export const email = new sst.aws.Email("EmailSes", {
  sender: domain,
  dmarc: "v=DMARC1; p=quarantine; adkim=s; aspf=s;",
  dns: sst.cloudflare.dns(),
});

Link to docs with incorrect example: https://github.com/sst/ion/blob/dev/platform/src/components/aws/email.ts#L103

fwang commented 2 weeks ago

hmm i just tried the following (sstion.com is a domain i bought on Cloudflare)

export const email = new sst.aws.Email("EmailSes", {
  sender: "sstion.com",
  dmarc: "v=DMARC1; p=quarantine; adkim=s; aspf=s;",
  dns: sst.cloudflare.dns(),
});

And on deploy, I can see 4 DNS records on Cloudflare. 3 dkim records to verify the domain, and 1 dmarc record.

Screen Shot 2024-08-28 at 12 38 16 PM

I confirmed the 3 dkim records matches those shown in the SES console.

Screen Shot 2024-08-28 at 12 39 20 PM

It took a couple of minutes for domain to get verified by SES.

Screen Shot 2024-08-28 at 12 37 07 PM

Any difference in our setups?

claughinghouse commented 2 weeks ago

There shouldn't be any difference between our setups. I'm traveling but will try with a fresh deploy within the next week or so.

claughinghouse commented 2 weeks ago

@fwang just tested again on a new deploy:

email.ts - This fails to complete and hangs at verification.

import { domain } from "./domain";
export const email = new sst.aws.Email("EmailSes", {
  sender: domain,
  dmarc: "v=DMARC1; p=quarantine; adkim=s; aspf=s;",
  dns: sst.cloudflare.dns(),
});

email.ts - This succeeds and subsequent deploys adding in the dmarc: "v=DMARC1; p=quarantine; adkim=s; aspf=s;", from above on on a second deploy to the same stage, all resources are created and verification succeeds.

import { domain } from "./domain";
export const email = new sst.aws.Email("EmailSes", {
  sender: domain,
  // dmarc: "v=DMARC1; p=quarantine; adkim=s; aspf=s;",
  dns: sst.cloudflare.dns(),
});

domain.ts

export const domain =
  {
    production: "my.tld.com",
    dev: "my.dev.tld.com",
  }[$app.stage] || `${$app.stage}.my.tld.com`;

sst.config.ts:

export default $config({
  app(input) {
    return {
      name: "app-dev",
      removal: input?.stage === "production" ? "retain" : "remove",
      home: "cloudflare",
      providers: {
        aws: {
          region: "us-east-2",
        },
        cloudflare: true,
      },
    };
  },
  async run() {
    const infra = await import("./infra");

    return {
      api: infra.api.url,
      auth: infra.auth.url,
      app: infra.app.url,
      www: infra.www.url,
    };
  },
});

I do get this error now tihe 3.0.83:

EmailSes sst:aws:Email → EmailSesTXTRecordDmarcdeploytestmytldcom cloudflare:index:Record either 'value' (present: false) or 'data' (present: false) must be provided

If needed I can provide more logs/non-sanitized logs via discord if needed.

ctrimm commented 5 days ago

Stumbled on this issue and figured I would try to help.

This sounds related to #876, #872, and other discussions I've seen on this issue. I'm running sst version => 3.1.2.

Try the following -

  1. Manually install cloudflare provider with sst command line -> sst install cloudflare
  2. Try to run your deploy again with sst deploy ...

If this does not work, try to set your cloudflare provider to a specific version. In this case -

providers: {
  aws: true,
    cloudflare: {
      version: "5.24.1"
    }
},

This seems to have resolved my issues.