Make your life easier by starting with the best folder structure for your use-case

Most companies and ops teams will face the challenge in managing multiple environments (e.g. development, staging, pre-production, production) for their applications. Sometimes even in multiple regions. So you better think about how you organize all these files in terraform.

Terraform doesn’t care what’s in what file, as long as the file ends with .tf in your current directory. You can work with symlinks from other folders to share configurations or define the ssh key of the admin individually per team member by adding the file to .gitignore. I assume you work with git (or some version control system), if not: lol!

Folder structure organized by region

Here you can fine an example folder structure organized by regions and accounts.

├── eu-central-1
│   ├── backend
│   │   ├── dev
│   │   ├── prod
│   │   └── stage
│   ├── shop
│   │   ├── dev
│   │   ├── prod
│   │   │   ├── iam.tf
│   │   │   ├── main.tf
│   │   │   ├── network.tf
│   │   │   ├── service.database.tf
│   │   │   ├── service.reverseproxy.tf
│   │   │   ├── service.webserver.tf
│   │   │   ├── ssh_admin.shared.tf -> ../../ssh_admin.tf
│   │   │   ├── variables.shared.euc1.tf -> ../../variables.tf
│   │   │   ├── variables.shared.shop.tf -> ../variables.tf
│   │   │   └── variables.tf
│   │   ├── stage
│   │   └── variables.tf
│   ├── ssh_admin.tf
│   └── variables.tf
├── us-east-1
│   ├── frontend
│   │   ├── dev
│   │   ├── prod
│   │   └── stage
│   └── shop
│       ├── dev
│       ├── prod
│       └── stage
├── us-west-1
|    ├── frontend
|    │   ├── dev
|    │   ├── prod
|    │   └── stage
|    └── shop
|        └── prod
├── globals
│   └── data
│       └── certs
│           └── ssh
│               └── user.id_rsa.pub
└── modules
    └── company
        ├── ECS-EC2
        │   ├── main.tf
        │   ├── output.tf
        │   └── variables.tf
        └── rds-cluster
            ├── main.tf
            ├── output.tf
            └── variables.tf

While eu-central-1, us-east-1 and us-west-1 are obviously the AWS regions, backend, shop or frontend can and should be separate AWS accounts.

Why the hell would I need more then one AWS Account?

Sigh…ever heard of best practices? RTFM! AWS has service limits. There are soft and hard limits. Also: think security! If you are using microservices which only talk to each other using a public APIs, is there even a need to have all services in the same account?

Read more about accounts

Make use of symlinks to share variables across multiple regions or accounts.

If you need to have your different applications talk to each other using a private network, make use of VPC peering, but remember there are also limits on how many VPC can be linked.

You need to think about what application / micro-service “deserves” a separate account and which once can stay together (because they are sharing a database for example).

Access resources in different regions or accounts in terraform

While separating the configs per region or service or environment gives you a nice overview on a filesystem level, you will face the issue of accessing resource in other regions or accounts. Especially resources which are global, like Route53.

I dedicated a separate article explaining the terraform AWS provider configuration and resource configuration to solve this.

Read more