我有一个节点服务器在私有子网内的 AWS ECS Fargate 中运行。 我已设置任务策略以允许发送电子邮件
resource "aws_iam_role_policy" "ecs_task_ses_policy" {
name = "${var.environment}-ecs-task-ses-policy"
role = aws_iam_role.ecs_task_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ses:*"
]
Resource = "*"
}
]
})
}
并且我已允许任务安全组上的所有出站流量
resource "aws_security_group" "ecs_tasks" {
name = "${local.common_name}-ecs-tasks-sg"
description = "Security group for ECS tasks"
vpc_id = aws_vpc.this.id
ingress {
description = "Allow inbound from ALB"
from_port = 4000
to_port = 4000
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = local.common_tags
}
并且我为 SES 设置了 VPC 终端节点
resource "aws_vpc_endpoint" "ses" {
vpc_id = aws_vpc.this.id
service_name = "com.amazonaws.${var.aws_region}.email-smtp"
vpc_endpoint_type = "Interface"
subnet_ids = aws_subnet.private[*].id
security_group_ids = [aws_security_group.vpc_endpoints.id]
private_dns_enabled = true
tags = merge({
Name = "${local.common_name}-ses-endpoint"
}, local.common_tags)
}
但是我无法发送电子邮件,因为请求超时。
我正在使用
nodemailer
和 @aws-sdk/client-ses
import { createTransport, Transporter } from 'nodemailer';
import { SES, SendRawEmailCommand } from '@aws-sdk/client-ses';
...
this.transporter = createTransport({
SES: {
ses: new SES({ region }),
aws: { SendRawEmailCommand },
},
});
...
async sendMail(options: {
to: string | string[];
subject: string;
text?: string;
html?: string;
}) {
try {
await this.transporter.sendMail({
from: this.from,
...options,
});
this.logger.log(`Email sent successfully to ${options.to}`);
} catch (error) {
this.logger.error(`Failed to send email to ${options.to}:`, error);
throw error;
}
}
我在一些资源中发现AWS SDK SES客户端仅使用HTTPS而不是SMTP。
允许从我的任务发送电子邮件但无需手动创建 SES 凭据的正确方法是什么,因为我想使用分配的角色来提供凭据?
AWS SES 目前仅支持 SMTP 接口的 VPC 终端节点,不支持 AWS API 接口。您的代码尝试使用 AWS API 通过 SES 发送电子邮件。您当前拥有的代码不会使用 SMTP 端点。
您提到您有一个“私有”VPC 子网。子网类型的典型术语如下:
如果您的子网有到 NAT 网关的路由,那么您根本不需要配置任何 VPC 终端节点,因为到 SES API 的连接将通过 NAT。如果您实际上有一个“隔离”子网,根本没有到 AWS API 的路由,那么不幸的是,您唯一的选择就是切换到在代码中使用 SMTP 库(而不是 AWS 开发工具包)来将电子邮件发送到您的VPC 端点。