Skip to content

Terraform Setup

Installation

This project requires Terraform to run. You might use a different package manager to install it depending on your system.

For Macs, you can use brew:

brew install terraform

Anaconda users on any architecture should be able to use conda or mamba:

conda install -c conda-forge terraform

We also use tflint for linting, and terraform-docs to help with documentation of resources. These can be installed in the same manner, e.g.:

conda install -c conda-forge tflint go-terraform-docs

There are a number of pre-commit checks that run on committing as well as in CI. To install the checks, run the following from the repository root:

pre-commit install

You can manually run the pre-commit checks using:

pre-commit run --all-files

Bootstrapping remote state

When deploying a new version of your infrastrucutre, Terraform diffs the current state against what you have specified in your infrastructure-as-code. The current state is tracked in a JSON document, which can be stored in any of a number of locations (including local files).

This project stores remote state using the S3 backend.

Different applications or environments can be isolated from each other by using different S3 buckets for holding their state. We reuse a terraform configuration (terraform/s3-remote-state) for setting up the S3 backend

Note

The S3 remote state configuration is not a proper module because it contains a provider block. Different deployments of the configuration are controlled by giving it different tfvars files, and capturing the outputs for use in a tfbackend file.

Here is an example set of commands for bootstrapping a new S3 backend for a deployment. Suppose the deployment is a QA environment of our Snowflake project:

cd terraform/snowflake/environments/qa  # Go to the new environment directory
mkdir remote-state  # Create a remote-state directory
cd remote-state
ln -s ../../../s3-remote-state/main.tf main.tf  # symlink the s3 configuration
terraform init  # initialize the remote state backend
terraform apply -var="owner=dse" -var="environment=qa" -var="project=snowflake"  # Create the infrastructure
terraform output > ../dse-snowflake-qa.tfbackend  # Pipe the outputs to a .tfbackend

cd ..
terraform init -backend-config=./dse-snowflake-qa.tfbackend  # Configure the deployment with the new backend.

Deploying Infrastructure

When you are ready to deploy a new version of the infrastructure, run

terraform apply

This will output the changes to the infrastructure that will be made, and prompt you for confirmation.

Updating terraform dependencies

Terraform deployments include a lockfile with hashes of installed packages. Because we have mixed development environments (i.e., Macs locally, Linux in CI), it is helpful to include both Mac and Linux builds of terraform packages in the lockfile. This needs to be done every time package versions are updated:

terraform init -upgrade  # Upgrade versions
terraform providers lock -platform=linux_amd64 -platform=darwin_amd64  # include Mac and Linux binaries

Requirements

Name Version
terraform >= 1.0
aws 4.56.0
random 3.4.3

Providers

Name Version
aws 4.56.0
random 3.4.3

Modules

No modules.

Resources

Name Type
aws_batch_compute_environment.default resource
aws_batch_job_definition.default resource
aws_batch_job_queue.default resource
aws_ecr_repository.default resource
aws_eip.this resource
aws_iam_group.aae resource
aws_iam_group_membership.aae resource
aws_iam_group_policy_attachment.aae_dsa_project resource
aws_iam_group_policy_attachment.aae_list_all_my_buckets resource
aws_iam_group_policy_attachment.aae_self_manage_creentials resource
aws_iam_policy.access_snowflake_loader resource
aws_iam_policy.batch_submit_policy resource
aws_iam_policy.default_ecr_policy resource
aws_iam_policy.dof_demographics_read_write_access resource
aws_iam_policy.mwaa resource
aws_iam_policy.s3_dsa_project_policy resource
aws_iam_policy.s3_list_all_my_buckets resource
aws_iam_policy.s3_scratch_policy resource
aws_iam_policy.self_manage_credentials resource
aws_iam_role.aws_batch_service_role resource
aws_iam_role.batch_job_role resource
aws_iam_role.ecs_task_execution_role resource
aws_iam_role.mwaa resource
aws_iam_role_policy_attachment.aws_batch_service_role resource
aws_iam_role_policy_attachment.dof_demographics_read_write_access resource
aws_iam_role_policy_attachment.ecs_task_execution_access_snowflake_loader resource
aws_iam_role_policy_attachment.ecs_task_execution_role_policy resource
aws_iam_role_policy_attachment.mwaa_batch_submit_role resource
aws_iam_role_policy_attachment.mwaa_execution_role resource
aws_iam_role_policy_attachment.s3_scratch_policy_role_attachment resource
aws_iam_user.arman resource
aws_iam_user.cd_bot resource
aws_iam_user.esa resource
aws_iam_user.kim resource
aws_iam_user.monica resource
aws_iam_user.rocio resource
aws_iam_user_policy_attachment.batch_cd_bot_policy_attachment resource
aws_iam_user_policy_attachment.ecr_cd_bot_policy_attachment resource
aws_internet_gateway.this resource
aws_mwaa_environment.this resource
aws_nat_gateway.this resource
aws_route_table.private resource
aws_route_table.public resource
aws_route_table_association.private resource
aws_route_table_association.public resource
aws_s3_bucket.dof_demographics_public resource
aws_s3_bucket.dsa_project resource
aws_s3_bucket.mwaa resource
aws_s3_bucket.scratch resource
aws_s3_bucket_policy.dof_demographics_public_read_access resource
aws_s3_bucket_public_access_block.dof_demographics_public resource
aws_s3_bucket_public_access_block.mwaa resource
aws_s3_bucket_versioning.dof_demographics_public resource
aws_s3_bucket_versioning.dsa_project resource
aws_s3_bucket_versioning.mwaa resource
aws_security_group.batch resource
aws_security_group.mwaa resource
aws_subnet.private resource
aws_subnet.public resource
aws_vpc.this resource
random_id.private_subnet resource
random_id.public_subnet resource
aws_availability_zones.available data source
aws_caller_identity.current data source
aws_iam_policy_document.access_snowflake_loader data source
aws_iam_policy_document.assume data source
aws_iam_policy_document.assume_role_policy data source
aws_iam_policy_document.aws_batch_service_policy data source
aws_iam_policy_document.batch_submit_policy_document data source
aws_iam_policy_document.default_ecr_policy_document data source
aws_iam_policy_document.dof_demographics_public_read_access data source
aws_iam_policy_document.dof_demographics_read_write_access data source
aws_iam_policy_document.mwaa data source
aws_iam_policy_document.s3_dsa_project_policy_document data source
aws_iam_policy_document.s3_list_all_my_buckets data source
aws_iam_policy_document.s3_scratch_policy_document data source
aws_iam_policy_document.self_manage_credentials data source
aws_secretsmanager_secret.snowflake_loader_secret data source

Inputs

Name Description Type Default Required
environment Deployment environment of the resource string "dev" no
owner Owner of the resource string "dse" no
project Name of the project the resource is serving string "infra" no
region Region for AWS resources string "us-west-2" no
snowflake_loader_secret ARN for SecretsManager login info to Snowflake with loader role object({ test = string, latest = string }) null no

Outputs

Name Description
state Resources from terraform-state