Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/gravitational/teleport/llms.txt

Use this file to discover all available pages before exploring further.

The official Teleport Terraform provider lets you manage every Teleport dynamic resource — roles, users, SSO connectors, join tokens, and more — using infrastructure-as-code. Because the provider calls the same gRPC API as tctl, any resource you can create in the Teleport Web UI or with the CLI can be declared in HCL and applied with terraform apply. The provider is published at the custom Terraform registry address terraform.releases.teleport.dev/gravitational/teleport. Pin the version to your Teleport cluster’s major version to maintain compatibility.

Provider installation and configuration

terraform block

terraform {
  required_providers {
    teleport = {
      source  = "terraform.releases.teleport.dev/gravitational/teleport"
      version = "~> 17.0"   # match your Teleport major version
    }
  }
}

provider block

The Teleport provider authenticates with the cluster using credentials obtained from a Teleport Machine ID bot, a tctl terraform env session, or a long-lived identity file.
provider "teleport" {
  # Proxy Service address (host:port)
  addr = "example.teleport.sh:443"

  # Option 1 — Machine ID bot (recommended for CI/CD)
  # The provider discovers credentials from TELEPORT_* environment variables
  # set by `tctl terraform env` or a Machine ID output.

  # Option 2 — Identity file (for dedicated servers)
  # identity_file_path = "/opt/teleport/terraform-identity"

  # Option 3 — Profile from tsh login (local development only)
  # profile_name = ""
  # profile_dir  = ""
}
For CI/CD pipelines, run eval "$(tctl terraform env)" before terraform apply. This creates a short-lived Machine ID bot, obtains certificates, and exports them as TELEPORT_* environment variables that the provider automatically reads.
Never store long-lived Teleport credentials in Terraform state or VCS. Use Machine ID (tbot) with a short TTL for automated pipelines. See the Terraform Getting Started guide for platform-specific examples.

Key resources

teleport_role

Creates or updates a Teleport role resource.
resource "teleport_role" "developer" {
  version = "v8"
  metadata = {
    name        = "developer"
    description = "Developer access to staging resources"
    labels = {
      managed-by = "terraform"
    }
  }

  spec = {
    allow = {
      logins = ["{{internal.logins}}", "dev"]

      node_labels = {
        env = ["staging"]
      }

      kubernetes_labels = {
        env = ["staging"]
      }
      kubernetes_groups = ["developers"]

      db_names  = ["{{internal.db_names}}"]
      db_users  = ["{{internal.db_users}}"]
      db_labels = {
        env = ["staging"]
      }

      app_labels = {
        env = ["staging"]
      }

      rules = [
        {
          resources = ["session"]
          verbs     = ["list", "read"]
        }
      ]

      request = {
        roles       = ["prod-access"]
        max_duration = "8h"
        reason = {
          mode = "required"
        }
      }
    }

    deny = {}

    options = {
      max_session_ttl      = "8h0m0s"
      forward_agent        = false
      require_session_mfa  = "no"
    }
  }
}

teleport_user

Creates a local Teleport user with assigned roles and traits.
resource "teleport_user" "alice" {
  metadata = {
    name = "alice@example.com"
  }

  spec = {
    roles = [
      teleport_role.developer.metadata.name,
      "access"
    ]

    traits = {
      logins           = ["alice", "ubuntu"]
      kubernetes_users = ["alice"]
      db_users         = ["alice"]
    }
  }
}

teleport_github_connector

Configures GitHub as an SSO provider.
resource "teleport_github_connector" "github" {
  metadata = {
    name = "github"
  }

  spec = {
    client_id     = var.github_client_id
    client_secret = var.github_client_secret
    redirect_url  = "https://example.teleport.sh:443/v1/webapi/github/callback"

    teams_to_roles = [
      {
        organization = "my-org"
        team         = "engineers"
        roles        = [teleport_role.developer.metadata.name]
      },
      {
        organization = "my-org"
        team         = "sre"
        roles        = ["editor"]
      }
    ]
  }
}

teleport_oidc_connector

