Три юзкейса Terraform, к реализации которых вам пора приступать
В тех инженерных организациях, где применяются инструменты для программирования инфраструктуры (IaC), например, Terraform, они обычно используются вполсилы. В этой статье разобрано не менее трёх вариантов использования Terraform и автоматизации в духе IaC, которые не связаны напрямую с традиционной инфраструктурой, отвечающей за управление рабочей нагрузкой приложений.
Мы заметили, что через работу многих команд, занятых администрированием платформ красной нитью проходит явная пробуксовка с освоением философии «as code». Естественно, там используются OpenTofu или Terraform (здесь и далее я буду называть их в совокупности «TF») для управления вычислительными и прочими облачными ресурсами, но при этом команда обычно не переходит к применению тех же принципов во всех аспектах, связанных с эксплуатацией предметной области.
Цель не в том, чтобы спорадически автоматизировать отдельные вещи; на самом деле, мы хотим автоматизировать всё. Все без исключения процессы и операции должны быть выражены в коде.
Почему? Потому что, как только удастся этого добиться, вы выйдете при управлении системами на новый уровень согласованности и надёжности, причём, даже в тех системах, где обычно до программирования инфраструктуры добирались в последнюю очередь.
В этой статье мы заострим внимание на некоторых ресурсах, которыми (вы удивитесь!) тоже можно управлять. Это:
Надеемся, вы придёте к тем же выводам, которые мы сами проповедуем всем, с кем нам доводится работать: если вы хотите сделать солидную платформу, то на ней нужно программировать все аспекты инфраструктуры.
❯ Почему не принято всё делать через Terraform?
Есть ряд причин, по которым разработчики могут быть не склонны использовать Terraform для развёртывания некоторых ресурсов, например, Git-репозиториев, а также для управления пользователями или мониторинга. Зачастую доводится видеть, что инженеры об этом просто не задумываются, так как более сосредоточены на реализации других деталей с нуля. Что касается Git-репозиториев, программисты могут воспринимать работу с ними как проблему «что было раньше — курица или яйцо»? В таком случае репозитории создаются вручную до того развёртывать код — поэтому автоматизации всех процессов через Terraform не происходит. Кроме того, часто приходится работать в цейтноте, инженеров торопят, чтобы те поскорее выкатили продукт — поэтому они предпочитают придерживаться проверенных рабочих потоков, а не исследовать новые. Использование Terraform для управления всей системой — как раз такой подход.
❯ Управление аккаунтами членов команды и ролевой контроль доступа
Управление пользовательскими аккаунтами и ролями сразу в нескольких SaaS-продуктах может превратиться в настоящую головную боль, особенно, если в этих продуктах не поддерживается технология единого входа (SSO). Именно эту задачу зачастую приходится решать старшему руководству и командам инженеров. Тратятся целые часы рабочего времени, которое лучше было бы потратить на развитие стратегических инициатив. К счастью, TF может значительно облегчить этот процесс.
Прежде, чем перейти к примерам, стоит отметить: по-видимому, многие вендоры SaaS начали забывать, насколько важна технология SSO с точки зрения безопасности. Как подчёркивается в статье The SSO Wall of Shame, многие вендоры предлагают SSO, но лишь в качестве преимум-возможности. Она увязывается с дорогостоящими «корпоративными» планами тарификации, либо плата за неё многократно превышает базовую стоимость простейшей функциональной версии продукта. Такая практика размотивирует людей пользоваться SSO и, напротив, плодит безответственное отношение к безопасности. В особенности актуальна данная проблема для небольших организаций, которым, возможно, не по карману дорогостоящие тарифные планы.
В типичной организации, занятой разработкой ПО, как правило, применяется несколько сервисных платформ, на которых требуется управлять как пользователями, так и уровнями доступа. Обычный абсолютно минимальный стек может включать AWS, GitHub, CloudFlare и Datadog (для начала). Тем командам, которые не могут позволить себе SSO, доступом к этим сервисам приходится управлять вручную, а это трудоёмкая задача. Всякий раз, когда кто-то увольняется, либо в организации появляется новый сотрудник, кому-то придётся зайти на все эти платформы и самостоятельно добавить или удалить конкретного члена организации. При работе с TF можно централизовать управление пользователями и их учётными данными, поэтому вся работа становится гораздо проще (и надёжнее).
AWS предлагает своим пользователям сервис IAM Identity Center (ранее AWS SSO), упрощающий управление аккаунтом AWS и связанными с ним ролями. Но если организация пока не вскочила в вагон SSO или пользуется набором разных сервисов, часть из которых поддерживает SSO, а часть — нет, именно при помощи TF можно стандартизировать добавление и удаление аккаунтов, причём, независимо от вендора. Сервис TF Root Modules позволяет определять пользователей и роли в файле team.yaml, автоматически создавать эти сущности и управлять ими сразу на всех платформах, которыми вы пользуетесь.
Вот отрывок из файла team.yaml, описывающего гипотетическую команду DevOps:
devops_team:
name: DevOps
description: Internal DevOps Team
privacy: closed
members:
- name: Jane Doe
gh_username: JaneyDoe100
email: doe@abccorp.com
gh_role: maintainer
datadog_role: Standard
- name: John Smith
gh_username: CloudWizard1212
email: smith@abccorp.com
gh_role: member
datadog_role: Read-Only
- name: Finn Mertens
gh_username: IceKing99
email: mertens@abccorp.com
gh_role: member
datadog_role: Standard
В этом центральном файле можно управлять информацией о нашей команде как кодом. Тогда добавить новый сервис или аккаунт можно будет не в N кликов, а просто обновив этот файл. Затем можно прочитать этот файл и развернуть данную команду на всех сервисах, использующих TF. В следующем примере обновим GitHub и Datadog:
locals {
# Решили выразить эту информацию в виде YAML-файла, который будем загружать вместо переменной,
# так, чтобы другие члены команды могли без труда добавлять / редактировать / удалять записи,
# даже не зная TF
team_data = yamldecode(file("${path.root}/team.yaml"))
}
resource "github_team" "devops" {
name = local.team_data.devops_team.name
description = local.team_data.devops_team.description
privacy = local.team_data.devops_team.privacy
}
resource "github_team_members" "devops_members" {
for_each = { for member in local.team_data.devops_team.members : member.gh_username => member }
team_id = github_team.devops.id
username = each.value.gh_username
role = each.value.gh_role
}
module "datadog_users" {
source = "masterpointio/datadog/users"
version = "X.X.X"
users = [ for member in local.team_data.devops_team.members: {
email = member.email,
name = member.name,
role = [member.datadog_role],
username = member.gh_username
}
]
}
Это простой пример, но на нём должно быть понятно, какие возможности открываются, если управлять пользователями и ролями по технологии IaC. Пользуясь IaC, а не заходя на каждую платформу отдельно, если потребуется добавить в команду новых членов или удалить старых, можно просто изменить единственный файл, а затем всё автоматически обновить, как только в коде будут развёрнуты новые изменения. Кроме того, поскольку все изменения отслеживаются в Git, мы располагаем всей исторической информацией о том, кто внёс изменение, что именно было изменено, когда и почему.
❯ Управление репозиториями Git
Если вы управляете репозиториями с кодом, расположенными в GitHub, GitLab или на других Git-провайдерах, то вполне представляете, какой головной болью это может оборачиваться, в особенности при работе с полирепозиторием. Требуется управлять защитой веток и обеспечивать согласованность в контроле доступа в масштабе всех этих репозиториев? Да, это по-настоящему сложно. Не приходится удивляться, что опять приходится прибегать к технологиям IaC для поддержания согласованных и безопасных конфигураций репозиториев.
Во многих организациях от разработчиков требуется вручную обустраивать репозитории с кодом. В результате от проекта к проекту возникает лоскутное одеяло несогласованных конфигураций и настроек безопасности. Без стандартизации в каждом из репозиториев могут действовать разные правила защиты веток, принципы контроля доступа, а также другие настройки. Из-за этого сложнее обеспечить строгое соблюдение наилучших практик. Выкатывание новой конфигурации превращается в целый проект. В конце концов, вся описанная неоднородность может порождать уязвимости и осложнять управление репозиториями в большом масштабе.
Мы категорически за то, чтобы не изобретать велосипед, особенно, когда в наличии есть такое множество отличных готовых модулей, поддержка которых обеспечивается сообществом. GitHub-репозиторий Terraform — не исключение. Нам нравится модуль, подготовленный нашими товарищами из Mineiros (теперь эта команда поддерживает Terramate): https://github.com/mineiros-io/terraform-github-repository. В этом модуле предлагаются разнообразные возможности, далеко не ограниченные элементарным ресурсом github_repository. В частности, здесь есть приватный репозиторий, ключи развёртывания, предназначенные только для чтения, механизмы управления ветками и защиты веток, стратегии слияния, метаданные и многое другое. Вот упрощённый пример, демонстрирующий, как при помощи этого модуля можно развернуть множество репозиториев:
locals {
repositories = {
backend-api = {
name = "backend-api"
license_template = "apache-2.0"
gitignore_template = "Go"
},
infra = {
name = "infra"
license_template = "mit"
gitignore_template = "Terraform"
}
}
}
module "repositories" {
source = "mineiros-io/repository/github"
version = "0.18.0"
for_each = local.repositories
name = each.value.name
license_template = each.value.license_template
gitignore_template = each.value.gitignore_template
}
❯ Управление мониторингом и алертингом
Ещё одна задача, зачастую вызывающая сложности у разработчиков — вручную настраивать конфигурации мониторинга и алертинга. Неудивительно, что здесь может получиться мешанина несогласованных пороговых значений и настроек, различающихся в разных сервисах и стеках. Если не стандартизировать эту работу, то в схожих экземплярах развёрнутого приложения могут отличаться критерии для выдачи алерта. Опять же, из-за этого сложно обеспечить согласованное следование наилучшим практикам. Из-за такой несогласованности какие-то оповещения могут не поступать, а другие получаться зашумленными. Поэтому бывает сложно управлять мониторингом в большом масштабе.
Но есть выход получше! Выражая в коде пороги ваших метрик и конфигурации алертов, можно добиться, чтобы все команды совместно работали в общем контексте. Разработчику становится проще добавить новый алерт либо поправить имеющийся, который уже всех свёл с ума своими ложноположительными срабатываниями. Кроме того, управляя таким уровнем интеграции, мы не скатываемся в «ClickOps»: то есть, не приходится развёртывать сложную инфраструктуру через UI, предоставляемые провайдерами. Напротив, можно прямо в коде закладывать как ресурсы приложений, так и конфигурации для их мониторинга, а также версионировать их вместе.
Мы — большие фанаты библиотеки Cloud Posse Module, к счастью, мы являемся её контрибьюторами и участвуем в поддержке. В ней есть два отличных модуля, ориентированных именно на этот юзкейс: terraform-datadog-platform и terraform-aws-datadog-integration. При помощи интеграционного модуля удобно активировать исходную интеграцию между интересующими нас аккаунтами AWS и аккаунтом Datadog, а также платформенный модуль, помогающий сконфигурировать разнообразные ресурсы Datadog, в том числе:
Вот пример конфигурации монитора, которую мы используем при работе со многими клиентами:
rds-cpuutilization:
enabled: true
name: "[${environment}] (RDS) CPU utilization is high"
query: |
avg(last_15m):avg:aws.rds.cpuutilization{env:${environment}} by {dbinstanceidentifier} > 90
type: metric alert
message: |
{{#is_warning}}
{{dbinstanceidentifier}} CPU Utilization above {{warn_threshold}}%
{{/is_warning}}
{{#is_alert}}
{{dbinstanceidentifier}} CPU Utilization above {{threshold}}%
{{/is_alert}}
escalation_message: ""
tags: ${tags}
priority: 3
notify_no_data: false
notify_audit: false
require_full_window: true
enable_logs_sample: false
force_delete: true
include_tags: true
locked: false
renotify_interval: 60
timeout_h: 0
evaluation_delay: 60
new_group_delay: 0
new_host_delay: 300
groupby_simple_monitor: false
renotify_occurrences: 0
renotify_statuses: []
validate: true
no_data_timeframe: 10
threshold_windows: {}
thresholds:
critical: 90
warning: 85
Если программировать мониторинг таким образом, то не только улучшается общая согласованность всех SRE-операций, но и удаётся существенно сократить количество итераций при разработке и ускорить доставку приложений в продакшен.
❯ Заключение
Программирование инфраструктуры (IaC) — мощный подход, значительно упрощающий управление софтверной архитектурой. К сожалению, во многих инженерных организациях с IaC не дорабатывают. Не поймите нас неправильно: уже большой шаг вперёд, если IaC в вашей организации применяется для развёртывания инфраструктуры приложений, в частности, контейнеров и баз данных. Но, пренебрегая этой техникой при мониторинге и управлении репозиториями, вы недополучаете массу пользы, которую она могла бы принести. Вот почему мы работаем с TF: так можно выразить в коде гораздо больше, нежели только конфигурацию вычислительных ресурсов и хранилищ.
Для перехода к полностью автоматизированной инфраструктуре нужна серьёзная самоотдача всей команды, но польза от этого очевидна. Используя IaC на полную мощность, можно создавать боле надёжные и эффективные платформы, которые очень пригодятся вам при масштабировании ваших приложений и всей организации.
Читайте также:
Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале ↩