В данной статье будет рассказано о том, как настроить проверку HTTP эндпоинтов с SMS уведомлениями c помощью Route 53, CloudWatch и SNS используя terraform.
Проверка кода ответа URL — самая базовая проверка работоспособности сайта или API. Если вы размещаете свой проект на AWS и используете Route53 для DNS и CloudWatch для мониторинга, то в процессе вы можете столкнуться с некоторыми подводными камнями.
Первый и самый главный заключается в том, что несмотря на то что Route53 — глобальный сервис AWS не привязанный к конкретному региону, это не распространяется на проверки здоровья (healthcheck).
Вторым моментом, который необходимо учитывать является то, что далеко не все регионы обладают данным функционалом. То есть если ваш проект сосредоточен в регионе eu-central-1 (Франкфурт), то все настройки, связанные с проверками HTTP, необходимо применять в других регионах, например us-east-1. Более того, поскольку регион в terraform прописывается в блоке provider, и его нельзя переопределить для ресурсов CloudWatch и SNS, может возникнуть необходимость создать отдельный провайдер с другим регионом и явно задавать его для всех ресурсов этих сервисов.
Третьим «сюрпризом» можно назвать то что terraform не поддерживает создание почтовых подписок на темы (topic) в SNS. Поэтому в данном примере будет рассмотрен пример с отправкой сообщений по SMS. Больше информации можно найти здесь.
И, взяв эти знания на вооружение, приступим.
Допустим, у нас есть есть некий проект в регионе eu-central-1, состоящий из инстанса в EC2 и записи DNS, которая смотрит на этот инстанс:
provider "aws" {
region = "eu-central-1"
}
resource "aws_route53_zone" "root" {
name = "example.com"
}
data "aws_ami" "debian_buster" {
most_recent = true
owners = ["136693071363"]
filter {
name = "name"
values = ["debian-10-amd64-*"]
}
}
resource "aws_instance" "deb" {
ami = data.aws_ami.debian_buster.id
instance_type = "t2.micro"
}
resource "aws_route53_record" "root" {
zone_id = aws_route53_zone.root.zone_id
name = "example.com"
type = "A"
ttl = 300
records = aws_instance.web.public_ip
}
Здесь мы видим создание инстанса t2.micro из AMI Debian Buster и создание записи DNS example.com, которая смотрит на внешний IP данного инстанса
И мы хотим добавить к нему проверку URL https://example.com/. Получается следующий код:
resource "aws_route53_health_check" "main_page" {
fqdn = aws_route53_record.root.fqdn
port = 443
type = "HTTPS"
resource_path = "/"
failure_threshold = "3"
request_interval = "30"
}
Здесь задается проверка каждые 30 секунд из всех доступных регионов. После 3-х неуспешных запросов проверка будет считаться неудачной и это послужит сигналом для CloudWatch.
Следующим шагом является создание сигналов тревоги (alert) в CloudWatch и темы в SNS. И здесь начинаются проблемы. Как уже было сказано, ранее Route53 поддерживает создание проверок не во всех регионах, на момент написания (13.06.2020) это:
- us-east-1
- us-west-1
- us-west-2
- eu-west-1
- ap-southeast-1
- ap-southeast-2
- ap-northeast-1
- sa-east-1
Используемый нами регион eu-central-1 в данный список не входит, поэтому все последующие настройки необходимо создавать в другом регионе, где есть проверки. Для примера возьмем us-east-1 и создадим новый провайдер AWS с псевдонимом (alias) healthcheck:
provider "aws" {
alias = "healthcheck"
region = "us-east-1"
}
Для всех последующих ресурсов необходимо явно указать, какой провайдер необходимо использовать. Начнем с темы SNS и настроим подписку на нее по SMS:
resource "aws_sns_topic" "alarms" {
provider = aws.healthcheck
name = "alarms"
display_name = "alarms"
}
resource "aws_sns_topic_subscription" "alarms" {
provider = aws.healthcheck
topic_arn = aws_sns_topic.alarms.arn
protocol = "sms"
endpoint = "+7 999 999 99 99"
}
Теперь, создаем сигнал тревоги в CloudWatch, связывающий проверку здоровья в Route53 с топиком SNS. При изменении состояния проверки будет направляться сообщение в SNS, откуда будет приходить на наш телефон:
resource "aws_cloudwatch_metric_alarm" "main_page_down" {
provider = aws.healthcheck
alarm_name = "main_page_down"
alarm_description = "Main page is down"
comparison_operator = "LessThanThreshold"
threshold = 1
evaluation_periods = 1
treat_missing_data = "breaching"
actions_enabled = true
alarm_actions = [aws_sns_topic.alarms.arn]
ok_actions = [aws_sns_topic.alarms.arn]
insufficient_data_actions = [aws_sns_topic.alarms.arn]
namespace = "AWS/Route53"
metric_name = "HealthCheckStatus"
statistic = "Minimum"
period = 60
unit = "None"
dimensions = {
HealthCheckId = aws_route53_health_check.main_page.id
}
}
Здесь мы видим, что если хотя бы одна проверка за 1 минуту дала отрицательный результат, то необходимо отправить сообщение в SNS. Отсутствие или недостаток данных считается ошибкой. Проверка условия совершается каждую минуту.
Готово! Теперь, если проверяемый URL перестанет отвечать или будет отвечать ошибкой, то на телефон придет SMS сообщение.