Сабмодули
TerraCi поддерживает вложенные сабмодули для организации связанной инфраструктуры внутри родительского модуля.
Что такое сабмодули?
Сабмодули — это Terraform-модули, вложенные глубже уровня стандартного паттерна:
infrastructure/
└── platform/
└── production/
└── us-east-1/
└── ec2/ # Родительский модуль (глубина 4)
├── main.tf # Файлы родительского модуля
├── rabbitmq/ # Сабмодуль (глубина 5)
│ └── main.tf
└── redis/ # Сабмодуль (глубина 5)
└── main.tfИдентификация модулей
| Путь | Тип | ID |
|---|---|---|
platform/production/us-east-1/ec2 | Родитель | platform/production/us-east-1/ec2 |
platform/production/us-east-1/ec2/rabbitmq | Сабмодуль | platform/production/us-east-1/ec2/rabbitmq |
Конфигурация
Сабмодули обнаруживаются автоматически. Любая директория с .tf файлами, вложенная глубже уровня паттерна, считается сабмодулем:
structure:
pattern: "{service}/{environment}/{region}/{module}"Примеры использования
Группировка EC2 инстансов
ec2/
├── main.tf # Общие security groups, IAM roles
├── rabbitmq/
│ └── main.tf # EC2 для RabbitMQ
└── elasticsearch/
└── main.tf # EC2 для ElasticsearchКластеры баз данных
databases/
├── main.tf # Общие VPC, подсети
├── postgresql/
│ └── main.tf # PostgreSQL RDS
├── redis/
│ └── main.tf # ElastiCache Redis
└── mongodb/
└── main.tf # DocumentDBМикросервисы
Группировка микросервисов по доменам:
services/
├── auth/
│ └── main.tf
├── payments/
│ └── main.tf
└── notifications/
└── main.tfЗависимости сабмодулей
Сабмодули могут зависеть от:
- Родительского модуля
- Других сабмодулей того же родителя
- Модулей вне родителя
Зависимость от родителя
# В ec2/rabbitmq/main.tf
data "terraform_remote_state" "ec2_parent" {
backend = "s3"
config = {
key = "platform/production/us-east-1/ec2/terraform.tfstate"
}
}Зависимости между сабмодулями
# В ec2/app/main.tf
data "terraform_remote_state" "rabbitmq" {
backend = "s3"
config = {
key = "platform/production/us-east-1/ec2/rabbitmq/terraform.tfstate"
}
}Сопоставление имён
TerraCi использует умное сопоставление имён для сабмодулей:
| Имя remote state | Соответствует |
|---|---|
ec2_rabbitmq | ec2/rabbitmq |
ec2-rabbitmq | ec2/rabbitmq |
rabbitmq | ec2/rabbitmq (в том же контексте) |
Сгенерированный пайплайн
Сабмодули отображаются как обычные джобы:
plan-platform-prod-us-east-1-ec2:
stage: deploy-plan-0
# ...
plan-platform-prod-us-east-1-ec2-rabbitmq:
stage: deploy-plan-1
needs:
- apply-platform-prod-us-east-1-ec2
# ...Индекс родительских модулей
TerraCi поддерживает индекс связей родитель-потомок:
type Module struct {
components map[string]string // именованные сегменты из паттерна
segments []string // упорядоченные имена сегментов
Path string
RelativePath string
Parent *Module // Ссылка на родителя (для сабмодулей)
Children []*Module // Ссылки на потомков (для родителей)
}Это позволяет:
- Запрашивать все сабмодули родителя
- Находить родителя сабмодуля (через
m.Parent) - Проверять, является ли модуль сабмодулем (через
m.IsSubmodule()) - Строить точные цепочки зависимостей
Лучшие практики
1. Группируйте связанные ресурсы
Объединяйте ресурсы, которые деплоятся вместе:
app/
├── main.tf # ECS-кластер, балансировщик нагрузки
├── api/
│ └── main.tf # API-сервис
└── worker/
└── main.tf # Фоновый воркер2. Выносите общую конфигурацию в родитель
Размещайте общие ресурсы в родительском модуле:
# В ec2/main.tf
resource "aws_security_group" "shared" {
name = "ec2-shared-sg"
}
output "shared_security_group_id" {
value = aws_security_group.shared.id
}# В ec2/rabbitmq/main.tf
data "terraform_remote_state" "parent" {
# ...
}
resource "aws_instance" "rabbitmq" {
vpc_security_group_ids = [
data.terraform_remote_state.parent.outputs.shared_security_group_id
]
}3. Единообразное именование
Используйте единообразные имена для сабмодулей:
✓ ec2/rabbitmq
✓ ec2/redis
✓ ec2/elasticsearch
✗ ec2/rabbit-mq
✗ ec2/Redis
✗ ec2/es4. Ограничивайте глубину вложенности
Хотя TerraCi поддерживает неограниченную вложенность сабмодулей, глубокие иерархии сложны в управлении. Рекомендуется реструктуризация при слишком глубокой вложенности:
# Вместо глубокой вложенности:
platform/prod/us-east-1/services/backend/api/v2/main.tf
# Используйте плоскую структуру:
platform/prod/us-east-1/backend-api/main.tfФильтрация сабмодулей
# Только сабмодули
terraci generate --include "*/*//*/*/**"
# Исключить конкретный сабмодуль
terraci generate --exclude "*/*/us-east-1/ec2/rabbitmq"
# Только родительские модули
terraci generate --exclude "*/*/*/*/*"Устранение неполадок
Сабмодули не обнаруживаются
- Убедитесь, что директория сабмодуля содержит
.tfфайлы - Убедитесь, что сабмодуль вложен глубже уровня паттерна
Родитель не привязан
Если родитель сабмодуля не определяется:
- Убедитесь, что родитель существует на глубине паттерна
- Проверьте, что родитель содержит
.tfфайлы - Запустите
terraci validate -vдля просмотра деталей обнаружения
Следующие шаги
- Структура проекта — паттерны директорий и обнаружение модулей
- Фильтры — include/exclude паттерны для выбора модулей