Terraform — это инструмент для управления инфраструктурой как кодом (англ. Infrastructure as Code, сокр. IaC). В основном Terraform используется для работы с облачными провайдерами, такими как Amazon Web Services, Microsoft Azure, Google Cloud Platform, Oracle Cloud, но также присутствует поддержка Active Directory, Docker, VMware vSphere.
Terraform предназначен для декларативного управления, то есть вам не нужно создавать ресурсы вручную, например в веб-интерфейсе. Достаточно заранее описать в конфигурационном файле то, как будет выглядеть инфраструктура, и запустить готовую конфигурацию.
В конфигурационных файлах Terraform используется собственный язык разметки — HashiCorp Configuration Language (HCL). Взаимодействие с провайдером происходит при помощи API.
Установка Terraform
Terraform представляет собой кросс-платформенное программное обеспечение, которое можно установить на ОС Windows, Linux и macOS, в том числе через сборку из исходного кода. Инструкции и способы установки перечислены на официальном сайте HashiCorp. Устанавливать инструмент будем на ОС Ubuntu 22.04.2 в редакции LTS. Для этого воспользуемся официальным репозиторием от разработчиков Terraform.
- Обновляем списки пакетов, далее устанавливаем gnupg и software-properties-common, которые необходимы для дальнейшей работы с репозиторием HashiCorp:
sudo apt update && sudo apt -y install gnupg software-properties-common
- Устанавливаем официальный GPG-ключ для репозитория HashiCorp:
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
- Проверяем отпечаток ключа:
gpg --no-default-keyring
--keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg
--fingerprint
- Добавляем официальный репозиторий HashiCorp. Команда lsb_release -cs автоматически опознает используемый дистрибутив ОС и подберет необходимый репозиторий:
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg]
https://apt.releases.hashicorp.com $(lsb_release -cs) main" |
sudo tee /etc/apt/sources.list.d/hashicorp.list
- Обновляем списки пакетов и устанавливаем Terraform:
sudo apt update && sudo apt -y install terraform
- Убедимся, что Terraform корректно установился, введя команду для вывода доступных параметров утилиты terraform:
terraform -help
На этом установка успешно завершена.
Создаем конфигурацию для Docker-контейнера c ОС Ubuntu
Далее напишем конфигурацию, с помощью которой будем создавать объекты в уже установленный на хосте Docker, не прибегая непосредственно к утилите docker.
- Создаем директорию с именем terraform-docker, в которой будет храниться конфигурация контейнера, и переходим в нее:
mkdir terraform-docker && cd terraform-docker
- Создаем файл с именем main.tf — в нем будет располагаться вся необходимая конфигурация. Для начала создадим контейнер с ОС Ubuntu, взяв за основу одноименный образ. Конфигурация будет следующей:
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
}
}
provider "docker" {
host = "unix:///var/run/docker.sock"
}
# Pulls the image
resource "docker_image" "ubuntu" {
name = "ubuntu:latest"
}
# Create a container
resource "docker_container" "ubuntu-test" {
image = docker_image.ubuntu.image_id
name = "ubuntu-test"
must_run = true
command = [ "tail",
"-f",
"/dev/null"
}
}
Теперь чуть подробнее опишу директивы и параметры, которые использую в этом конфигурационном файле.
required_providers задает наименование провайдера (конечной системы), с которой мы будем взаимодействовать. В нашем случае это Docker.
host = “unix:///var/run/docker.sock” указывает полный путь до сокета Docker. Если он запущен на Windows, то необходимо прописать IP-адрес сервера, где установлен Docker Desktop, и стандартный порт для его удаленных подключений — 2375.
resource “docker_image” “ubuntu” задается тип объекта — образ Docker с названием ubuntu.
name = “ubuntu:latest” задается имя образа — ubuntu с тегом latest.
resource “docker_container” “ubuntu-test” создает контейнер с именем ubuntu-test, внутри которого будет запущена команда tailf -f /dev/null. Опция must_run = true означает, что контейнер будет продолжать работать в фоновом режиме.
Сохраняем файл и выходим из него.
Далее инициализируем директорию:
terraform init
Проверяем конфигурационный файл на наличие ошибок:
terraform validate
Если в файле будет ошибка, то вы увидите ее описание и номер строки. Если же ошибок нет, то отобразится фраза Success! The configuration is valid.
Далее необходимо вывести план действий для ресурсов, которые будут созданы с помощью конфигурационного файла:
terraform plan
Как можно увидеть, будет создан Docker-контейнер с именем ubuntu-test из образа ubuntu с тегом latest.
Для создания ранее описанного объекта необходимо выполнить команду:
terraform apply
Далее вы увидите следующий запрос на разрешение создать контейнер:
Необходимо ввести yes и нажать на клавишу Enter. После этого будет создан контейнер:
Убедимся, что контейнер с именем foo действительно был создан. Выведем список работающих контейнеров Docker:
docker ps
Контейнер был успешно создан и запущен. Войдем внутрь оболочки bash:
docker exec -it ubuntu-test /bin/bash
И выведем основную информацию об используемом дистрибутиве:
cat /etc/os*
Создаем конфигурацию для Docker-контейнера с сервером Nginx
Развернем еще один контейнер, но теперь воспользуемся образом веб-сервера Nginx. Чтобы к веб-серверу был сетевой доступ, необходимо пробросить порт 8080. Для каждого нового объекта необходимо создавать новую директорию и новый конфигурационный файл.
- Создаем директорию с именем terraform-nginx и переходим в нее:
mkdir terraform-nginx && cd terraform-nginx
- Создаем файл main.tf со следующей конфигурацией:
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
}
}
provider "docker" {
host = "unix:///var/run/docker.sock"
}
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = "nginx-test"
ports {
internal = 80
external = 8000
}
}
Среди новых параметров добавились internal и external в блоке ports, внешний и внутренний порт службы.
Сохраняем файл и выходим из него.
Теперь нужно проверить файл и создать объект.
- Инициализируем нашу директорию:
terraform init
- Проверяем конфигурационный файл на наличие ошибок:
terraform validate
- Для создания ранее описанного объекта необходимо выполнить команду:
terraform apply
Проверяем, действительно ли контейнер с nginx был создан и запущен:
docker ps
И убедимся, что nginx работает, отправив запрос на порт 8080:
curl -i 0.0.0.0:8000
Создаем прочие объекты Docker при помощи конфигурации Terraform
Помимо создания контейнеров, при помощи Terraform можно создавать такие объекты Docker, как сети, секреты и тома.
В отдельной новой директории создаем конфигурационный файл main.tf со следующим содержимым:
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
}
}
provider "docker" {
host = "unix:///var/run/docker.sock"
}
resource "docker_network" "private_network" {
name = "new_network"
}
resource "docker_secret" "secret1" {
name = " secret1"
data = base64encode("{"secret1": "s3cr3t"}")
}
resource "docker_volume" "shared_volume" {
name = "shared_volume"
}
Для каждого объекта (сеть, секрет, том) предоставляется свой блок.
В качестве сетевого драйвера будет создана сеть типа bridge с именем new_network.
В качестве секрета будет создан секрет с именем secret1, в котором будет закодировано (base64) слово secret1.
В качестве тома будет создан том с именем shared_volume.
Для запуска конфигурации используем те же команды, что и раньше:
terraform init
terraform validate
terraform apply
Убедимся, что объекты были успешно созданы:
docker network ls
docker volume ls
Подводя итог, можно сказать, что Terraform используется не только для работы с облачными провайдерами, но также и с локальными системами, такими как Docker. Простая конфигурация позволяет автоматизировать рутинные действия, что сэкономит немало времени.