Skip to content

OpenTofu

Create virtual machine environments on public clouds with OpenTofu

OpenTofu is an open-source “Infrastructure as Code” tool that you can use to create virtual machines on public clouds with one click.

Pigsty uses OpenTofu by default and provides Terraform-compatible .tf templates for Alibaba Cloud, AWS (global and China), Azure, GCP, Tencent Cloud, Hetzner, Vultr, DigitalOcean, and Linode. The aliyun-s3.tf template also creates a private OSS bucket and dedicated RAM read/write credentials for S3/pgBackRest scenarios.


Quick Start

Install OpenTofu

On macOS, you can use Homebrew to install OpenTofu:

brew install opentofu
tofu version

For Debian, Ubuntu, RHEL, and other platforms, refer to the OpenTofu installation guide. The package and command name is tofu.

Initialize and Apply

Enter the cloud-template directory, select a template, initialize provider plugins, and apply the configuration:

cd ~/pigsty/terraform
cp spec/aliyun.tf terraform.tf         # Select template
tofu init                              # Install cloud provider plugins (first use)
tofu plan                              # Review the execution plan
tofu apply                             # Create resources after interactive confirmation

After reviewing the plan, run tofu apply and type yes to confirm. OpenTofu will then create VMs and related cloud resources.

Get IP Address

After creation, print the public IP address of the admin node:

tofu output -raw meta_ip

Configure SSH Access

Global-cloud templates usually also provide an executable ssh_command output:

tofu output -raw ssh_command

The repository’s ./ssh script is a compatibility tool for legacy templates whose outputs are all IP addresses and whose root password is PigstyDemo4. It iterates over the IaC outputs, treats them as IP addresses, writes them to ~/.ssh/pigsty_config, and distributes keys with sshpass. It is suitable for compatibility templates such as aliyun.tf, aliyun-full.tf, aliyun-oss.tf, and aliyun-pro.tf. Do not run it against modern templates that output ssh_command, private IPs, or access keys.

When using a compatible template:

./ssh       # Write SSH config and distribute keys
ssh meta    # Login using hostname instead of IP
Using SSH Config File

If you want to use the configuration in ~/.ssh/pigsty_config, ensure your ~/.ssh/config includes:

Include ~/.ssh/pigsty_config

Destroy Resources

After testing, you can destroy all created cloud resources with one click:

tofu destroy

Terraform Compatibility and Migration

The directory and file names remain terraform/, .tf, terraform.tfvars, .terraform.lock.hcl, and terraform.tfstate because OpenTofu intentionally supports these compatibility names. Terraform remains available as an explicit compatibility option:

make IAC_CLI=terraform plan

Use only one CLI in a working directory at a time. Before migrating existing state, preserve it and compare both plans:

cp -p terraform.tfstate "terraform.tfstate.pre-tofu.$(date +%Y%m%d%H%M%S)"
terraform plan
tofu init
tofu plan

Continue only when the OpenTofu plan contains the changes you expect. Never delete terraform.tfstate while reinitializing providers.


Template Specs

Pigsty provides multiple predefined cloud resource templates in the terraform/spec/ directory:

Template File Cloud Provider Description
aliyun.tf Alibaba Cloud Single-node meta template, supports all distributions and AMD/ARM (default)
aliyun-s3.tf Alibaba Cloud Single node + private OSS bucket and RAM read/write credentials for S3/pgBackRest
aliyun-full.tf Alibaba Cloud Four-node sandbox, supports all distributions and AMD/ARM
aliyun-oss.tf Alibaba Cloud Six-node build template, supports all distributions and AMD/ARM
aliyun-pro.tf Alibaba Cloud Seven-node multi-distribution test template
aws.tf AWS Global AWS single node, Debian 12/13, AMD/ARM
aws-cn.tf AWS Legacy single-node environment for AWS China
azure.tf Azure Single node, Debian 12/13, AMD/ARM
gcp.tf GCP Single node, Debian 12/13, AMD/ARM
qcloud.tf Tencent Cloud Tencent Cloud single-node environment
hetzner.tf Hetzner Single node, Debian 12/13, AMD/ARM
vultr.tf Vultr Single node, Debian 12/13, currently AMD only
digitalocean.tf DigitalOcean Single node, Debian 12/13, currently AMD only
linode.tf Linode Single node, Debian 12/13, currently AMD only

