Configuration
Terraform projects in nx-terraform support various configuration options for managing environment-specific variables, backend settings, and project metadata. Understanding configuration options helps you manage complex infrastructure setups.
Overview
Configuration in nx-terraform includes:
- Environment Variables - Using
tfvarsfiles - Backend Configuration - Connecting to backends
- Project Metadata - Project type and relationships
- Target Configurations - Environment-specific target runs
Environment Variables (tfvars)
Terraform projects support environment-specific variables via tfvars files.
Structure
packages/my-infra/
├── main.tf
├── variables.tf
└── tfvars/
├── dev.tfvars
├── staging.tfvars
└── prod.tfvars
Variable Definitions
Define variables in variables.tf:
variable "environment" {
description = "Environment name"
type = string
}
variable "instance_count" {
description = "Number of instances"
type = number
default = 1
}
variable "instance_type" {
description = "Instance type"
type = string
}
tfvars Files
Create environment-specific values:
dev.tfvars:
environment = "dev"
instance_count = 1
instance_type = "t3.micro"
prod.tfvars:
environment = "prod"
instance_count = 3
instance_type = "t3.large"
Using Configurations
You can pass different var files per environment using Nx configurations in your project.json by overriding the args array:
{
"targets": {
"terraform-plan": {
"options": {
"args": ["-var-file=tfvars/dev.tfvars"]
},
"configurations": {
"prod": {
"args": ["-var-file=tfvars/prod.tfvars"]
}
}
}
}
}
Paths in -var-file are relative to the project root (where the command runs). Then use configurations with targets:
# Plan with dev configuration (default)
nx run my-infra:terraform-plan
# Plan with prod configuration
nx run my-infra:terraform-plan --configuration=prod
The configurations override the args to use different var files:
- Default → uses
tfvars/dev.tfvars --configuration=prod→ usestfvars/prod.tfvars
Backend Configuration
Backend Projects
Backend projects generate backend.config after applying:
# packages/terraform-setup/backend.config
bucket = "my-workspace-terraform-setup-abc123"
key = "terraform-setup/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-setup-lock"
encrypt = true
Stateful Projects
Stateful projects reference the backend:
# packages/my-infra/backend.tf
terraform {
backend "s3" {
config_file = "../../terraform-setup/backend.config"
}
}
Or for local backend:
terraform {
backend "local" {
path = "terraform.tfstate"
}
}
Backend Configuration Options
AWS S3 Backend
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "my-project/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
Local Backend
terraform {
backend "local" {
path = "terraform.tfstate"
}
}
Project Metadata and Target Options
Backend Project
Backend projects do not set terraform-init.metadata.backendProject (they are the backend themselves). They have no terraform-init target metadata for backend:
{
"root": "packages/terraform-setup",
"projectType": "application"
}
Stateful Project
Stateful projects reference their backend via terraform-init target metadata:
{
"root": "packages/my-infra",
"projectType": "application",
"targets": {
"terraform-init": {
"metadata": { "backendProject": "terraform-setup" }
}
},
"metadata": {
"nx-terraform": {
"projectType": "stateful"
}
}
}
Module Project Metadata
Module projects have metadata['nx-terraform'].projectType: 'module':
{
"root": "packages/networking",
"projectType": "application",
"metadata": {
"nx-terraform": { "projectType": "module" }
}
}
Target Configurations
Configuration Support
Targets support configurations by overriding the args array to pass different -var-file arguments:
{
"targets": {
"terraform-plan": {
"options": {
"args": ["-var-file=tfvars/dev.tfvars"]
},
"configurations": {
"prod": {
"args": ["-var-file=tfvars/prod.tfvars"]
}
}
}
}
}
Use configurations with targets:
# Uses tfvars/dev.tfvars
nx run my-infra:terraform-plan
# Uses tfvars/prod.tfvars
nx run my-infra:terraform-plan --configuration=prod
Supported Targets
These targets support configurations:
terraform-planterraform-destroy
Note: terraform-apply uses the plan file from terraform-plan, so it doesn't need a var file argument.
Configuration Pattern
The recommended pattern is to override args in your project.json target configurations for different environments:
Example project.json:
{
"targets": {
"terraform-plan": {
"options": {
"args": ["-var-file=tfvars/dev.tfvars"]
},
"configurations": {
"prod": {
"args": ["-var-file=tfvars/prod.tfvars"]
},
"staging": {
"args": ["-var-file=tfvars/staging.tfvars"]
}
}
}
}
}
Environment Variables
Terraform Environment Variables
Set Terraform-specific environment variables:
export TF_LOG=DEBUG
export TF_VAR_instance_count=5
nx run my-infra:terraform-plan
Provider Environment Variables
Set provider-specific variables:
# AWS
export AWS_ACCESS_KEY_ID=your-key
export AWS_SECRET_ACCESS_KEY=your-secret
export AWS_REGION=us-east-1
# Azure
export ARM_CLIENT_ID=your-client-id
export ARM_CLIENT_SECRET=your-secret
Project Configuration Files
project.json
Main project configuration:
{
"root": "packages/my-infra",
"sourceRoot": "packages/my-infra",
"projectType": "application",
"targets": {
"terraform-init": { "metadata": { "backendProject": "terraform-setup" }, ... },
"terraform-plan": { ... }
},
"metadata": {
"nx-terraform": {
"projectType": "module"
}
}
}
Individual projects can override the default command arguments by defining their own args in target configurations.
Configuration Best Practices
1. Environment Separation
- Use separate
tfvarsfiles per environment - Keep environment configs in version control
- Document environment-specific requirements
2. Variable Management
- Use clear variable names
- Provide sensible defaults
- Document variable purposes
- Use type constraints
3. Backend Configuration
- Use
backend.configfor consistency - Keep backend configs in version control (if safe)
- Document backend requirements
4. Secrets Management
- Don't commit secrets to
tfvars - Use environment variables for secrets
- Consider secret management tools
- Use
.gitignorefor sensitive files
Configuration Examples
Example 1: Multi-Environment Setup
packages/
├── terraform-setup/ # Backend
└── web-infra/ # Infrastructure
├── main.tf
├── variables.tf
└── tfvars/
├── dev.tfvars
└── prod.tfvars
Example 2: Shared Variables
Create a shared variables file:
# shared.tfvars
common_tag = "managed-by-terraform"
Reference in environment files:
# dev.tfvars
environment = "dev"
instance_count = 1
Example 3: Conditional Configuration
Use variables for conditional logic:
# main.tf
resource "aws_instance" "example" {
count = var.environment == "prod" ? 3 : 1
# ...
}
Troubleshooting
For configuration issues, see the Troubleshooting Guide.
Related Topics
- Backend Types - Learn about backend configuration
- Project Types - Understand project metadata
- Multiple Environments Example - Practical configuration examples