Terraform Compatibility

Oxid reads your .tf files natively and works with all Terraform providers. Here's what's supported, what's different, and how to migrate.

What Works

Oxid supports the core Terraform configuration language. You can point Oxid at an existing Terraform project and it will work:

Resources

All resource types from all providers are supported. Resources are declared with the same resource block syntax.

resource "aws_instance" "web" {
  ami           = "ami-0abcdef1234567890"
  instance_type = var.instance_type
  subnet_id     = aws_subnet.public[0].id

  tags = {
    Name = "web-server"
  }
}

Data sources

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }
}

Variables and outputs

variable "instance_type" {
  type    = string
  default = "t3.micro"
}

output "instance_ip" {
  value     = aws_instance.web.public_ip
  sensitive = false
}

Locals

locals {
  common_tags = {
    Environment = var.environment
    ManagedBy   = "oxid"
  }
}

Provider configuration

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

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

count and for_each

resource "aws_subnet" "public" {
  count             = 3
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
  availability_zone = data.aws_availability_zones.available.names[count.index]
}

resource "aws_iam_user" "team" {
  for_each = toset(["alice", "bob", "carol"])
  name     = each.value
}

depends_on and lifecycle

resource "aws_instance" "api" {
  # ...
  depends_on = [aws_iam_role_policy.api]

  lifecycle {
    create_before_destroy = true
    ignore_changes        = [tags]
  }
}

What's Different

State format

Terraform uses a monolithic JSON file (terraform.tfstate). Oxid uses a relational database (SQLite or PostgreSQL). This enables SQL queries, built-in history, and concurrent access.

# Terraform
cat terraform.tfstate | jq '.resources[].instances[].attributes.id'

# Oxid
oxid query "SELECT address, json_extract(attributes, '$.id') FROM resources"

No modules (yet)

Oxid does not yet support Terraform modules (module blocks). If your configuration uses modules, you will need to flatten them or wait for module support.

NoteModule support is on the roadmap. For now, use Oxid with module-free configurations or flatten your modules into the root.

No provisioners

Terraform provisioners (provisioner "local-exec", provisioner "remote-exec") are not supported. Use cloud-init, user data, or external tools for post-provisioning tasks.

No remote backends for state

Oxid does not use Terraform's backend system for its own state. Instead, it uses SQLite locally or PostgreSQL for teams. However, Oxid can read Terraform remote backends during sync and import.

Migration Path

Migrating from Terraform to Oxid is straightforward:

Step 1: Initialize Oxid

In your existing Terraform project directory:

oxid init

This downloads providers and auto-imports from terraform.tfstate if present.

Step 2: Verify state

oxid state list
oxid plan

The plan should show no changes if the import was successful and your config has not drifted.

Step 3: Start using Oxid

From this point, use oxid plan and oxid apply instead of their Terraform equivalents. Your .tf files remain unchanged.

# Edit your .tf files as usual
vim main.tf

# Plan and apply with Oxid
oxid plan
oxid apply

Step 4 (optional): Sync from remote backend

If your Terraform state is in a remote backend (S3, etc.), sync it into Oxid:

oxid sync

Feature Comparison

Feature                  Terraform    Oxid
─────────────────────    ─────────    ────
HCL .tf files            Yes          Yes
Resources                Yes          Yes
Data sources             Yes          Yes
Variables                Yes          Yes
Outputs                  Yes          Yes
Locals                   Yes          Yes
count                    Yes          Yes
for_each                 Yes          Yes
depends_on               Yes          Yes
lifecycle                Yes          Yes
Modules                  Yes          Not yet
Provisioners             Yes          No
State locking            DynamoDB     Database transactions
State format             JSON file    SQLite / PostgreSQL
SQL queries              No           Yes
Change history           No           Yes (built-in)
Blast radius             No           Yes (built-in)
Drift detection          Partial      Yes (built-in)
Parallelism              Wave-based   Event-driven per-resource
Encrypted outputs        No           Yes (pgcrypto)