Teleport Workload Identity with SPIFFE: Achieving Zero Trust in Modern Infrastructure
May 23
Virtual
Register Today
Teleport logoTry For Free
Fork me on GitHub

Teleport

Set up the Teleport Terraform Provider

Teleport Terraform Provider

Teleport Terraform Provider

Length: 07:38

This guide demonstrates how to set up the Terraform provider for Teleport on Linux and macOS.

Terraform is intended to be used with Machine ID, Teleport's feature for providing identities to machines and services, rather than users. This tutorial will show you how to use a local Machine ID bot to try it out.

For instructions on managing users and roles via Terraform, read the "Managing users and roles with IaC" guide.

For instructions on managing the Teleport dynamic resources as code using GitOps, read the guide to using the Teleport Terraform provider with Spacelift and Machine ID.

Prerequisites

  • A running Teleport cluster version 15.3.0 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.

    On Teleport Enterprise, you must use the Enterprise version of tctl, which you can download from your Teleport account workspace. Otherwise, visit Installation for instructions on downloading tctl and tsh for Teleport Community Edition.

  • Terraform >= 1.0.0+

    terraform version

    Terraform v1.0.0

    To import existing Teleport resources as Terraform resources, you must have Terraform version v1.5.0 or above.

  • To check that you can connect to your Teleport cluster, sign in with tsh login, then verify that you can run tctl commands using your current credentials. tctl is supported on macOS and Linux machines.

    For example:

    tsh login --proxy=teleport.example.com --user=[email protected]
    tctl status

    Cluster teleport.example.com

    Version 15.3.0

    CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

    If you can connect to the cluster and run the tctl status command, you can use your current credentials to run subsequent tctl commands from your workstation. If you host your own Teleport cluster, you can also run tctl commands on the computer that hosts the Teleport Auth Service for full permissions.

Step 1/4. Create Teleport credentials for Terraform

Terraform needs a signed identity file from the Teleport cluster certificate authority to manage resources in the cluster. To prepare credentials using a local Teleport bot:

  1. Create a folder called teleport-terraform to hold temporary files:

    mkdir -p teleport-terraform
    cd teleport-terraform
  2. Terraform needs a Teleport role that gives it permission to manage your cluster's resources. The bot creates identity documents that have this role. Configure the necessary role by pasting the following content into a terraform_role.yaml file:

    kind: role
    metadata:
      name: terraform
    spec:
      allow:
        db_labels:
          '*': '*'
        app_labels:
          '*': '*'
        node_labels:
          '*': '*'
        rules:
          - resources:
            - app
            - cluster_auth_preference
            - cluster_networking_config
            - db
            - device
            - github
            - login_rule
            - oidc
            - okta_import_rule
            - role
            - saml
            - session_recording_config
            - token
            - trusted_cluster
            - user
            - access_list
            - node
            verbs: ['list','create','read','update','delete']
    version: v7
    

    These settings configure a role named terraform with the permissions required to manage resources in your Teleport cluster.

  3. Create the terraform role by running the following command:

    tctl create terraform_role.yaml
    role 'terraform' has been created
  4. Create two scripts that let you quickly and repeatably create and destroy our local Terraform bot. First, create a new file called create_and_run_terraform_bot.sh, open it in an editor, and paste in the following content:

    #! /usr/bin/env bash
    
    TOKEN=$(tctl bots add terraform-test --roles=terraform --format=json | jq -r '.token_id')
    tbot start \
      --destination-dir=./terraform-identity \
      --token="$TOKEN" \
      --data-dir=./tbot-data \
      --join-method=token \
      --auth-server=tele.example.com:443
      # Replace with the host and port of your Teleport Auth Service
      # or Teleport Proxy Service
    

    When run, this creates a new bot with the token retrieved from the JSON output. That token is piped into the start command. For security reasons, we don't allow bot join tokens to be created in any way other than adding a bot, so for local development work, you must manually manage the bot and its token.

    The bot manages its state data in a folder called tbot-data in the current working directory.

  5. Edit create_and_run_terraform_bot.sh to replace tele.example.com:443 with the domain name and port of the Teleport Proxy Service in your cluster.

  6. Create another file called remove_terraform_bot.sh, open it in an editor, and paste in the following content:

    #! /usr/bin/env bash
    
    tctl bots rm terraform-test
    rm -rfv ./terraform-identity
    rm -rfv ./tbot-data
    

    This script will be used later to clean up our bot in between runs and when we're done.

  7. In a new terminal window, run the create_and_run_terraform_bot.sh script to create the new bot and start it:

    chmod +x create_and_run_terraform_bot.sh
    ./create_and_run_terraform_bot.sh

