Fork me on GitHub

Teleport

Terraform Provider

Improve
Teleport Terraform Provider

Teleport Terraform Provider

Length: 07:38

This guide will explain how to:

  • Set up Teleport's Terraform provider on Linux and Mac.
  • Configure Teleport users and roles using the Terraform provider.

Prerequisites

  • A running Teleport cluster. For details on how to set this up, see one of our Getting Started guides.

  • The tctl admin tool and tsh client tool version >= 12.1.1.

    tctl version

    Teleport v12.1.1 go1.19

    tsh version

    Teleport v12.1.1 go1.19

    See Installation for details.

  • A running Teleport Enterprise cluster. For details on how to set this up, see our Enterprise Getting Started guide.

  • The Enterprise tctl admin tool and tsh client tool version >= 12.1.1, which you can download by visiting the customer portal.

    tctl version

    Teleport Enterprise v12.1.1 go1.19

    tsh version

    Teleport v12.1.1 go1.19

Cloud is not available for Teleport v.
Please use the latest version of Teleport Enterprise documentation.

To connect to Teleport, log in to your cluster using tsh, then use tctl remotely:

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

Cluster teleport.example.com

Version 12.1.1

CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

You can run subsequent tctl commands in this guide on your local machine.

For full privileges, you can also run tctl commands on your Auth Service host.

To connect to Teleport, log in to your cluster using tsh, then use tctl remotely:

tsh login --proxy=myinstance.teleport.sh [email protected]
tctl status

Cluster myinstance.teleport.sh

Version 12.1.2

CA pin sha256:sha-hash-here

You must run subsequent tctl commands in this guide on your local machine.

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

mkdir -p teleport-terraform
cd teleport-terraform

Step 1/3. Create a Terraform user

Enable impersonation

In order for Terraform to manage resources in your Teleport cluster, it needs a signed identity file from the cluster's certificate authority. The Terraform user cannot request this itself, and requires another user to impersonate this account in order to request a certificate.

Create a role that enables your user to impersonate the Terraform user. First, paste the following YAML document into a file called terraform-impersonator.yaml:

kind: role
version: v5
metadata:
  name: terraform-impersonator
spec:
  # SSH options used for user sessions
  options:
    # max_session_ttl defines the TTL (time to live) of SSH certificates
    # issued to the users with this role.
    max_session_ttl: 10h

  # The allow section declares a list of resource/verb combinations that are
  # allowed for the users of this role. By default, nothing is allowed.
  allow:
    impersonate:
      users: ['terraform']
      roles: ['terraform']

  # The deny section uses the identical format as the 'allow' section.
  # Deny rules always override allow rules.
  deny:
    node_labels:
      '*': '*'

Next, create the role:

tctl create terraform-impersonator.yaml

Assign the terraform-impersonator role to your Teleport user by running the following commands, depending on whether you authenticate as a local Teleport user or via the github, saml, or oidc authentication connectors:

Retrieve your local user's configuration resource:

tctl get users/$(tsh status -f json | jq -r '.active.username') > out.yaml

Edit out.yaml, adding terraform-impersonator to the list of existing roles:

  roles:
   - access
   - auditor
   - editor
+  - terraform-impersonator

Apply your changes:

tctl create -f out.yaml

Retrieve your github configuration resource:

tctl get github/github --with-secrets > github.yaml

Edit github.yaml, adding terraform-impersonator to the teams_to_roles section. The team you will map to this role will depend on how you have designed your organization's RBAC, but it should be the smallest team possible within your organization. This team must also include your user.

Here is an example:

  teams_to_roles:
    - organization: octocats
      team: admins
      roles:
        - access
+       - terraform-impersonator

Apply your changes:

tctl create -f github.yaml
Warning

Note the --with-secrets flag in the tctl get command. This adds the value of spec.signing_key_pair.private_key to saml.yaml. This is a sensitive value, so take precautions when creating this file and remove it after updating the resource.

Retrieve your saml configuration resource:

tctl get --with-secrets saml/mysaml > saml.yaml

Edit saml.yaml, adding terraform-impersonator to the attributes_to_roles section. The attribute you will map to this role will depend on how you have designed your organization's RBAC, but it should be the smallest group possible within your organization. This group must also include your user.

Here is an example:

  attributes_to_roles:
    - name: "groups"
      value: "my-group"
      roles:
        - access
