Теоретические вопросы: ответы
Вопрос 1: Что такое IaC
Ответ: Infrastructure as Code (IaC) — подход к управлению IT-инфраструктурой через конфигурационные файлы вместо ручных операций в интерфейсе.
Два ключевых преимущества:
- Версионирование и Code Review: инфраструктура хранится в git, изменения проходят ревью в Pull Requests
- Воспроизводимость: одна конфигурация создаёт идентичные окружения Dev/Test/Prod — нет «у меня работает»
Вопрос 2: Императивный vs декларативный
Ответ: Terraform — декларативный инструмент.
- Императивный: описываем шаги — «создай VM, установи nginx, открой порт 80». Примеры: Bash-скрипты, AWS CLI команды.
- Декларативный: описываем желаемое конечное состояние — «должен существовать S3-бакет с именем X и тегами Y». Terraform сам вычисляет, какие шаги нужны для достижения этого состояния.
Вопрос 3: terraform plan
Ответ:
terraform plan показывает предпросмотр изменений — что будет создано, изменено или удалено. Реальные ресурсы не изменяются.
Необходимо запускать перед каждым terraform apply для проверки, что изменения соответствуют ожиданиям. Особенно важно в продакшн-окружениях.
Вопрос 4: terraform.tfstate
Ответ:
terraform.tfstate — файл состояния, который хранит текущее состояние всей инфраструктуры, управляемой Terraform.
Почему нельзя в публичный git:
- Содержит ID всех ресурсов, IP-адреса, ARN — чувствительные данные об инфраструктуре
- Может содержать значения переменных, включая секреты
- Открывает злоумышленникам полную карту вашей инфраструктуры
Вопрос 5: Файлы после terraform init
Ответ: после
terraform init появляются два объекта:
.terraform/— директория с провайдерами и плагинами. Terraform скачивает сюда провайдер AWS (бинарный файл). При последующихinitиспользует кэш, не скачивает заново..terraform.lock.hcl— файл блокировки версий провайдеров. Фиксирует точные версии и хеши плагинов. Гарантирует, что все члены команды используют одинаковые версии. Должен быть закоммичен в git.
Вопрос 6: Провайдеры
Ответ: провайдер — плагин Terraform, который реализует взаимодействие с конкретной платформой или сервисом.
Пример: провайдер hashicorp/aws предоставляет ресурсы:
aws_instance— EC2-инстанс (виртуальная машина)aws_s3_bucket— S3-бакет (объектное хранилище)aws_security_group— Security Group (виртуальный файрвол)aws_vpc— Virtual Private Cloud (изолированная сеть)
Практические задания: решения
Задание 1: Структура проекта
# variables.tf
variable "bucket_name" {
description = "Глобально уникальное имя S3-бакета"
type = string
default = "pd2025-myname-bucket"
}
variable "aws_region" {
description = "Регион AWS"
type = string
default = "eu-central-1"
}
# providers.tf — блок terraform{} с required_providers
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
Структура файлов:
s3-project/
├── providers.tf # блок terraform{} и provider "aws"
├── main.tf # ресурс aws_s3_bucket
├── variables.tf # объявление переменных с типами и defaults
├── outputs.tf # output для имени/ARN бакета
└── terraform.tfvars # конкретные значения переменных
Задание 2: Последовательность команд
# Терминал
# 1. Инициализация (скачать провайдер AWS)
terraform init
# 2. Предпросмотр изменений (ничего не создаёт)
terraform plan -var-file="terraform.tfvars"
# 3. Создание ресурсов (ввести "yes" при запросе)
terraform apply -var-file="terraform.tfvars"
# 4. Удаление всех ресурсов
terraform destroy -var-file="terraform.tfvars"
Задание 3: Анализ ошибки
В конфигурации три проблемы:
- Хардкод секретов в provider — ключи не должны быть в
.tf-файлах. Нужно использовать~/.aws/credentials - Дублирование имени бакета — оба ресурса используют
bucket = "my-bucket". S3 имена глобально уникальны — apply упадёт с ошибкой - Нет required_providers — современный Terraform требует явного объявления провайдеров в блоке
terraform {}
# main.tf — ИСПРАВЛЕННАЯ ВЕРСИЯ
terraform {
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
provider "aws" {
region = "eu-central-1"
# Ключи НЕ здесь — берутся из ~/.aws/credentials
}
resource "aws_s3_bucket" "bucket" {
bucket = "myname-primary-bucket-2025" # уникальное имя
}
resource "aws_s3_bucket" "backup" {
bucket = "myname-backup-bucket-2025" # другое уникальное имя
}
Задание 4: Конфигурация S3 с тегами и output
# main.tf
resource "aws_s3_bucket" "app_bucket" {
bucket = var.bucket_name
tags = {
Name = var.bucket_name
Environment = var.environment
}
}
# outputs.tf
output "bucket_arn" {
description = "ARN созданного S3-бакета"
value = aws_s3_bucket.app_bucket.arn
}
Задание 5: Утечка секретов в git
Немедленные шаги при утечке ключей AWS в публичный git:
- Немедленно деактивировать ключи в IAM Console → Users → Security credentials → Deactivate/Delete ключи
- Создать новые ключи AWS и обновить
~/.aws/credentials - Проверить CloudTrail на подозрительную активность (несанкционированные запросы)
- Удалить secrets из git-истории через
git filter-branchили BFG Repo-Cleaner - Добавить в .gitignore:
terraform.tfvars,*.tfvars,*.tfstate - Настроить pre-commit hook для предотвращения коммита секретов в будущем
Важно: простое удаление файла из git-репозитория НЕ удаляет его из истории. Файл останется доступным через старые коммиты. Нужно очистить историю специальными инструментами.