🔖 Справочник: Terraform — команды и синтаксис

⚡ Главные команды Terraform

  • terraform init — инициализация проекта, скачать провайдеры
  • terraform validate — проверить синтаксис конфигурации
  • terraform fmt — форматировать .tf файлы (авто-отступы)
  • terraform plan — предпросмотр изменений (ничего не меняет)
  • terraform apply — применить конфигурацию (создать ресурсы)
  • terraform destroy — удалить все управляемые ресурсы
  • terraform state list — список ресурсов в state
  • terraform output — показать outputs после apply

Основные команды Terraform

Жизненный цикл проекта

# Терминал (PowerShell или bash)

# 1. Инициализация — скачать провайдеры, создать .terraform/ и .terraform.lock.hcl
terraform init

# 2. Проверка синтаксиса — найти ошибки без применения
terraform validate

# 3. Форматирование — привести код к стандартному виду (пробелы, отступы)
terraform fmt
terraform fmt -recursive   # рекурсивно по всем поддиректориям

# 4. Предпросмотр изменений — показать что будет создано/изменено/удалено
terraform plan
terraform plan -var-file="terraform.tfvars"   # с явным файлом переменных
terraform plan -out=tfplan                    # сохранить план в файл

# 5. Применение — создать/обновить ресурсы (запросит подтверждение yes)
terraform apply
terraform apply -var-file="terraform.tfvars"
terraform apply tfplan                        # применить сохранённый план
terraform apply -auto-approve                 # без подтверждения (опасно в prod)

# 6. Удаление — уничтожить все ресурсы конфигурации
terraform destroy
terraform destroy -var-file="terraform.tfvars"
terraform destroy -auto-approve               # без подтверждения

# Показать текущие outputs
terraform output
terraform output instance_public_ip           # конкретный output

Работа со state

# Терминал

# Список ресурсов в state
terraform state list

# Показать подробности конкретного ресурса
terraform state show aws_instance.web_server

# Переместить ресурс в state (при рефакторинге)
terraform state mv aws_instance.old_name aws_instance.new_name

# Удалить ресурс из state (без удаления реального ресурса)
terraform state rm aws_s3_bucket.my_bucket

# Импортировать существующий AWS-ресурс в state
terraform import aws_s3_bucket.my_bucket my-existing-bucket-name

Структура HCL-блоков

Блок terraform{} с required_providers

# providers.tf
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"     # любая 5.x, не 6.x
    }
  }

  # Опционально: remote backend для командной работы
  # backend "s3" {
  #   bucket = "my-tf-state"
  #   key    = "env/terraform.tfstate"
  #   region = "eu-central-1"
  # }
}

provider "aws" {
  region = var.aws_region
  # Credentials из ~/.aws/credentials (через aws configure)
}

Блок resource

# main.tf
# resource "ТИП_РЕСУРСА" "ЛОКАЛЬНОЕ_ИМЯ" { ... }

resource "aws_s3_bucket" "app_bucket" {
  bucket = var.bucket_name   # переменная из variables.tf

  tags = {
    Name        = var.bucket_name
    Environment = "dev"
    ManagedBy   = "Terraform"
  }
}

resource "aws_security_group" "web_sg" {
  name        = "web-server-sg"
  description = "Allow HTTP and SSH"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]   # SSH (в prod — ограничить своим IP)
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"            # весь исходящий трафик
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "web_server" {
  ami                    = "ami-0de02246788e4a354"  # Amazon Linux 2023, eu-central-1
  instance_type          = var.instance_type
  vpc_security_group_ids = [aws_security_group.web_sg.id]  # ссылка на ресурс выше

  user_data = file("install_docker.sh")   # скрипт установки

  tags = {
    Name      = "WebServer"
    CreatedBy = "Terraform"
  }
}

Блок variable

# variables.tf
variable "aws_region" {
  description = "Регион AWS для развёртывания ресурсов"
  type        = string
  default     = "eu-central-1"
}

variable "bucket_name" {
  description = "Глобально уникальное имя S3-бакета"
  type        = string
  default     = "my-group-bucket"
}

variable "instance_type" {
  description = "Тип EC2-инстанса"
  type        = string
  default     = "t2.micro"
}

variable "volume_size" {
  description = "Размер корневого тома в GB"
  type        = number
  default     = 10
}

# Переменная без default — будет запрошена при apply
variable "key_pair_name" {
  description = "Имя Key Pair для SSH-доступа к EC2"
  type        = string
}

Файл terraform.tfvars — значения переменных

# terraform.tfvars
# Этот файл задаёт значения переменных для конкретного окружения

aws_region    = "eu-central-1"
bucket_name   = "pd2025-myname-bucket"
instance_type = "t2.micro"
volume_size   = 10
key_pair_name = "ich"
Безопасность: если файл содержит секреты — добавьте в .gitignore. Стандартные имена, которые Terraform подхватывает автоматически: terraform.tfvars и *.auto.tfvars. Остальные нужно передавать явно: -var-file="myfile.tfvars".

Блок output

# outputs.tf
output "bucket_id" {
  description = "Имя (ID) созданного S3-бакета"
  value       = aws_s3_bucket.app_bucket.id
}

output "bucket_arn" {
  description = "ARN S3-бакета"
  value       = aws_s3_bucket.app_bucket.arn
}

output "instance_id" {
  description = "ID EC2-инстанса"
  value       = aws_instance.web_server.id
}

output "instance_public_ip" {
  description = "Публичный IP-адрес EC2-инстанса"
  value       = aws_instance.web_server.public_ip
}

output "ssh_command" {
  description = "Команда для SSH-подключения к инстансу"
  value       = "ssh -i ~/.ssh/${var.key_pair_name}.pem ec2-user@${aws_instance.web_server.public_ip}"
}

Блок data (data source)

# main.tf — получить актуальный AMI без хардкода ID
data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

# Использование: data.aws_ami.amazon_linux_2023.id

Структура Terraform-проекта

# Рекомендуемая структура файлов Terraform-проекта
my-terraform-project/
├── main.tf           # основные ресурсы (EC2, S3, SG и т.д.)
├── variables.tf      # объявление переменных (name + type + description + default)
├── outputs.tf        # выводимые значения после apply
├── providers.tf      # блок terraform{} и provider "aws"
├── terraform.tfvars  # значения переменных (НЕ секреты!)
├── .gitignore        # исключить: .terraform/, *.tfstate, *.tfstate.backup
└── install_docker.sh # опционально: user_data скрипт для EC2

Рекомендуемый .gitignore для Terraform-проекта

# .gitignore — для Terraform-проекта
# Директория с провайдерами (скачивается при terraform init)
.terraform/

# Файлы состояния (содержат чувствительные данные)
*.tfstate
*.tfstate.backup

# Файл с переменными, если содержит секреты
# terraform.tfvars   # раскомментировать, если файл содержит секреты

# Сохранённые планы
*.tfplan

# Переопределения (локальные настройки разработчика)
override.tf
override.tf.json
*_override.tf
*_override.tf.json

Операторы версионирования

Оператор Значение Пример
= 5.0.0 Точная версия version = "= 5.0.0"
>= 5.0 Версия 5.0 и выше required_version = ">= 1.5.0"
~> 5.0 Любая 5.x, но не 6.x (pessimistic) version = "~> 5.0"
~> 5.31.0 Любая 5.31.x, но не 5.32 version = "~> 5.31.0"