Недавно, на личном опыте столкнулся с тем, что команда не может организовать верхнеуровневую архитектуру для хранения и работы с инфраструктурным кодом.
Сегодня я бы хотел подробнее погрузиться в эту тему, и рассказать о том, как можно уложить инфраструктурные блоки по полочкам, и какие паттерны для этого существуют.
Пост поделен на две части. Сегодня мы поговорим о том, что такое инфраструктурный модуль, а также как этим модули могут выглядеть. В следующей части мы поговорим о том, как организовать работу с инфраструктурными репозиториями.
Поехали!
Модуль — это проект который описывает конфигурацию каких-либо инфраструктурных компонентов и их связи между собой. Деплоится как единое целое.
В данном посте, я намеренно даю такое общее описание модуля, чтобы его можно было рассматривать в отрыве от реализации (Terraform, Pulumi, Cloud SDK).
Monolith Module
Монолитный модуль — Самый простой способ организовать хранения инфраструктуры. Мы просто создаем один проект и внутри него описываем и держим абсолютно всё.
Монолиты имеет смысл сохранять при небольшой команде и при малом количестве инфраструктурных компонентов. Но чаще всего такой монолит разрастается до состояния, в котором новому члену команды нужно несколько дней, чтобы разобраться в его устройстве.
Монолит становится невозможно поддерживать, ведь каждое изменение, может сломать абсолютно всю инфраструктуру, и в этот момент мы теряем контроль над монолитным модулем.
Пример "Монолитного модуля"
Вся инфраструктура описана внутри одного проекта. В нём одновременно описаны вычислительные ресурсы, сети, хранилища, доступы и приложения. Всё хранится в одном или нескольких файлах. Нет разделения на логические блоки. Любое изменение требует работы с целым проектом.
infra/
├── database.yaml
├── main.yaml
└── vpc.yaml
Application Group Module
Application Group Module — Способ организации кода, когда инфра для всех сервисов команды помещается в один общий модуль.
Если ваше приложение состоит из нескольких микросервисов, и вы управляете их инфраструктурой с помощью одного модуля — у вас Application Group Module.
Если ваша команда разрабатывает несколько приложений, и вы управляете ими как одним целым — у вас Application Group Module.
Иметь Application Group Module привлекательно, потому что позволяет думать, обо всем приложении как о чем-то цельном, плюс, хорошо работает, если вся инфраструктура для приложения находиться в управлении одной команды.
Также, может быть хорошим промежуточным состоянием при "распиле" Монолитных Модулей.
Пример "Application Group Module"
infra/
├── team-a
│ ├── service-1
│ │ ├── db.yaml
│ │ └── main.yaml
│ ├── service-2
│ │ ├── db.yaml
│ │ └── main.yaml
│ └── service-3
│ ├── db.yaml
│ └── main.yaml
└── team-b
├── service-1
│ ├── db.yaml
│ └── main.yaml
├── service-2
│ ├── db.yaml
│ └── main.yaml
└── service-3
├── db.yaml
└── main.yaml
Application Module
Application Module — Данный способ организации кода, когда один модуль ограничивает одно приложение, или один микросервис.
Все, что нужно одному кокретному микросервису или приложению собрано в один модуль, без внешних зависимостей.
Идеально ложиться на микросервисную архитектуру приложений.
Ровно до тех пор, пока у вас не появится общесервисной шины, или у всех микросервисов как зависимость будет кластер Kubernetes...
Из минусов такого подхода, можно выделить необязательное дублирование кода.
Пример "Application Module"
infra/
├── microservice-1
│ ├── db.yaml
│ └── main.yaml
├── microservice-2
│ ├── db.yaml
│ └── main.yaml
├── microservice-3
│ ├── db.yaml
│ └── main.yaml
├── microservice-4
│ ├── db.yaml
│ └── main.yaml
└── microservice-5
├── db.yaml
└── main.yaml
Service Module
Service Module — Способ организации кода, когда каждую сервисную часть для нашего приложения мы оборачиваем в отдельным модуль.
Например:
- Отдельный модуль для Базы данных
- Отдельный модуль для Application Server
- Отдельный модуль для сети
- Отдельный модуль для кеша и т.д.
Данный способ показывает самую высокую гибкость из всех возможных способов организации IaC. Дополнительно, ошибки при таком подходе будут влиять только на конкретное приложение.
При этом, из минусов данного подхода — Большое количество модулей привносит сложность само по себе.
Пример "Service Module"
infra/
├── db
│ └── main.yaml
├── ecs
│ └── main.yaml
├── iam
│ └── main.yaml
├── kubernetes
│ └── main.yaml
├── s3
│ └── main.yaml
└── vpc
└── main.yaml
А как инфраструктурный код устроен у вас?
Top comments (0)