В этой статье мы рассмотрим новые дизайны пользовательского интерфейса Amazon Web Services (AWS) для CloudWatch, а также запланируем ежедневную проверку выставления счетов для оповещения о перерасходе средств. Для этой цели мы должны использовать лямбда-функцию, потому что CloudWatch не предлагает ежедневных предупреждений о расходах.

CloudWatch: новый пользовательский интерфейс 

AWS вскоре запустит свой новый дизайн пользовательского интерфейса для CloudWatch. Ниже приведен пример уведомления, которое AWS предоставляет нам.

В конце уведомления нам предоставляется возможность зарегистрироваться и опробовать новый дизайн. Прежде чем оценить новый дизайн, давайте быстро взглянем на текущий.

Переход на новый интерфейс CloudWatch теперь выглядит следующим образом.

Более новое уведомление теперь отображается в верхней части экрана, что позволяет нам оставлять отзывы о новом дизайне. В настоящее время у вас все еще есть возможность вернуться к старому интерфейсу, но это будет удалено в ближайшее время.

Что касается параметров в левой части экрана, изменений нет, но в этих других параметрах также был изменен пользовательский интерфейс.

Настройка ежедневного оповещения о выставлении счетов 

В этой части статьи мы сосредоточим наше внимание на настройке ежедневного оповещения о выставлении счетов. Для достижения этой цели необходимо настроить несколько служб:

  • Лямбда-функция для расчета ежедневного изменения счета.
  • Тема SNS, чтобы отправлять нам уведомления, если мы нарушаем наш лимит расходов.
  • Роль IAM для получения правильных разрешений для запуска лямбды и вызова темы SNS.
  • CloudWatch Event Rules для настройки ежедневного расписания для вызова функции Lambda.

Мы также рассмотрим группы журналов CloudWatch для мониторинга нашей функции Lambda.

SNS тема уведомления

Первый шаг — создание простой службы уведомлений (SNS). Это позволяет AWS отправлять и получать уведомления. Для нашего ежедневного уведомления о выставлении счетов нам необходимо получать уведомление по электронной почте, когда мы нарушаем наш дневной лимит.

Перейдите к SNS через Сервисы. Начните с создания темы, просто добавив имя. После создания темы нажмите «Создать подписку». Это позволяет нам выбрать «электронную почту» и установить адрес электронной почты. Вам будет отправлено письмо, в котором будет ссылка для подтверждения вашего адреса электронной почты. В окне сведений запишите ARN. Это потребуется при создании роли IAM.

Лямбда-функция

Теперь остановимся на лямбде. На целевой странице Lambda выберите функцию создания.

Нам нужно заполнить некоторую основную информацию, чтобы создать наш шаблон функции Lambda. В качестве имени функции добавьте имя, которое будет относиться к лямбде. Я использовал Daily_Billing_Alerts. Измените среду выполнения на Python 3.8. Для роли «Выполнение» выберите «Создать новую роль с базовыми разрешениями Lambda». На этом этапе лямбда создаст исполнительную роль. В этом примере наш файл называется Daily_Billing_Alerts-role-7rseajla. Заданы разрешения на загрузку журналов в Amazon CloudWatch Logs. Это то, что мы добавим в ближайшее время.

Теперь нажмите кнопку Создать функцию.

ПРИМЕЧАНИЕ. Мы будем использовать Python для создания нашей лямбда-функции, но я не буду слишком сильно фокусироваться на самом коде. 

После создания лямбда-функции мы будем вносить поправки в следующие три области лямбды: код функции, переменные среды и роль выполнения.

Давайте начнем с добавления кода функции. Скопируйте и вставьте следующий код Python в код функции в lambda_function (или по ссылке GitHub).

import json
import boto3
import os
from datetime import datetime, timedelta

# import environment variables
limit = float(os.environ['limit'])
sns_topic = os.environ['sns_topic']


def calculate_deltas(values):
    deltas = []
    max_position = len(values)
    for i in range(1, max_position):
        if values[i] < values[i - 1]:
            deltas.append(values[i])
        else:
            deltas.append(values[i] - values[i - 1])
    return deltas


def lambda_handler(event, context):

    client = boto3.client('cloudwatch', region_name='us-east-1')

    response = client.get_metric_data(
        MetricDataQueries=[
            {
                "Id": "m1",
                "MetricStat": {
                    "Metric": {
                        "Namespace": "AWS/Billing",
                        "MetricName": "EstimatedCharges",
                        "Dimensions": [
                            {
                                "Name": "Currency",
                                "Value": "USD"
                            }
                        ]
                    },
                    "Period": 3600,
                    "Stat": "Maximum",
                    "Unit": "None"
                }
            }
        ],
        StartTime=datetime.now() - timedelta(hours=24),
        EndTime=datetime.now(),
        ScanBy='TimestampAscending'
    )

    spent = 0

    for results in response["MetricDataResults"]:
        values = results["Values"]
        print(f"Timestamps of the datapoints:\n{results['Timestamps']}")
        print(f"Values of the datapoints:\n{values}")

        my_deltas = calculate_deltas(values)
        spent = sum(my_deltas)

        print(f"Deltas:\n{my_deltas}")
        print(f"Spent on the period:\n{spent}")

        if spent > limit:
            print("The threshold was breached, sending notification")
            sns_client = boto3.client('sns', region_name='us-east-1')
            message_body = {
                'default': {
                    'body': 'Daily spent limit breached',
                    'limit': limit,
                    'spent': "{:.2f}".format(spent)
                }
            }
            publish_response = sns_client.publish(
                TargetArn=sns_topic,
                Message=json.dumps({'default': json.dumps(message_body)}),
                MessageStructure='json'
            )
            print(publish_response)

    return {
        'statusCode': 200,
        'body': json.dumps({
            'limit': limit,
            'spent': "{:.2f}".format(spent),
        })
    }

 

