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 {
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.
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
}
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.Apply to adopt the resource
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.