lesson ── terraform-beginner ── ~10 мин ── 2 шагов
Не всё, что нужно в Terraform-коде, Terraform создаёт сам. Иногда надо узнать текущий AWS account ID, или прочитать VPC, который настроил другой человек. Для этого есть data-блоки.
data похож на resource, но он ничего не создаёт, только читает.
Никакого state-управления, никаких изменений в облаке. См.
tf-data-source.
интерактивный sandbox
Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.
stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя
Создай main.tf:
data "aws_caller_identity" "current" {}data "aws_region" "current" {}output "my_account" {value = data.aws_caller_identity.current.account_id
}
output "my_region" {value = data.aws_region.current.name
}
Обрати внимание:
data, не resource.aws_caller_identity нет аргументов, пустые {}.data.aws_caller_identity.current.account_id.Запусти:
cd /home/student/tf-data
terraform init -input=false
terraform apply -auto-approve -input=false
В выводе должны появиться твои account ID и регион.
В LocalStack account ID: обычно 000000000000 или 123456789012. Не пугайся, это нормально для эмулятора.
✓ Data блоки прочитались, output содержит регион.
Самое полезное применение data, подставлять значения в ресурсы. Добавь в main.tf бакет, имя которого включает account ID:
resource "aws_s3_bucket" "demo" { bucket = "linuxlab-${data.aws_caller_identity.current.account_id}-logs" tags = {Region = data.aws_region.current.name
AccountId = data.aws_caller_identity.current.account_id
}
}
Запусти apply ещё раз:
terraform apply -auto-approve
Terraform: (1) запросит data; (2) вычислит имя; (3) создаст бакет. Граф зависимостей понимает: бакет зависит от data, значит data сначала.
Если apply ругается «name too long»: это значит account ID длинный. Можно укоротить через `substr(data.aws_caller_identity.current.account_id, 0, 8)`.
✓ Бакет создан с данными из data-блоков. data → resource: работает.
S3, не единственный AWS-ресурс. Тот же паттерн «data → resource» работает с любым ресурсом, который LocalStack эмулирует:
# IAM-роль, имя которой включает регион и account
resource "aws_iam_role" "worker" { name = "linuxlab-worker-${data.aws_region.current.name}" assume_role_policy = jsonencode({Version = "2012-10-17"
Statement = [{Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" } Condition = { StringEquals = {"aws:SourceAccount" = data.aws_caller_identity.current.account_id
}
}
}]
})
}
# SQS-очередь с именем из data
resource "aws_sqs_queue" "events" { name = "linuxlab-events-${data.aws_region.current.name}"}
И ещё одно про data, drift. Если кто-то снаружи удалит ресурс,
который ты читаешь через data, это не упадёт сразу. Data
выполнится при следующем plan/apply, и тогда выяснится что
объекта больше нет, упадёт с ошибкой. Data, не подписка на
изменения, а разовое чтение. Поэтому для критичных зависимостей
лучше resource (где ты сам управляешь), чем data (где кто-то
снаружи может всё поломать).
То же самое на OpenTofu, data-источники AWS-провайдера идентичны: тот же набор полей, те же атрибуты. См. tf-opentofu-parity.
Ты прочитал текущий account ID и регион через data, использовал их в имени бакета и в outputs. Это базовый паттерн: data-блок для контекста, resource-блок для создания.
команды
data "aws_caller_identity" "current" {}узнать кто ты сейчасdata "aws_region" "current" {}в каком регионе работаешьterraform refreshперечитать data из облакаконцепции