Три юзкейса Terraform, к реализации которых вам пора приступать

В тех инженерных организациях, где применяются инструменты для программирования инфраструктуры (IaC), например, Terraform, они обычно используются вполсилы. В этой статье разобрано не менее трёх вариантов использования Terraform и автоматизации в духе IaC, которые не связаны напрямую с традиционной инфраструктурой, отвечающей за управление рабочей нагрузкой приложений.

c53dfa1513a8f2a58e7709f02d1ebfed.jpeg

Мы заметили, что через работу многих команд, занятых администрированием платформ красной нитью проходит явная пробуксовка с освоением философии «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-канале

Перейти ↩

© Habrahabr.ru