Let's think about this for a second
In a real-world project, you'll typically organize things by splitting the network layer (VPC, subnet), compute layer (server), and storage layer (database/bucket) into a module structure (`modules/network`, `modules/compute`, `modules/storage`) — each layer's output gets wired into the next layer's input, like passing the network module's subnet_id output into the compute module's subnet_id input. When you call the three modules in order inside the root config, Terraform figures out the dependency graph on its own.
Let's connect this to a real scenario
Split things into three modules: `modules/network/` (VPC + subnet), `modules/compute/` (server, taking subnet_id as an input), and `modules/storage/` (database) — then wire them together in the root `main.tf` with `module "network" { ... }` → `module "compute" { subnet_id = module.network.subnet_id }` → `module "storage" { ... }`. Run `terraform plan` and you can preview the resources for every layer all at once.
Let's look at an example
# root main.tf
module "network" {
source = "./modules/network"
}
module "compute" {
source = "./modules/compute"
subnet_id = module.network.subnet_id
}
module "storage" {
source = "./modules/storage"
}
output "web_server_ip" {
value = module.compute.public_ip
}$ terraform apply
module.network.aws_vpc.main: Creating...
module.network.aws_subnet.app: Creating...
module.compute.aws_instance.web: Creating...
module.storage.aws_db_instance.main: Creating...
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.Try it in 5 minutes
Create the three module folders (network/compute/storage) yourself and wire them together from the root config — then run `terraform plan` and verify all the layers are connected correctly.
A quick word of caution
Before you actually apply against a provider with real credentials/costs (like AWS) in a production project, read through `terraform plan` carefully — going over the free tier limit can rack up real charges.