Гид по технологиям

Модули Terraform: повторное использование кода на примере S3

• 6 min read • DevOps • Обновлено 25 Nov 2025
Модули Terraform: S3 и повторное использование
Модули Terraform: S3 и повторное использование

Обложка: структура Terraform и облачные ресурсы

В этой статье мы разберём, как создавать повторно используемые модули в Terraform на примере S3 Bucket (бакета). Модули помогают избежать копирования кода: один и тот же модуль можно подключить в нескольких средах с разными значениями переменных.

Ключевая идея: вынести повторяемую конфигурацию в каталог-модуль и подключать его из root-конфигураций с нужными параметрами.

Что понадобится

  1. Базовое понимание Terraform. (Определение: Terraform — инструмент для управления инфраструктурой как кодом.)
  2. Установленный Terraform на вашей машине.
  3. Аккаунт AWS (создайте при необходимости).
  4. Доступы IAM пользователя с access_key и secret_key. Храните их в безопасном месте и не публикуйте.

Важно: никогда не выкладывайте реальные секреты в репозитории. Используйте переменные окружения, secret manager или CI/CD секреты.

Что мы сделаем

  1. Напишем собственный модуль для S3.
  2. Подключим модуль из root-конфигурации и создадим бакет.
  3. Удалим ресурсы при помощи terraform destroy.

Структура проекта (рекомендуемая)

Рекомендуемая структура каталогов:

  • modules/
    • aws-s3/
      • main.tf
      • variables.tf
      • outputs.tf (опционально)
  • main.tf
  • variables.tf
  • terraform.tfvars

Создадим директорию модуля:

mkdir -p modules/aws-s3

Модуль: modules/aws-s3

Создайте файл modules/aws-s3/main.tf и вставьте следующий блок — это сам модуль, создающий S3 Bucket:

resource "aws_s3_bucket" "s3_bucket" {  
  bucket = var.bucket_name  
  acl    = "public-read"  
  policy = <

Пример кода модуля Terraform

Объяснение ключевых частей модуля:

  • resource aws_s3_bucket — ресурс, создающий бакет.
  • bucket = var.bucket_name — имя бакета задаётся через входную переменную.
  • policy — JSON‑политика доступа, здесь простой пример публичного доступа для чтения объектов.
  • website — блок конфигурации для статического сайта.
  • tags — метки, передаваемые через переменные.

Переменные модуля

Создайте modules/aws-s3/variables.tf и объявите входные параметры модуля:

variable "bucket_name" {
  description = "Name of the s3 bucket. Must be unique."
  type = string
}

variable "tags" {
  description = "Tags to set on the bucket."
  type = map(string)
  default = {}
}

Определение переменных Terraform

Вы также можете добавить outputs.tf внутри модуля, например, чтобы экспортировать ARN бакета:

output "bucket_arn" {
  value = aws_s3_bucket.s3_bucket.arn
  description = "ARN созданного S3 бакета"
}

Root-конфигурация: вызов модуля

В корне проекта создайте main.tf, который будет подключать модуль и содержать провайдера:

provider "aws" {
      region     = "${var.region}"
      access_key = "${var.access_key}"
      secret_key = "${var.secret_key}"
}


module "website_s3_bucket" {
  source = "./modules/aws-s3"

  bucket_name = "${var.bucket_name}"

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

Root main.tf с вызовом модуля

Пояснение:

  • source — путь к модулю. Может быть локальным (как здесь) или указывать на реестр (registry) или VCS.
  • Один и тот же source можно использовать в нескольких module-блоках с разными параметрами для создания нескольких бакетов.

Определение переменных в root

Создайте variables.tf в корне, где объявите переменные провайдера и имя бакета. Пример:

variable "access_key" {
     description = "Access key to AWS console"
}
variable "secret_key" {
     description = "Secret key to AWS console"
}
variable "region" {
     description = "Region of AWS VPC"
}
variable "bucket_name" {
  description = "(Required) Creates a unique bucket name"
  type        = "string"
  default     = "test-bucket-terraform-example"
}

Пример расширения variables.tf

Пример terraform.tfvars (пример значений)

Ниже — пример файла terraform.tfvars. Никогда не коммитьте реальные ключи. Используйте placeholder или безопасные механизмы хранения секретов:

region = "eu-west-3"
access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"

Important: Замените YOUR_ACCESS_KEY и YOUR_SECRET_KEY на безопасно переданные в CI/CD или локальные переменные окружения. Не храните секреты в коде.

Команды: инициализация, план, применение, удаление

Перед выполнением убедитесь, что terraform доступен и credentials корректны.

  • Инициализация плагинов провайдера:

terraform init

  • Просмотр изменений (без применения):

terraform plan

  • Применение плана (создание ресурсов):

terraform apply

  • Удаление созданных ресурсов:

terraform destroy

После успешного terraform apply вы увидите сообщение об изменениях, например, 1 added, 0 destroyed. Проверьте в консоли AWS S3 — бакет должен появиться.

Безопасность и соответствие (Security & GDPR)

  • Не храните секреты в репозитории. Используйте хранилище секретов (AWS Secrets Manager, HashiCorp Vault) или переменные окружения в CI.
  • Минимизируйте права: создавайте IAM-пользователя с набором прав, нужным для создания S3 (principle of least privilege).
  • По умолчанию не делайте бакет публичным, если в этом нет необходимости. В примере выше acl = “public-read” и политика делает объекты публичными — это подходит только для публичных статических сайтов.
  • Для персональных данных применяйте шифрование на серверной стороне (SSE) и включайте версионирование и логирование доступа при необходимости.

Практические рекомендации и лучшие практики

  • Используйте переменные и outputs для изоляции конфигурации.
  • Добавьте validation в переменные (Terraform 0.13+), чтобы раннее поймать ошибки ввода.
  • Поддерживайте версионирование модулей (например, тегируйте в Git) и используйте версии при подключении к remote‑registry.
  • Тестируйте модули локально и в отдельной test‑среде перед production.
  • Пишите README внутри modules/aws-s3 с описанием переменных, outputs и примеров использования.

Пример: подключение одного модуля дважды (staging и prod)

module "staging_bucket" {
  source = "./modules/aws-s3"
  bucket_name = "my-app-staging-bucket"
  tags = { Environment = "staging" }
}

module "prod_bucket" {
  source = "./modules/aws-s3"
  bucket_name = "my-app-prod-bucket"
  tags = { Environment = "production" }
}

Когда модуль не подходит или ограничения

  • Если требуется создание большого количества разнообразных ресурсов с разной логикой — целесообразно разделять на несколько специализированных модулей.
  • Для ресурсов с крайне динамическими именами/параметрами возможно удобнее генерировать конфигурацию программно (через Terragrunt, Terraform Cloud/Workspaces или внешние скрипты).

Альтернативные подходы

  • Terragrunt — слой над Terraform для DRY в управлении конфигурациями и переиспользования общих параметров.
  • Использование модулей из Terraform Registry для стандартных шаблонов облачных ресурсов.

Мини‑методология разработки модулей (шаги)

  1. Сформулировать контракт: входные переменные и outputs.
  2. Реализовать resource-блоки и default‑значения.
  3. Добавить validation и документацию (README).
  4. Написать тесты/проверки в тестовой среде.
  5. Версионировать и публиковать (если публичный модуль).

Критерии приёмки

  • Модуль корректно создаёт и удаляет ресурс без ошибок.
  • Все обязательные переменные описаны и валидируются.
  • Outputs возвращают полезные значения (ARN, имя, URL сайта).
  • Документация включает пример использования и список переменных.
  • Нет секретов в репозитории; доступы задаются безопасно.

Чек‑лист по ролям

  • Разработчик:
    • Создал модуль с документированными переменными и outputs.
    • Добавил validation и примеры.
  • DevOps/Инженер по безопасности:
    • Проверил IAM-права и исключил лишние привилегии.
    • Убедился в отсутствии секретов в коде.
  • Тестировщик:
    • Прогнал terraform plan/apply/destroy в тестовой среде.
    • Проверил влияние на существующие ресурсы.

Сниппет: пример валидации переменной (Terraform >=0.13)

variable "bucket_name" {
  description = "Name of S3 bucket"
  type = string
  validation {
    condition = length(var.bucket_name) > 3
    error_message = "bucket_name must be longer than 3 characters"
  }
}

Примеры тестовых случаев / acceptance

  • При корректных input-значениях terraform apply создаёт бакет и outputs содержат ARN.
  • При пустом или коротком имени — валидация предотвращает apply.
  • При terraform destroy бакет удаляется и в AWS консоли ресурс исчезает.

Edge‑case gallery (типичные проблемы и их решения)

  • Ошибка: bucket name already exists — S3 имена глобально уникальны. Решение: использовать префикс/суффикс с идентификатором окружения.
  • Ошибка: AccessDenied при создании — проверьте права IAM.
  • Проблемы с публичным доступом — учитывайте настройки блокировок публичного доступа в аккаунте AWS.

Decision flow (простое дерево принятия решения)

flowchart TD
  A[Нужно ли переиспользовать конфигурацию?] -->|Да| B[Вынести в модуль]
  A -->|Нет| C[Оставить в root]
  B --> D{Требуется версия/публикация?}
  D -->|Да| E[Версионировать и публиковать]
  D -->|Нет| F[Использовать локальный модуль]

Заключение

Мы создали простой модуль Terraform для S3, подключили его из root-конфигурации и рассмотрели важные вопросы безопасности, валидации и практик повторного использования. Модули упрощают поддержку и распространяют единый стандарт конфигурации по всем окружениям.

Короткое резюме

  • Модуль инкапсулирует ресурс(ы) и интерфейс (переменные/outputs).
  • source указывает на путь модуля (локально или в registry).
  • Никогда не храните секреты в репозитории; применяйте минимальные права.

Спасибо за чтение. Если нужно, могу подготовить README.md для вашего модуля или добавить пример outputs/validation/CI‑pipeline.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро