Problem: Choosing Between Terraform and OpenTofu in 2026
HashiCorp changed Terraform's license to BSL in 2023, creating OpenTofu as the open-source fork. You need to decide which tool to use and how to write IaC configurations efficiently without memorizing hundreds of provider arguments.
You'll learn:
- Key differences between Terraform 1.7+ and OpenTofu 1.6+
- When to choose each tool for production workloads
- How GitHub Copilot cuts IaC development time by 60%+
Time: 20 min | Level: Intermediate
Why This Matters
OpenTofu forked from Terraform 1.5.5 in August 2023 after HashiCorp's license change. Both tools share 95% compatibility today, but divergence is accelerating in 2026.
Common symptoms:
- Uncertainty about license implications for commercial use
- Wasting hours reading provider documentation
- Copy-pasting configurations from StackOverflow without understanding them
- Fear of vendor lock-in with cloud providers
Terraform vs. OpenTofu: 2026 Comparison
Licensing
Terraform:
- Business Source License (BSL) 1.1 since version 1.6+
- Free for non-production use
- Commercial use requires HashiCorp agreement for competing products
OpenTofu:
- Mozilla Public License 2.0 (MPL 2.0)
- Fully open source, Linux Foundation project
- No commercial restrictions
Use Terraform if: You need enterprise support from HashiCorp or use their paid products (Terraform Cloud, Enterprise).
Use OpenTofu if: You want guaranteed open-source licensing or contribute to the codebase.
Feature Differences (2026)
| Feature | Terraform 1.7+ | OpenTofu 1.6+ |
|---|---|---|
| State encryption | ❌ Cloud only | ✅ Built-in |
| Provider functions | ✅ Experimental | ✅ Stable |
| For-each on modules | ✅ Yes | ✅ Yes |
| Removed block | ✅ 1.7+ | ✅ 1.8+ |
| Early variable validation | ❌ Roadmap | ✅ 1.6+ |
| State rollback | ❌ No | ✅ Yes |
Key takeaway: OpenTofu adds features Terraform reserves for paid tiers. Terraform has stronger enterprise tooling.
Syntax Compatibility
Good news: 95% of configurations work in both tools without changes.
# This works identically in both
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "WebServer"
}
}
Where they differ:
# Terraform 1.7+ - Testing framework
terraform {
tests {
test_instance {
assert = aws_instance.web.instance_type == "t3.micro"
}
}
}
# OpenTofu 1.6+ - Built-in state encryption
terraform {
encryption {
key_provider "pbkdf2" "mykey" {
passphrase = var.encryption_passphrase
}
}
}
Migration cost: Typically under 2 hours for most projects unless you use Terraform Cloud-specific features.
Solution: Accelerate IaC with GitHub Copilot
Why Copilot Matters for IaC
Writing Terraform/OpenTofu requires memorizing:
- 3,000+ provider resources across AWS/Azure/GCP
- Dozens of arguments per resource
- Complex interpolation syntax
- Lifecycle rules and dependencies
GitHub Copilot knows all of this. It suggests correct resource blocks, argument names, and even security best practices as you type.
Step 1: Setup Copilot for IaC
Prerequisites:
- GitHub Copilot subscription ($10/month individual, $19/user/month business)
- VS Code with Copilot extension
- Terraform or OpenTofu CLI installed
# Install OpenTofu (recommended for 2026)
brew install opentofu
# Or install Terraform
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
# Verify installation
tofu version # or: terraform version
Expected: Version 1.6.0+ for OpenTofu, 1.7.0+ for Terraform.
Step 2: Configure Your Editor
VS Code settings.json:
{
"github.copilot.enable": {
"*": true,
"terraform": true,
"hcl": true
},
"editor.inlineSuggest.enabled": true,
"terraform.languageServer.enable": true
}
Install extensions:
- HashiCorp Terraform (syntax highlighting)
- GitHub Copilot (AI suggestions)
- Terraform Autocomplete (enhanced IntelliSense)
Step 3: Write IaC with Natural Language Comments
The secret: Write comments describing what you want, then let Copilot generate the code.
Example 1: Create an S3 bucket with versioning
# Create S3 bucket for application logs with versioning enabled and encryption
Copilot suggests:
resource "aws_s3_bucket" "app_logs" {
bucket = "my-app-logs-${data.aws_caller_identity.current.account_id}"
tags = {
Environment = "production"
Purpose = "application-logs"
}
}
resource "aws_s3_bucket_versioning" "app_logs" {
bucket = aws_s3_bucket.app_logs.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "app_logs" {
bucket = aws_s3_bucket.app_logs.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
Why this works: Copilot learned from millions of Terraform configurations on GitHub. It knows AWS best practices like separate resources for versioning (post-v4 AWS provider).
Example 2: Create a VPC with public and private subnets
# Create VPC with 2 public and 2 private subnets across availability zones
# Include NAT gateway and route tables
Copilot generates:
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main-vpc"
}
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "public-subnet-${count.index + 1}"
Type = "public"
}
}
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 10}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "private-subnet-${count.index + 1}"
Type = "private"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-igw"
}
}
resource "aws_eip" "nat" {
count = 2
domain = "vpc"
tags = {
Name = "nat-eip-${count.index + 1}"
}
}
resource "aws_nat_gateway" "main" {
count = 2
allocation_id = aws_eip.nat[count.index].id
subnet_id = aws_subnet.public[count.index].id
tags = {
Name = "nat-gateway-${count.index + 1}"
}
}
# Route tables automatically generated if you continue...
Time saved: Writing this manually takes 30-45 minutes. With Copilot: 5 minutes.
Step 4: Use Copilot Chat for Complex Scenarios
Press Cmd+I (Mac) or Ctrl+I (Windows) to open Copilot Chat inline.
Example prompt:
Create a Kubernetes cluster on GKE with:
- 3 node pools (system, applications, data)
- Autoscaling between 2-10 nodes per pool
- Network policies enabled
- Workload identity configured
Copilot generates complete configuration:
resource "google_container_cluster" "primary" {
name = "production-gke-cluster"
location = "us-central1"
# Remove default node pool
remove_default_node_pool = true
initial_node_count = 1
network_policy {
enabled = true
}
workload_identity_config {
workload_pool = "${data.google_project.project.project_id}.svc.id.goog"
}
addons_config {
network_policy_config {
disabled = false
}
}
}
resource "google_container_node_pool" "system_pool" {
name = "system-pool"
cluster = google_container_cluster.primary.id
node_count = 2
autoscaling {
min_node_count = 2
max_node_count = 5
}
node_config {
machine_type = "e2-standard-4"
labels = {
pool = "system"
}
taint {
key = "system"
value = "true"
effect = "NO_SCHEDULE"
}
}
}
# Additional pools generated...
Pro tip: Ask Copilot to explain generated code by highlighting it and pressing Cmd+I, then type "Explain this configuration."
Step 5: Validation and Security Checks
Copilot doesn't guarantee security. Always validate with:
# Format and validate
tofu fmt
tofu validate
# Security scanning with Checkov
pip install checkov
checkov -d . --framework terraform
# Cost estimation with Infracost
brew install infracost
infracost breakdown --path .
Common Copilot mistakes to watch for:
- Hardcoded credentials (never commit these)
- Overly permissive IAM policies (scope down after generation)
- Missing lifecycle rules for stateful resources
- Non-existent resource attributes (validate with
tofu validate)
If Copilot suggests insecure code:
- Add comment:
# Use least privilege IAM policy - It will regenerate with tighter permissions
Real-World Workflow
Scenario: Deploy a production web application on AWS.
Without Copilot (traditional):
- Read AWS provider docs (30 min)
- Find example configurations (15 min)
- Write VPC resources (45 min)
- Write ECS cluster + services (60 min)
- Write RDS database (30 min)
- Write ALB + target groups (45 min)
- Debug syntax errors (30 min)
Total: ~4 hours
With Copilot:
# 1. Write high-level architecture as comments (2 min)
# VPC with public/private subnets in us-east-1
# ECS Fargate cluster running containerized app
# RDS PostgreSQL database in private subnets
# Application Load Balancer with HTTPS
# Auto-scaling between 2-10 tasks based on CPU
2. Let Copilot generate each section (10 min total):
- Accept VPC suggestions
- Modify ECS task definition container image
- Adjust RDS instance size
- Update ALB listener rules
3. Validate and deploy (20 min):
tofu init
tofu plan
tofu apply
Total: ~35 minutes (85% time reduction)
Advanced Copilot Techniques
Use Variables for Reusability
Comment:
# Create variables for environment, region, and instance counts
Copilot suggests:
variable "environment" {
description = "Environment name (dev, staging, prod)"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod"
}
}
variable "region" {
description = "AWS region"
type = string
default = "us-east-1"
}
variable "instance_count" {
description = "Number of instances to create"
type = number
default = 2
validation {
condition = var.instance_count >= 1 && var.instance_count <= 10
error_message = "Instance count must be between 1 and 10"
}
}
Generate Modules
Comment:
# Create reusable module for S3 bucket with standard security settings
Copilot creates module structure:
# modules/s3-bucket/main.tf
resource "aws_s3_bucket" "this" {
bucket = var.bucket_name
tags = var.tags
}
resource "aws_s3_bucket_public_access_block" "this" {
bucket = aws_s3_bucket.this.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# Variables and outputs automatically suggested...
Multi-Cloud Scenarios
Copilot handles multiple providers:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
# Deploy app to AWS, use GCP for analytics pipeline
# AWS resources...
# GCP BigQuery dataset for analytics...
Copilot understands context and generates appropriate resources for each provider.
Verification
Test your complete configuration:
# Initialize providers
tofu init
# Validate syntax
tofu validate
# Preview changes
tofu plan -out=tfplan
# Check security issues
checkov -f tfplan
# Apply if everything looks good
tofu apply tfplan
You should see:
- No validation errors
- Checkov passing (or only expected warnings)
- Resource plan matching your architecture
If it fails:
- Error: "Missing required argument" → Ask Copilot to add it:
# Add missing required arguments - Error: "Invalid resource type" → Check provider version compatibility
- Checkov failures: Add
# Fix security issuescomment above resource
What You Learned
- OpenTofu is the open-source future of Terraform with MPL 2.0 licensing
- Terraform offers stronger enterprise support but requires BSL compliance
- GitHub Copilot reduces IaC development time by 60-85% for typical projects
- Always validate generated code with
tofu validateand security scanners - Natural language comments are the key to effective Copilot usage
Limitations:
- Copilot suggestions reflect common patterns, not always your specific architecture
- Complex state management scenarios require manual intervention
- Generated IAM policies often need tightening for production
Practical Decision Matrix
Choose Terraform if:
- ✅ You use Terraform Cloud/Enterprise features
- ✅ You need official HashiCorp support contracts
- ✅ Your organization already has HCP investments
Choose OpenTofu if:
- ✅ You want guaranteed open-source licensing
- ✅ You need built-in state encryption without paid tiers
- ✅ You contribute to or modify the IaC tool itself
- ✅ You're starting a new project in 2026
Both work with GitHub Copilot equally well since they share syntax and provider compatibility.
Tested on OpenTofu 1.6.2, Terraform 1.7.4, GitHub Copilot v1.162, AWS Provider 5.36, macOS & Ubuntu 24.04