Skip to main content

Getting Started with Kubiya Terraform Provider

This guide will walk you through setting up and using the Kubiya Control Plane Terraform Provider to manage your AI agent infrastructure as code.

Prerequisites

Before you begin, ensure you have:
  • Terraform >= 1.0 installed (Download)
  • Kubiya Control Plane Access (hosted or self-hosted)
  • API Key from your Kubiya Control Plane

Step 1: Obtain Your API Key

For Hosted Control Plane (SaaS)

  1. Navigate to https://compose.kubiya.ai
  2. Go to SettingsAPI Keys
  3. Click Generate New API Key
  4. Copy and securely store your API key

For Self-Hosted Control Plane

  1. Access your self-hosted control plane dashboard
  2. Navigate to SettingsAPI Keys
  3. Generate and copy your API key
  4. Note your control plane base URL (e.g., https://control-plane.your-company.com)

Step 2: Configure Environment Variables

Set up your authentication credentials:

Hosted Control Plane

export KUBIYA_CONTROL_PLANE_API_KEY="kcp_your_api_key_here"

Self-Hosted Control Plane

export KUBIYA_CONTROL_PLANE_API_KEY="kcp_your_api_key_here"
export KUBIYA_CONTROL_PLANE_BASE_URL="https://control-plane.your-company.com"
For production environments, consider using a secrets management solution like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault instead of environment variables.

Step 3: Create Your First Configuration

Create a new directory for your Terraform configuration:
mkdir kubiya-terraform
cd kubiya-terraform
Create a file named main.tf:
terraform {
  required_version = ">= 1.0"

  required_providers {
    controlplane = {
      source  = "kubiya/control-plane"
      version = "~> 1.0"
    }
  }
}

# Provider configuration
# Authentication is via environment variables
provider "controlplane" {
  # KUBIYA_CONTROL_PLANE_API_KEY (required)
  # KUBIYA_CONTROL_PLANE_BASE_URL (optional - defaults to https://control-plane.kubiya.ai)
}

# Create a production environment
resource "controlplane_environment" "production" {
  name         = "production"
  display_name = "Production Environment"
  description  = "Production environment for AI agents"
  tags         = ["production", "managed-by-terraform"]

  configuration = jsonencode({
    region         = "us-east-1"
    max_workers    = 10
    auto_scaling   = true
    retention_days = 90
  })
}

# Create a DevOps team
resource "controlplane_team" "devops" {
  name        = "devops-team"
  description = "DevOps and platform engineering team"

  # Runtime: "default" (Agno) or "claude_code" (Claude Code SDK)
  runtime = "claude_code"

  configuration = jsonencode({
    max_agents     = 10
    slack_channel  = "#devops-agents"
    alert_on_error = true
  })
}

# Create an operations agent
resource "controlplane_agent" "ops_assistant" {
  name        = "ops-assistant"
  description = "AI agent for DevOps operations"

  # Model options: "kubiya/claude-sonnet-4", "kubiya/gpt-4", etc.
  model_id = "kubiya/claude-sonnet-4"

  # Runtime: "default" or "claude_code"
  runtime = "claude_code"

  # Assign to team
  team_id = controlplane_team.devops.id

  # LLM configuration
  llm_config = jsonencode({
    temperature = 0.7
    max_tokens  = 4096
  })

  # Agent-specific configuration
  configuration = jsonencode({
    capabilities = ["kubernetes", "terraform", "monitoring"]
    permissions  = ["read", "execute"]
  })
}

# Outputs for reference
output "environment_id" {
  value       = controlplane_environment.production.id
  description = "Production environment ID"
}

output "team_id" {
  value       = controlplane_team.devops.id
  description = "DevOps team ID"
}

output "agent_id" {
  value       = controlplane_agent.ops_assistant.id
  description = "Operations assistant agent ID"
}

Step 4: Initialize Terraform

Initialize your Terraform working directory:
terraform init
Expected output:
Initializing the backend...

Initializing provider plugins...
- Finding kubiya/control-plane versions matching "~> 1.0"...
- Installing kubiya/control-plane v1.0.0...

Terraform has been successfully initialized!

Step 5: Plan Your Changes

Preview what Terraform will create:
terraform plan
Review the planned changes carefully. You should see:
  • 1 environment to create
  • 1 team to create
  • 1 agent to create

Step 6: Apply Your Configuration

Create the resources:
terraform apply
Type yes when prompted to confirm. Expected output:
controlplane_environment.production: Creating...
controlplane_team.devops: Creating...
controlplane_environment.production: Creation complete after 2s [id=env-xxxxx]
controlplane_team.devops: Creation complete after 2s [id=team-xxxxx]
controlplane_agent.ops_assistant: Creating...
controlplane_agent.ops_assistant: Creation complete after 3s [id=agent-xxxxx]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Outputs:

agent_id = "agent-xxxxx"
environment_id = "env-xxxxx"
team_id = "team-xxxxx"

Step 7: Verify Your Resources

Check the created resources:
# View outputs
terraform output

# View state
terraform show
You can also verify the resources in your Kubiya Control Plane dashboard.

Step 8: Make Changes

Update your configuration in main.tf. For example, change the agent description:
resource "controlplane_agent" "ops_assistant" {
  name        = "ops-assistant"
  description = "Enhanced AI agent for DevOps operations" # Updated
  # ... rest of configuration
}
Apply the changes:
terraform plan   # Review changes
terraform apply  # Apply changes

Using Data Sources

Look up existing resources using data sources. Create a file named data.tf:
# Look up an existing environment
data "controlplane_environment" "existing_prod" {
  id = "env-xxxxx"  # Use your actual environment ID
}

# Reference it in outputs
output "existing_env_name" {
  value = data.controlplane_environment.existing_prod.name
}

# Use it to create dependent resources
resource "controlplane_agent" "another_agent" {
  name     = "data-analyst"
  model_id = "kubiya/claude-sonnet-4"
  runtime  = "claude_code"

  # Reference the existing environment
  configuration = jsonencode({
    environment = data.controlplane_environment.existing_prod.name
  })
}

Best Practices for Operators

1. Use Variables

Create variables.tf:
variable "environment" {
  description = "Environment name (dev, staging, production)"
  type        = string
  default     = "production"
}

variable "team_name" {
  description = "Team name"
  type        = string
}

variable "agent_model" {
  description = "LLM model for agents"
  type        = string
  default     = "kubiya/claude-sonnet-4"
}
Create terraform.tfvars:
environment = "production"
team_name   = "platform-engineering"
agent_model = "kubiya/claude-sonnet-4"

2. Use Remote State

Configure remote state storage in backend.tf:
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "kubiya/production/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

3. Organize with Modules

Create reusable modules:
modules/
  agent-team/
    main.tf
    variables.tf
    outputs.tf
environments/
  production/
    main.tf
  staging/
    main.tf

4. Use Workspaces

Manage multiple environments:
# Create workspaces
terraform workspace new production
terraform workspace new staging

# Switch between workspaces
terraform workspace select production
terraform apply

terraform workspace select staging
terraform apply

Cleanup

When you’re done experimenting, destroy the resources:
terraform destroy
Type yes when prompted.
Be careful with terraform destroy in production environments. Consider using -target to destroy specific resources or implement lifecycle rules to prevent accidental deletion.

Troubleshooting

Authentication Errors

If you see authentication errors:
# Verify environment variables are set
echo $KUBIYA_CONTROL_PLANE_API_KEY
echo $KUBIYA_CONTROL_PLANE_BASE_URL

# Re-export if needed
export KUBIYA_CONTROL_PLANE_API_KEY="your-key"

Provider Not Found

If Terraform can’t find the provider:
# Clear cache and reinitialize
rm -rf .terraform .terraform.lock.hcl
terraform init

Resource Already Exists

If resources already exist:
# Import existing resources
terraform import controlplane_agent.ops_assistant agent-xxxxx

Next Steps

Now that you have a basic configuration running:
  1. Configure Provider Options - Learn about advanced configuration
  2. Explore Resources - Detailed documentation for all resources
  3. Review Examples - End-to-end examples for operators
  4. Learn About Policies - Implement governance with OPA Rego
  5. Set Up Jobs - Automate workflows with scheduled jobs

Additional Resources