# HCL: язык, на котором пишут Terraform _Основы Terraform · TerraformLab Knowledge Base_ **TL;DR:** HCL (HashiCorp Configuration Language): это язык, на котором описывают желаемое состояние инфраструктуры. Похож на JSON, но людям читать легче: можно писать комментарии, переменные, циклы. ## Что такое HCL HCL расшифровывается как **HashiCorp Configuration Language**, язык, придуманный компанией HashiCorp специально для описания инфраструктуры. На нём вы пишете «я хочу один S3-бакет с такими-то тегами и один EC2-инстанс рядом», а Terraform превращает это в API-вызовы к облаку. HCL не язык программирования в полном смысле. Это **декларативный** язык: вы описываете желаемое состояние, а не последовательность шагов. В этом главное отличие от Python или bash. ## Из чего состоит файл .tf HCL-файл, это набор **блоков**. Каждый блок описывает одну сущность: ресурс, переменную, провайдер, output. Базовая структура блока: ```hcl тип_блока "первая_метка" "вторая_метка" { аргумент_один = "значение" аргумент_два = 42 вложенный_блок { под_аргумент = true } } ``` Конкретный пример, описание S3-бакета: ```hcl resource "aws_s3_bucket" "demo" { bucket = "my-unique-name-12345" tags = { Owner = "student" Project = "terraform-hello" } } ``` Здесь: - `resource`, тип блока (мы создаём ресурс). - `"aws_s3_bucket"`, первая метка, говорит **что именно** за ресурс. - `"demo"`, вторая метка, наше внутреннее имя для этого бакета. Внутри файла его можно звать `aws_s3_bucket.demo`. - `bucket`, `tags`, аргументы блока. ## Типы блоков, которые встречаются чаще всего - `resource`, создать что-то в облаке (бакет, виртуалку, базу). - `data`, прочитать что-то из облака (узнать ID существующей подсети). См. [tf-resource-block](/terraform/kb/tf-resource-block.md) и [tf-data-source](/terraform/kb/tf-data-source.md) позже. - `variable`, входной параметр конфигурации (имя бакета снаружи). - `output`, что вернуть наружу (ID созданного бакета). - `provider`, какой провайдер используется и с какими настройками (AWS, GCP, Azure). - `terraform`, мета-блок с настройками самого Terraform: какие версии провайдеров, где хранить state. - `locals`, вычисляемые внутренние значения. - `module`, подключить переиспользуемый модуль (в beginner-треке не используется). ## Выражения и интерполяция Значения в HCL не обязательно строки. Можно ссылаться на другие ресурсы, вызывать функции, считать арифметику: ```hcl resource "aws_s3_bucket" "logs" { bucket = "${aws_s3_bucket.demo.bucket}-logs" # читай так: «возьми атрибут bucket у ресурса aws_s3_bucket.demo и добавь -logs» } output "bucket_count" { value = length(aws_s3_bucket.demo.tags) # length, встроенная функция, считает элементы списка/map } ``` Конструкция `${...}` называется **interpolation**, подстановка. В современном HCL её часто можно опускать, если выражение. Это единственное содержимое строки: `bucket = aws_s3_bucket.demo.id` работает так же, как `bucket = "${aws_s3_bucket.demo.id}"`. ## Комментарии В HCL три способа закомментировать: ```hcl # однострочный (самый частый) // тоже однострочный (наследие C-стиля) /* многострочный блок-комментарий */ ``` Используйте `#`, это конвенция HashiCorp. ## Чем HCL отличается от JSON JSON тоже валидный формат для Terraform, называется JSON syntax (`.tf.json`). Но в реальной работе никто его не пишет руками. Причины: - В HCL можно писать комментарии. В JSON, нельзя. - В HCL не нужны кавычки вокруг ключей и запятые в конце списков. - В HCL читаемые многострочные строки через `heredoc` (`<