├── _modules │ ├── network │ │ ├── dev │ │ │ └── main.tf │ │ ├── nonprod │ │ │ └── main.tf │ │ └── prod │ │ └── main.tf │ └── services │ ├── dev │ │ └── main.tf │ ├── nonprod │ │ └── main.tf │ └── prod │ └── main.tf ├── dev │ ├── main.tf │ └── vars.tf ├── nonprod │ ├── main.tf │ └── vars.tf ├── prod ├── main.tf └── vars.tf This is a simple main.tf that has separated modules for activating APIs and subnetworks for a new project. This terraform skeleton also shows how to benifit from breaking down sections into modules plus uses examples on how to execute simple logic like count.index and for_each to keep the terraform code minimal. The goal of this is to create multi environment deployment from a single repo.
- The network module uses a
for_eachloop
resource "google_compute_subnetwork" "default" { for_each = local.subnet_data project = "${var.project}" name = "${var.name}" ip_cidr_range = each.value region = each.key network = "${google_compute_network.default.self_link}" } - The services module activates a
count.indexparameter
resource "google_project_service" "project_services" { project = "${var.project}" count = "${length(local.api_list)}" service = "${element(local.api_list, count.index)}" } Generally speaking as each environment goes up (dev -> nonprod -> prod) security for a project becomes more strict. To achieve this change the environments main.tf modules source to point at the corresponding module environments folder. _modules/services/dev/main.tf into _modules/services/nonprod/main.tf
then reduce the amout of API's that are enabled or remove subnets upon project creation.
Inside the modules folder /_modules/services/nonprod/main.tf alter the list of APIs that get enabled. The same goes for /_modules/services/prod/main.tf file.
In each environment the only part that changes per environment main.tf is the source part of the module.
module "api_services" { source = "../_modules/services/dev/" project = "${data.google_project_services.project.project}" } module "api_services" { source = "../_modules/services/nonprod/" project = "${data.google_project_services.project.project}" } The commands are the same but to deploy a specific environment the terraform plan and terraform apply must contain the folder.
For example:
To deploy a dev environment - (from the root directory)
terraform init /dev terraform plan /dev terraform apply /dev To deploy a nonprod environment - (from the root directory)
terraform init /nonprod terraform plan /nonprod terraform apply /nonprod