Run the Teleport Terraform Provider on Terraform Cloud
This guide demonstrates how to use the Terraform provider for Teleport using HCP Terraform or Terraform Enterprise.
This guide does not cover running the Terraform provider locally, in other CI/CD environments, or in short-lived cloud VMs. In any of these cases, refer to a dedicated guide:
How it works
Terraform Cloud joining with self-hosted Terraform Enterprise requires Teleport Enterprise. Terraform Cloud joining with public HCP Terraform (https://app.terraform.io) is supported in Teleport Community Edition.
When running the Teleport Terraform provider on Terraform Cloud, you can use its built-in Machine ID support to dynamically authenticate to your Teleport cluster without any shared secrets. When run in this configuration, the Terraform provider proves its identity to the Teleport Auth Service using Terraform Cloud's Workload Identity tokens.
While following this guide, you'll configure your Teleport cluster to accept join requests from Terraform Cloud runs and configure the provider to authenticate using the Terraform Cloud join method.
Note that this guide applies to both the public HCP Terraform a.k.a. Terraform Cloud, as well as self-hosted Terraform Enterprise. This does not apply to Terraform or OpenTofu when run on other CI/CD platforms like Spacelift, so refer to our generic CI and Cloud guide to configure the provider in these environments.
Prerequisites
-
A running Teleport cluster. If you want to get started with Teleport, sign up for a free trial.
-
The
tctl
admin tool andtsh
client tool.Visit Installation for instructions on downloading
tctl
andtsh
.
-
To check that you can connect to your Teleport cluster, sign in with
tsh login
, then verify that you can runtctl
commands using your current credentials.For example:
$ tsh login --proxy=teleport.example.com --user=email@example.com
$ tctl status
# Cluster teleport.example.com
# Version 17.0.0-dev
# CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678If you can connect to the cluster and run the
tctl status
command, you can use your current credentials to run subsequenttctl
commands from your workstation. If you host your own Teleport cluster, you can also runtctl
commands on the computer that hosts the Teleport Auth Service for full permissions. -
$ terraform version
# Terraform v1.0.0To import existing Teleport resources as Terraform resources, you must have Terraform version
v1.5.0
or above. -
An account and project on either the public Terraform Cloud SaaS or a Terraform Enterprise instance
-
The Teleport Terraform provider, v16.4.0 or later
Step 1/4: Configure Terraform Cloud joining in Teleport
To start, the Teleport Auth Service needs to be configured to accept join
requests from Terraform Cloud runs. We'll do this by creating a bot named
terraform
which the Teleport Terraform provider will use in a later step.
kind: bot
version: v1
metadata:
name: terraform
spec:
# The terraform-provider role is a built-in role granting access to every
# resource supported by the terraform provider.
roles: ["terraform-provider"]
Create the bot from the new YAML manifest:
$ tctl create -f terraform_bot.yaml
bot 'terraform' has been created
Next, the new bot needs to be allowed to authenticate with Terraform Cloud
Workload Identity credentials. Create a file named terraform_token.yaml
with this content, depending on whether you are using Terraform Cloud or
self-hosted Terraform Enterprise:
- HCP Terraform
- Terraform Enterprise
kind: token
version: v2
metadata:
name: terraform
spec:
roles: [Bot]
join_method: terraform_cloud
bot_name: terraform
terraform_cloud:
allow:
- organization_name: ExampleOrganization
project_name: example-project
workspace_name: example-workspace
Teleport Enterprise is required to use Terraform Enterprise joining.
Self-hosted Terraform Enterprise installations will need to additionally
configure the hostname
parameter:
kind: token
version: v2
metadata:
name: terraform
spec:
roles: [Bot]
join_method: terraform_cloud
bot_name: terraform
terraform_cloud:
hostname: terraform.example.com
allow:
- organization_name: ExampleOrganization
project_name: example-project
workspace_name: example-workspace
This hostname
value should match the iss
parameter of the JWTs issued
to your Terraform Enterprise runs, without the https://
prefix. For more
information, refer to the Terraform Enterprise documentation.
Note that if hostname
is not configured, it will default to the Terraform
Cloud issuer and join attempts will fail.
This token, named terraform
, allows Terraform Cloud runs to authenticate
with Teleport when all 3 of the values allowed in the token match those
of the job run by Terraform Cloud.
Make sure to replace the organization, project, and workspace names to match
your Terraform Cloud project or projects. If desired, the fields
organization_id
, project_id
, and workspace_id
can be used as well to
specify exact resource IDs. The values must exactly match those shown in the
Terraform Cloud dashboard.
Note that each allow
rule must specify at least an organization_name
or
organization_id
, and at least one other option (workspace and/or project).
If desired, all workspaces under a project can be allowed by leaving
workspace_name
(or workspace_id
) unset. You can specify as many allow
rules as you want, and at least one must match for a run to be able to join.
Once finished, create the token:
$ tctl create -f terraform_token.yaml
token 'terraform' has been created
Step 2/4: Configure Terraform Cloud to issue Workload Identity tokens
Terraform Cloud needs to be configured to issue JWTs during runs. This only requires that an environment variable is set in the Terraform Cloud dashboard. To do so:
- Navigate to https://app.terraform.io/
- Navigate to your desired organization, project, and workspace
- From the workspace sidebar, select "Variables"
- Under "Workspace Variables", click the "Add variable" button
- Select the "Environment variable" ("env") category
- For the key, enter:
TFC_WORKLOAD_IDENTITY_AUDIENCE_TELEPORT
- For the value, enter your Teleport cluster name. If using Teleport Enterprise
(Cloud), this would look like
example.teleport.sh
. - If desired, enter a description. For example, "Workload identity token request for Teleport"
The end result should look like this:
Once this variable is set, all subsequent runs in this workspace will be issued
JWTs with the audience configured in the variable value, i.e.
example.teleport.sh
as shown here.
Step 3/4: Configure the Terraform Provider
In your provider.tf
or similar, configure the teleport
provider:
provider "teleport" {
addr = "example.teleport.sh:443"
join_method = "terraform_cloud"
join_token = "terraform"
audience_tag = "teleport"
}
These parameters must be set:
addr
should match the public hostname and port of your Teleport clusterjoin_method
should beterraform_cloud
. Note that Terraform Enterprise also uses the same join method, with a hostname as configured in Step 1.join_token
should match the name of thetoken
resource created in Step #2audience_tag
should match the suffix on the key of the variable created in the Terraform Cloud dashboard. For example, given the variable keyTFC_WORKLOAD_IDENTITY_AUDIENCE_TELEPORT
, the audience tag should beteleport
.
Be sure to remove any preexisting identity_file_path
; it is replaced by
join_method
and join_token
.
For a complete example, consider this minimal provider.tf
:
terraform {
cloud {
organization = "ExampleOrganization"
workspaces {
name = "example-workspace"
}
}
required_providers {
teleport = {
source = "terraform.releases.teleport.dev/gravitational/teleport"
version = "13.3.7"
}
}
}
provider "teleport" {
addr = "example.teleport.sh:443"
join_method = "terraform_cloud"
join_token = "terraform"
audience_tag = "teleport"
}
resource "teleport_role" "test" {
version = "v7"
metadata = {
name = "test"
description = "Dummy role to validate Terraform Provider setup"
labels = {
test = "yes"
}
}
}
Step 4/4: Run Terraform
You should now be able to perform a Terraform plan
or apply
. All types of
triggers should work, including CLI, API, and Git, so long as the run is
coordinated by Terraform Cloud.
Assuming your local terraform
is authenticated to Terraform Cloud, try:
$ terraform plan
The workflow should successfully execute, depending on your Terraform configuration.
Troubleshooting
Extracting a JWT for debugging purposes
If you need to view a JWT sample for debugging purposes, you can create a
null_resource
that prints the JWT for the run:
resource "null_resource" "print_token" {
provisioner "local-exec" {
command = "echo TFC_WORKLOAD_IDENTITY_TOKEN_TELEPORT: $TFC_WORKLOAD_IDENTITY_TOKEN_TELEPORT"
}
}
Once applied, you should see the encoded JWT printed in your Terraform log.
These values can be decoded either by hand or with any number of tools, for
example jwt-cli
.
Note that these JWTs are generally valid for 2 hours and can potentially be used to authenticate to your Teleport cluster, so this value should be treated with care. The full encoded token should not be shared.
This may be useful for determining the exact issuer (iss
) value needed to
configure Terraform Enterprise join tokens, or if you need to request support.