Инфраструктура как код (IaC), Terraform, основные концепции, руководство для начинающих IaC - процесс управления и подготовки всей ИТ-инфраструктуры с использованием машиночитаемых файлов-определений
Terraform - один из самых популярных инструментов для разработки инфраструктуры как кода (IaC)
Используется командами DevOps для автоматизации инфраструктурных задач Terraform - инструмент подготовки с открытым исходным кодом, разработанный HashiCorp и написанный на языке GO
Использует простой для понимания язык HCL (язык конфигурации HashiCorp)
Жизненный цикл Terraform состоит из:
1. Инициализация - инициализирует (локальную) среду Terraform
2. Планирование - сравнивает состояние, создает и отображает план выполнения. Не меняет развертывание.
3. Применение - выполняет план. Это потенциально меняет развертывание.
4. Уничтожение - удаляет все ресурсы, которые управляются этой конкретной средой terraform.
Провайдер несет ответственность за понимание взаимодействия с API и предоставление ресурсов.
Это исполняемый плагин, который содержит код, необходимый для взаимодействия с API сервиса.
В конфигурациях Terraform должно быть указано, какие поставщики требуются Terraform для устанавки и использования.
У Terraform более сотни поставщиков различных технологий.
Каждый поставщик затем предоставляет пользователю terraform доступ к своим ресурсам.
Например, через провайдера AWS есть доступ к сотням ресурсов AWS, таких как инстансы EC2, пользователи AWS и т.д.
Файлы конфигурации Terraform:
1. Файл конфигурации (файлы *.tf):
- Здесь указываем поставщика и ресурсы, которые будут развернуты, тип ресурса и настройки, относящиеся к ресурсам.
2. Файл объявления переменных (variables.tf или variables.tf.json):
- Здесь объявляем входные переменные, необходимые для предоставления ресурсов
3. Файлы определения переменных (terraform.tfvars):
- Здесь мы присваиваем значения входным переменным
4. Файл состояния (terraform.tfstate):
- файл состояния создается один раз после запуска Terraform. В нем хранится информация о управляемой инфраструктуре.
У провайдеров (плагинов) terraform, все методы делятся на два класса:
- resource - для создания ресурса и (или) объекта
- data_source - для получения данных о ресурсе (объекте) не изменяемом в рамках данной конфигурации.
Установка Terraform на Linux
Ubuntu/Debian:
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
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
sudo apt update && sudo apt install terraform
... E: The repository 'https://apt.releases.hashicorp.com jammy Release' does not have a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details.
... Вариант 2:
sudo snap install terraform --classic
terraform -version
Поддержка завершения табуляции для всех имен команд и некоторых аргументов команд:
terraform -install-autocomplete
Начало работы с Terraform
Общие шаги по развертыванию ресурса(ов) в облаке следующие:
- Настройте облачную учетную запись у любого облачного провайдера (AWS, Azure, OCI)
- Установите Terraform
- Добавьте поставщика – AWS, Azure, OCI, GCP или другие
- Написание конфигурационных файлов
- Инициализация поставщиков терраформирования
- ПЛАНИРОВАНИЕ (ПРОБНЫЙ ЗАПУСК) с использованием terraform plan
- ПРИМЕНИТЬ (создать ресурс) с помощью terraform apply
- УНИЧТОЖИТЬ (удалить ресурс) с помощью terraform destroy
Импортируйте существующую инфраструктуру
Если вы уже создали свою инфраструктуру вручную, в Terraform есть функция импорта существующих ресурсов
В настоящее время Terraform может импортировать ресурсы только в состояние.
Он не создает для них конфигурацию.
Перед запуском импорта необходимо вручную написать блок конфигурации ресурса, которому будет сопоставлен импортируемый объект. Например:
resource "aws_instance" "import_example" {
# ...instance configuration...
}
Теперь можно запустить импорт terraform, чтобы прикрепить существующий экземпляр к этой конфигурации ресурса:
$ terraform import aws_instance.import_example i-hgrt34f32cws
Эта команда:
- находит экземпляр AWS с идентификатором i-hgrt34f32cws (который был создан вне Terraform)
- присоединяет его к имени aws_instance.import_example в состоянии Terraform.
Чтобы просмотреть список команд, выполните команду terraform без дополнительных аргументов:
Usage: terraform [global options] <subcommand> [args]
Main commands: init Prepare your working directory for other commands validate Check whether the configuration is valid plan Show changes required by the current configuration apply Create or update infrastructure destroy Destroy previously-created infrastructure
All other commands: console Try Terraform expressions at an interactive command prompt fmt Reformat your configuration in the standard style force-unlock Release a stuck lock on the current workspace get Install or upgrade remote Terraform modules graph Generate a Graphviz graph of the steps in an operation import Associate existing infrastructure with a Terraform resource login Obtain and save credentials for a remote host logout Remove locally-stored credentials for a remote host metadata Metadata related commands output Show output values from your root module providers Show the providers required for this configuration refresh Update the state to match remote systems show Show the current state or a saved plan state Advanced state management taint Mark a resource instance as not fully functional untaint Remove the 'tainted' state from a resource instance version Show the current Terraform version workspace Workspace management
Global options (use these before the subcommand, if any): -chdir=DIR Switch to a different working directory before executing the given subcommand. -help Show this help output, or the help for a specified subcommand. -version An alias for the "version" subcommand.
Чтобы получить конкретную справку по любой конкретной команде, используйте -help опцию с соответствующей подкомандой.
Например, чтобы просмотреть справку о подкоманде "validate", вы можете запустить terraform validate -help.
Опция chdir предписывает Terraform изменить свой рабочий каталог на указанный каталог перед запуском данной подкоманды.
Это означает, что любые файлы будут считаны или записаны в указанный каталог.
Переключение рабочего каталога:
terraform -chdir=environments/production apply
Автоматизируйте настройки репозитория Gitlab с помощью Terraform
Создайте в Gitlab - User Settings - Access Tokens
Экспортируйте свой Gitlab PAT (токен частного доступа) через командную строку, установив переменную окружения:
export TF_VAR_gitlab_token=YOURTOKEN
Чтоб избежать раскрытия конфиденциальной информации - поместите ее в свой файл .bashrc/.zshrc
Затем эта переменная окружения будет доступна в HCL (собственном языке программирования Terraform) через var.gitlab_token
Убедитесь, что вы предоставляете как минимум разрешения repo_read, repo_write для PAT
или если под рутом /root/.terraformrc:
provider_installation {
network_mirror {
url = "https://terraform-mirror.yandexcloud.net/"
include = ["registry.terraform.io/*/*"]
}
direct {
exclude = ["registry.terraform.io/*/*"]
}
}
Теперь мы можем добавить Gitlab provider, чтобы Terraform могла взаимодействовать с Gitlab
Инициализируйте каталог terraform, который загрузит необходимый код для взаимодействия с Gitlab API в каталог .terraform:
terraform init
Соберем информацию по списку репозиториев (my_group_name - замените на имя своей группы у репозиториев)
В примере мы узнаем инфу по репозиториям, содержащим в названии слова nginx и backup resources.tf:
data "gitlab_group" "group" {
full_path = "my_group_name"
}
data "gitlab_projects" "nginx_projects" {
group_id = data.gitlab_group.group.id
order_by = "name"
include_subgroups = true
search = "nginx" # filter out repos containing the word 'nginx'
}
data "gitlab_projects" "backup_projects" {
group_id = data.gitlab_group.group.id
order_by = "name"
include_subgroups = true
search = "backup" # filter out repos containing the word 'backup'
}
Файл для переменных variables.tf:
variable "gitlab_token" {}
А это - вывод в консоль output.tf:
output "nginx_repo_id_name" {
description = "ID and NAME of the nginx repo"
value = [data.gitlab_projects.nginx_projects.projects.*.id, data.gitlab_projects.nginx_projects.projects.*.name]
}
output "backup_repo_id_name" {
description = "ID and NAME of the backup repo"
value = [data.gitlab_projects.nginx_projects.projects.*.id, data.gitlab_projects.nginx_projects.projects.*.name]
}
Посмотрите план выполнения:
terraform plan
Выполните (создастся состояние в файле terraform.tfstate):
terraform apply
Создание репозитория и добавление публичного ssh ключа для дальнейшего деплоя
create_repo.tf (вместо 11 - поставьте свой id группы, подсмотрите в terraform.tfstate или copy group id на странице группы):
resource "gitlab_project" "test_repo_name" {
name = "test_repo_name"
description = "Test repository created by Terraform"
namespace_id = 11
}
resource "gitlab_deploy_key" "test_repo_name_deploy_key" {
project = gitlab_project.test_repo_name.id
title = "terraform repo ssh public key"
key = "ssh-rsa AAAAB3N..."
}
Выполните:
terraform apply
Пустой реозиторий будет создан, ключ добавлен в настройки репозитория
Еще пример для закрепления
Допустим у нас есть аккаунт в Digital Ocean, мы знаем соответственно токен доступа и залили туда ssh ключи
Как получить по токену доступа к Digital Ocean идентификатор ID от SSH ключей или NAME
export DIGITALOCEAN_ACCESS_TOKEN=YourToken
curl -X GET https://api.digitalocean.com/v2/account/keys -H "Authorization: Bearer $DIGITALOCEAN_ACCESS_TOKEN"
Чтоб избежать раскрытия конфиденциальной информации - поместите ее в свой файл .bashrc/.zshrc
Затем эта переменная окружения будет доступна в HCL (собственном языке программирования Terraform) через var.gitlab_token
YourToken - соответственно подставляете свой, в выводе будут данные по залитым ключам
Допустим, у нас уже залит ключ с именем TEST_SSH_PUB_KEY
С файлом провайдера все постаринке: cat provider.tf