When using a template, copy the template file to terraform.tf:

cd ~/pigsty/terraform
cp spec/aliyun-full.tf terraform.tf   # Use Alibaba Cloud 4-node sandbox template
tofu init && tofu apply

Variable Configuration

Variables differ between templates. Alibaba Cloud templates support the full multi-distribution matrix and default to u26. Global AWS, Azure, GCP, Tencent Cloud, and Hetzner support Debian 12/13 with AMD/ARM selection and generally default to d12/amd64. Vultr, DigitalOcean, and Linode currently expose AMD instance choices only.

Architecture and Distribution

variable "architecture" {
  description = "Architecture type (amd64 or arm64)"
  type        = string
  default     = "amd64"    # Comment this line to use arm64
  #default     = "arm64"   # Uncomment to use arm64
}

variable "distro" {
  description = "Distribution code (the exact set depends on the template)"
  type        = string
  default     = "d12"       # Global-cloud templates usually default to Debian 12; Alibaba Cloud defaults to u26
}

Resource Configuration

Alibaba Cloud templates expose the following resource parameters in a locals block. Other cloud templates use provider-specific instance, disk, and network variables or local values; consult the selected .tf file.

locals {
  bandwidth        = 100                    # Public bandwidth (Mbps)
  disk_size        = 40                     # System disk size (GB)
  spot_policy      = "SpotWithPriceLimit"   # Spot policy: NoSpot, SpotWithPriceLimit, SpotAsPriceGo
  spot_price_limit = 5                      # Max spot price (only effective with SpotWithPriceLimit)
}

Alibaba Cloud Configuration

Credential Setup

Add your Alibaba Cloud credentials to environment variables, for example in ~/.bash_profile or ~/.zshrc:

export ALICLOUD_ACCESS_KEY="<your_access_key>"
export ALICLOUD_SECRET_KEY="<your_secret_key>"
export ALICLOUD_REGION="cn-shanghai"

Supported Images

The following are commonly used ECS Public OS Image prefixes in Alibaba Cloud:

The currently recommended and validated baselines are Rocky Linux 9.8 / 10.2, Debian 12.15 / 13.6, and Ubuntu 22.04.5 / 24.04.4 / 26.04.0.

Distro Code x86_64 Image Prefix aarch64 Image Prefix
CentOS 7.9 el7 centos_7_9_x64 -
Rocky 8.10 el8 rockylinux_8_10_x64 rockylinux_8_10_arm64
Rocky 9.8 el9 rockylinux_9_8_x64 rockylinux_9_8_arm64
Rocky 10.2 el10 rockylinux_10_2_x64 rockylinux_10_2_arm64
Debian 11.11 d11 debian_11_11_x64 -
Debian 12.15 d12 debian_12_15_x64 debian_12_15_arm64
Debian 13.6 d13 debian_13_6_x64 debian_13_6_arm64
Ubuntu 22.04.5 LTS u22 ubuntu_22_04_x64_20G ubuntu_22_04_arm64_20G
Ubuntu 24.04.4 LTS u24 ubuntu_24_04_x64_20G ubuntu_24_04_arm64_20G
Ubuntu 26.04.0 LTS u26 ubuntu_26_04_x64_20G ubuntu_26_04_arm64_20G
Anolis 8.10 an8 anolisos_8_10_x64 anolisos_8_10_arm64
Alibaba Cloud Linux 3 al3 aliyun_3_x64_20G_alibase_[0-9]+ aliyun_3_arm64_20G_alibase_[0-9]+

OSS Storage Configuration

The aliyun-s3.tf template additionally creates an OSS bucket and related permissions for PostgreSQL PITR backup:

  • OSS Bucket: Creates a private bucket named pigsty-oss
  • RAM User: Creates a dedicated pigsty-oss-user user
  • Access Key: Generates AccessKey and saves to ~/pigsty.sk
  • RAM Policy: Grants the user oss:* permissions on the bucket and its objects for read/write use

AWS Configuration

Credential Setup