Configures an OIDC identity provider (Okta, Google Workspace, Entra ID, etc.).
resource "teleport_oidc_connector" "okta" {
  metadata = {
    name = "okta"
  }

  spec = {
    client_id     = var.oidc_client_id
    client_secret = var.oidc_client_secret
    issuer_url    = "https://dev-123456.okta.com"
    redirect_url  = "https://example.teleport.sh:443/v1/webapi/oidc/callback"

    claims_to_roles = [
      {
        claim = "groups"
        value = "engineers"
        roles = [teleport_role.developer.metadata.name]
      },
      {
        claim = "groups"
        value = "sre"
        roles = ["editor"]
      }
    ]
  }
}

teleport_saml_connector

Configures a SAML identity provider.
resource "teleport_saml_connector" "okta_saml" {
  metadata = {
    name = "okta-saml"
  }

  spec = {
    acs                = "https://example.teleport.sh:443/v1/webapi/saml/acs"
    entity_descriptor  = var.saml_idp_metadata_xml   # XML string from your IdP

    attributes_to_roles = [
      {
        name  = "groups"
        value = "engineers"
        roles = [teleport_role.developer.metadata.name]
      }
    ]
  }
}

teleport_provision_token

Creates a join token for enrolling Teleport agents.
resource "random_string" "agent_token" {
  length  = 32
  special = false
}

resource "teleport_provision_token" "agent_pool" {
  metadata = {
    name    = random_string.agent_token.result
    expires = timeadd(timestamp(), "876000h")  # ~100 years; use TTL for ephemeral tokens
  }

  spec = {
    roles = ["Node", "App", "Db", "Kube"]
    # For IAM joining (no token needed on the node):
    # allow = [
    #   {
    #     aws_account = "123456789012"
    #     aws_regions = ["us-east-1"]
    #   }
    # ]
    # join_method = "iam"
  }
}
Static join tokens are a security risk if leaked. Prefer IAM, EC2, GitHub Actions, or other attestation-based join methods in production. Set a short expiry if you must use static tokens.

Complete role and user example

The following module creates a read-only role, a developer role, and a user assigned to the developer role:
# roles.tf

resource "teleport_role" "read_only" {
  version = "v8"
  metadata = {
    name = "read-only"
  }
  spec = {
    allow = {
      rules = [
        {
          resources = ["node", "app", "db", "kube_cluster"]
          verbs     = ["list", "read"]
        }
      ]
    }
    deny    = {}
    options = { max_session_ttl = "4h0m0s" }
  }
}

resource "teleport_role" "developer" {
  version = "v8"
  metadata = {
    name = "developer"
  }
  spec = {
    allow = {
      logins    = ["{{internal.logins}}", "ubuntu"]
      node_labels = { env = ["staging"] }
      request   = { roles = ["editor"] }
    }
    deny    = {}
    options = { max_session_ttl = "8h0m0s" }
  }
}

# users.tf

resource "teleport_user" "alice" {
  metadata = {
    name = "alice@example.com"
  }
  spec = {
    roles  = [teleport_role.developer.metadata.name, "access"]
    traits = {
      logins = ["alice"]
    }
  }
}

Importing existing resources

You can bring existing Teleport resources under Terraform management without recreating them.
1

Add an import block to your configuration

import {
  to = teleport_role.existing_admin
  id = "editor"   # resource name as shown by tctl get role/editor
}

resource "teleport_role" "existing_admin" {
  # spec will be populated after the import
}
2

Run terraform plan with generate-config

terraform plan -generate-config-out=generated.tf
Terraform will write the full HCL representation of the imported resource into generated.tf. Review the output and move the relevant blocks into your own .tf files.
3

Apply to adopt the resource

terraform apply
Terraform imports the resource into state without making changes. Future apply runs will manage it.
Alternatively, use the legacy terraform import command directly:
terraform import teleport_role.developer developer
terraform import teleport_user.alice alice@example.com
terraform import teleport_github_connector.github github

Provider authentication methods

Machine ID (CI/CD)

Use tbot or tctl terraform env to obtain short-lived credentials. Best for automated pipelines with zero secrets stored at rest.

Spacelift / Terraform Cloud

Native integrations allow the provider to authenticate via platform-provided OIDC tokens without long-lived credentials.

Identity File

Export an identity file with tbot and reference it via identity_file_path in the provider block. Suitable for dedicated servers.

Local tsh Profile

For local development, tsh login populates a profile that the provider reads automatically. Not for production use.

Build docs developers (and LLMs) love