By the end of this guide we will setup the statesman backend for state management. We will also setup the cli and use it to create our first “unit”. A unit is a versioned state in statesman. We will also configure our first terraform/opentofu resources to use the newly created unit and create a simple resource. Lets dig in!

Prerequisites

1

Configure publicly accessible URL

Opentaco services expected to be publicly accessible for oauth flow to function correctly. OPENTACO_PUBLIC_BASE_URL is the env variable where you expect your service to be hosted that is public facing.If you are running a load balancer, it is the public side of that load balancer.If its a single server, it is the public endpoint.If you are running it through ngrok on your local machine it is the ngrok url, not localhost.
2

Setup Auth provider

Navigate to https://auth0.com, create an account and sign in.You’re going to want to create a native app. Once you do that it’ll take you to a screen where you can select a technology - we don’t need this. You can instead go to settings.In the settings tab take note of the domain, client id and client secret. Feel free to store them in environment variables as follows:
OPENTACO_AUTH_ISSUER=https://[[auth0 domain]]/ # trailing slash is IMPORTANT!
OPENTACO_AUTH_CLIENT_ID=[[auth0 client id]]
OPENTACO_AUTH_CLIENT_SECRET=[[auth0 client secret]]
In the settings tab scroll down to callback urls and add the following callback url: http://127.0.0.1:8585/callbackYou also need to set this value: https://OPENTACO_PUBLIC_BASE_URL/oauth/oidc-callbackAfter you added both values hit save changesOnce we have these values we can export them in our .zshrc, .bashrc, .profile, .zprofile or whatever is applicable on your platform.
3

Setup Cloud provider

Statesman relies on an S3 compatible storage, in case of AWS we will need to have an S3 Bucket. You can create an S3 bucket using the AWS Console or using the AWS CLI. Take note of your bucket name as we will need it in future steps.In addition we will be needing aws cli credentials to be configured for Statesman to be able to access the S3 bucket. Configure a set of credentials and make note of the following values:
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_DEFAUlT_REGION

Configure Statesman Backend

The first component we want to configure is the statesman backend, this will be the main gatekeeper for all your state management, enforcing proper management for all users and systems requiring access to state.
1

Setup Env file

The next thing you’ll want to do is to setup Statesman - the state management service.First we’ll want to make an env file for your service.We’ll need the values from the settings page of our Auth0 application:
OPENTACO_AUTH_ISSUER
OPENTACO_AUTH_CLIENT_ID
OPENTACO_AUTH_CLIENT_SECRET
Then we need to create two more:
OPENTACO_AUTH_AUTH_URL="https://{Your-Auth0-domain}/authorize"
OPENTACO_AUTH_TOKEN_URL="https://{Your-Auth0-domain}/oauth/token"
Note that these are specific to Auth0, if you use another provider they may use different endpoints. That is why they are defined separately and not computed.The next values we need are from S3:
OPENTACO_S3_BUCKET=your-open-taco-bucket-name
OPENTACO_S3_PREFIX=a-folder-within-that-bucket
OPENTACO_S3_REGION=your-aws-region
And lastly the OPENTACO_PUBLIC_BASE_URL which is where you expect your service to be hosted that is public facing.If you are running a load balancer, it is the public side of that load balancer.If its a single server, it is the public endpoint.If you are running it through ngrok on your local machine it is the ngrok url, not localhost. The reason for this is that the SSO providers expect an ssl termination to be present.

Complete Environment Configuration

We should have these values in our .env now:
OPENTACO_S3_BUCKET='your-bucket-name'  # not a uri, the name itself
OPENTACO_S3_REGION='aws-region' # like us-east-1
OPENTACO_S3_PREFIX='folder-name'
OPENTACO_AUTH_ISSUER='https://[[your-auth0-app-domain]]/' # trailing slash is IMPORTANT!
OPENTACO_AUTH_CLIENT_ID='your-auth0-app-clientid'
OPENTACO_AUTH_CLIENT_SECRET='your-auth0-app-client-secret'
OPENTACO_AUTH_AUTH_URL='{your-auth0-app-domain}/authorize'
OPENTACO_AUTH_TOKEN_URL='{your-auth0-app-domain}/oauth/token'
OPENTACO_PUBLIC_BASE_URL='https://public.url/opentaco'
AWS_ACCESS_KEY_ID='your-aws-access-key-id'
AWS_SECRET_ACCESS_KEY='your-aws-secret-access-key'
AWS_DEFAULT_REGION='your-cli-region'
2

Run Statesman

Use the docker-compose.yml in examples:
version: '3.8'

services:
    statesman:
        image: ${STATESMAN_IMAGE:-ghcr.io/diggerhq/digger/taco-statesman:latest}
        ports:
            - "${OPENTACO_PORT:-8080}:8080"
        env_file:
            - .env  # Copy from .env.example and customize
        volumes:
            # Optional: persist data if using file-based storage later
            - statesman-data:/app/data
        healthcheck:
            test: ["CMD", "curl", "-f", "http://localhost:8080/healthz"]
            interval: 30s
            timeout: 10s
            retries: 3
            start_period: 40s
        restart: unless-stopped
        container_name: opentaco-statesman

volumes:
    statesman-data:
        driver: local
Place your .env in the same directory.

Starting the Service

Run docker-compose up:
docker-compose up -d
3

Verify Statesman is running

You can verify statesman is running with:
curl http://localhost:8080/healthz
If all goes well you will see:
{"service":"opentaco","status":"ok"}

Configure Taco CLI

1

Install Cli

The first thing you’ll want to do is visit our releases page here and check the latest taco/cli release. Right now it is v0.1.7
# For Linux AMD64 (most common)
curl -L https://github.com/diggerhq/digger/releases/download/taco/cli/v0.1.7/taco-linux-amd64 -o taco
chmod +x taco

