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(-ies): infrastructure for the application <APP_NAME>
modules/ Reusable child modules
networks/ [Root module] Account level network config (shared across all apps, environments, and terraform workspaces)
test/ Infrastructure tests
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:
devstagingprod
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):
-
Make sure you have an application that meets the application requirements for using this infrastructure.
Tip: You don't need an actual application to deploy until you want to set up the application environment (the last step).
-
Review and optionally update your project configuration
Important: Make sure you review and understand /infra/project-config/main.tf. Configuration here can have broad impact that is hard to change later, so be reasonably confident things are right initially.
Note: Some application config impacts other layers besides the application environment. So if you want to minimize back and forth during set up, you should read the requirements for setting up an application environment and configure #### your application infrastructure with what you currently know you need (e.g. a database, external service access).
-
Set up application environment
Tip: If you don't yet have an application meeting the application requirements for using this infrastructure, you can copy this example app to your repository to have something that will run for testing the infrastructure, and swap in your actual application code later.
Use the Platform CLI to add another application to an existing repo
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
Set up the following before launching to end users in production:
- HTTPS support
- Custom domains
- Monitoring alerts
- Web application firewall (WAF)
- Staging and production environments
- Additional applications
- Background jobs
- Custom environment variables and secrets
- Identity provider
- User notifications
- Pull request (preview) environments
- Service command execution
- Outbound public internet access
- CI/CD system notifications
- Destroy infrastructure
- Develop and test infrastructure in isolation using workspaces
- Making infrastructure changes
- Upgrade database
Additional documentation can be found in the documentation directory.