Skip to main content

Run the Teleport Terraform Provider in CI or Cloud

This guides covers how to run the Teleport Terraform Provider from:

  • your CI/CD pipelines on:
    • GitHub Actions (we'll use the github join method)
    • GitlabCI (we'll use the gitlab join method)
    • CircleCI (we'll use the circleci join method)
  • a cloud VM on:
    • AWS (we'll use the aws join method)
    • GCP (we'll use the gcp join method)
note

Running the Terraform provider with native MachineID is supported on Azure, inside a Kubernetes pod, and on servers with Trusted Platform Module (TPM). While those setups are not described in details in this guide, you can follow their regular MachineID guides and replace the "Configure tbot" step by passing the join method and token to the provider.

HCP Terraform (Terraform Cloud) and self-hosted Terraform Enterprise are supported but require special configuration, so refer to our dedicated guide.

This guide does not cover running Teleport locally, on a dedicated server or on certain platforms. See the following more specific guides for those cases:

How it works

This setup asks the runtime (the CI/CD system, cloud provider, container engine, ...) for an identity proof. This proof is then used directly by the Terraform provider to connect to Teleport and obtain credentials. In this setup, there is no tbot daemon involved as the Terraform provider can natively obtain the identity proof and join the Teleport cluster.

The setup only works for select runtimes which Teleport has a delegated join method for (e.g. GitHub Actions, GitLab CI, ...)

Prerequisites

You need either:

  • A GCP or AWS VM with terraform installed
  • A git repo able to run GitHub Actions, GitLab CI or CircleCI jobs

You also need:

  • A running Teleport cluster version 17.0.0-dev or above. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.

  • The tctl admin tool and tsh client tool.

    Visit Installation for instructions on downloading tctl and tsh.

Step 1/4. Create the Terraform provider bot

In this step you will create a bot named terraform.

Create a file named terraform-bot.yaml:

kind: bot
version: v1
metadata:
name: terraform
spec:
# The terraform-provider is a default role shipped in Teleport granting access
# to every resource supported by the terraform provider.
roles: ["terraform-provider"]

Then apply it with tctl:

$ tctl create terraform-bot.yaml

This is an admin-level action and requires MFA to complete
Tap any security key
Detected security key tap
bot "terraform" has been created

At this point, you should see your new bot:

$ tctl bots ls

Bot User Roles
--------- ------------- ------------------
terraform bot-terraform terraform-provider

Step 2/4. Create the bot join token

In this step you will create a token allowing a process to connect to Teleport as the terraform bot you created earlier.

The token type and configuration depends on where the Terraform provider is running. See the joining reference for more details about the joining process, the different join methods, types of tokens, and the fields they support.

To allow the Terraform Provider to join from GitHub Actions workflows in organization/repository, create the following terraform-bot-token.yaml:

kind: token
version: v2
metadata:
name: terraform-bot
spec:
roles: [Bot]
join_method: github
bot_name: terraform
github:
# allow specifies rules that control which GitHub Actions runs will be
# granted access. Those not matching any allow rule will be denied.
allow:
- repository: organization/repository

Create the bot token described by the terraform-bot-token.yaml manifest:

$ tctl create -f terraform-bot-token.yaml

This is an admin-level action and requires MFA to complete
Tap any security key
Detected security key tap
provision_token "terraform-bot" has been created

Step 3/4. Configure your Terraform provider

In this step you will write a minimal Terraform code that configures the provider to connect to your Teleport cluster and join with the token you previously created.

To do this you need:

  • your Teleport cluster domain including the port: teleport.example.com:443. You can find this in the URL when accessing the Web UI.
  • the join method of the token you've created. This is the spec.join_method field in the terraform-bot-token.yaml: token-join-method.

Create this minimal main.tf file:

terraform {
required_providers {
teleport = {
source = "terraform.releases.teleport.dev/gravitational/teleport"
version = "~> 17.0"
}
}
}

provider "teleport" {
addr = "teleport.example.com:443"
join_method = "token-join-method"
join_token = "terraform-bot"
}

# We must create a test role, if we don't declare resources, Terraform won't try to
# connect to Teleport and we won't be able to validate the setup.
resource "teleport_role" "test" {
version = "v7"
metadata = {
name = "test"
description = "Dummy role to validate Terraform Provider setup"
labels = {
test = "yes"
}
}

spec = {}
}

Copy the main.tf file in the GitHub repo that runs GitHub Actions pipelines.

Step 4/4. Run Terraform

This step shows minimal examples on how to run Terraform based on your environment. This code uses the default local backend which is not fit for production purposes. Especially in CI, you must use non-local Terraform backends so the Terraform state is persisted across CI pipelines.

In the repo containing your Terraform code, create a .github/workflows/teleport-terraform.yaml file with the following content:

name: Teleport Terraform Demo
# This is a basic workflow to help you get started.
# It will take the following action whenever a push is made to the "main" branch.
on:
push:
branches:
- main
jobs:
demo:
permissions:
# The "id-token: write" permission is required or Machine ID will not be
# able to authenticate with the cluster.
id-token: write
contents: read
name: terraform-plan
runs-on: ubuntu-latest

# You can find more advanced TF workflows at https://github.com/hashicorp/setup-terraform
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Init
id: init
run: terraform init
- name: Terraform Plan
id: plan
run: terraform plan -no-color

Commit the changes and push to the main branch to trigger the GitHub Actions workflow. You should see a successful Terraform plan in the workflow logs.