Перейти к основному содержимому

Terraform — модули и структура репозитория

Разработчику Архитектору Инженеру
Контекст

Базовый цикл CLI — практический путь; справочник HCL — 3.md.


Модули и layout репозитория

Одна папка с .tf-файлами — уже модуль (корневой). Сила Terraform — вызов модуля из другого модуля: один раз описали VPC или web-кластер, переиспользуете в stage и prod с разными параметрами.


Структура modules/ + live/

infrastructure/
├── modules/
│ ├── networking/vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── services/webserver-cluster/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── live/
├── stage/
│ ├── networking/vpc/
│ │ ├── main.tf # module "vpc" { source = "../../../modules/..." }
│ │ ├── backend.tf
│ │ └── terraform.tfvars
│ └── services/webserver-cluster/
│ ├── main.tf
│ └── backend.tf
└── prod/
└── ... # те же модули, другие tfvars и backend key

Разбор:

  • modules/ — переиспользуемая логика; изменение модуля влияет на все окружения после bump версии.
  • live/ — тонкие «обёртки»: вызов модулей, backend, значения переменных для конкретного env.
  • Отдельный state на стек (live/stage/.../terraform.tfstate) — изоляция: apply в stage не трогает prod.

Вызов модуля

module "webserver_cluster" {
source = "../../../modules/services/webserver-cluster"

cluster_name = "web-stage"
instance_count = 2
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.public_subnet_ids
}

variables.tf модуля объявляет контракт; outputs.tf экспортирует URL ALB, ID target group и т.д.


Провайдер только в root

В переиспользуемом модуле блок provider "aws" убирают. Настройка region, alias и credentials — в live/.../main.tf. Иначе модуль жёстко привязан к одному аккаунту/региону и его нельзя переиспользовать.

Для нескольких регионов или аккаунтов — provider "aws" { alias = "replica" } в root и providers = { aws = aws.replica } в module.


Связь стеков через remote state

Стек «сеть» публикует outputs; стек «приложение» читает их без дублирования ID:

data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "my-company-terraform-state"
key = "stage/networking/vpc/terraform.tfstate"
region = "eu-central-1"
}
}

resource "aws_instance" "app" {
subnet_id = data.terraform_remote_state.network.outputs.public_subnet_ids[0]
}

Разбор:

  • Порядок apply: сначала VPC-стек, затем зависимые сервисы.
  • Контракт между командами — outputs VPC-модуля; breaking change output = координация релизов.

Версионирование модулей

ИсточникПример sourceКогда
Локальный путьsource = "../../../modules/vpc"Monorepo, быстрая итерация
Gitsource = "git::https://...?ref=v1.2.0"Внутренняя библиотека модулей
Registrysource = "terraform-aws-modules/vpc/aws" + version = "5.0.0"Community modules

Pin версии модуля в prod; обновление — отдельный PR с diff плана.


Terragrunt (кратко)

Terragrunt — обёртка для DRY: общий backend и provider в родительских terragrunt.hcl, в листьях live/ только terraform { source = ... }. Имеет смысл при десятках однотипных стеков; для маленькой команды достаточно copy-paste backend.tf в каждом live-каталоге. См. справочник — Terragrunt.


См. также

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").