Configuration

Oxid reads standard Terraform .tf files (HCL format) natively. Variables, outputs, providers, backends - all the same syntax you already know.

File Format

Oxid reads .tf files written in HCL (HashiCorp Configuration Language). All .tf files in the working directory are automatically loaded and merged.

my-project/
  main.tf          # Resources and data sources
  variables.tf     # Variable declarations
  outputs.tf       # Output definitions
  providers.tf     # Provider configuration
  terraform.tfvars # Variable values
  backend.tf       # Backend configuration
NoteFile names are conventional - Oxid does not require specific file names. All .tf files in the directory are treated equally.

Resources

Resources are the primary building blocks of your infrastructure:

main.tf
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name        = "main-vpc"
    Environment = var.environment
  }
}

resource "aws_subnet" "public" {
  count             = var.az_count
  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]

  tags = {
    Name = "public-subnet-${count.index}"
  }
}

Variables

Declaring variables

variables.tf
variable "environment" {
  type        = string
  description = "Deployment environment"
  default     = "development"
}

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

variable "az_count" {
  type    = number
  default = 2
}

variable "enable_monitoring" {
  type    = bool
  default = true
}

variable "allowed_cidrs" {
  type    = list(string)
  default = ["10.0.0.0/8"]
}

variable "tags" {
  type = map(string)
  default = {
    ManagedBy = "oxid"
  }
}

Referencing variables

Use var.name to reference variables in your configuration:

resource "aws_instance" "web" {
  instance_type = var.instance_type
  tags          = merge(var.tags, { Name = "${var.environment}-web" })
}

Variable Values

terraform.tfvars

Create a terraform.tfvars file to set variable values:

terraform.tfvars
environment   = "production"
instance_type = "t3.large"
az_count      = 3

allowed_cidrs = [
  "10.0.0.0/8",
  "172.16.0.0/12",
]

tags = {
  ManagedBy   = "oxid"
  Environment = "production"
  Team        = "platform"
}

Environment variables

Set variables via TF_VAR_ prefixed environment variables:

export TF_VAR_environment="production"
export TF_VAR_instance_type="t3.large"
export TF_VAR_az_count=3

oxid plan

Variable Precedence

When the same variable is set in multiple places, Oxid uses this precedence (highest to lowest):

  1. TF_VAR_* environment variables (highest priority)
  2. terraform.tfvars file
  3. *.auto.tfvars files (alphabetical order)
  4. default value in variable declaration (lowest priority)

This matches Terraform's variable precedence exactly.

TipUse environment variables for secrets and per-environment overrides. Use .tfvars files for shared configuration.

Outputs

outputs.tf
output "vpc_id" {
  value       = aws_vpc.main.id
  description = "The ID of the VPC"
}

output "subnet_ids" {
  value = aws_subnet.public[*].id
}

output "db_password" {
  value     = aws_db_instance.main.password
  sensitive = true
}

Outputs are evaluated during apply and persisted to the state database. View them with oxid output.

Locals

Locals are named expressions that simplify your configuration:

locals {
  common_tags = {
    Environment = var.environment
    ManagedBy   = "oxid"
    Project     = "my-app"
  }

  name_prefix = "${var.environment}-${var.project_name}"
}

resource "aws_instance" "web" {
  tags = merge(local.common_tags, {
    Name = "${local.name_prefix}-web"
  })
}

Provider Configuration

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

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = local.common_tags
  }
}

Backend Configuration

Backend configuration tells Oxid where to find existing Terraform state for import and sync operations:

backend.tf
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}
NoteThe backend block is used by oxid sync and oxid init to locate existing Terraform state. Oxid's own state is always stored in its local SQLite database or the PostgreSQL backend configured via OXID_DATABASE_URL.

Data Sources

Data sources read information from your cloud provider without creating resources:

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

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

data "aws_availability_zones" "available" {
  state = "available"
}

resource "aws_instance" "web" {
  ami               = data.aws_ami.ubuntu.id
  instance_type     = var.instance_type
  availability_zone = data.aws_availability_zones.available.names[0]
}