Introducing the Loft Terraform Provider

Russ Centanni
Minute Read

We’re proud to announce our new terraform provider for Loft. For customers already managing infrastructure using Terraform, the terraform-provider-loft allows configuring Loft spaces and virtual clusters as terraform resources. Here’s a quick look at what’s in the release. For more details, head over to the provider’s documentation.

Prerequisites

If you'd like to follow along with these examples, or test drive the provider for your own infrastructure, you'll need the following installed:

  • A Kubernetes Cluster: Docker Desktop or KinD are great for running Kubernetes locally)
  • Terraform version 1.0 or greater
  • Loft Installed and a working login
  • Getting Started

    The first step is to add the provider to your terraform file.

    terraform {
      required_providers {
        loft = {t
          source = "registry.terraform.io/loft-sh/loft"
        }
      }
    }
    
    provider "loft" {}
    

    From your terminal, run terraform init. Terraform will download the provider to your system.

    $ terraform init
    

    Configuring Loft Authentication

    By default, the provider will use your current Loft credentials if you’ve logged in to loft using the loft login command. This is convenient for getting started, but this can be difficult to manage, especially if you frequently switch between different environments and don’t use the same credentials in each environment.

    Loft Configuration

    One option for managing this is to create a config file for each environment. This can be done with the --config option and the loft login command.

    First, log in to Loft with a custom configuration file path:

    $ loft login https://localhost:8443 --insecure --config dev.config.json
    

    Then refer to this file path using the config_path attribute:

    provider "loft" {
      config_path = "dev.config.json"
    }
    

    This option works as long as everyone uses the same file paths for their configuration, but can lead to accidentally leaking credentials if the files aren’t managed properly.

    Access Keys

    Another option for authentication is to configure the provider using access keys. This allows the credentials to be passed in through Terraform variables and managed as you would any other secrets. This is the recommended option for CI/CD environments.

    First, here’s how you might configure Terraform to use variables:

    variable "loft_host" {
      type        = string
      description = "The loft instance host (e.g. https://loft.example.com)"
    }
    
    variable "loft_access_key" {
      type        = string
      description = "The Loft access key."
      sensitive   = true
    }
    
    variable "loft_insecure" {
      type        = bool
      description = "Allow login into an insecure Loft instance"
    }
    
    provider "loft" {
      host       = var.loft_host
      access_key = var.loft_access_key
      insecure   = var.loft_insecure
    }
    

    Next we'll create a Loft access key for the provider to use. Head over to the "Users" page in the Loft UI:

    Loft User Management screen

    Select the user you wish to create an access key for, and click "Create Access Key":

    Click the Create Access Key button

    In the form, add a description for the Access Key's intended purpose and click create:

    Add a description for the new access key

    A dialog with the newly generated access key will be shown. This can be copied and then passed to terraform through the command line, environment variables, or .tfvars files

    Once the provider is configured to connect to Loft, it's time to manage resources.

    Manage a Space

    Creating a Loft space using terraform is as simple as providing the cluster and name of the space to a loft_space resource.

    resource "loft_space" "basic" {
      name    = "basic-space"
      cluster = "loft-cluster"
    }
    

    Sleep Mode

    One of the benefits of using Loft is the cost savings of using sleep mode. Configuring sleep mode on a space is done by using the sleep_after attribute.

    resource "loft_space" "basic" {
      name        = "basic-space"
      cluster     = "loft-cluster"
      sleep_after = "1h" # Sleep after one hour of inactivity
    }
    

    The sleep_after attribute accepts any Golang style duration string. You may already be familiar with this format from kubectl.

    Space Objects

    A convenient way to manage resources inside a space is by using space objects. Objects are Kubernetes resources that are synchronized by Loft. Here's an example of creating a space with some example config maps:

    resource "loft_space" "basic" {
      name    = "basic-space"
      cluster = "loft-cluster"
      objects = <<YAML
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: config-map-1
    data:
      key1: "value1"---apiVersion: v1
    kind: ConfigMap
    metadata:
      name: config-map-2
    data:
      key2: "value2"
    YAML
    }
    

    As you can see, multiple resources can be synced by using the YAML document separator---in the objects attribute.

    Import

    If you've been using Loft for a while, you likely have existing spaces that you'd like to start managing with Terraform. To enable this, the provider supports importing existing spaces into your Terraform state.

    To import an existing space, add a loft_space resource with the cluster and name attributes:

    resource "loft_space" "basic" {
      name    = "basic-space"
      cluster = "loft-cluster"
    }
    

    Next, run the terraform import command to import the resource into terraform.

    $ terraform import loft_space.basic loft-cluster/basic-space
    

    Finally, run terraform plan to see a diff of other attributes that should be added to your *.tf files to start managing the existing space's configuration.

    $ terraform plan
    

    Manage a Virtual Cluster

    The loft_virtual_cluster resource enables declarative management of Loft virtual clusters. Here's an example of creating a virtual cluster in the space we created earlier:

    resource "loft_space" "basic" {
      name    = "basic-space"
      cluster = "loft-cluster"
    }
    
    resource "loft_virtual_cluster" "basic" {
      name      = "basic-virtual-cluster"
      namespace = resource.loft_space.basic.name
      cluster   = resource.loft_space.basic.cluster
    }
    

    By using loft_virtual_cluster with the loft_space resource, virtual clusters can take advantage of sleep mode too.

    Virtual Cluster Objects

    Similar to spaces, it's also possible to synchronize Kubernetes resources to a virtual cluster. One difference to keep in mind is that you'll also need to create namespaces in the Virtual Cluster since you're not already scoped to one. Here's an example of adding a namespace and config map to the example virtual cluster above.

    resource "loft_space" "basic" {
      name    = "basic-space"
      cluster = "loft-cluster"
    }
    
    resource "loft_virtual_cluster" "basic" {
      name      = "basic-virtual-cluster"
      namespace = resource.loft_space.basic.name
      cluster   = resource.loft_space.basic.cluster
      objects   = <<YAML
    apiVersion: v1
    kind: Namespace
    metadata:
      name: my-namespace---apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-config-map
      namespace: my-namespace
    data:
      key: "value"
    YAML
    }
    

    Import

    Importing an existing virtual cluster so it can be managed with Terraform looks very similar to spaces. The key difference is that you'll need to provide the name of the virtual cluster. As an example, here's a command to import the virtual cluster from the previous examples:

    $ terraform import loft_virtual_cluster.basic loft-cluster/basic-space/basic-virtual-cluster
    

    For more advanced configuration options, see the loft_virtual_cluster documentation and the VCluster Helm charts.

    Conclusion

    If you're a Loft customer using Terraform, this provider enables a more seamless approach to managing Loft spaces and virtual clusters. We're just getting started and we hope you'll give it a try and reach out to us with feature requests:

  • Open issues in the terraform-provider-loft GitHub repo
  • Join us on Slack
  • Follow @loft_sh on Twitter
  • Sign up for our newsletter

    Be the first to know about new features, announcements and industry insights.