# Move to a directory in your PATH
sudo mv taco /usr/local/bin

# Alternative: Install to user directory (no sudo required)
mkdir -p ~/.local/bin
mv taco ~/.local/bin
# Add to PATH in your shell profile if not already there
echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
For other architectures:
# For Linux ARM64
curl -L https://github.com/diggerhq/digger/releases/download/taco/cli/v0.1.7/taco-linux-arm64 -o taco

# For Linux 386
curl -L https://github.com/diggerhq/digger/releases/download/taco/cli/v0.1.7/taco-linux-386 -o taco
Confirm Taco CLI is available with:
taco --help
2

Configure CLI Environment Variables

For the best experience in your shell you can configure the following environment vars for the CLI:

On macOS/Linux:

export OPENTACO_SERVER=https://my-opentaco.company.com
export OPENTACO_AUTH_ISSUER=https://[[auth0 domain]]/
export OPENTACO_AUTH_CLIENT_ID=[[auth0 client id]]
The env variable OPENTACO_SERVER is the address of your server which we’ll get to setting up later.

Create Your First Unit

Now that you have OpenTaco running and authentication configured, let’s walk through a complete example from creating a unit to running Terraform operations.
1

Authenticate Both Systems

First, complete both authentication flows:
# Authenticate taco CLI (for unit management)
taco login

# Authenticate Terraform (for cloud block operations)
terraform login localhost:8080
2

Create a Unit

Create a new unit to hold your Terraform state:
# Create a unit named "demo-project"
taco unit create demo-project
Verify the unit was created:
# List all units
taco unit ls

# Check unit details
taco unit info demo-project
3

Create a Terraform Configuration

Create a new directory and Terraform configuration:
# Create project directory
mkdir terraform-demo
cd terraform-demo
Create a main.tf file with cloud block configuration:
terraform {
    # Configure OpenTaco as cloud backend
    cloud {
        organization = "opentaco"
        hostname = "localhost:8080"  # Replace with your OpenTaco server
        workspaces {
            name = "demo-project"
        }
    }
}

# Example resources
resource "random_string" "demo" {
    length  = 16
    special = false
}

resource "local_file" "demo_output" {
    content  = "Generated string: ${random_string.demo.result}"
    filename = "${path.module}/demo-output.txt"
}

# Outputs
output "random_value" {
    value       = random_string.demo.result
    description = "Generated random string"
}

output "file_path" {
    value       = local_file.demo_output.filename
    description = "Path to output file"
}
4

Initialize Terraform

Initialize the Terraform project with the cloud backend:
terraform init
You should see output similar to:
Initializing Terraform Cloud...
Initializing provider plugins...
Terraform Cloud has been successfully initialized!
5

Plan your changes

Run a Terraform plan to see what will be created:
terraform plan
This will:
  1. Connect to OpenTaco using your stored credentials
  2. Create or use the “demo-project” workspace
  3. Show you the planned changes
6

Apply your configuration

Apply the Terraform configuration:
terraform apply
Type yes when prompted. This will:
  1. Create the random string resource
  2. Create a local file with the output
  3. Store the state remotely in OpenTaco
  4. Display the outputs
7

Verify state management

Check that your state is being managed by OpenTaco:
# View unit status with taco CLI
taco unit info demo-project

# Check if unit is locked during operations
taco unit ls

# View unit status (shows dependencies if any)
taco unit status demo-project
You can also check your local directory:
# Should show the created output file
ls -la
cat demo-output.txt
8

Make changes and update

Edit your main.tf to add another resource:
# Add this resource to your main.tf
resource "random_password" "secure_demo" {
    length  = 32
    special = true
}

# Add this output
output "secure_value" {
    value     = random_password.secure_demo.result
    sensitive = true
}
Plan and apply the changes:
terraform plan
terraform apply
9

Explore unit management

Try some unit management operations:
# Download the current state (if needed)
taco unit pull demo-project demo-state.json

# View the downloaded state
cat demo-state.json

# Check unit versions (if versioning is enabled)
taco unit versions demo-project

# View unit status and dependencies
taco unit status demo-project
10

cleanup

When you’re done experimenting:
# Destroy the Terraform resources
terraform destroy

# Delete the unit (optional)
taco unit rm demo-project

# Remove local files
rm -rf terraform-demo

Advanced Cloud Block Options

Multiple workspaces with tags:
terraform {
  cloud {
    hostname = "localhost:8080"
    organization = "my-org"  # Optional
    
    workspaces {
      tags = ["app:web", "env:production"]
    }
  }
}
Environment-specific configuration:
export TF_CLOUD_HOSTNAME=localhost:8080
export TF_WORKSPACE=my-workspace
terraform init

Troubleshooting

Troubleshooting Authentication

Re-authenticate if needed:
# Force re-authentication for taco CLI
taco logout && taco login

# Force re-authentication for Terraform cloud block
terraform login -force <your-opentaco-hostname>
Check stored credentials:
# View taco CLI credentials (used by taco commands)
cat ~/.config/opentaco/credentials.json

# View Terraform credentials (used by terraform cloud block)
cat ~/.terraform.d/credentials.tfrc.json
Common issues:
  • If taco unit ls fails: Your taco CLI authentication may have expired, run taco login
  • If terraform init/plan fails: Your terraform authentication may have expired, run terraform login again
  • Both credentials are independent - one expiring doesn’t affect the other

Next Steps

Now you can:
  • Set up RBAC to control who can access different units
  • Create multiple workspaces for different environments
  • Use the S3-compatible API for advanced integrations
  • Set up CI/CD pipelines using the cloud block
  • Explore dependency management between units