+       - terraform-impersonator

Apply your changes:

tctl create -f saml.yaml
Warning

Note the --with-secrets flag in the tctl get command. This adds the value of spec.signing_key_pair.private_key to saml.yaml. This is a sensitive value, so take precautions when creating this file and remove it after updating the resource.

Retrieve your oidc configuration resource:

tctl get oidc/myoidc --with-secrets > oidc.yaml

Edit oidc.yaml, adding terraform-impersonator to the claims_to_roles section. The claim you will map to this role will depend on how you have designed your organization's RBAC, but it should be the smallest group possible within your organization. This group must also include your user.

Here is an example:

  claims_to_roles:
    - name: "groups"
      value: "my-group"
      roles:
        - access
+       - terraform-impersonator

Apply your changes:

tctl create -f saml.yaml
Warning

Note the --with-secrets flag in the tctl get command. This adds the value of spec.signing_key_pair.private_key to saml.yaml. This is a sensitive value, so take precautions when creating this file and remove it after updating the resource.

Log out of your Teleport cluster and log in again to assume the new role.

Create the Terraform user

Put the following content into terraform.yaml:

kind: role
metadata:
  name: terraform
spec:
  allow:
    db_labels:
      '*': '*'
    app_labels:
      '*': '*'
    rules:
      - resources:
        - app
        - cluster_auth_preference
        - cluster_networking_config
        - db
        - github
        - oidc
        - role
        - saml
        - session_recording_config
        - token
        - trusted_cluster
        - user
        verbs: ['list','create','read','update','delete']
version: v5
---
kind: user
metadata:
  name: terraform
spec:
  roles: ['terraform']
version: v2

Create the terraform user and role.

tctl create terraform.yaml

Next, request a signed certificate for the Terraform user:

tctl auth sign --format=tls --user=terraform --out=auth

This command should result in three PEM-encoded files: auth.crt, auth.key, and auth.cas (certificate, private key, and CA certs, respectively).

Cloud is not available for Teleport v.
Please use the latest version of Teleport Enterprise documentation.

Step 2/3. Create a Terraform configuration

Paste the following into a file called main.tf to define an example user and role using Terraform.

Cloud is not available for Teleport v.
Please use the latest version of Teleport Enterprise documentation.
terraform {
  required_providers {
    teleport = {
      source  = "terraform.releases.teleport.dev/gravitational/teleport"
      version = ">= 12.1.1"
    }
  }
}

provider "teleport" {
  # Update addr to point to Teleport Auth/Proxy
  # addr               = "auth.example.com:3025"
  addr         = "proxy.example.com:443"
  cert_path    = "auth.crt"
  key_path     = "auth.key"
  root_ca_path = "auth.cas"
}

resource "teleport_role" "terraform-test" {
  metadata = {
    name        = "terraform-test"
    description = "Terraform test role"
    labels = {
      example = "yes"
    }
  }

  spec = {
    options = {
      forward_agent           = false
      max_session_ttl         = "30m"
      port_forwarding         = false
      client_idle_timeout     = "1h"
      disconnect_expired_cert = true
      permit_x11_forwarding   = false
      request_access          = "denied"
    }

    allow = {
      logins = ["this-user-does-not-exist"]

      rules = [
        {
          resources = ["user", "role"]
          verbs     = ["list"]
        }
      ]

      request = {
        roles = ["example"]
        claims_to_roles = [
          {
            claim = "example"
            value = "example"
            roles = ["example"]
          }
        ]
      }

      node_labels = {
        key    = ["example"]
        alabel = ["with", "multiple", "values"]
      }
    }

    deny = {
      logins = ["anonymous"]
    }
  }
}

resource "teleport_user" "terraform-test" {
  metadata = {
    name        = "terraform-test"
    description = "Test terraform user"
    expires     = "2022-10-12T07:20:50Z"

    labels = {
      test = "true"
    }
  }

  spec = {
    roles = ["terraform-test"]
  }
}

Step 3/3. Apply the configuration

Check the contents of the teleport-terraform folder:

Cloud is not available for Teleport v.
Please use the latest version of Teleport Enterprise documentation.
ls

main.tf auth.crt auth.key auth.cas terraform-impersonator.yaml terraform.yaml

Init terraform and apply the spec:

terraform init
terraform apply

Next Steps