SES라고 하면 어딘가 그리운 마음이 듭니다. 제가 처음으로 좋아했던 걸그룹의 이름과 같기 때문입니다. 이렇게 이야기를 하자니 어딘가 제 나이가 대충 드러나는 것 같아서 입이 쓰네요.
최근에 회사에서 서비스를 새로 개발하면서 사용자 계정 인증, 비밀번호 초기화 등의 알림을 위한 용도로 자동 Email 전송 솔루션이 필요해졌습니다. 보통은 Google Workspace에서 제공하는 SMTP를 사용하거나 AWS의 SES를 사용하는 것으로 나뉘는 것 같습니다. 회사에서 어차피 Google Workspace를 사용하기 때문에 구글 SMTP를 사용해볼까 했지만, 일일 전송 한도가 2,000건 밖에 되지 않는다는 사실을 알게 되었습니다.
사실 당장이야 2,000건도 차고 넘칠만한 한도이지만 나중에 서비스가 커지고 고객이 증가할 경우를 고려해본다면 다소 적어보였습니다. 그에 비해 SES는 제한량을 요청에 따라서 얼마든 늘릴 수 있고, 늘리지 않더라도 50,000건까지 넉넉하게 제한을 줍니다. 게다가 1,000건 당 $0.1의 저렴한 비용만을 부과해서, 5만 건을 전부 사용한다고 해도 $5의 비용만이 청구됩니다. 심지어 EC2에서 호스팅 하는 애플리케이션이라면 62,000건까지는 무료라고 하네요.
구축
AWS SES를 통해 SMTP를 이용하려면 몇가지 단계만 거치면 간단하게 이용할 수가 있습니다.
SMTP setting
SES console의 dashboard에서 SMTP settings 항목을 찾습니다. 아마 endpoint와 port가 이미 설정되어 있을 텐데요, 이것을 이용하려면 SMTP Username과 Password가 필요합니다. 아래쪽에서 Create SMTP credentials를 클릭합니다.
그러면 IAM 계정을 설정하는 페이지로 redirection되게 되고, 자동으로 IAM User를 설정해줍니다. 해당 IAM User가 생성되면 SMTP Username과 Password를 자동으로 생성되고 해당 정보를 CSV file로 제공해주는데요, 이는 변경이 불가능하니 보관에 유의하세요. git에 그대로 노출되면 매우 좋지 않은 결과가 나타날 수 있겠습니다.
위쪽 이미지를 보면 STARTTLS Port에 25, 587, 2587이 나와있는 걸 보실 수 있는데, 사실 EC2 인스턴스는 기본적으로 25번 포트의 송신 트래픽을 제한합니다. 물론 따로 요청해서 제한을 풀도록 할 수도 있지만, 대부분은 587 포트를 관행적으로 사용합니다.
Identities 등록
계정이 있다고해서 아무 Email 주소에서나 Email을 전송할 수 있는 것은 아닙니다. 보낼 주소를 등록해야 하는데요, Email만을 등록하는 방법과 Domail을 등록하는 2가지 방법이 있습니다.
Email로 등록
Email로 등록을 하게 되면 Email 주소를 검증하는 메일이 등록된 Email 주소로 옵니다. 해당 검증 링크를 클릭해 Email 주소를 Verify 할 수 있습니다. 하지만 대부분의 경우 발신 전용 메일이라고 해서 no-reply@site.com과 같은 형식의 Email이 오는 것을 확인할 수 있습니다. Email 주소를 검증해야 하는데, 그러면 해당 이름의 Email을 별도로 생성해야 할까요?
Domain으로 등록
Domain을 통해서 등록을 하게 되면 해당 Domain을 포함하는 Email에 대해서는 별도의 검증을 하지 않습니다. 따라서 저희는 site.com라는 Domain을 등록해서 처리하면 될 것 같습니다. 간단하게 Domain을 등록한 뒤에 Email에 no-reply@site.com를 추가하면 별도의 인증 절차 없이 바로 사용이 가능합니다...만,
DNS
그것은 Route 53이라는 AWS 내의 DNS를 이용해서 Domain을 발급받았을 때의 이야기입니다. 만약 GoDaddy 등의 외부 업체를 이용한 경우라면 Domain 등록 절차에서 제공되는 TXT field나 CNAME field 등을 알맞게 설정해 주어야 합니다. 실제로 해당 Domain이 운영 중이든 아니든, Server가 올라가 있든 그렇지 않든 상관하지 않고 DNS의 설정에 따라서 달라지니 각 DNS 업체 간 이용 방법을 별도로 찾아보면 좋겠습니다.
그리고...?
여기서 잊지 말아야 할 것은, 아직까지 우리는 Sandbox를 해제한 적이 없다는 사실입니다. 아마 SES 콘솔에서는 아래와 같은 화면을 볼 수 있을 거예요.
Sandbox에 있는 동안은 과금이 되지 않으며, Verified 된 Domain과 Email로만 송신이 가능합니다. 따라서 위 이미지에 보이는 Request production access를 눌러 AWS에 직접 Case를 열어 요청을 할 필요가 있습니다. 대개 하루에서 이틀 정도 걸린다고 하는데 저는 6시간 만에 승인이 났었습니다.
결론
남은 것은 Code에서 해당 값을 잘 이용해서 적절한 메시지를 전송하는 일입니다. 아래 코드는 Go를 기준으로, gomail이라는 라이브러리를 이용해 작성된 코드입니다. 언어마다 SMTP를 지원하는 라이브러리가 있을 거예요.
func (m *MsgSubscriber) sendMail(email, name, subject, body string) error {
opt := m.smtpOpt
// 생성된 Credential 참고
dialer := gomail.NewDialer(opt.Host, opt.Port, opt.Username, opt.Password)
msg := gomail.NewMessage()
// SenderEmail: `no-reply@site.com`
msg.SetHeader("From", msg.FormatAddress(opt.SenderEmail, opt.SenderName))
msg.SetHeader("To", msg.FormatAddress(email, name))
msg.SetHeader("Subject", subject)
msg.SetBody("text/html", body)
}