Programming Phoenix LiveView Book Club!

So I’m sharing the final solution as a way of paying it forward, I wouldn’t have gotten this far without several blog- and forum posts, stack overflow and the ExAwsAmazonSES documentation (Read carefully, Everything is in there. I’m not sure why the AmazonSES documentation refers to using ExAwsAmazonSES if you have ex_aws already configured. I may be missing something, but ExAwsAmazonSES seems to be the better option).
I ended up with ex_aws in the end, so I don’t have to generate the security token by hand. It uses AWS_PROFILE, and loads the associatd key and secret as well. It will use aws sts and do the key rotation. No credentials in the production code or configuration code.

Dependencies used

      {:ex_aws, "~> 2.1"},
      {:ex_aws_sts, "~> 2.1"},
      {:configparser_ex, "~> 4.0"},
      {:hackney, "~> 1.9"},
      {:swoosh, "~> 1.14.1"},
      {:gen_smtp, "~> 1.2.0"},

Config for ex_aws and ExAwsAmazonSES in runtime.exs

I Found the idea to do this in runtime.exs in a suggestion. I might put the code in ~dev.exs~ again. I probably need to find an explanation of what to put where (dev.exs, config.exs, runtime.exs etc) I was following someone elses’ example and it seems to work for me. For production I’d probably use environment variables for the key and the secret, after creating a narrow IAM user that only has the permissions the app needs. So this will need some more factoring out.

 if config_env() == :prod or config_env() == :dev do
    IO.puts("Configuring AWS credentials")
    config :ex_aws,
      # Below works if you export AWS_PROFILE (specified by :awscli)
      access_key_id: [{:system, "AWS_ACCESS_KEY_ID"}, {:awscli, :system, 30}, :instance_role],
      secret_access_key: [{:system, "AWS_SECRET_ACCESS_KEY"}, {:awscli, :system, 30}, :instance_role],
      region: "eu-west-2" # London. fill in your own region here. 

    IO.puts("Configuring ExAwsAmazonSEs Mailer. config_env: #{config_env()}")
    config :pento, Pento.Mailer,
            adapter: Swoosh.Adapters.ExAwsAmazonSES

    config :swoosh, :api_client, Swoosh.ApiClient.Hackney
  else
    IO.puts("Not Configuring AWS credentials and mailer. config_env: #{config_env()}")
  end

Feedback most welcome. I’m glad it finally works and hope I can save someone some time in the future.

1 Like