Skip to content

Commit

Permalink
Template infra deploy #9650269532
Browse files Browse the repository at this point in the history
  • Loading branch information
nava-platform-bot committed Jun 24, 2024
1 parent 281db47 commit 7328e2b
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 100 deletions.
2 changes: 1 addition & 1 deletion .template-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fc5165967581804a5ad8b46c39b296f26eae3f53
628bdc5e8f7d5e869430c85e4787857f11b98863
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Develop and test infrastructure in isolation using workspaces

When developing infrastructure code, you often want to develop and test your changes in isolation so that:

- Your changes do not impact other engineers on the team
- Other engineers working on infrastructure do not revert your changes when making their own changes
- Other engineers can review your changes before applying them

This document describes a workflow that leverages [Terraform workspaces](https://developer.hashicorp.com/terraform/language/state/workspaces) for developing and testing infrastructure changes in isolation so that they can be tested and peer reviewed before being merged into main.

## Overview

By default, each Terraform root module has a single workspace named `default`. Workspaces allow you to deploy multiple instances of the root module configuration without configuring a new backend. When you run `terraform apply` in a separate workspace, a parallel set of infrastructure resources are created.

There are a few notable differences with resources created in a non-default workspace:

1. When using terraform, you cannot deploy the same resource with the same name. The `terraform apply` will fail with an error like "A resource with the ID already exists". Therefore, to avoid naming conflicts, we prefix the resource names with the workspace name.
2. Some resources, such as database and storage buckets, enable deletion protection to prevent accidental deletion. However, non-default workspaces are intended to be temporary, so deletion protection is disabled in non-default workspaces.
3. Resources that are difficult to create in isolation, such as [DNS records](https://github.com/navapbc/template-infra/blob/2cda6da18c84aa5a3dfb038ab32be4fac363af21/infra/modules/service/dns.tf#L3), are not created at all.

## Development workflow

Follow these steps if you want to develop and test a change to the service layer. Make the appropriate changes to the `-chdir` flag if you want to make a change to a different layer, such as the database layer or network layer.

### 1. Create a new workspace

First, make sure that the Terraform root module is initialized to the dev environment

```bash
terraform -chdir=infra/$app_name/service init -backend-config=dev.s3.tfbackend
```

Then creat a new workspace. Since the workspace name is used to prefix resource names, use a short workspace name to avoid hitting resource name size limits. Assuming you're only working on one thing at a time (following the Kanban principle of limiting work in progress), your initials would make a good workspace name. For example, if your name was Loren Yu, you could use `ly` as your workspace name.

```bash
terraform -chdir=infra/$app_name/service workspace new <WORKSPACE_NAME>
```

Verify that the new workspace was created and selected:

```bash
# List all workspaces, with a * next to the selected workspace
terraform -chdir=infra/$app_name/service workspace list
# - OR -
# Show your current selected workspace
terraform -chdir=infra/$app_name/service workspace show
```

### 2. Create resources in your workspace

```bash
terraform -chdir=infra/$app_name/service apply -var=environment_name=dev
# - OR -
make infra-update-app-service "APP_NAME=$app_name" ENVIRONMENT=dev
```

### 3. Clean up after merging to main and deploying changes to default workspace

Finally, after you merged your pull request and have deployed your changes to the default workspace, clean up your workspace so that you don't continue to accrue costs from the infrastructure resources.

```bash
# Destroy all infrastructure resources within the workspace
terraform -chdir=infra/$app_name/service destroy -var=environment_name=dev
# Select default workspace so that you can delete your workspace, since you can't delete the selected workspace
terraform -chdir=infra/$app_name/service workspace select default
# Delete your workspace
terraform -chdir=infra/$app_name/service delete <WORKSPACE_NAME>
```
59 changes: 0 additions & 59 deletions docs/infra/intro-to-terraform-workspaces.md

This file was deleted.

33 changes: 0 additions & 33 deletions docs/infra/intro-to-terraform.md

This file was deleted.

24 changes: 21 additions & 3 deletions docs/infra/making-infra-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Make changes to the account:
make infra-update-current-account
```

Make changes to the network:

```bash
make infra-update-network NETWORK_NAME=dev
```

Make changes to the application service in the dev environment:

```bash
Expand Down Expand Up @@ -48,9 +54,21 @@ Look in the script files for more details on usage.

## Using Terraform CLI directly

Finally, if the wrapper scripts don't meet your needs, you can always run `terraform` directly from the root module directory. You may need to do this if you are running terraform commands other than `terraform plan` and `terraform apply`, such as `terraform import`, `terraform taint`, etc. To do this, you'll need to pass in the appropriate `tfvars` and `tfbackend` files to `terraform init` and `terraform apply`. For example, to make changes to the application's service resources in the dev environment, cd to the `infra/app/service` directory and run:
Finally, if the wrapper scripts don't meet your needs, you can always run `terraform` directly. You may need to do this if you are running terraform commands other than `terraform plan` and `terraform apply`, such as `terraform import`, `terraform taint`, etc. To do this, you'll need to remember to run `terraform init` with the appropriate `tfbackend` file since the root modules are shared across multiple backends. For example, to make changes to the application's service resources in the dev environment:

```bash
project-root$ cd infra/app/service
infra/app-service$ terraform init -backend-config=dev.s3.tfbackend
infra/app-service$ terraform apply -var-file=dev.tfvars
```

or you can run the commands from the project root by using the `-chdir` flag.

```bash
infra/app/service$ terraform init -backend-config=dev.s3.tfbackend
infra/app/service$ terraform apply -var-file=dev.tfvars
project-root$ terraform init -chdir=infra/app/service -backend-config=dev.s3.tfbackend
project-root$ terraform apply -chdir=infra/app/service -var="environment_name=dev"
```

## See also

While developing infrastructure, you often don't want to make changes directly to the infrastructure before your infrastructure code has been tested, peer reviewed, and merged into main. In these situations, [use workspaces to develop and test your infrastructure changes in isolation](./develop-and-test-infrastructure-in-isolation-using-workspaces.md).
2 changes: 0 additions & 2 deletions docs/infra/set-up-infrastructure-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ You may need to set the Terraform version.
tfenv use 1.8.0
```

If you are unfamiliar with Terraform, check out this [basic introduction to Terraform](./intro-to-terraform.md).

### Install AWS CLI

The [AWS Command Line Interface (AWS CLI)](https://aws.amazon.com/cli/) is a unified tool to manage your AWS services. With just one tool to download and configure, you can control multiple AWS services from the command line and automate them through scripts. Install the AWS command line tool by following the instructions found here:
Expand Down
4 changes: 2 additions & 2 deletions infra/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ To get set up as a new developer on a project that has already been deployed to

1. [Set up infrastructure developer tools](/docs/infra/set-up-infrastructure-tools.md)
2. [Review how to make changes to infrastructure](/docs/infra/making-infra-changes.md)
3. [Review the infrastructure style guide](/docs/infra/style-guide.md)
4. (Optional) Set up a [terraform workspace](/docs/infra/intro-to-terraform-workspaces.md)
3. [Review how to develop and test infrastructure changes](/docs/infra/develop-and-test-infrastructure-in-isolation-using-workspaces.md)
4. [Review the infrastructure style guide](/docs/infra/style-guide.md)

## 📇 Additional reading

Expand Down

0 comments on commit 7328e2b

Please sign in to comment.