Skip to content

FAQ

What are the guiding principles for this project?

  1. No literals should be used anywhere in the code - All variables should be defined outside the code in a file that reflects the environment being deployed. This allows the same code to accommodate all customers, and it allows our customers to use the same code for all of their environments. This ensures consistency across environments with the ability to customize environments by simply changing the variables file. It also greatly simplifies our pipelines allowing us to use the same pipeline for all environments by simply changing the variables file that is used for each environment.
  2. When in doubt, use maps instead of lists - Maps allow us to define key-value pairs that can be referenced by key. This makes it easier to understand what each value represents. It allows us to avoid resource keys changing position in a list when new values are added or removed, which can cause unnecessary updates to resources and change the location of resources in the Terraform state file leading to potential resource destruction and recreation.
  3. Write code that allows us to build the entire infrastructure from a single execution of terraform apply and destroy with a single terraform destroy - Leverage Terraform's ability to manage dependencies between resources to build the entire infrastructure in a single execution. Avoid writing code that needs to be built incrementally or requires manually looking up resource IDs to supply as input to other resources. This allows us to deploy customer's infrastructure rapidly and to automate testing and the deployment/destruction of our dev environment.
  4. Nest related variables so that they intuitively reflect the dependencies/relationships between resources - For example, subnets are defined within the VPC variable. This makes it easier to understand the relationships between resources and to avoid errors when defining variables. It should be intuitive enough that even someone who isn't familiar with Terraform can make changes to the variables to customize an environment.

Why do we wrap every resource in its own module?

This AWS best practices document says to avoid wrapping single resources in modules, however, we have found that if we want to have consistent references to resources whether we are creating them or referencing an existing resource provided by a customer, the abstraction is required for normalizing the output of resource and data blocks. It also prevents the need to ever change a module name, which would have significant implications for the Terraform state file, potentially causing resources to be destroyed and recreated.

We learned early on that if we start out building resources by using Terraform resource blocks outside a module and later decided to wrap them in a module, refactoring the code will result in a new resource being created and the old resource being destroyed because of the resulting changes in the Terraform state file. We decided to start out with a module for all resources from the beginning to avoid this issue.

What branching strategy should be used for this project?

We use different directories for each environment, to avoid the need to maintain long-lived branches. This allows us to use a single branch for all environments and to use feature branches to develop new features. Pipelines can be run against a feature branch to validate the changes in any of the environments before merging them into the master branch. We can then merge the feature branches into the master branch and run the pipeline to deploy the changes to all environments.

Why don't we use Terraform to write long-form declarative infrastructure?

This method of writing IaC requires infrastructure to deployed incrementally. Resources that are dependencies for other resources must be created first so that their IDs can be looked up and supplied as input to the dependent resources. This process is slow and cumbersome. Our goal is to require as little input as possible to avoid human error, and enable rapid, reliable deployment of infrastructure.

What are the naming conventions for this project?

Under construction