cds-snc / notification-terraform

Terraform for notification.canada.ca
MIT License
13 stars 6 forks source link
notification-canada-ca

notification-terraform

Requires

Why are we using Terragrunt?

The promise of Terragrunt is to make it easier to maintain Terraform code by providing a wrapper around modules, adhering to "Don't repeat yourself" (DRY) configuration as well as better remote state management. For a complete explanation of features, take a look at the excellent documentation.

How is this repository structured?

The Terraform code contained in aws is split into several independent modules that all use their own remote Terraform state file. These modules know nothing about Terragrunt and are used by Terragrunt as simple infrastructure definitions. All the Terraform code in aws is environment agnostic, this means, it does not know if it runs in dev, staging, or production. This is achieved through variable interpolations. For example a Kubernetes cluster in staging requires less powerful compute nodes than in production. As a result the Kubernetes worker definition contains the var.primary_worker_instance_types variable.

The directory structure inside aws reflects the split into independent modules. For example, common, contains all the networking logic required inside the application, while eks and rds represent the deployments of the Kubernetes cluster and the RDS database. The advantage is that if changes need to be made to infrastructure, should they fail, the state file has less chance of corruption and blast radius is decreased. Additionally, there are significant time gains in running modules independently as the infrastructure dependency graph is limited.

Terragrunt scripts are found in env, which defines all the environment specific variables. Contained are subdirectories that define all the Terraform modules that should exist in each environment.

How do we run terragrunt plan locally?

Running terragrunt plan locally (as opposed to through the GitHub actions) can speed up development, in particular to see if your new terraform code is horribly broken. You will need two things:

Now:

Important notes:

How are changes applied to the different environments?

Changes are applied through Git merges to this repository. Terragrunt supports the idea of remote Terraform configurations based on tags. This mean we can setup the following continuous integration workflows:

Staging

Production

Necessary additional steps

⚠️ We had to perform some actions on other repositories or manually using the AWS Console. Here is a list of these actions:

Helpful commands

Within the Makefile, you can pull the Target Group ARNs using the get-tg-arns command

# If you would like to specify an environment, it can by done like so
AWS_PROFILE=notify-staging make get-tg-arns

What is each Terraform module

aws/cloudfront

Assets to create to serve static assets on CloudFront CDN.

aws/common

Common networking assets such as:

aws/dns

DNS specific outputs for the domain nameserver

aws/eks

Assets to create a working Elastic Kubernetes Service (EKS):

aws/elasticache

Assets an Elasticache Redis cluster.

aws/lambda-api

Assets to create and hook up a lambda function for the api: the lambda function, an api gateway, and the private container repository (currently required for deploying images into lambda functions).

To add or change environment variables we

aws/rds

Assets to create a working Relational Database Service (RDS) using Aurora PostgreSQL.

Preliminary architecture diagram

notify-temp-arch