![](https://habrastorage.org/getpro/habr/upload_files/ce4/94c/3d1/ce494c3d1fd1c0b3529537d6c4ff234d.png)
Управление распределенной архитектурой требует значительных трудозатрат и финансовых вложений. Для автоматизации этого процесса можно использовать различные самописные скрипты, но лучше воспользоваться готовыми решениями с открытым исходным кодом. Одним из наиболее известных решений для автоматизации управления инфраструктурой является Terraform. Это Open source решение для управления IaC от компании Hashicorp, разработанное в 2014 году. Решение придерживается декларативного стиля управления инфраструктурой, то есть, вы описываете в конфигурационном файле финальное состояние инфраструктуры, а Terraform приводит её к этому состоянию. В качестве примера можно привести автоматическое развертывание пула виртуальных машин, например для проведения обучения работе с каким-либо ПО.
Ручное создание пары десятков виртуалок может занять целый день, а с помощью Terraform это займет менее часа.
Для того, чтобы описание работы с Terraform не было “сферическим конем в вакууме”, мы в качестве наглядного примера, рассмотрим практический пример создания экземпляра EC2 в AWS.
Язык HCL
Для автоматизации работы с инфраструктурой Terraform использует собственный язык написания конфигурационных файлов Hashicorp Configuration Language (HCL). По сути, этот язык описывает желаемое состояние инфраструктуры в конфигурационном файле.
Сначала немного поговорим о синтаксисе языка HCL. Для описания того или иного создаваемого элемента необходимо подготовить блок, содержащий заключенные в фигурных скобках названия переменных, и их значения, передаваемые функциям.
Как и в большинстве языков программирования, в HCL используются аргументы для присвоения значений переменным. В Terraform эти переменные являются атрибутами, связанными с определенным типом блока. Таким образом, весь код HCL состоит из подобных блоков.
Приступим к написанию конфигурационного файла. В первой строке файла мы указываем слово terraform. Хотя этот параметр считается необязательным, настоятельно рекомендуется его указывать. Далее идет открывающая фигурная скобка. Соответственно в последней строке конфигурационного файла должна быть закрывающая скобка.
Например:
terraform {
…
}
А блок кода может иметь следующий вид:
provider “aws” {
region = “us-west-1”
}
А синтаксически правильный, хотя и практически бесполезный вариант всего конфига будет иметь следующий вид:
terraform {
provider “aws” {
region = “us-west-1”
}
}
Вот собственно и все, что нам необходимо знать о синтаксисе HCL. Далее немного поговорим о том, как построено хранение конфигурационных файлов в Terraform.
Хранение файлов
Все конфигурационные файлы Terraform должны размещаться в одном каталоге. Так, для того примера, который мы будем рассматривать далее мы можем создать каталог под названием EC2. По умолчанию Terraform предполагает, что все файлы с .tf*расширениями в данном каталоге являются частью конфигурации, независимо от имен файлов.
Для грамотной организации больших конфигурации потребуются три файла:
variables.tf – для всех объявленных входных переменных.
provider.tf – для объявленных поставщиков, которых вы используете.
main.tf – для объявления фактических ресурсов, которые будут созданы.
Однако, такая структура не является обязательной. Мы можем поместить весь наш код в один файл и все будет корректно работать. В рамках примера из сегодняшней статьи мы будем использовать только main.tf.
Далее перейдем к рассмотрению смысловых составляющих кода, то есть к наполнению файлов кодом.
Простой пример
Итак, напомню, наша задача развернуть экземпляр EC2 в облаке AWS. В рамках этой статьи мы будем разворачивать экземпляр только с базовыми настройками. Для более глубокого погружения у нас будет следующая статья.
Теперь давайте подробнее поговорим о том, как подготовить необходимые конфигурационные данные. Прежде всего, нам необходимо определиться с теми провайдерами, которых мы будем использовать. Поскольку мы собираемся развернуть экземпляр EC2 на AWS, нам нужно объявить необходимых поставщиков:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
В первой строке, напомним, мы открываем блок terraform, который хотя и не является обязательным с точки зрения синтаксиса системы, но рекомендуется его указывать, особенно когда вы создаете инфраструктуру на удаленной системе.
Вложенный блок required providers, определяет требуемых провайдеров. Нам потребуется поставщик aws с указанными параметрами source и version.
Несколько слов о провайдерах и их взаимодействии с Terraform. Для того, чтобы Terraform поддерживал ту или иную технологию, на серверах Terraform должен быть установлен плагин от соответствующего провайдера, содержащий собственный набор конфигураций, типов ресурсов и источников данных. Здесь можно провести некоторые аналогии с библиотеками в языках высокого уровня.
Далее у нас идет описание самого провайдера, аналогичное примеру, представленному в начале статьи. В поле region мы указываем желаемый регион.
provider "aws" {
region = “us-west-1”
}
Значение имеет строковый тип, поэтому оно заключено в пару двойных кавычек ( “” ). Плагин провайдера содержит набор ресурсов, которые мы можем использовать в своей конфигурации. В нашем примере провайдер aws предоставляет ресурс aws_instance, с помощью которого мы создаем экземпляр с именем myec2.
resource “aws_instance” “myec2” {
ami = “ami-00831fc7c1e3ddc60”
instance_type = “t2.micro”
}
Далее нам необходимо заполнить атрибуты, используемые ресурсом aws_instance. Первый атрибут – ami это идентификатор образа машины Amazon для экземпляра EC2. Второй атрибут instance_type - это атрибут, который определяет размер создаваемой машины. В рамках данной статьи мы не будем подробно рассматривать тему значений экземпляров, отметим лишь, что t2.micro является наиболее дешевым вариантом (надеюсь вы помните, что в облаках за каждый запущенный экземпляр виртуалки нужно платить) для экспериментов с облачными решениями.
С базовыми настройками ресурса мы закончили. Но сейчас мы “приколотили” значения жестко, а для полноценного использования Terraform лучше использовать переменные. Давайте их объявим для тех блоков, которые мы уже рассмотрели.
variable "region" {
default = "us-west-1"
description = "AWS Region"
}
variable "ami" {
default = "ami-00831fc7c1e3ddc60"
description = "Amazon Machine Image ID for Ubuntu Server 20.04"
}
variable "type" {
default = "t2.micro"
description = "Size of VM"
}
Мы объявили три переменные region, ami и type. Теперь мы применим значения этих переменных в нашем конфигурационном файле. На значения переменных можно ссылаться с помощью var.<variable name>
.
Но Terraform позволяет не только присваивать значения переменным, но и получать значения, после преобразований, с помощью функции output.
Соберем нашу конфигурацию в виде единого файла main.tf
.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = var.region
}
variable "region" {
default = "us-west-1"
description = "AWS Region"
}
variable "ami" {
default = "ami-00831fc7c1e3ddc60"
description = "Amazon Machine Image ID for Ubuntu Server 20.04"
}
variable "type" {
default = "t2.micro"
description = "Size of VM"
}
resource "aws_instance" "myec2" {
ami = var.ami
instance_type = var.type
tags = {
name = "Demo System"
}
}
output "instance_id" {
instance = aws_instance.demo.id
}
Сохраним данную конфигурацию в файле и перейдем к выполнению команд для работы с Terraform.
Три основные команды
Перед началом применения нашей конфигурации необходимо инициализировать провайдера и установить плагин AWS. Это можно сделать с помощью команды:
terraform init
Результатом успешного выполнения команды является сообщение об успешной инициализации, аналогичное приведенному на рисунке.
![](https://habrastorage.org/getpro/habr/upload_files/509/325/a4b/509325a4b0cb3a9df9d87beda74397ca.png)
После этого нам необходимо произвести валидацию подготовленного ранее конфигурационного файла. За выполнение этой задачи отвечает команда
terraform plan
![](https://habrastorage.org/getpro/habr/upload_files/a07/36c/0c2/a0736c0c22bcc16b63e07e7cab6741d8.png)
В случае, если валидация прошла успешно и никаких ошибок выявлено не было, мы можем применить нашу конфигурацию с помощью команды
terraform apply
Результатом успешного выполнения этой команды будет создание экземпляра EC2 в облаке Amazon.
Заключение
Как видно, работать с кодом в инфраструктуре IaC не слишком сложно. Однако сегодня мы рассмотрели только базовый пример создания экземпляра и многие интересные функции HCL пока остались за кадром.
В следующей статье мы усложним нашу инфраструктуру, наделив нашу создаваемую виртуальную инфраструктуру различными полезными настройками.
Статья подготовлена в преддверии старта курса DevOps практики и инструменты. Узнать подробнее о курсе и зарегистрироваться на бесплатный урок можно по ссылке ниже.