Terraform lets you define infrastructure (VPS instances, networks, DNS records) as code, applied consistently and version-controlled, rather than manually clicking through a hosting provider's control panel.
Infrastructure as Code vs Manual Provisioning
| Factor | Manual (Control Panel) | Infrastructure as Code |
|---|---|---|
| Reproducibility | Manual steps, easy to forget something | Exact, repeatable definition |
| History/audit trail | Limited to provider's own logs | Full Git history of every change |
| Review process | No natural review step | Changes can go through pull request review |
| Disaster recovery | Manually rebuild from memory/notes | Re-apply the same code |
Prerequisites
- Terraform installed on your local machine or a management server
- API credentials for your VPS provider (most major providers have a Terraform provider)
Step 1 — Install Terraform
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform -y
Step 2 — Create a Project Directory
mkdir ~/terraform-vps && cd ~/terraform-vps
Step 3 — Define the Provider
nano main.tf
terraform {
required_providers {
yourprovider = {
source = "yourprovider/yourprovider"
version = "~> 1.0"
}
}
}
provider "yourprovider" {
api_token = var.api_token
}
The exact provider source and configuration depend on your specific VPS host — consult their Terraform provider documentation.
Step 4 — Define a VPS Resource
resource "yourprovider_instance" "web1" {
name = "web-server-1"
region = "nyc1"
size = "s-2vcpu-4gb"
image = "ubuntu-24-04-x64"
}
Step 5 — Define Variables
nano variables.tf
variable "api_token" {
description = "API token for provider authentication"
type = string
sensitive = true
}
nano terraform.tfvars
api_token = "your_actual_token"
Never commit terraform.tfvars to version control — add it to .gitignore.
Step 6 — Initialize Terraform
terraform init
Step 7 — Preview Changes
terraform plan
Shows exactly what Terraform will create/change/destroy, without actually making changes — always review this before applying.
Step 8 — Apply the Configuration
terraform apply
Confirm when prompted.
Step 9 — Track State
Terraform maintains a state file (terraform.tfstate) tracking what it created — for team use, store this remotely (many providers offer remote state backends) rather than locally, to avoid conflicts between team members.
Making a Change
resource "yourprovider_instance" "web1" {
name = "web-server-1"
region = "nyc1"
size = "s-4vcpu-8gb" # upgraded
image = "ubuntu-24-04-x64"
}
terraform plan
terraform apply
Destroying Infrastructure
terraform destroy
Use with extreme caution — this removes everything Terraform manages according to the current configuration.
Combining Terraform with Ansible
A common pattern: Terraform provisions the VPS itself (creating the instance), then Ansible configures software and settings on it — each tool focused on what it does best.
Common Errors
"Error: Invalid provider configuration" — verify API credentials and provider source/version match your hosting provider's current documentation.
State file conflicts in a team setting — use a remote state backend rather than a local file shared manually.
Best Practices
- Always run
terraform planbeforeapplyand review the output carefully - Never commit files containing secrets/API tokens to version control
- Use remote state storage for any team-managed infrastructure
Continue Reading
- How to Use Ansible for Server Configuration Management
- How to Version Control Your Server Configuration
- How to Migrate a Full VPS to a New Provider
Browse more articles in DevOps & CI/CD.
