Terraform Infrastructure
Terraform is an open-source infrastructure as code software tool that enables you to safely and predictably create, change, and improve infrastructure.
The Terraform infrastructure generator creates a Terraform infrastructure project. The generated application includes security best practices through Checkov security checks.
Generate a Terraform Project
Section titled “Generate a Terraform Project”You can generate a new Terraform project in two ways:
- Install the Nx Console VSCode Plugin if you haven't already
- Open the Nx Console in VSCode
- Click
Generate (UI)in the "Common Nx Commands" section - Search for
@aws/nx-plugin - terraform#project - Fill in the required parameters
- name: tf-infra
- Click
Generate
pnpm nx g @aws/nx-plugin:terraform#project --name=tf-infrayarn nx g @aws/nx-plugin:terraform#project --name=tf-infranpx nx g @aws/nx-plugin:terraform#project --name=tf-infrabunx nx g @aws/nx-plugin:terraform#project --name=tf-infraYou can also perform a dry-run to see what files would be changed
pnpm nx g @aws/nx-plugin:terraform#project --name=tf-infra --dry-runyarn nx g @aws/nx-plugin:terraform#project --name=tf-infra --dry-runnpx nx g @aws/nx-plugin:terraform#project --name=tf-infra --dry-runbunx nx g @aws/nx-plugin:terraform#project --name=tf-infra --dry-runOptions
Section titled “Options”| Parameter | Type | Default | Description |
|---|---|---|---|
| name Required | string | - | The name of the project. |
| type | string | application | Whether this is a terraform lib (re-usable modules) or app (deployable). |
| directory | string | packages | The directory of the new project. |
| subDirectory | string | - | The sub directory the project is placed in. By default this is the project name. |
Generator Output
Section titled “Generator Output”The generator creates different file structures depending on the project type:
Application Type
Section titled “Application Type”For application projects (--type=application), the generator creates a complete Terraform application with remote state management:
Directorysrc
- main.tf Main Terraform configuration file
- providers.tf Provider configuration with S3 backend
- variables.tf Input variable definitions
- outputs.tf Output value definitions
Directoryenv Environment-specific variable files
- dev.tfvars Development environment variables
Directorybootstrap Bootstrap configuration for remote state
- main.tf S3 bucket and policies for state storage
- providers.tf AWS provider configuration
- variables.tf Bootstrap variable definitions
- project.json Project configuration and build targets
Library Type
Section titled “Library Type”For library projects (--type=library), the generator creates a simpler structure for reusable Terraform modules:
Directorysrc
- main.tf Main Terraform module file
- project.json Project configuration and build targets
Implementing your Terraform Infrastructure
Section titled “Implementing your Terraform Infrastructure”You can start writing your Terraform infrastructure inside src/main.tf, for example:
locals { account_id = data.aws_caller_identity.current.account_id aws_region = data.aws_region.current.id}
resource "null_resource" "print_info" { # triggers = { # always_run = timestamp() # }
provisioner "local-exec" { command = "echo 'AWS Region: ${local.aws_region}, AWS Account: ${local.account_id}, Environment: ${var.environment}'" }}
# Declare your infrastructure hereresource "aws_s3_bucket" "my_bucket" { bucket = "my-unique-bucket-name"}Cross project dependencies
Section titled “Cross project dependencies”If you wanted to execute a module from a seperate project (lib), you could do so as follows:
module "lib_module" { source = "../../path/to/my-lib/src"}This will automatically update the Nx graph to add a dependency between your consuming application and your lib.
Environment Configuration
Section titled “Environment Configuration”Configure environment-specific variables in the src/env/*.tfvars files.
To add new environments, create a new src/env/<environment>.tfvars file with the environment-specific variables and add new entries for apply, destroy, init, plan in the project.json for the new env configuration. For example, let’s assume we want to add a prod env:
# Production environment variablesenvironment = "prod"region = "us-west-2"{ "targets": { "apply": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform apply ../../../dist/packages/infra/terraform/dev.tfplan" }, "prod": { "command": "terraform apply ../../../dist/packages/infra/terraform/prod.tfplan" } }, "options": { "forwardAllArgs": true, "cwd": "{projectRoot}/src" }, "dependsOn": ["plan"] }, "destroy": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform destroy -var-file=env/dev.tfvars" }, "prod": { "command": "terraform destroy -var-file=env/prod.tfvars" } }, "options": { "forwardAllArgs": true, "cwd":"{projectRoot}/src" }, "dependsOn": ["init"] }, "init": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform init -reconfigure -backend-config=\"region=$(aws configure get region)\" -backend-config=\"bucket=$(aws sts get-caller-identity --query Account --output text)-tf-state-$(aws configure get region)\" -backend-config=\"key=my-scope-my-project/dev/terraform.tfstate\"" }, "prod": { "command": "terraform init -reconfigure -backend-config=\"region=$(aws configure get region)\" -backend-config=\"bucket=$(aws sts get-caller-identity --query Account --output text)-tf-state-$(aws configure get region)\" -backend-config=\"key=my-scope-my-project/prod/terraform.tfstate\"" } }, "options": { "forwardAllArgs": true, "cwd": "{projectRoot}/src" } }, "plan": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform plan -var-file=env/dev.tfvars -out=../../../dist/packages/infra/terraform/dev.tfplan" }, "prod": { "command": "terraform plan -var-file=env/dev.tfvars -out=../../../dist/packages/infra/terraform/prod.tfplan" } }, "options": { "forwardAllArgs": true, "cwd": "{projectRoot}/src" }, "dependsOn": ["init"] } }}Remote State Bootstrap (Application Projects Only)
Section titled “Remote State Bootstrap (Application Projects Only)”For application projects, before deploying your infrastructure, you’ll need to bootstrap the remote state backend. This creates an S3 bucket to store your Terraform state files:
pnpm nx bootstrap tf-infrayarn nx bootstrap tf-infranpx nx bootstrap tf-infrabunx nx bootstrap tf-infraAvailable Targets
Section titled “Available Targets”The available targets depend on your project type:
Common Targets (Both Application and Library)
Section titled “Common Targets (Both Application and Library)”Validating your Infrastructure
Section titled “Validating your Infrastructure”You can validate your Terraform configuration using the validate target:
pnpm nx validate tf-infrayarn nx validate tf-infranpx nx validate tf-infrabunx nx validate tf-infraFormatting your Code
Section titled “Formatting your Code”Format your Terraform code using the fmt target:
pnpm nx fmt tf-infrayarn nx fmt tf-infranpx nx fmt tf-infrabunx nx fmt tf-infraSecurity Testing
Section titled “Security Testing”Run security checks on your infrastructure using Checkov with the test target:
pnpm nx test tf-infrayarn nx test tf-infranpx nx test tf-infrabunx nx test tf-infraYou will find your security test results in the root dist folder, under dist/packages/<my-terraform-project>/checkov.
Application-Only Targets
Section titled “Application-Only Targets”The following targets are only available for application type projects:
Planning your Infrastructure
Section titled “Planning your Infrastructure”Before applying changes, you can see what Terraform will do by running the plan target:
pnpm nx plan tf-infrayarn nx plan tf-infranpx nx plan tf-infrabunx nx plan tf-infraThis will create a plan file in dist/packages/<my-terraform-project>/terraform/dev.tfplan.
Initializing Terraform
Section titled “Initializing Terraform”Initialize your Terraform working directory with the init target:
pnpm nx run tf-infra:inityarn nx run tf-infra:initnpx nx run tf-infra:initbunx nx run tf-infra:initDeploying to AWS
Section titled “Deploying to AWS”After planning, you can deploy your infrastructure to AWS using the apply target:
pnpm nx apply tf-infrayarn nx apply tf-infranpx nx apply tf-infrabunx nx apply tf-infraGetting Outputs
Section titled “Getting Outputs”Retrieve output values from your Terraform configuration:
pnpm nx output tf-infrayarn nx output tf-infranpx nx output tf-infrabunx nx output tf-infraDestroying Infrastructure
Section titled “Destroying Infrastructure”When you need to tear down your infrastructure, use the destroy target:
pnpm nx destroy tf-infrayarn nx destroy tf-infranpx nx destroy tf-infrabunx nx destroy tf-infraDestroying Bootstrap Resources
Section titled “Destroying Bootstrap Resources”To clean up the bootstrap resources (S3 bucket for state storage):
pnpm nx bootstrap-destroy tf-infrayarn nx bootstrap-destroy tf-infranpx nx bootstrap-destroy tf-infrabunx nx bootstrap-destroy tf-infraMore Information
Section titled “More Information”For more information about Terraform, please refer to the Terraform Documentation and AWS Provider Documentation.