Step 2/4. Prepare a Terraform configuration file

To prepare a Terraform configuration file:

  1. Create a new file called provider.tf and open it in an editor.

  2. Use the Teleport Terraform provider and connect it to your Teleport cluster by pasting the following content into the provider.tf file:

    terraform {
      required_providers {
        teleport = {
          source  = "terraform.releases.teleport.dev/gravitational/teleport"
          version = "~> 15.0"
        }
      }
    }
    
    provider "teleport" {
      # Update addr to point to your Teleport Cloud tenant URL's host:port
      addr               = "mytenant.teleport.sh:443"
      identity_file_path = "terraform-identity/identity"
    }
    
    # creates 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 = {
      }
    }
    
    
    terraform {
      required_providers {
        teleport = {
          source  = "terraform.releases.teleport.dev/gravitational/teleport"
          version = "~> 15.0"
        }
      }
    }
    
    provider "teleport" {
      # Update addr to point to Teleport Auth/Proxy
      # addr              = "auth.example.com:3025"
      addr               = "proxy.example.com:443"
      identity_file_path = "terraform-identity/identity"
    }
    
    # creates 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 = {
      }
    }
    
    

Step 3/4. Validate the configuration

To apply the configuration:

  1. Check the contents of the teleport-terraform folder:

    ls

    provider.tf terraform-identity/ create_and_run_terraform_bot.sh remove_terraform_bot.sh terraform_role.yaml

  2. Initialize the working directory that contains Terraform configuration files by running the following command:

    terraform init
  3. Execute the Terraform plan defined in the configuration file by running the following command:

    terraform apply
  4. When you're done, use Ctrl-C to stop the Terraform bot. Then run the remove_terraform_bot.sh script to remove the bot and clean up the terraform-identity folder:

    chmod +x remove_terraform_bot.sh
    ./remove_terraform_bot.sh

    If you need to start the bot back up, you can run the two bot scripts as many times as necessary.

Step 4/4. [Optional] Import existing resources

This section shows you how to import existing dynamic Teleport resources as Terraform resources.

If you already created Teleport resources using another client tool like tctl or the Kubernetes Operator, and want to manage all Teleport resources using your Terraform configuration, follow these steps to generate a .tf file that contains resource blocks that represent your existing Teleport resources.

By defining all Teleport resources in one place, you can help ensure that your cluster configuration matches your expectations.

Add an import block

  1. On your workstation, navigate to your root Teleport Terraform module.

  2. Open a file in your text editor to configure Terraform imports. To keep your configuration tidy, open a new file called imports.tf.

  3. Add an import block to imports.tf. Use the to field to indicate the name of the resource you want to generate configuration for in Terraform. The following example imports a Teleport role called myrole:

    import {
      to = teleport_role.myrole
    }
    

Retrieve the ID of your resource

  1. Retrieve the ID of the resource. The method to use depends on the resource type. Use the following rules to do so:

    If the resource is teleport_provision_token, the ID is the metadata.id of the resource.

    If the resource can only have one instance, use the name of the resource type without the teleport prefix. For example:

    ResourceID
    teleport_cluster_maintenance_configcluster_maintenance_config
    teleport_cluster_networking_configcluster_networking_config

    For all other resources, the ID is always the metadata.name of the resource.

    For example, the teleport_role resource uses the role's metadata.name field for its ID. To find all possible role IDs, run the following command:

    tctl get roles --format json | jq '.[].metadata.name'
  2. In the import block, assign the id field to the resource ID you retrieved earlier. For example, to import a Teleport role with a metadata.name of myrole, add the following:

      import {
        to = teleport_role.myrole
    +   id = "myrole"
      }
    

Generate a configuration file

  1. Generate a resource configuration

    terraform plan -generate-config-out=imported-resources.tf
  2. Inspect the resulting file, imported-resources.tf. If the new resource block looks correct, you can check the file into source control.

Next steps