Skip to content

Use ExAws SES adapter with ECS task-role credentials#613

Open
ryan-mahoney wants to merge 5 commits into
mainfrom
582-support-exaws-ses-for-swoosh
Open

Use ExAws SES adapter with ECS task-role credentials#613
ryan-mahoney wants to merge 5 commits into
mainfrom
582-support-exaws-ses-for-swoosh

Conversation

@ryan-mahoney

Copy link
Copy Markdown
Member

Summary

  • Switch the production Swoosh mailer from Swoosh.Adapters.AmazonSES (static AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY) to Swoosh.Adapters.ExAwsAmazonSES, which resolves credentials via ExAws's :instance_role provider — picking up ECS task-role credentials at runtime.
  • Add :ex_aws and :sweet_xml deps required by the ExAws-backed adapter.
  • Pass AWS_REGION into the ECS task container so the runtime config can select the ExAws adapter (otherwise it falls back to Swoosh.Adapters.Logger).
  • Preserve the optional AWS_SES_CONFIGURATION_SET passthrough.

Closes #582.

Test plan

  • mix compile --warnings-as-errors passes locally.
  • mix format --check-formatted config/runtime.exs passes.
  • terraform fmt -check infra/modules/service/task.tf passes.
  • Post-deploy: confirm the ECS task receives AWS_REGION and that the first SES send succeeds (no AccessDenied in CloudWatch).
  • Post-deploy: verify the task role (not the execution role) is the principal making ses:SendEmail calls.

Copilot AI review requested due to automatic review settings May 5, 2026 03:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates production email delivery to use Swoosh’s ExAws-backed SES adapter so AWS credentials are resolved at runtime from the ECS task role (instead of relying on static AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY env vars).

Changes:

  • Switch prod runtime mailer configuration to Swoosh.Adapters.ExAwsAmazonSES and configure ExAws to use the :instance_role credential provider.
  • Add ExAws-related dependencies (:ex_aws, :sweet_xml) and update mix.lock.
  • Pass AWS_REGION into the ECS task environment so the runtime config can enable SES in production.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
mix.exs Adds ExAws/SweetXml dependencies needed for the ExAws SES adapter.
mix.lock Locks newly added ExAws/SweetXml (and transitive) dependencies.
config/runtime.exs Updates production runtime config to use ExAwsAmazonSES with instance-role credentials and preserves configuration set passthrough.
infra/modules/service/task.tf Adds AWS_REGION to ECS task env so prod runtime config can select SES adapter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mix.exs
{:gen_smtp, "~> 1.0"},
{:phoenix_swoosh, "~> 1.2"},
{:ex_aws, "~> 2.1"},
{:sweet_xml, "~> 0.6"},

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

False positive — ~> 0.6 in Hex means >= 0.6.0 and < 1.0.0 (see Version docs), so 0.7.5 is in range and satisfies both our constraint and ex_aws's transitive ~> 0.7 requirement. mix.exs and mix.lock agree, and mix deps.get resolves cleanly. Leaving as-is to match the constraint published in the Swoosh.Adapters.ExAwsAmazonSES docs.

Comment thread config/runtime.exs
config :ex_aws,
access_key_id: [:instance_role],
secret_access_key: [:instance_role],
region: ses_region

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 50d6ad4 — added http_client: ExAws.Request.Req to the :ex_aws config. We already depend on :req, and ex_aws ships ExAws.Request.Req as a built-in alternative to the default Hackney client. Confirmed via deps/ex_aws/lib/ex_aws/instance_meta.ex:18 that instance-role credential resolution goes through config.http_client.request/5, so this is required for the credential lookup to work in ECS.

@paulswartz
paulswartz changed the base branch from ps-xtwr to main May 12, 2026 23:36
@paulswartz

Copy link
Copy Markdown
Member

@ryan-mahoney needs a rebase

paulswartz and others added 5 commits May 13, 2026 22:12
Without this, ExAws falls back to its default ExAws.Request.Hackney,
which is not in our deps. Instance-role credential resolution makes
HTTP calls to the ECS metadata endpoint via the configured http_client,
so SES sends would fail at runtime.
@ryan-mahoney
ryan-mahoney force-pushed the 582-support-exaws-ses-for-swoosh branch from 50d6ad4 to d77d1f0 Compare May 14, 2026 02:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support ExAWS SES for Swoosh

3 participants