Published on

Try OpenTofu for Your Next IaC Project

Authors
  • avatar
    Name
    Parminder Singh
    Twitter

In one of my previous articles, I discussed why and how to adopt Infrastructure as Code (IaC) to manage your cloud infrastructure efficiently. There are several tools and frameworks available for IaC, most notably Terraform, Pulumi, Ansible, Puppet, etc. These tools allow you to define and manage your infrastructure as code, enabling automation, repeatability, and scalability in your cloud environment. In this article I want to introduce OpenTofu - an open-source alternative to Terraform that has gained popularity.

HashiCorp, the company behind Terraform, switched Terraform's licensing to the Business Source License (BSL) in 2023. This led to the creation of OpenTofu, a fork of Terraform that aims to keep the project open and community-driven. OpenTofu is managed and maintained by the Linux Foundation and has a growing community of contributors and users. Click here to read the manifesto.

Why Choose OpenTofu over Terraform?

Both tools do essentially the same thing, but here's why you might want to give OpenTofu a shot.

Licensing

OpenTofu uses the Mozilla Public License v2.0 (MPL). You can use it, modify it, and even make money with it, all without any restrictions.

Terraform uses the Business Source License (BSL). This license puts some limits on how you can use Terraform commercially, especially if you're building something that competes with HashiCorp.

Community Driven

OpenTofu is open source and driven by an active community of contributors. You can expect faster innovation, quicker bug fixes, and a more responsive development process.

Feature parity with Terraform

OpenTofu aims to be compatible with Terraform, so you can often use your existing Terraform configurations with OpenTofu. But it also adds new features and improvements based on what the community needs, like built-in state encryption.

State Management

Just like Terraform, OpenTofu uses a state file to keep track of your infrastructure. This (JSON) file maps the configuration to the actual resources in your cloud environment. It's a good idea to secure and version-control this file as it can help track changes and recover from failures. Read more.

The state file from the demo config below is large, but here's a snippet from the file.

{
      "mode": "managed",
      "type": "aws_eip_association",
      "name": "singh",
      "provider": "provider[\"registry.opentofu.org/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "allocation_id": "eipalloc-096bd339fb1d4fb60",
            "allow_reassociation": null,
            "id": "eipassoc-09c06e980f870b713",
            "instance_id": "i-0663f391aaec5166e",
            "network_interface_id": "eni-049e9af5f71af6d11",
            "private_ip_address": "172.31.32.101",
            "public_ip": "44.225.217.8"
          },
          "sensitive_attributes": [],
          "private": "bnVsbA==",
          "dependencies": [
            "aws_eip.singh",
            "aws_instance.singh",
            "aws_key_pair.singh"
          ]
        }
      ]
    }

State and Plan Encryption

OpenTofu supports encrypting state and plan files at rest, both locally and in remote backends. This helps securing sensitive information in your infrastructure code. Read more.

Tofu Graph

OpenTofu provides a command-line utility called tofu graph that allows you to generate a visual representation of your infrastructure as defined in your OpenTofu configuration files. This graph helps understand the relationships between different resources and how they depend on each other.

Tofu Graph generated from the configuration below Tofu Graph generated from the configuration below

OpenTofu Language

On a high level, the main purpose of the OpenTofu language is declaring resources (infrastructure components) and their configurations. OpenTofu uses the same HCL (HashiCorp Configuration Language) as Terraform. The basic building block of OpenTofu configurations is a resource block. A resource block defines a single resource in your infrastructure, like a virtual machine, a storage account, or a network interface. There's a block type, a block label, and a block body. Here's an example of a resource block in OpenTofu.


<BLOCK TYPE> "<BLOCK LABEL>" "<BLOCK LABEL>" {
  # Block body
  <IDENTIFIER> = <EXPRESSION> # Argument
}

resource "azurerm_storage_queue" "example" {
  name                = "example"
  resource_group_name = azurerm_resource_group.example.name
  account_name        = azurerm_storage_account.example.name
}

The language is declarative, meaning it represents the desired state of the infrastructure. As steps, you first define, this state, the plan and apply commands to create or update the infrastructure to match the desired state.

Demo

In the demo configuration below we are:

  • creating a VPC and a subnet
  • an internet gateway and a route table
  • associating the subnet with the route table
  • creating a static IP
  • creating an instance and 2 buckets
# Configure the AWS provider
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "us-west-2"
}

# Create a VPC
resource "aws_vpc" "singh" {
  cidr_block = "10.0.0.0/16"
}

# Create a subnet
resource "aws_subnet" "singh" {
  vpc_id     = aws_vpc.singh.id
  cidr_block = "10.0.1.0/24"
}

# Create an internet gateway
resource "aws_internet_gateway" "singh" {
  vpc_id = aws_vpc.singh.id
}

# Create a route table
resource "aws_route_table" "singh" {
  vpc_id = aws_vpc.singh.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.singh.id
  }
}

# Associate the route table with the subnet
resource "aws_route_table_association" "singh" {
  subnet_id      = aws_subnet.singh.id
  route_table_id = aws_route_table.singh.id
}

# Create a security group
resource "aws_security_group" "singh" {
  name = "allow_ssh"
  vpc_id = aws_vpc.singh.id

 ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# Create an Elastic IP (Static IP)
resource "aws_eip" "singh" {
  domain = "vpc"
}

# Create a Network Interface
resource "aws_network_interface" "singh" {
  subnet_id       = aws_subnet.singh.id
  private_ip = "10.0.1.10"
  security_groups = [aws_security_group.singh.id]
}

# Attach the EIP to the Network Interface
resource "aws_eip_association" "singh" {
  instance_id   = aws_instance.singh.id
  allocation_id = aws_eip.singh.id
}

# Create a new key pair
resource "aws_key_pair" "singh" {
  key_name   = "opentofu-keypair"
  public_key = file("~/.ssh/id_rsa.pub") # my public key. You can generate one as well
}

# Create an EC2 instance
resource "aws_instance" "singh" {
  ami           = "ami-0fa40e25bf4dda1f6"
  instance_type = "t2.micro"
  key_name = aws_key_pair.singh.key_name

  tags = {
    Name = "Singh-OpenTofu Instance"
  }
}

# Create S3 buckets
resource "aws_s3_bucket" "bucket1" {
  bucket = "opentofu-bucket1-singh"

  tags = {
    Name = "OpenTofu Bucket 1"
  }
}

resource "aws_s3_bucket" "bucket2" {
  bucket = "opentofu-bucket2-singh"

  tags = {
    Name = "OpenTofu Bucket 2"
  }
}

To apply the configuration, you can run the following commands:

## sets up your OpenTofu project and downloads the necessary components.
$ tofu init

## shows you what OpenTofu will change in your infrastructure before it actually makes those changes.
$ tofu plan

## apply the changes
$ tofu apply

## destroy the resources
$ tofu destroy

This example shows how easy it is to define and deploy resources in AWS (or any cloud) with OpenTofu (and other IaC tools). The same approach can be used to manage infrastructure across different cloud providers and even on-premises environments. It's repeatable, scalable, and secure.

Conclusion

If you're looking for an open-source, community-driven tool with strong security features, give OpenTofu a try. If you have tried Terraform before, you'll find OpenTofu very familiar, but with some added benefits. Check out the OpenTofu website to learn more and get involved in the community. If you have used OpenTofu, I'd love to hear about your experience and how it compares to Terraform.