Основные команды 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" |