12 промтов для Terraform и IaC: от модулей до multi-cloud
Terraform давно стал стандартом де-факто для управления инфраструктурой как кодом (IaC). Согласно отчёту HashiCorp State of Cloud Strategy Survey 2025, более 70% организаций используют Terraform для provisioning облачных ресурсов. Но даже опытные инженеры тратят часы на написание модулей, отладку state-файлов и настройку multi-cloud. Я собрал 12 проверенных промтов, которые ускоряют рутину и помогают избежать типовых ошибок. Каждый промт сопровождается реальным примером кода.
1. Генерация структуры модуля Terraform
Когда использовать: при старте нового модуля для VPC, базы данных или Kubernetes.
Промт: «Создай структуру модуля Terraform для AWS VPC с поддержкой public/private subnet, NAT Gateway и VPC Flow Logs. Включи файлы main.tf, variables.tf, outputs.tf, versions.tf и README.md с примерами использования.»
Пример вывода:
# main.tf
resource "aws_vpc" "this" {
cidr_block = var.cidr_block
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = var.vpc_name
}
}
resource "aws_subnet" "public" {
count = length(var.public_subnet_cidrs)
vpc_id = aws_vpc.this.id
cidr_block = var.public_subnet_cidrs[count.index]
map_public_ip_on_launch = true
availability_zone = var.availability_zones[count.index]
}
Пояснение: Промт задаёт чёткую спецификацию — тип ресурсов и файлы. Это экономит 15–20 минут на ручном создании скелета.
2. Преобразование существующей инфраструктуры в Terraform (import)
Когда использовать: миграция с AWS Console или CloudFormation в Terraform.
Промт: «Напиши блоки Terraform для импорта существующей AWS RDS instance (id: db-abc123) и Security Group (id: sg-xyz789). Сгенерируй resource-блоки с минимальным набором аргументов и команду terraform import.»
Пример вывода:
resource "aws_db_instance" "legacy_db" {
identifier = "db-abc123"
# Другие атрибуты будут заполнены после terraform import
}
Команда: terraform import aws_db_instance.legacy_db db-abc123
Пояснение: Промт фокусируется на минимальном блоке, достаточном для импорта, а затем вы можете выполнить terraform plan и увидеть реальную конфигурацию.
3. Оптимизация Terraform state (remote state + locking)
Когда использовать: при работе в команде, чтобы избежать конфликтов.
Промт: «Настрой remote state для Terraform с бэкендом S3 и DynamoDB для state locking. Дай конфигурацию backend.tf и инструкцию по созданию S3 bucket и DynamoDB table через AWS CLI.»
Пример вывода:
# backend.tf
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/network/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
Инструкция по созданию:
aws s3api create-bucket --bucket my-terraform-state-bucket --region us-east-1
aws dynamodb create-table --table-name terraform-locks --attribute-definitions AttributeName=LockID,AttributeType=S --key-schema AttributeName=LockID,KeyType=HASH --billing-mode PAY_PER_REQUEST
Пояснение: Такой промт предотвращает потерю state и параллельные изменения. Без remote state в команде из 5 человек конфликты случаются еженедельно.
4. Multi-cloud: единый модуль для AWS, Azure и GCP
Когда использовать: если компания использует несколько облаков.
Промт: «Создай Terraform модуль для виртуальной машины, который работает в AWS (EC2), Azure (VM) и GCP (Compute Engine). Используй count и provider aliases. Включи поддержку переменных для типа инстанса, региона и SSH-ключа.»
Пример вывода:
# modules/compute/main.tf
resource "aws_instance" "this" {
count = var.cloud_provider == "aws" ? 1 : 0
ami = var.aws_ami
instance_type = var.instance_type
key_name = var.ssh_key_name
}
resource "azurerm_virtual_machine" "this" {
count = var.cloud_provider == "azure" ? 1 : 0
name = var.vm_name
location = var.region
resource_group_name = var.resource_group_name
# ...
}
Пояснение: Этот подход позволяет переиспользовать логику между облаками, хотя требует поддержки провайдер-специфичных переменных. Идеально для стартапов, которые не хотят быть привязаны к одному вендору.
5. Автоматическая генерация outputs для всех ресурсов
Когда использовать: после создания модуля нужно быстро получить outputs для передачи в другие модули.
Промт: «Сгенерируй блоки output для всех ресурсов в файле main.tf. Для каждого resource создай output с именем ресурса и основными атрибутами (id, arn, name).»
Пример вывода:
output "vpc_id" {
value = aws_vpc.this.id
}
output "public_subnet_ids" {
value = aws_subnet.public[*].id
}
Пояснение: Промт экономит время на ручном перечислении outputs. После генерации нужно вручную проверить названия атрибутов.
6. Terraform code review: поиск уязвимостей и нарушений best practices
Когда использовать: перед merge request.
Промт: «Проверь следующий Terraform код на уязвимости и нарушения best practices: [вставь код]. Укажи конкретные строки, уровень критичности и предложи исправления. Особое внимание удели hardcoded secrets, открытым security groups и отсутствию version constraints.»
Пояснение: Такой промт помогает выявить типовые проблемы, например, публичный доступ к S3 bucket или отсутствие encryption. Ручной review занимает 30 минут, а промт — 2 минуты.
7. Написание Terraform для Kubernetes (EKS, AKS, GKE)
Когда использовать: при развёртывании кластера и node groups.
Промт: «Напиши Terraform модуль для создания EKS кластера с managed node group, IAM roles, security group и VPC CNI. Используй официальный модуль terraform-aws-eks. Добавь переменные для версии Kubernetes и размера node group.»
Пример вывода:
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
cluster_name = var.cluster_name
cluster_version = var.k8s_version
vpc_id = var.vpc_id
subnet_ids = var.subnet_ids
eks_managed_node_groups = {
main = {
desired_size = 2
min_size = 1
max_size = 5
instance_types = ["t3.medium"]
}
}
}
Пояснение: Официальные модули (terraform-aws-eks) экономят 100+ строк кода. Промт задаёт минимальную конфигурацию для production-ready кластера.
8. Terraform workspaces: управление окружениями (dev/staging/prod)
Когда использовать: при развёртывании одной конфигурации в нескольких окружениях.
Промт: «Создай Terraform конфигурацию с поддержкой workspaces для окружений dev, staging и prod. Используй переменную environment для настройки размера инстансов, количества реплик и тегов. Включи пример команды для создания workspace.»
Пример вывода:
# variables.tf
variable "environment" {
description = "Environment name (dev, staging, prod)"
type = string
}
# main.tf
resource "aws_instance" "app" {
instance_type = var.environment == "prod" ? "t3.large" : "t3.micro"
tags = {
Environment = var.environment
}
}
Команда: terraform workspace new dev && terraform workspace select dev
Пояснение: Workspaces — лёгкий способ изолировать окружения без копирования кода. Однако для серьёзных проектов лучше использовать отдельные каталоги.
9. Terraform data sources: получение существующих ресурсов
Когда использовать: когда нужно использовать существующий VPC, subnet или AMI.
Промт: «Напиши data source для получения существующего AWS VPC по тегу Name, а также всех public subnet в этой VPC. Используй фильтр и вывод ID.»
Пример вывода:
data "aws_vpc" "selected" {
filter {
name = "tag:Name"
values = [var.vpc_name]
}
}
data "aws_subnets" "public" {
filter {
name = "vpc-id"
values = [data.aws_vpc.selected.id]
}
filter {
name = "map-public-ip-on-launch"
values = ["true"]
}
}
Пояснение: Data sources — ключевой элемент для работы с уже существующей инфраструктурой. Без них пришлось бы хардкодить ID.
10. Terraform modules registry: поиск и кастомизация
Когда использовать: когда нужен готовый модуль для RDS, ELB или S3.
Промт: «Найди в Terraform Registry модуль для AWS RDS PostgreSQL с поддержкой Multi-AZ, backup retention и deletion protection. Выведи пример использования с минимальными переменными и outputs для endpoint и port.»
Пример вывода:
module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "~> 6.0"
identifier = "my-db"
engine = "postgres"
engine_version = "16.3"
instance_class = "db.t3.medium"
allocated_storage = 100
backup_retention_period = 7
deletion_protection = true
vpc_security_group_ids = [var.security_group_id]
db_subnet_group_name = var.subnet_group_name
}
output "db_endpoint" {
value = module.rds.db_instance_endpoint
}
Пояснение: Registry содержит тысячи модулей, но важно указывать version constraint, чтобы избежать breaking changes.
11. Terraform plan/policy as code (Sentinel)
Когда использовать: когда нужно запретить определённые ресурсы или настройки (например, запрет публичных S3 buckets).
Промт: «Напиши политику Sentinel для Terraform Cloud, которая запрещает создание S3 bucket с public access. Политика должна проверять блоки resource и блокировать план, если public_access_block не установлен.»
Пример вывода:
import tfplan
# Получаем все ресурсы S3 bucket
s3_buckets = filter tfplan.resource_changes as _, rc {
rc.mode == "managed" and rc.type == "aws_s3_bucket"
}
# Проверяем, что public_access_block установлен
violations = filter s3_buckets as _, bucket {
not bucket.applied.public_access_block exists
}
if length(violations) > 0 {
print("S3 buckets must have public_access_block configured.")
for violations as _, v {
print(v.address)
}
return false
}
return true
Пояснение: Sentinel — встроенный инструмент HashiCorp для policy-as-code. Позволяет внедрить compliance без ручных проверок.
12. Terraform debugging: логирование и устранение ошибок
Когда использовать: когда terraform apply выдаёт cryptic error.
Промт: «Объясни, как включить debug-логирование в Terraform для диагностики ошибок при создании AWS ALB. Дай пример команды и покажи, как интерпретировать типичные ошибки (например, «Error creating ALB: AccessDenied»).»
Пример вывода:
export TF_LOG=DEBUG
export TF_LOG_PATH=./terraform.log
terraform apply
Пояснение: Уровни логирования: TRACE, DEBUG, INFO, WARN, ERROR. DEBUG подходит для большинства случаев. Ошибка AccessDenied обычно означает нехватку прав IAM.
Заключение
Эти 12 промтов покрывают 80% повседневных задач Terraform-инженера: от создания модулей до multi-cloud и policy-as-code. Используйте их как шпаргалку — копируйте промт, вставляйте в AI-инструмент и адаптируйте под свой проект. Главное — всегда проверяйте сгенерированный код на тестовом окружении. Какие промты вы используете чаще всего? Делитесь в комментариях к статье в нашем блоге.
Комментарии