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-infra
yarn nx g @aws/nx-plugin:terraform#project --name=tf-infra
npx nx g @aws/nx-plugin:terraform#project --name=tf-infra
bunx nx g @aws/nx-plugin:terraform#project --name=tf-infra
You 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-run
yarn nx g @aws/nx-plugin:terraform#project --name=tf-infra --dry-run
npx nx g @aws/nx-plugin:terraform#project --name=tf-infra --dry-run
bunx nx g @aws/nx-plugin:terraform#project --name=tf-infra --dry-run
Options
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. |
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=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=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 run tf-infra:bootstrap
yarn nx run tf-infra:bootstrap
npx nx run tf-infra:bootstrap
bunx nx run tf-infra:bootstrap
Available 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 run tf-infra:validate
yarn nx run tf-infra:validate
npx nx run tf-infra:validate
bunx nx run tf-infra:validate
Formatting your Code
Section titled “Formatting your Code”Format your Terraform code using the fmt
target:
pnpm nx run tf-infra:fmt
yarn nx run tf-infra:fmt
npx nx run tf-infra:fmt
bunx nx run tf-infra:fmt
Security Testing
Section titled “Security Testing”Run security checks on your infrastructure using Checkov with the test
target:
pnpm nx run tf-infra:test
yarn nx run tf-infra:test
npx nx run tf-infra:test
bunx nx run tf-infra:test
You 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 run tf-infra:plan
yarn nx run tf-infra:plan
npx nx run tf-infra:plan
bunx nx run tf-infra:plan
This 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:init
yarn nx run tf-infra:init
npx nx run tf-infra:init
bunx nx run tf-infra:init
Deploying to AWS
Section titled “Deploying to AWS”After planning, you can deploy your infrastructure to AWS using the apply
target:
pnpm nx run tf-infra:apply
yarn nx run tf-infra:apply
npx nx run tf-infra:apply
bunx nx run tf-infra:apply
Getting Outputs
Section titled “Getting Outputs”Retrieve output values from your Terraform configuration:
pnpm nx run tf-infra:output
yarn nx run tf-infra:output
npx nx run tf-infra:output
bunx nx run tf-infra:output
Destroying Infrastructure
Section titled “Destroying Infrastructure”When you need to tear down your infrastructure, use the destroy
target:
pnpm nx run tf-infra:destroy
yarn nx run tf-infra:destroy
npx nx run tf-infra:destroy
bunx nx run tf-infra:destroy
Destroying Bootstrap Resources
Section titled “Destroying Bootstrap Resources”To clean up the bootstrap resources (S3 bucket for state storage):
pnpm nx run tf-infra:bootstrap-destroy
yarn nx run tf-infra:bootstrap-destroy
npx nx run tf-infra:bootstrap-destroy
bunx nx run tf-infra:bootstrap-destroy
More Information
Section titled “More Information”For more information about Terraform, please refer to the Terraform Documentation and AWS Provider Documentation.