Terraform — это фреймворк для управления инфраструктурой как кодом (IaC), разработанный компанией HashiCorp. Он позволяет описывать, создавать, изменять и удалять ресурсы в облачных, локальных и гибридных средах с помощью декларативного синтаксиса.
Конфигурации в Terraform пишутся на языке HCL (HashiCorp Configuration Language) — простом, читаемом формате, близком к YAML, но ориентированном на инфраструктурные сценарии. Код хранится в
.tf
Ключевые принципы работы Terraform:
- Declarative — ты описываешь, что должно быть, а не как это сделать.
- Plan — перед применением Terraform показывает, какие изменения будут сделаны.
- Apply — на этом этапе ресурсы создаются или изменяются.
- State — текущее состояние инфраструктуры хранится в виде файла (), который используется для расчёта дельты при следующих изменениях.
terraform.tfstate
- Idempotent — повторное применение кода не приводит к повторному созданию ресурсов, если ничего не изменилось.
Пример использования:
С помощью Terraform можно за одну операцию:
- создать VPC и подсети в AWS,
- развернуть EC2-инстансы с нужным образом,
- задать правила firewall’а (Security Groups),
- настроить IAM-политики и роли,
- автоматически подключить всё к балансировщику.
Поддержка облаков и провайдеров:
Terraform работает через провайдеры (providers), каждый из которых знает, как управлять тем или иным API. Поддерживаются:
- AWS, Azure, Google Cloud, Alibaba Cloud;
- Kubernetes, Helm, Cloudflare, GitHub, Datadog, Vault, vSphere и сотни других.
Почему Terraform стал стандартом:
- 💡 Прозрачность — можно видеть, какие изменения будут сделаны, до их применения.
- 🔁 Повторяемость — та же конфигурация применима к любому окружению (dev, staging, prod).
- 🔐 Контроль версий — код хранится в Git, можно отслеживать, сравнивать и откатывать изменения.
- 🤝 Совместимость с CI/CD пайплайнами, GitOps-подходом, политиками безопасности и тестами (,
tflint
,checkov
).OPA
Terraform широко используется в DevOps, SRE и платформенных командах, где важно быстро и безопасно управлять масштабируемой инфраструктурой — особенно в мультиоблачной или гибридной архитектуре.
📁 Пример Terraform-модуля: EC2-инстанс с переменными
📁 Структура проекта:
terraform-project/ ├── main.tf ├── variables.tf ├── outputs.tf ├── terraform.tfvars └── modules/ └── ec2-instance/ ├── main.tf ├── variables.tf └── outputs.tf
🔧 main.tf
(корень проекта):
main.tf
provider "aws" { region = "us-east-1" } module "web_server" { source = "./modules/ec2-instance" instance_name = "frontend-node" instance_type = "t3.micro" ami_id = "ami-0c55b159cbfafe1f0" }
🧩 modules/ec2-instance/main.tf
:
modules/ec2-instance/main.tf
resource "aws_instance" "this" { ami = var.ami_id instance_type = var.instance_type tags = { Name = var.instance_name } }
📥 modules/ec2-instance/variables.tf
:
modules/ec2-instance/variables.tf
variable "instance_name" { description = "Name tag for the EC2 instance" type = string } variable "instance_type" { description = "Type of EC2 instance" type = string default = "t2.micro" } variable "ami_id" { description = "AMI ID for the instance" type = string }
📤 modules/ec2-instance/outputs.tf
:
modules/ec2-instance/outputs.tf
output "instance_id" { value = aws_instance.this.id } output "public_ip" { value = aws_instance.this.public_ip }
📦 terraform.tfvars
(значения по умолчанию):
terraform.tfvars
instance_type = "t3.micro" ami_id = "ami-0c55b159cbfafe1f0"
💡 Что делает этот модуль:
- Разворачивает EC2-инстанс с заданной AMI и типом.
- Использует переиспользуемую логику из подкаталога .
modules/ec2-instance
- Передаёт значения через переменные.
- Отдаёт ID и публичный IP-адрес инстанса через outputs.
Такой подход позволяет:
- легко масштабировать инфраструктуру;
- переиспользовать один модуль в разных окружениях;
- передавать значения через или переменные окружения;
.tfvars
- подключать в CI/CD пайплайны и GitOps-сценарии.
☁️ Хранение состояния: remote backend
(S3 + DynamoDB)
remote backend
Чтобы несколько человек или CI-система могли безопасно работать с Terraform-проектом, рекомендуется хранить
terraform.tfstate
📄 backend.tf
(можно объединить с main.tf
):
backend.tf
main.tf
terraform { backend "s3" { bucket = "my-terraform-state-bucket" key = "envs/dev/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-lock-table" encrypt = true } }
🔒 DynamoDB используется для блокировок и предотвращает одновременное применение (
terraform apply
🔎 Пример data source
: получение последнего AMI
data source
Terraform позволяет подтягивать данные без создания ресурсов.
data "aws_ami" "latest_amazon_linux" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } }
Потом можно использовать:
ami = data.aws_ami.latest_amazon_linux.id
📦 Terraform + Helm (для управления Kubernetes)
Для развёртывания Helm-чартов прямо из Terraform используют Helm provider.
provider "helm" { kubernetes { config_path = "~/.kube/config" } } resource "helm_release" "nginx" { name = "nginx" repository = "https://charts.bitnami.com/bitnami" chart = "nginx" version = "15.2.0" set { name = "service.type" value = "LoadBalancer" } }
✅ Преимущества такой связки:
- Один создаёт кластер (через
terraform apply
) и тут же устанавливает Helm-чарты.aws_eks_cluster
- Всё версионируется, управляется кодом и полностью автоматизируется.
- Можно динамически передавать значения между модулями и чартами.