# Terraform --- ## Terraform - Terraform – это инструмент от компании Hashicorp, помогающий декларативно управлять инфраструктурой. - Унифицирует работу с различными облачными и виртуальными платформами - Описание инфраструктуры хранится в конфигурационных .tf файлах - хранение состояния инфраструктуры (state) --- ## HCL - JSON-like синтаксис - Блоки и аргументы - Переменные - Функции - Управляющие конструкции: циклы, условия --- ## С чего начинаем - минимальная структура файлов - main.tf - outputs.tf - variables.tf - terraform.tfvars - terraform init - безопасно для повтора - .gitignore --- ## variables.tf - здесь описываем переменные ```bash variable "region" { description = "GCP - Region" default = "europe-north1" } ``` --- ## terraform.tfvars - здесь описываются значения переменных - для каждого деплоя достаточно меня значения здесь - должен быть в .gitignore --- ## основные команды - terraform init - terraform plan - terraform apply - terraform output - terraform destroy --- ## Провайдеры - провайдер - это плагин который добавляет в терраформ набор ресурсов и источников данных - может использоваться несколько провайдеров одновременно - для конкретного ресурса или модуля можно указывать мета-аругмент `provider` --- ## Провайдеры - может использовать один провайдер под разными алиасами для разных * провайдер без алиаса является конфигурацией по умолчанию для данного провайдера - можно указывать требования по конкретным провайдерам и их версиям * текущая версия и ее патчи * указание минимально разрешенной версии --- ## provider ``` provider "aws" { region = "us-east-1" } provider "aws" { alias = "west" region = "us-west-2" } resource "aws_instance" "example" { provider = aws.west # ... } ``` --- ## ресурсы - основная сущность в терраформе - предоставляется провайдером - часто соответствует ресурсу в облаке - набор аттрибутов определяется провайдером - имеет набор мета-аргументов, которые не зависят от провайдера и определяют управление ресурсом на уровне обработки терраформом --- ## depends_on - список ресурсов и/или модулей от которых зависит текущий ресурс или модуль - указывается если нельзя указать аргумент зависящий от другого ресурса - с модулями работает, начиная с версии 0.13 - [документация](https://www.terraform.io/language/meta-arguments/depends_on) --- ## count - определяет кол-во экземляров ресурса или модуля - позволяет управлять созданием/удалением ресурса - позволяет описывать условия для создания ресурса - описание в стейте терраформа становится списком `module.<NAME>[<INDEX>]` - в ресурсе можно использовать переменную `count.index` - [документация](https://www.terraform.io/language/meta-arguments/count) --- ## пример использования count ```bash variable "create_users" { type = list(string) description = "List of users" } resource "random_password" "password" { count = length(var.create_users) length = 8 special = true override_special = "_%@" } ``` --- ## Пример с условием ```bash count = var.number_of_instances > 0 && var.disk_size > 0 ? var.number_of_instances : 0 name = "my_instance_${count.index}" ``` <!-- .element: style="font-size:40%;padding:0px" --> --- ## for_each - проходит по каждому элементу set или map - для прохода по списку требуется преобразования с помощью toset - работает для ресурса, модуля, динамичского блока - создает переменную each для доступа к элементам списка или словаря - each.key - each.values - описание в стейте терраформа - `<TYPE>.<NAME>[<KEY>]`, где `<KEY>` ключ map или set - [документация](https://www.terraform.io/language/meta-arguments/for_each) --- ## пример с динамическим блоком ```bash resource "helm_release" "redis-k8s" { name = var.name namespace = var.namespace create_namespace = var.create_namespace repository = "https://charts.bitnami.com/bitnami" chart = "redis" version = var.chart_version values = [file("${path.module}/values.yaml"), var.value] dynamic "set" { for_each = var.set content { name = set.key value = set.value } } } ``` --- ## data-sources - каждый провайдер предоставляет источники данных, также как и ресурсы - источник данных через определенные аргументы позволяет получить данные о ресурсах облака - доступ через конструкцию `data` ```bash data "yandex_vpc_network" "network" { name = var.network_name } data "yandex_vpc_subnet" "subnet" { name = var.subnet_name } ``` --- ## Переменные - Input Variables - аргументы для ресурса или модуля - Output Values - значения которые можно достать из ресурса или модуля - Local Values - удобно использовать для промежуточных вычислений --- ## Input Variables - каждая переменная описывается в секции `variable` - часто используется файл variables.tf - используются следующие аргументы для описания переменной - default - type - description - validation - sensitive - nullable - передаваемые значения выставляются через `*.tfvars` файлы --- ## Типы переменных - [документация](https://www.terraform.io/language/expressions/types) - простые - string - number - boolean - структурные - list(`<TYPE>`), list(any) - set(`<TYPE>`), set(any) - map(`<TYPE>`), map(any) - object({`<ATTR NAME>` = `<TYPE>` ... }) - tuple([`<TYPE>`, ...]) --- ## Output Values - обычно прописываются в outputs.tf ```bash output "host" { value = yandex_mdb_postgresql_cluster.cluster.host[0].fqdn description = "The database host." } output "password" { value = { for k, v in random_password.password : var.users[k].name => v.result } description = "The database password." sensitive = true } ``` --- ## Local Values - задаются в секции `locals {}` - обращение производится через префикс `local.<name>` ``` locals { instance_ids = concat(aws_instance.blue.*.id, aws_instance.green.*.id) } locals { private_key_path = "${var.ssh_keys_path}/${var.ssh_user}" } ``` --- ## Locals ```bash locals { values_yaml = { smtp = { host = var.smtp_host port = var.smtp_port login = var.smtp_login externalSecret = { name = var.smtp_secret_name key = var.smtp_secret_key } } service = { port = var.service_port } } } ``` --- ## Locals ```bash resource "helm_release" "postfix" { name = var.name namespace = var.namespace create_namespace = var.create_namespace chart = "${path.module}/../../../helm-charts/charts/postfix" values = [file("${path.module}/values.yaml"), yamlencode(local.values_yaml), var.value] dynamic "set" { for_each = var.set content { name = set.key value = set.value } } } ``` --- ## Provisioner - терраформ предоставляет набор провижинеров для выполнения действий, выходящих за рамки апи ресурсов - file - local-exec - remote-exec - также для многих облаков существует специальный аргумент для запуска стартатовых скриптов - user-data - metadata - возможен запуск нескольких провиженеров - возможен запуск провиженера без ресурса (`null-resource`) - [документация](https://www.terraform.io/language/resources/provisioners/syntax) --- ## State - терраформ сохраняет состояние инфраструктуры - по умолчанию используется локальный файл - проблематично работать командой - можно хранить в гите - могут быть проблемы с параллельной работой - отсутствуют блокировки - --- # Практика --- # Ваши вопросы
{"metaMigratedAt":"2023-06-17T03:04:56.284Z","metaMigratedFrom":"Content","title":"Terraform","breaks":true,"contributors":"[{\"id\":\"3385ceb9-5869-46ee-ac82-51698eb477a8\",\"add\":7894,\"del\":289}]"}
    377 views