Чтобы обеспечить некоторую гибкость в функции, мы создадим две переменные среды с именами limit и sns_topic. Переменная limit будет суммой, о которой вы хотите получать уведомления, когда она будет нарушена. Таким образом, это может быть 10, 10000 или 1000000 долларов! В целях этой демонстрации я установлю предел в 0,20, чтобы позволить запускать оповещения. (Я стараюсь сохранить свой собственный счет до минимальной суммы!). Переменная sns_topic будет содержать ARN нашего раздела SNS.

Последняя часть, которую нам нужно настроить, — это добавить к роли, созданной функцией Lambda. Под ролью Выполнение вы увидите свою роль. Нажав на Просмотр Daily_Billing_Alerts-role-7rseajla, вы перейдете к обзору роли в IAM.

  • Отсюда выберите добавить встроенную политику. Затем выберите JSON
  • Вставьте следующий код JSON, убедившись, что вы изменили ресурс для SNS на ARN вашей темы SNS.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:*"
            ],
            "Resource": "arn:aws:sns:us-east-1:************:NotifyMe"
        }
    ]
}

Это позволит получить доступ к CloudWatch и полный доступ к нашей теме SNS.

Метрические данные

Одна часть кода Python, о которой я хочу кратко рассказать, — это метрические данные. Приведенные ниже данные метрик добавляются в формате JSON, но как мы узнаем, какие метрические данные использовать или даже найти?

MetricDataQueries=[
            {
                "Id": "m1",
                "MetricStat": {
                    "Metric": {
                        "Namespace": "AWS/Billing",
                        "MetricName": "EstimatedCharges",
                        "Dimensions": [
                            {
                                "Name": "Currency",
                                "Value": "USD"
                            }
                        ]
                    },
                    "Period": 3600,
                    "Stat": "Maximum",
                    "Unit": "None"
                }
            }
        ]

Один из способов сделать это — через сам CloudWatch. Я выделил две области. Первый — это параметр «Метрика» с левой стороны. Это переместит вас к экрану ниже. Второй — это текущие метрики, доступные для использования / просмотра. Чем больше функций вы используете в AWS, тем больше становится доступных показателей. Я выделил Billing, так как это метрика, которую мы используем.

При нажатии Billing вы увидите еще пару подзаголовков.

Метрика, которая нам нужна для этой лямбды, находится под полной оценочной стоимостью. Взглянув на название метрики, которое я указал, вы увидите EstimatedCharges. Если вы помните, это имя использовалось в коде Python.

Опять же, я выделил пару шагов для подражания. Прежде всего, убедитесь, что метрика отмечена, и затем выберите вкладку Graphed метрики. Это позволит нам скорректировать наши метрические критерии.

Я нажал на стрелку вниз и изменил период времени на 1 час. Перейдите на вкладку «Источник».

Теперь вот интересная часть. Если мы сравним приведенную ниже информацию с нашим фрагментом кода Python, мы увидим те же метрические детали.

Давайте снова посмотрим на часть кода JSON:

MetricDataQueries=[
            {
                "Id": "m1",
                "MetricStat": {
                    "Metric": {
                        "Namespace": "AWS/Billing",
                        "MetricName": "EstimatedCharges",
                        "Dimensions": [
                            {
                                "Name": "Currency",
                                "Value": "USD"
                            }
                        ]
                    },
                    "Period": 3600,
                    "Stat": "Maximum",
                    "Unit": "None"
                }
            }
        ]

Данные метрики в JSON используют те же значения, что и атрибуты Period и Stat.

Это отличный способ получить необходимую информацию, поскольку CloudWatch делает за нас тяжелую работу! Я настоятельно рекомендую изучить эти показатели, если вы хотите сделать что-то интересное с Lambda!

Вывод

Мы прошли через некоторые интересные функции в этой статье. Мы начали с рассмотрения нового улучшенного пользовательского интерфейса CloudWatch от AWS. Затем мы прошли через процесс настройки функции Lambda, которая использовала SNS для отправки уведомления и использовала CloudWatch для вызова ежедневного расписания функции Lambda.

CloudWatch использовался во многих случаях этой конфигурации, с добавлением определения местоположения метрической информации и просмотра журналов вызванной функции Lambda. Когда расписание запускается ежедневно, это будет место, чтобы проверить, есть ли какие-либо проблемы.