Issue
I'm trying to send emails through my Java application that I'm running on a container in Fargate. My containers are running in a VPC behind a API gateway, the connections to external services are made through VPC endpoints.
All that infra is deployed using Terraform. The Java app runs ok localy, but not when deployed to AWS, so I'm thinking that there is one missing config.
The Java app follows the AWS guidelines found here:
https://docs.aws.amazon.com/ses/latest/dg/send-email-raw.html
Following are some spinets of the Terraform code:
# SECURITY GROUPS
resource "aws_security_group" "security_group_containers" {
name = "security_group_containers_${var.project_name}_${var.environment}"
vpc_id = var.vpc_id
ingress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
self = true
}
egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "security_group_containers_${var.project_name}_${var.environment}"
}
}
resource "aws_security_group" "security_group_ses" {
name = "security_group_ses_${var.project_name}_${var.environment}"
vpc_id = var.vpc_id
ingress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "security_group_ses_${var.project_name}_${var.environment}"
}
}
# VPC
resource "aws_vpc" "main" {
cidr_block = var.cidr
enable_dns_support = true
enable_dns_hostnames = true
}
resource "aws_subnet" "private_subnet" {
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnets[0]
availability_zone = "us-east-1b"
tags = {
Name= "private_subnet_${var.project_name}_${var.environment}"
}
}
# VPC ENDPOINT
resource "aws_vpc_endpoint" "ses_endpoint" {
security_group_ids = [aws_security_group.security_group_ses]
service_name = "com.amazonaws.${var.aws_region}.email-smtp"
vpc_endpoint_type = "Interface"
subnet_ids = [aws_subnet.private_subnet.id]
private_dns_enabled = true
tags = {
"Name" = "vpc_endpoint_ses_${var.project_name}_${var.environment}"
}
vpc_id = aws_vpc.main.id
}
If there are any important service missing tell me so I can add it.
As you can see I'm keeping all traffic open, so the solution found here doesn't works for me. When the app tries to send an email I get to following error:
software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: Connect to email.us-east-1.amazonaws.com:443 [email.us-east-1.amazonaws.com/52.0.170.238, email.us-east-1.amazonaws.com/54.234.96.52, email.us-east-1.amazonaws.com/34.239.37.81, email.us-east-1.amazonaws.com/18.208.125.60, email.us-east-1.amazonaws.com/52.204.223.71, email.us-east-1.amazonaws.com/18.235.72.5, email.us-east-1.amazonaws.com/18.234.10.182, email.us-east-1.amazonaws.com/44.194.249.132] failed: connect timed out
I think that I'm missing some config to make the java awssdk use the VPC endpoint.
Edit 01 - adding execution policies:
arn:aws:iam::aws:policy/AmazonSESFullAccess
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:*"
],
"Resource": "*"
}
]
}
arn:aws:iam::aws:policy/AmazonECS_FullAccess (too large)
arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
Edit 02 - changed to use a SMTP library:
The code used can be found here
Everything worked fine with SMTP
Solution
You've created a VPC endpoint for the SES SMTP API, but the error message you are getting email.us-east-1.amazonaws.com:443
is for the AWS SES Service API. You can see the two sets of APIs here. If you are using the AWS SDK to interact with SES in your Java application, then you need to change VPC endpoint to be service_name = "com.amazonaws.${var.aws_region}.email"
Your current endpoint configuration would work if you were configuring your Java application to use SMTP (such as with the JavaMail API).
Answered By - Mark B
Answer Checked By - Terry (JavaFixing Volunteer)