# data-блок: читаем то, что уже есть в облаке _Ресурсы и data-источники · TerraformLab Knowledge Base_ **TL;DR:** data, это блок, который запрашивает существующую инфру и отдаёт её атрибуты в HCL. Terraform ничего не создаёт; он только читает. Используется чтобы привязаться к ресурсам, которые сделаны не Terraform'ом или живут в другом проекте. ## Зачем нужен data `resource` создаёт что-то новое. `data` читает что-то существующее. Разница, фундаментальная: - `resource "aws_s3_bucket" "demo" { ... }` → Terraform отвечает за этот бакет. Создаёт, изменяет, удаляет. - `data "aws_caller_identity" "current" {}` → Terraform просто спрашивает у AWS «кто я сейчас?» и кладёт ответ в переменную. Никакого state-управления. Data-блоки нужны когда: - В вашем коде надо знать текущий AWS account ID, а его как-то надо получить. - VPC создали другой командой, а вам нужен его ID для нового ресурса. - Хотите выбрать самую свежую Ubuntu AMI без хардкодинга. ## Синтаксис Похож на resource, но с ключевым словом `data`: ```hcl data "aws_caller_identity" "current" {} data "aws_region" "current" {} output "my_account_id" { value = data.aws_caller_identity.current.account_id } output "my_region" { value = data.aws_region.current.name } ``` Адрес: `data.тип.имя.атрибут`. Префикс `data.`, обязателен, иначе Terraform решит что это resource. ## Типичные data-источники AWS Самые частые в реальной работе: ```hcl # Кто я сейчас (account ID, ARN, user ID) data "aws_caller_identity" "current" {} # В каком регионе работаем data "aws_region" "current" {} # Список AZ в этом регионе data "aws_availability_zones" "available" { state = "available" } # Найти конкретную AMI data "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] # Canonical filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] } } # Использовать resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" } ``` ## Когда data, а когда resource Правило: **если этим объектом управляете вы (создаёте/уничтожаете). `resource`. Если это «дано извне», `data`.** Признаки что нужен `data`: - Объект уже существует, и не вы его создавали. - Объектом управляет другая команда или другой Terraform-проект. - Это вспомогательная информация (account ID, регион, latest AMI). ## data в LocalStack Не все AWS data-источники работают в LocalStack одинаково: - **Работают хорошо:** `aws_caller_identity`, `aws_region`, `aws_availability_zones` (возвращают захардкоженные значения для тестов). - **Работают частично:** `aws_ami` (возвращает пустой список. AMI'ев в LocalStack нет). - **Не работают:** что-то завязанное на реальные AWS-сервисы которые LocalStack community не эмулирует. В учебных задачах используйте только надёжные data-источники. ## Подводные камни - **data блок ничего не блокирует от изменения.** Если вы читаете `data "aws_s3_bucket" "shared"` и кто-то снаружи удалит этот бакет, следующий `plan` ругнётся, но данные с прошлого `apply` всё ещё могут быть в state. Это рассинхронизация. - **data выполняется на каждом plan/apply.** Каждый запуск он ходит в API. Если у вас 50 data-блоков с медленными запросами, plan будет медленным. - **`(known after apply)` бывает и у data.** Если data-блок зависит от ресурса, который ещё не создан, его атрибуты будут «известны после apply». Это создаёт цепочку: создать resource → дёрнуть data → использовать атрибут → создать следующий resource. - **Не используйте data для проверки «существует ли».** Если data-блок не нашёл объект, он упадёт с ошибкой. Это не способ сделать `if exists then ... else ...`. Для условной логики есть `try()` и `can()` функции. - **data не имеет lifecycle.** Блок `lifecycle { ... }` в data не работает, нечем управлять. ## Команды ```bash terraform plan ``` При plan все data-источники опрашиваются, прежде чем считать diff. Поэтому plan тоже бьёт по API. ```bash terraform refresh ``` Принудительно перечитать state с реальными значениями из облака: включая data. ```bash terraform console ``` Интерактивно проверить значение data в expressions. Удобно для отладки сложных filter'ов. ## См. также - [Блок resource: главный кирпич Terraform](/terraform/kb/tf-resource-block.md) - [Ссылки в HCL: как читать aws_s3_bucket.demo.bucket](/terraform/kb/tf-references.md) - [AWS Provider: настройки и где Terraform берёт ключи](/terraform/kb/aws-provider.md)