Skip to content

root module

Aleksej Komnenovic edited this page Jun 30, 2026 · 3 revisions

Root Module (aws/)

The only module you call directly. Child modules are internal.

Files

File Purpose
main.tf Module composition + precondition validations
variables.tf Top-level structured object variables
outputs.tf Root outputs (33 values)
locals.tf Component creation flags, cross-module wiring
data.tf aws_region, aws_caller_identity, aws_availability_zones
versions.tf Provider requirements

Module Composition (main.tf)

The root module conditionally instantiates four child modules:

module "vpc" {
  count  = local.create_vpc ? 1 : 0
  source = "./modules/vpc"

  nat_gateway_mode               = var.vpc.nat_gateway_mode
  enable_vpc_endpoints           = var.vpc.enable_vpc_endpoints
  create_public_subnets          = local.needs_public_subnets
  additional_interface_endpoints = local.vpc_additional_endpoints
  # ...
}

module "storage" {
  count  = local.create_storage ? 1 : 0
  source = "./modules/storage"
  # ...
}

module "database" {
  count      = local.create_database ? 1 : 0
  source     = "./modules/database"
  depends_on = [module.vpc]
  # ...
}

module "ecs" {
  count      = local.create_ecs ? 1 : 0
  source     = "./modules/ecs"
  depends_on = [module.vpc, module.storage, module.database]
  # ...
}

Precondition Validations

Three terraform_data resources enforce dependency rules:

  1. brms_dependencies: BRMS requires the Database Module (database set), plus object storage satisfied by either the Storage Module (storage set) or brms.external_buckets (for cross-account deployments). Two preconditions enforce this: local.create_database, and local.create_storage || length(coalesce(var.brms.external_buckets, [])) > 0.
  2. agent_dependencies: Agent requires Storage Module
  3. vpc_validation (existing-VPC mode): requires vpc.id and at least one private_subnet_id. Additionally, when any enabled ALB is internet-facing (alb_internal = false, the default), at least one public_subnet_id is required (the local.needs_public_subnets check). Set alb_internal = true on each component to deploy ALBs in private subnets and make public subnets optional.

Creation Flags (locals.tf)

Boolean flags control which modules are instantiated:

locals {
  create_vpc      = var.vpc != null && var.vpc.create
  create_storage  = var.storage != null
  create_bucket   = local.create_storage && var.storage.create_bucket
  create_database = var.database != null
  create_brms     = var.brms != null
  create_agent    = var.agent != null
  create_ecs      = local.create_brms || local.create_agent
}

Derived locals

Two more locals translate component settings into VPC wiring:

  • needs_public_subnets is true when any enabled component has alb_internal = false. It is passed to the VPC module as create_public_subnets and gates the public-subnet precondition in vpc_validation.
  • vpc_additional_endpoints computes the extra interface VPC endpoints to provision: kms when brms.secrets_provider.type = "aws-kms", bedrock-runtime when brms.ai.provider = "amazon-bedrock", plus any vpc.additional_vpc_endpoints. It is passed to the VPC module as additional_interface_endpoints.

Cross-Module Wiring

The root main.tf handles cross-module security group rules:

resource "aws_security_group_rule" "database_from_brms" {
  count                    = local.create_brms && local.create_database ? 1 : 0
  type                     = "ingress"
  from_port                = local.database_port  # 5432
  to_port                  = local.database_port  # 5432
  protocol                 = "tcp"
  source_security_group_id = module.ecs[0].brms_tasks_security_group_id
  security_group_id        = module.database[0].security_group_id
}

This allows BRMS ECS tasks to connect to the Aurora database. See Security Architecture for details.

Data Flow

See Variable System for how configuration flows from root variables to child modules.

Clone this wiki locally