Defining Terraform project structure
Terraform looks for all .tf files in the current directory, loads them & determines the desired state of infrastructure. This sounds fairly simple; so basically we can write terraform configuration file in the same directory & that’s it! However, there is minor challenge here – there are some resources in the infrastructure which we wish to create once & use it forever.
Terraform handles incremental infrastructural changes very nicely, but this could be a problem sometimes as it will not change anything if nothing has changed in the configuration even if we wish to destroy & recreate resources. So basically, it’s not even an option to keep all our terraform configuration files in the same directory.
To handle this situation, we can breakdown infrastructure resources into 3 main categories:
- Account level resources – Created only once, like state buckets, users with no access permissions
- Environment level resource – Created only once but updated as infrastructure evolves. This includes IAM roles, policies, s3 buckets & EBS volumes for data, cloudwatch groups etc.
- Actual compute resources – These are the resources mainly destroyed & recreated every time environment is rebuild, which includes EC2 instances, lambda functions, API gateway endpoints etc.
Although I personally prefer above mentioned project structure for simple projects; for further complicated projects, standard terraform modules can be used as shown below –