This project practices infrastructure-as-code and uses the Terraform framework. This directory contains the infrastructure code for this project, including infrastructure for all application resources. This terraform project uses the AWS provider. It is based on the Nava platform infrastructure template.
The structure for the infrastructure code looks like this:
infra/ Infrastructure code
project-config/ Project-level configuration for account-level resources and resource tags
accounts/ [Root module] IaC and IAM resources
[app_name]/ Application directory: infrastructure for the main application
modules/ Reusable child modules
networks/ [Root module] Account level network config (shared across all apps, environments, and terraform workspaces)
Each application directory contains the following:
app-config/ Application-level configuration for the application resources (different config for different environments)
build-repository/ [Root module] Docker image repository for the application (shared across environments and terraform workspaces)
database/ [Root module] Configuration for database (different config for different environments)
service/ [Root module] Configuration for containers, such as load balancer, application service (different config for different environments)
Details about terraform root modules and child modules are documented in module-architecture.
The infrastructure derives all of its configuration from static configuration modules:
- Project config
- App config (per application)
The configuration modules contain only statically known information and do not have any side effects such as creating infrastructure resources. As such, they are used as both (a) root modules by shell scripts and CI/CD workflows and (b) child modules called by root modules across the infrastructure layers. See infrastructure configuration for more info.
The infrastructure is designed to operate on different layers:
- Account layer
- Network layer
- Build repository layer (per application)
- Database layer (per application)
- Service layer (per application)
This project has the following AWS environments:
dev
staging
prod
The environments share the same root modules but will have different configurations. Backend configuration is saved as .tfbackend
files. Most .tfbackend
files are named after the environment. For example, the [app_name]/service
infrastructure resources for the dev
environment are configured via dev.s3.tfbackend
. Resources for a module that are shared across environments, such as the build-repository, use shared.s3.tfbackend
. Resources that are shared across the entire account (e.g. /infra/accounts) use <account name>.<account id>.s3.tfbackend
.
This project relies on Make targets in the root Makefile, which in turn call shell scripts in ./bin. The shell scripts call terraform
commands. Many of the shell scripts are also called by the Github Actions CI/CD.
Generally, you should use the Make targets or the underlying bin scripts, but you can call the underlying terraform commands if needed. See making-infra-changes for more details.
To set up this project for the first time (i.e., it has never been deployed to the target AWS account):
- Install this template into an application that meets the Application Requirements
- Configure the project (These values will be used in subsequent infra setup steps to namespace resources and add infrastructure tags.)
- Set up infrastructure developer tools
- Set up AWS account
- Set up the virtual network (VPC)
- For each application:
To get set up as a new developer on a project that has already been deployed to the target AWS account:
- Set up infrastructure developer tools
- Review how to make changes to infrastructure
- Review how to develop and test infrastructure changes
- Review the infrastructure style guide
Additional documentation can be found in the documentation directory.