Terraform Provider
Manage SixDegree resources using infrastructure-as-code with Terraform.
GitHub Repository | Terraform Registry
Overview
The SixDegree Terraform provider allows you to define and manage your SixDegree infrastructure as code. Instead of manually configuring discovery providers, MCP endpoints, model providers, and other resources through the UI or API, you can declare your entire configuration in Terraform and manage it with version control.
Why use Terraform for SixDegree?
- Declarative Configuration: Define your entire SixDegree setup in code, making it easy to understand and reproduce
- Version Control: Track changes to your infrastructure configuration over time
- Reproducibility: Easily spin up identical environments for development, staging, and production
- Team Collaboration: Share and review infrastructure changes through pull requests
- Automation: Integrate with CI/CD pipelines to automatically provision and update resources
- Consistency: Avoid configuration drift and manual errors by managing everything through code
Common use cases include:
- Setting up discovery providers for GitHub, GitLab, Argo CD, and Docker registries
- Configuring MCP endpoints with custom authentication and tool permissions
- Managing model providers (OpenAI, Anthropic, xAI) and their associated models
- Creating chat suggestions and OAuth service configurations
- Provisioning complete environments with all necessary integrations
Installation
Add to your Terraform configuration:
terraform {
required_providers {
sixdegree = {
source = "sixdegreeai/sixdegree"
}
}
}
provider "sixdegree" {
host = "https://api.sixdegree.ai"
access_token = var.sixdegree_access_token
}
Authentication
The provider supports three authentication methods:
Option 1: Using SixDegree CLI (Recommended)
data "external" "sixdegree_auth" {
program = ["bash", "-c", "echo '{\"token\":\"'$(sixdegree auth token)'\"}'"]
}
provider "sixdegree" {
host = "https://api.sixdegree.ai"
access_token = data.external.sixdegree_auth.result.token
}
Option 2: Environment Variables
export SIXDEGREE_ACCESS_TOKEN=$(sixdegree auth token)
export SIXDEGREE_HOST="https://api.sixdegree.ai"
provider "sixdegree" {
# Automatically uses environment variables
}
Option 3: Direct Configuration
provider "sixdegree" {
host = "https://api.sixdegree.ai"
access_token = var.sixdegree_access_token
}
Resources
Environment
Manages an environment in SixDegree.
resource "sixdegree_environment" "production" {
name = "Production"
instance_url = "https://prod.sixdegree.ai"
stripe_subscription_id = "sub_xxxxx"
invited_users = [
"user1@example.com",
"user2@example.com"
]
}
MCP Endpoint
Manages an MCP (Model Context Protocol) endpoint configuration.
resource "sixdegree_mcp_endpoint" "example" {
name = "PostgreSQL Tools"
url = "https://mcp-postgres.example.com/v1"
description = "PostgreSQL database tools"
headers = {
"X-Custom-Header" = "value"
}
sixdegree_auth = false
supports_resources = true
active = true
allowed_tools = ["query", "execute"]
denied_tools = ["drop_table"]
}
For OAuth authentication:
resource "sixdegree_mcp_endpoint" "github" {
name = "GitHub MCP"
url = "https://mcp-github.example.com"
oauth_service_id = sixdegree_oauth_service.github.id
active = true
}
Model Provider
Manages model provider configurations (OpenAI, Anthropic, xAI).
resource "sixdegree_model_provider" "anthropic" {
type = "anthropic"
name = "Anthropic Claude"
api_key = var.anthropic_api_key
default = true
}
resource "sixdegree_model_provider" "openai" {
type = "openai"
name = "OpenAI"
api_key = var.openai_api_key
default = false
}
resource "sixdegree_model_provider" "xai" {
type = "xai"
name = "xAI Grok"
api_key = var.xai_api_key
default = false
}
Model
Manages model configurations.
resource "sixdegree_model" "claude_opus" {
name = "claude-3-opus-20240229"
description = "Claude 3 Opus model"
provider_id = sixdegree_model_provider.anthropic.id
default = true
}
resource "sixdegree_model" "gpt4" {
name = "gpt-4"
description = "GPT-4 model"
provider_id = sixdegree_model_provider.openai.id
default = false
}
Discovery Provider
Manages discovery providers that continuously discover entities and relations from external systems.
resource "sixdegree_discovery_provider" "github" {
name = "GitHub Production"
provider_type = "github"
enabled = true
interval = 300 # 5 minutes (minimum 60 seconds)
config = jsonencode({
token = var.github_token
selectors = [
{
organization = "myorg"
repo_name = ".*"
}
]
})
}
resource "sixdegree_discovery_provider" "argo" {
name = "Argo CD Staging"
provider_type = "argo"
enabled = true
interval = 300
config = jsonencode({
api_url = "https://argocd.example.com/api/v1/"
token = var.argo_token
})
}
resource "sixdegree_discovery_provider" "docker" {
name = "GHCR Docker Registry"
provider_type = "docker"
enabled = true
interval = 600
config = jsonencode({
registry_type = "ghcr"
api_url = "https://ghcr.io/"
username = "myusername"
token = var.docker_token
selectors = [
{
namespace_pattern = "myorg"
repository_pattern = "^(app1|app2)$"
max_tags = 10
exclude_tags = [".*-dev.*", "latest"]
}
]
})
}
Supported provider types:
github- GitHub repositories, issues, pull requestsgitlab- GitLab projects and resourcesargo- Argo CD applicationsvercel- Vercel deploymentsdocker- Docker registries (Docker Hub, GHCR, ECR)file- File-based discoveryfossa- FOSSA license compliancemeta- Meta integrations
OAuth Service
Manages OAuth service configurations for authenticating with external services.
resource "sixdegree_oauth_service" "github" {
name = "GitHub OAuth"
provider_type = "github"
client_id = var.github_oauth_client_id
client_secret = var.github_oauth_client_secret
redirect_uri = "https://app.sixdegree.ai/oauth/callback"
}
Chat Suggestion
Manages chat suggestions that appear in the SixDegree chat interface.
resource "sixdegree_chat_suggestion" "onboarding" {
title = "Getting Started"
description = "Learn about your infrastructure"
prompt = "Show me an overview of all my repositories and their recent activity"
icon = "rocket"
category = "onboarding"
order = 1
}
Complete Example
terraform {
required_providers {
sixdegree = {
source = "sixdegreeai/sixdegree"
}
}
}
variable "sixdegree_access_token" {
type = string
sensitive = true
}
variable "github_token" {
type = string
sensitive = true
}
variable "anthropic_api_key" {
type = string
sensitive = true
}
variable "db_mcp_token" {
type = string
sensitive = true
}
# Provider configuration
provider "sixdegree" {
host = "https://api.sixdegree.ai"
access_token = var.sixdegree_access_token
}
# Configure GitHub discovery
resource "sixdegree_discovery_provider" "github" {
name = "GitHub Production"
provider_type = "github"
enabled = true
interval = 300
config = jsonencode({
token = var.github_token
selectors = [
{
organization = "myorg"
repo_name = ".*"
}
]
})
}
# Configure Anthropic model provider
resource "sixdegree_model_provider" "anthropic" {
type = "anthropic"
name = "Anthropic Claude"
api_key = var.anthropic_api_key
default = true
}
# Enable Claude Opus
resource "sixdegree_model" "claude_opus" {
name = "claude-3-opus-20240229"
description = "Claude 3 Opus model"
provider_id = sixdegree_model_provider.anthropic.id
default = true
}
# MCP endpoint
resource "sixdegree_mcp_endpoint" "database_tools" {
name = "Database Tools"
url = "https://mcp-db.example.com"
description = "PostgreSQL tools for querying databases"
headers = {
"Authorization" = "Bearer ${var.db_mcp_token}"
}
sixdegree_auth = false
supports_resources = true
active = true
allowed_tools = ["query", "list_tables", "describe_table"]
}
# Chat suggestion
resource "sixdegree_chat_suggestion" "repos_overview" {
title = "Repository Overview"
description = "Get an overview of all repositories"
prompt = "Show me all repositories and their recent activity"
icon = "git-branch"
category = "repositories"
order = 1
}
output "model_provider_id" {
value = sixdegree_model_provider.anthropic.id
}
output "mcp_endpoint_id" {
value = sixdegree_mcp_endpoint.database_tools.id
}
Best Practices
Use Variables for Sensitive Data
Always store sensitive data in variables marked as sensitive:
variable "sixdegree_access_token" {
type = string
sensitive = true
}
variable "github_token" {
type = string
sensitive = true
}
Use External Data Source for CLI Integration
For the best developer experience, use the external data source to fetch tokens from the SixDegree CLI:
data "external" "sixdegree_auth" {
program = ["bash", "-c", "echo '{\"token\":\"'$(sixdegree auth token)'\"}'"]
}
provider "sixdegree" {
access_token = data.external.sixdegree_auth.result.token
}
Remote State
Use remote state for team collaboration:
terraform {
backend "s3" {
bucket = "terraform-state"
key = "sixdegree/production"
region = "us-east-1"
}
}
Organize with Modules
Create reusable modules for common patterns:
module "sixdegree_monitoring" {
source = "./modules/sixdegree-monitoring"
github_token = var.github_token
anthropic_api_key = var.anthropic_api_key
environment_id = var.environment_id
}
Use jsonencode for Complex Config
When configuring discovery providers, use jsonencode() to ensure proper JSON formatting:
config = jsonencode({
token = var.token
selectors = [
{ organization = "myorg" }
]
})
Data Sources
Data sources allow you to reference existing SixDegree resources.
sixdegree_environment
data "sixdegree_environment" "production" {
name = "Production"
}
output "environment_id" {
value = data.sixdegree_environment.production.id
}
sixdegree_model_provider
data "sixdegree_model_provider" "anthropic" {
type = "anthropic"
}
resource "sixdegree_model" "claude" {
provider_id = data.sixdegree_model_provider.anthropic.id
name = "claude-3-5-sonnet-20241022"
}
Importing Existing Resources
Import existing SixDegree resources into Terraform state.
Import Environment
terraform import sixdegree_environment.production env_abc123
Import Discovery Provider
terraform import sixdegree_discovery_provider.github dp_xyz789
Import MCP Endpoint
terraform import sixdegree_mcp_endpoint.example mcp_abc123
Import Model Provider
terraform import sixdegree_model_provider.anthropic mp_xyz789
Bulk Import
Create a script to import multiple resources:
#!/bin/bash
# Import all environments
terraform import sixdegree_environment.production env_prod123
terraform import sixdegree_environment.staging env_stag456
# Import discovery providers
terraform import sixdegree_discovery_provider.github dp_github001
terraform import sixdegree_discovery_provider.gitlab dp_gitlab002
# Import model providers
terraform import sixdegree_model_provider.anthropic mp_anthropic001
terraform import sixdegree_model_provider.openai mp_openai002
State Management
Remote State Backend
Configure remote state for team collaboration:
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "sixdegree/production/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
State Locking
Use DynamoDB for state locking with S3 backend:
resource "aws_dynamodb_table" "terraform_locks" {
name = "terraform-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
State Migration
Migrate existing resources to new modules:
# Move resource to module
terraform state mv sixdegree_discovery_provider.github module.github.sixdegree_discovery_provider.main
# Remove resource from state (without destroying)
terraform state rm sixdegree_chat_suggestion.old
# Import into new location
terraform import module.suggestions.sixdegree_chat_suggestion.main cs_abc123
Testing Terraform Configurations
Validation
# Format check
terraform fmt -check
# Validate configuration
terraform validate
# Plan without applying
terraform plan -out=plan.tfplan
# Review plan
terraform show plan.tfplan
Testing Frameworks
Use Terratest for automated testing:
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
func TestSixDegreeInfrastructure(t *testing.T) {
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
TerraformDir: "../examples/complete",
Vars: map[string]interface{}{
"sixdegree_access_token": getTestToken(),
},
})
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
// Verify outputs
environmentID := terraform.Output(t, terraformOptions, "environment_id")
assert.NotEmpty(t, environmentID)
}
Pre-commit Hooks
Add .pre-commit-config.yaml:
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.83.5
hooks:
- id: terraform_fmt
- id: terraform_validate
- id: terraform_docs
- id: terraform_tflint
CI/CD Integration
GitHub Actions
name: Terraform
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.6.0
- name: Terraform Format
run: terraform fmt -check
- name: Terraform Init
run: terraform init
env:
TF_VAR_sixdegree_access_token: ${{ secrets.SIXDEGREE_TOKEN }}
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
run: terraform plan -out=plan.tfplan
env:
TF_VAR_sixdegree_access_token: ${{ secrets.SIXDEGREE_TOKEN }}
TF_VAR_github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Terraform Apply
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: terraform apply -auto-approve plan.tfplan
env:
TF_VAR_sixdegree_access_token: ${{ secrets.SIXDEGREE_TOKEN }}
GitLab CI
variables:
TF_ROOT: ${CI_PROJECT_DIR}/terraform
TF_STATE_NAME: ${CI_PROJECT_NAME}
stages:
- validate
- plan
- apply
before_script:
- cd ${TF_ROOT}
- terraform init
validate:
stage: validate
script:
- terraform fmt -check
- terraform validate
plan:
stage: plan
script:
- terraform plan -out=plan.tfplan
artifacts:
paths:
- ${TF_ROOT}/plan.tfplan
expire_in: 1 week
only:
- merge_requests
apply:
stage: apply
script:
- terraform apply -auto-approve plan.tfplan
dependencies:
- plan
only:
- main
Troubleshooting
Common Issues
Authentication Failures:
# Verify token is valid
export SIXDEGREE_ACCESS_TOKEN=$(degree auth token)
degree whoami
# Check token in Terraform
terraform console
> var.sixdegree_access_token
Provider Not Found:
# Clear plugin cache
rm -rf .terraform
# Reinitialize
terraform init
Resource Already Exists:
# Import existing resource
terraform import sixdegree_discovery_provider.github dp_existing123
# Or remove from state and recreate with different name
terraform state rm sixdegree_discovery_provider.github
Configuration Drift:
# Check for drift
terraform plan
# Refresh state
terraform refresh
# Force recreation
terraform taint sixdegree_discovery_provider.github
terraform apply
Debugging
Enable debug logging:
export TF_LOG=DEBUG
export TF_LOG_PATH=terraform.log
terraform apply
View provider requests:
export TF_LOG_PROVIDER=TRACE
terraform apply
Advanced Patterns
Dynamic Configuration
Use for_each for multiple similar resources:
variable "discovery_providers" {
type = map(object({
type = string
interval = number
config = map(string)
}))
}
resource "sixdegree_discovery_provider" "providers" {
for_each = var.discovery_providers
name = each.key
provider_type = each.value.type
enabled = true
interval = each.value.interval
config = jsonencode(each.value.config)
}
Conditional Resources
variable "enable_github_discovery" {
type = bool
default = true
}
resource "sixdegree_discovery_provider" "github" {
count = var.enable_github_discovery ? 1 : 0
name = "GitHub"
provider_type = "github"
enabled = true
interval = 300
config = jsonencode({ token = var.github_token })
}
Module Composition
module "discovery" {
source = "./modules/discovery"
github_token = var.github_token
gitlab_token = var.gitlab_token
argo_token = var.argo_token
}
module "models" {
source = "./modules/models"
anthropic_api_key = var.anthropic_api_key
openai_api_key = var.openai_api_key
}
module "mcp" {
source = "./modules/mcp"
database_token = var.database_token
slack_token = var.slack_token
}
Development
Local Development Setup
To use a locally built provider:
-
Build the provider:
cd terraform-provider-sixdegree
go build -o terraform-provider-sixdegree -
Create
~/.terraformrc:provider_installation {
dev_overrides {
"sixdegreeai/sixdegree" = "/path/to/terraform-provider-sixdegree"
}
direct {}
} -
Run Terraform commands as usual. Terraform will use your local build.
Documentation Generation
The provider uses tfplugindocs to auto-generate documentation from schema and examples:
# Generate docs
make docs
# Validate docs
make docs-validate
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Run tests:
make test - Submit pull request