Списком
Уявіть компанію, що розгортає нове production-середовище вручну: адміністратор входить у консоль AWS, клацає у десятках меню, створює VPC, підмережі, security groups, EC2-інстанси, налаштовує балансувальник — і все це займає кілька годин. Наступне середовище (staging, dev) він намагається зробити ідентичним першому — і це майже неможливо без помилок.
IaC (Infrastructure as Code) вирішує цю проблему: інфраструктура описується у текстових конфігураційних файлах, що зберігаються у системі контролю версій, рецензуються як звичайний код і автоматично застосовуються. Результат — відтворювані, версіоновані та автоматизовані середовища.
Infrastructure as Code (IaC) — практика управління та провізіонування обчислювальної інфраструктури за допомогою машинозчитуваних конфігураційних файлів замість ручних операцій через консоль або CLI.
Ключові переваги IaC:
| Перевага | Опис | Приклад |
|---|---|---|
| Відтворюваність | Однаковий код → однакова інфраструктура | Dev, staging, production ідентичні |
| Версіонування | Код в Git → повна історія змін | Можна відкотити до попередньої конфігурації |
| Автоматизація | Інфраструктура деплоїться автоматично в CI/CD | Нові середовища за хвилини, а не дні |
| Рецензування | Pull Request → перегляд колегами | Запобігання помилкам у конфігурації |
| Документація | Код є документацією самої інфраструктури | Нові члени команди розуміють систему з коду |
| Тестування | Конфігурацію можна перевіряти (lint, validate) | terraform validate, cfn-lint |
| Drifт-детекція | Виявлення ручних змін, що відхиляються від коду | terraform plan показує різниці |
Imperative (Процедурний) підхід: Описуємо послідовність кроків для досягнення бажаного стану.
# Bash-скрипт (imperative)
aws ec2 create-vpc --cidr-block 10.0.0.0/16
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.1.0/24
aws ec2 run-instances --image-id ami-xxx --instance-type t3.medium
Проблема: важко управляти станом; при повторному запуску — дублювання ресурсів.
Declarative (Декларативний) підхід: Описуємо бажаний кінцевий стан; інструмент сам визначає, що потрібно зробити.
# Terraform (declarative)
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
Інструмент порівнює поточний стан із бажаним і вносить лише необхідні зміни. Terraform, CloudFormation, ARM — декларативні.
| Категорія | Опис | Приклади |
|---|---|---|
| Провізіонування | Створення інфраструктури | Terraform, CloudFormation, Pulumi |
| Конфігурування | Налаштування ОС та ПЗ | Ansible, Chef, Puppet, SaltStack |
| Immutable infra | Заміна замість змін | Packer (AMI), Docker |
Terraform (HashiCorp, 2014) — найпопулярніший мультихмарний IaC-інструмент.
Ключові характеристики:
terraform.tfstateterraform plan показує зміни до їхнього застосуванняAWS CloudFormation (CFN) — рідний IaC-сервіс AWS.
Характеристики:
ARM Templates — рідний IaC-формат Azure (JSON). Складні для читання та написання.
Azure Bicep — DSL поверх ARM, що компілюється у JSON ARM-шаблони. Більш читабельний:
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: 'mystorageaccount'
location: 'eastus'
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
}
Pulumi — IaC з використанням повноцінних мов програмування (Python, TypeScript, Go, C#):
import pulumi
import pulumi_aws as aws
vpc = aws.ec2.Vpc("main", cidr_block="10.0.0.0/16")
Перевага Pulumi: можна використовувати умови, цикли, функції — все, що доступно у Python/TypeScript. Ідеальний для команд з сильними розробницькими навиками.
Cloud Deployment Manager — рідний IaC-сервіс GCP (YAML/Jinja2). Менш популярний, ніж Terraform.
Config Connector — управління GCP-ресурсами через Kubernetes Custom Resources.
В GCP здебільшого використовують Terraform через його мультихмарність.
┌────────────────────────────────────────────────────────────────┐
│ Terraform Core │
│ HCL Config Files (.tf) ──► State Comparison ──► Execution Plan│
└────────────────────────┬───────────────────────────────────────┘
│ Plugin Protocol (gRPC)
▼
┌─────────────────────────────────────────┐
│ Provider Plugins │
│ aws │ azurerm │ google │ k8s │
└─────────────────────────────────────────┘
│ API Calls
▼
Хмарні провайдери
(AWS, Azure, GCP, ...)
my-infrastructure/
├── main.tf # Основні ресурси
├── variables.tf # Оголошення змінних
├── outputs.tf # Вихідні значення
├── providers.tf # Конфігурація провайдерів
├── terraform.tfvars # Значення змінних (не комітити в Git!)
└── modules/ # Перевикористовувані модулі
└── vpc/
├── main.tf
├── variables.tf
└── outputs.tf
Provider (Провайдер):
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "eu-central-1"
}
Resource (Ресурс):
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "main-vpc"
Environment = var.environment
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id # Референс на ресурс aws_vpc.main
cidr_block = "10.0.1.0/24"
availability_zone = "eu-central-1a"
}
Variables (Змінні):
# variables.tf
variable "environment" {
description = "Середовище (dev/staging/prod)"
type = string
default = "dev"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Лише dev, staging або prod."
}
}
variable "instance_type" {
type = string
default = "t3.medium"
}
Outputs (Вихідні значення):
# outputs.tf
output "vpc_id" {
description = "ID створеного VPC"
value = aws_vpc.main.id
}
output "public_subnet_id" {
value = aws_subnet.public.id
}
Data Sources (Джерела даних):
# Отримати найновіший AMI Amazon Linux 2023
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.medium"
}
# 1. Ініціалізація проєкту (завантаження провайдерів)
terraform init
# 2. Форматування коду
terraform fmt
# 3. Перевірка синтаксису
terraform validate
# 4. Планування змін (показує, що буде зроблено)
terraform plan -var-file="prod.tfvars"
# 5. Застосування змін
terraform apply -var-file="prod.tfvars" -auto-approve
# 6. Знищення всіх ресурсів
terraform destroy
# 7. Показати поточний стан
terraform show
# 8. Список ресурсів у стані
terraform state list
Count (Умовний/кратний ресурс):
resource "aws_instance" "web" {
count = var.environment == "prod" ? 3 : 1
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.medium"
tags = {
Name = "web-${count.index + 1}"
}
}
For Each (Ітерація по колекції):
variable "subnets" {
default = {
public-1a = { cidr = "10.0.1.0/24", az = "eu-central-1a" }
public-1b = { cidr = "10.0.2.0/24", az = "eu-central-1b" }
private-1a = { cidr = "10.0.3.0/24", az = "eu-central-1a" }
}
}
resource "aws_subnet" "all" {
for_each = var.subnets
vpc_id = aws_vpc.main.id
cidr_block = each.value.cidr
availability_zone = each.value.az
tags = { Name = each.key }
}
State File (terraform.tfstate) — файл, що зберігає поточний стан усіх керованих ресурсів (ID, атрибути). Terraform порівнює його з описом у .tf-файлах для визначення необхідних змін.
Критично важливо:
Remote State (S3 + DynamoDB):
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/vpc/terraform.tfstate"
region = "eu-central-1"
encrypt = true
dynamodb_table = "terraform-locks" # State locking
}
}
State Locking: DynamoDB-таблиця запобігає одночасному застосуванню змін кількома розробниками (race condition).
Модуль — перевикористовуваний блок Terraform-конфігурації. Аналог функції у програмуванні.
Виклик модуля:
# Використання публічного модуля (Terraform Registry)
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.5.2"
name = "main-vpc"
cidr = "10.0.0.0/16"
azs = ["eu-central-1a", "eu-central-1b", "eu-central-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
}
Terraform Registry (registry.terraform.io) — публічна бібліотека перевірених модулів для типових ресурсів (VPC, EKS, RDS, ALB тощо).
1. Структура проєкту:
infrastructure/
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ └── terraform.tfvars
│ ├── staging/
│ └── prod/
├── modules/
│ ├── vpc/
│ ├── eks/
│ └── rds/
└── common/
└── providers.tf
2. Версіонування провайдерів та модулів:
Завжди фіксуйте версію: version = "~> 5.0" (minor оновлення дозволено, major — ні).
3. Тегування всіх ресурсів:
locals {
common_tags = {
Project = var.project
Environment = var.environment
ManagedBy = "Terraform"
Owner = var.team
}
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = local.common_tags
}
4. Secrets Management — ніколи не хардкодити:
# Неправильно
resource "aws_db_instance" "main" {
password = "MySecretPassword123" # НЕБЕЗПЕЧНО!
}
# Правильно — з AWS Secrets Manager або Parameter Store
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/db/password"
}
resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db_password.secret_string
}
5. Статичний аналіз та lint:
terraform validate — перевірка синтаксисуtfsec або checkov — аналіз безпеки конфігураціїterraformdocs — автогенерація документації з коментарівТиповий GitOps-workflow:
Розробник GitHub PR CI Pipeline CD Pipeline
│ │ │ │
├─ git push ───►│ │ │
│ ├─ lint ──────►│ │
│ ├─ validate ──►│ │
│ ├─ plan ──────►│ (terraform plan) │
│ │ PR review │ │
│ PR Approved │ │ │
│ ├─ merge ─────►│ │
│ │ ├─ apply ───────────►│
│ │ │ (terraform apply) │
│ │ │ │
│ │ │ Infrastructure
│ │ │ Created
Приклад GitHub Actions Pipeline для Terraform:
name: Terraform CI/CD
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.7.0"
- name: Terraform Init
run: terraform init
env:
AWS_ACCESS_KEY_ID: $
- name: Terraform Plan
run: terraform plan -out=tfplan
if: github.event_name == 'pull_request'
- name: Terraform Apply
run: terraform apply tfplan
if: github.ref == 'refs/heads/main'
Configuration Drift — стан, коли реальна інфраструктура відхиляється від конфігурації в коді (внаслідок ручних змін, збоїв тощо).
Виявлення:
terraform plan # Показує різниці між кодом та реальним станом
Автоматичний моніторинг:
terraform plan у CI та надсилання сповіщеньIaC є фундаментальною практикою сучасної хмарної інженерії, що забезпечує відтворюваність, версіонування та автоматизацію управління інфраструктурою. Ручне управління через консоль неприйнятне для production-середовищ.
Terraform є стандартом де-факто для мультихмарного IaC завдяки широкій підтримці провайдерів, потужній екосистемі модулів та декларативному підходу.
Remote State + State Locking є обов’язковими для командної роботи. Зберігання стану в S3+DynamoDB запобігає конфліктам та забезпечує централізований контроль.
Модульність та DRY-принцип дозволяють перевикористовувати конфігурації між середовищами та проєктами, скорочуючи дублювання та помилки.
Інтеграція у CI/CD pipeline з автоматичними plan при PR та apply після злиття — золотий стандарт GitOps, що поєднує ревізування коду з безпечним автоматичним розгортанням.