Мониторинг HTTP в AWS с помощью Terraform

В данной статье будет рассказано о том, как настроить проверку 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 сообщение.

Posted in Web

Добавить комментарий