Both global and China-region templates can read standard AWS environment variables or credential files:

export AWS_ACCESS_KEY_ID="<your_access_key>"
export AWS_SECRET_ACCESS_KEY="<your_secret_key>"
export AWS_REGION="us-west-2"

# ~/.aws/config
[default]
region = us-west-2

# ~/.aws/credentials
[default]
aws_access_key_id = <YOUR_AWS_ACCESS_KEY>
aws_secret_access_key = <AWS_ACCESS_SECRET>

aws.tf reads ~/.ssh/id_rsa.pub by default. The legacy China-region aws-cn.tf instead reads this dedicated public key:

~/.aws/pigsty-key.pub
AWS templates may need adjustments

aws.tf uses a rolling lookup for official Debian AMIs. aws-cn.tf uses a hard-coded China-region AMI and ~/.aws/pigsty-key.pub; verify the target region, AMI, and key before deployment.


Tencent Cloud Configuration

Credential Setup

Add Tencent Cloud credentials to environment variables:

export TENCENTCLOUD_SECRET_ID="<your_secret_id>"
export TENCENTCLOUD_SECRET_KEY="<your_secret_key>"
export TENCENTCLOUD_REGION="ap-beijing"
Tencent Cloud templates may need adjustments

Tencent Cloud templates are community-contributed examples and may need adjustments based on your specific requirements.

Other Cloud Credentials

# Azure: az login is recommended; for a service principal, use all four
export ARM_CLIENT_ID="<client_id>"
export ARM_CLIENT_SECRET="<client_secret>"
export ARM_SUBSCRIPTION_ID="<subscription_id>"
export ARM_TENANT_ID="<tenant_id>"

# GCP: gcloud auth application-default login is also supported
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account-key.json"

# Hetzner / Vultr / DigitalOcean / Linode
export HCLOUD_TOKEN="<api_token>"
export VULTR_API_KEY="<api_key>"
export DIGITALOCEAN_TOKEN="<api_token>"
export LINODE_TOKEN="<api_token>"

The GCP template also requires a project variable, for example tofu apply -var="project=my-project". Except for AWS China, current key-based templates read ~/.ssh/id_rsa.pub by default; edit the selected template to use another public-key path.


Shortcut Commands

Pigsty provides OpenTofu-first Makefile shortcuts. Set IAC_CLI=terraform explicitly to use Terraform instead.

cd ~/pigsty/terraform

make init       # tofu init
make validate   # tofu validate
make plan       # tofu plan
make u          # interactive tofu apply + legacy ./ssh (compatible templates only)
make d          # interactive tofu destroy
make apply      # interactive tofu apply
make destroy    # interactive tofu destroy
make out        # tofu output
make ssh        # Run ssh script to configure SSH access
make r          # Reset terraform.tf to repository state

For modern templates with ssh_command, private-IP, or other non-IP outputs, run tofu apply directly; do not use make u, which invokes the legacy ./ssh script afterward. Automatic confirmation is available only through deliberately named up-auto, apply-auto, and destroy-auto targets.


Notes

Cloud Resource Costs

Cloud resources created with OpenTofu incur costs. After testing, promptly use tofu destroy to destroy resources to avoid unnecessary expenses.

It’s recommended to use pay-as-you-go instance types for testing. Templates default to using Spot Instances to reduce costs.

Default Password

Alibaba Cloud and Tencent Cloud templates set the default root password to PigstyDemo4; Linode uses PigstyDemo4! to satisfy its password-complexity rules. Current AWS, Azure, GCP, Hetzner, Vultr, and DigitalOcean templates primarily use SSH public-key authentication and do not share a default root password. Example passwords are for temporary tests only; change them or disable password login in production.

Security Group Configuration

These templates target demonstration and development. Their current security groups or cloud firewalls allow all or nearly all inbound traffic from 0.0.0.0/0 (some also include ::/0), not just the ports Pigsty requires. Restrict source networks and ports before deployment; do not use these defaults unchanged in production.

SSH Access

After creation, SSH login to the admin node using:

ssh root@<public_ip>

Alibaba Cloud templates that retain the legacy output and password conventions can also use ./ssh or make ssh to write SSH aliases. For other templates, use their ssh_command output.