Наш DevOps отдел, как одно из ключевых звеньев в разработке и выпуске приложений, развивается очень бурно и стремительно. Причем, как качественно, так и количественно. Достаточно сложно представить, чтобы хоть какой-то из процессов DevOps не был автоматизирован. А особенно моделирование и развертывание инфраструктуры.
Infrastructure as a Code — одно из логичных направлений DevOps, позволяющее описывать, моделировать и изменять инфраструктуру в формате кода с применением многолетних практик разработки приложений. А еще оно помогает упростить масштабирование и контроль инфраструктуры в целом, а также сократить цикл развертывания и доставки приложения пользователю.
А теперь — ближе к делу. Одним из мощнейших инструментов моделирования и развертывания инфраструктуры является Terraform, разработанный компанией HashiCorp.
Что это?
Terraform — инструмент, позволяющий разрабатывать, изменять и версионировать инфраструктуру вашего сервиса в формате кода. Инфраструктура описывается в конфигурационных файлах и может применяться, как к работающей системе, так и к совершенно новой.
По своему формату, разработка terraform конфигурации напоминает описание инфраструктурных компонентов, необходимых для работы вашего приложения.
В целом формат описания инфраструктуры достаточно декларативен. Для него используется специально разработанный язык программирования HashiCorp Configuration Language (HCL). Но, можно использовать и просто JSON.
Применение на практике
Давайте взглянем на несколько примеров. В первом мы создадим AWS VPC с подсетью. Для это нам придется воспользоваться документацией AWS. Она поможет понять все нюансы настройки.
Итак, создаем директорию “infrastructure” и описываем все необходимые для развертывания конфиги. Так как terraform выгружает все файлы c .tf расширением из директории, мы можем сразу разделять код по отдельным конфигам-модулям для простоты поиска и изменения отдельных частей инфраструктуры.
Далее описываем провайдера. В нашем случае это AWS.
Обратите внимание, что `${}` используется для интерполяции. Этот способ позволяет указать, какие значения мы вводим самостоятельно.
Далее необходимо описать сам VPC resource используя следующую конструкцию.
Единственным обязательным параметром для создания VPC является CIDR блок.
Сейчас мы хотим предоставить доступ в интернет всем ресурсам, расположенным внутри нашей VPC. Для этого нам необходимо создать Internet gateway и подключить его к нашему VPC.
Далее мы опишем подсеть и свяжем ее с VPC. Давайте предположим, что в нашем VPC будет всего одна подсеть, покрывающая весь доступный пул адресов.
Обратите внимание на директиву/переменную `output` (мы ее не описывали). Благодаря ней, у нас появляется возможность указать, какие данные должен запомнить Terraform и вернуть пользователю после выполнения.
Теперь, когда у нас есть подсеть, остается лишь описать несколько завершающих шагов. AWS автоматически ассоциирует подсеть с Main RouteTable, которая создается для каждой VPC. Но для того чтобы иметь полный контроль над исходящим трафиком, давайте создадим для подсети собственную RouteTable.
Бинго! А сейчас мы заставим подсеть работать. Для этого надо явно описать ассоциацию c RouteTable.
Итак, мы описали всю инфраструктуру VPC и подсети. Давайте теперь посмотрим на все созданные в директории файлы и запустим планирование. Планирование — операция, позволяющая нам увидеть, что будет происходить в процессе “apply”. По сути, это симуляция развертывания реальной инфраструктуры.
Отлично, terraform составил план, согласно описанной конфигурации. По этому плану он создаст на нашем AWS аккаунте в eu-west-2 (London) регионе 5 ресурсов:
- VPC
- Gateway
- Subnet
- Route Table
- Route Table Association
Пока все идет хорошо. Давайте попробуем выполнить операцию “apply”, предназначенную для реального развертывания инфраструктуры на AWS.
Ура, работает! Вы также могли заметить, что в завершении операции terraform вывел в “output ID” подсети (запомним его для проверки), как мы это и описывали. Давайте теперь убедимся, что все описанное действительно было создано.
Идем на AWS и смотрим: появилась ли в у нас новая Virtual Private Cloud с именем VPC.
Смотрим на Internet Gateway, связанный с нашим VPC.
Да, он на месте. Теперь взглянем на подсети. Помните Subnet ID, который мы получили в “output” после “apply”. Вот он: `subnet-62e4a219`? Ищем его!
Отлично! Наконец, убедимся, что ассоциация подсети с личной Route Table прошла успешно. Найдем Route Table по его ID, указанному в созданной Subnet.
Вывод
Как видите, сам процесс описания ресурсов очень прост и понятен даже не знакомому с синтаксисом HCL человеку. Сам Terraform, как и любой инструмент, обладает рядом преимуществ и недостатков.
Явные преимущества состоят в следующих пунктах:
- Очень грамотная и качественная документация, отвечающая практически на любые вопросы инженера.
- Декларативность и понятность синтаксиса конфигурации.
- Возможность работы, как с популярными провайдерами вроде AWS так и с “Ad Hoc решениям”.
- Управление состоянием. Terraform автоматически определяет, какая часть вашей конфигурации уже развернута, какую следует удалить, а какую — добавить.
- Open Source и очень активное коммьюнити. Оно помогает инструменту стремительно развиваться и соответствовать всем требования рынка.
- Иммутабельность.
Выделить минусы не так просто. На наш взгляд, они крутятся вокруг statefil`a:
- Иммутабельность. Да, она уже была. Но это не только преимущество, но и недостаток. В чем сложность работы одной команды над одними и теми же конфигами? В том, что разные люди могут с легкостью перезаписать “statefile”, используемый Terraform’ом при “plan” и “apply” операциях. А это может привести к непредвиденным последствиям.
- Terraform хранит statefile в обыкновенном текстовом формате. Это может стать проблемой при использовании систем контроля версий. Если кто-то его повредит во время merg`a или любой другой операции, вам (вероятно) предстоит разворачивать всю инфраструктуру заново.