# How to set up AWS SES with LocalStack

Amazon Simple Email Service (SES) is a cloud-based email service provider that can integrate into any application for high-volume email automation. LocalStack, on the other hand, is a local cloud emulator that lets you build and test cloud applications entirely on your machine. With its help, we can quickly try out SES locally in our project. In this article, I will present an example configuration of LocalStack with SES.

## Initial configuration

Add SES libraries - [AWSSDK.Core](https://www.nuget.org/packages/AWSSDK.Core), [AWSSDK.Extensions.NETCore.Setup](https://www.nuget.org/packages/AWSSDK.Extensions.NETCore.Setup) and [AWSSDK.SimpleEmail](https://www.nuget.org/packages/AWSSDK.SimpleEmail):

```bash
dotnet add package AWSSDK.Core
dotnet add package AWSSDK.Extensions.NETCore.Setup
dotnet add package AWSSDK.SimpleEmail
```

Add LocalStack libraries - [LocalStack.Client](https://www.nuget.org/packages/LocalStack.Client) and [LocalStack.Client.Extensions](https://www.nuget.org/packages/LocalStack.Client.Extensions):

```bash
dotnet add package LocalStack.Client
dotnet add package LocalStack.Client.Extensions
```

Register services in `Program.cs`:

```csharp
builder.Services.AddLocalStack(builder.Configuration);
builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions());
builder.Services.AddAWSServiceLocalStack<IAmazonSimpleEmailService>();
```

Add LocalStack settings in `appsettings`:

```csharp
"LocalStack": {
  "UseLocalStack": true,
  "Session": {
    "RegionName": "us-east-1"
  },
  "Config": {
    "LocalStackHost": "localhost",
    "EdgePort": 4566
  }
},
```

## Docker compose

Add `docker-compose.yaml`:

```csharp
services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"
    image: localstack/localstack
    ports:
      - "127.0.0.1:4566:4566"            # LocalStack Gateway
      - "127.0.0.1:4510-4559:4510-4559"  # external services port range
    environment:
      - DEBUG=${DEBUG:-0}
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"
```

## Problem with email verification

Each time we restart the container, we will be forced to re-verify the email address from which we send emails. To avoid this, let's use a script that runs when the container is started:

```bash
#!/bin/bash

echo "Verifying SES email addresses..."

awslocal ses verify-email-identity --email noreply@poc.com

awslocal ses list-identities

echo "SES email verification completed!"
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you used a region other than "us-east-1" in appsettings, you must include it when verifying your email using the --region variable.</div>
</div>

Name the file `init-aws.sh` and place it in the same folder as `docker-compose.yaml`. You still need to modify docker-compose itself:

```bash
services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"
    image: localstack/localstack
    ports:
      - "127.0.0.1:4566:4566"            
      - "127.0.0.1:4510-4559:4510-4559"
    environment:
      - DEBUG=${DEBUG:-0}
      - PERSISTENCE=1
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "./init-aws.sh:/etc/localstack/init/ready.d/init-aws.sh"    # Add script
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Remember to rebuild the container after making changes!</div>
</div>

```bash
docker compose down
docker compose up -d
```

## Bonus

The source code is available [here](https://github.com/Katarzyna-Kadziolka/MailingPoC) :)
