Using Terraform Providers in Isolation
Tags: devops, tutorial, opensource, terraform
Published: 2023-08-06 07:54:32

## Is This Guide for Me?
If you need to use Terraform providers in an isolated environment, or in case you don't have access to the Terraform Registry, look no further.

> The `Telmate/proxmox` provider is used as an example in this guide. Configurations are performed on a Linux distribution, but can be applied anywhere with slight modifications.

<!-- -->
> Quick tip: To install Terraform CLI on Linux or Mac without hassle, check out [Homebrew](https://brew.sh).

## Table of Contents
1. [Find the Source Code](#find-the-source-code)
1. [Get the Binaries](#get-the-binaries)
1. [Place the Binaries Somewhere Locally](#place-the-binaries-somewhere-locally)
1. [Configure the Terraform CLI](#configure-the-terraform-cli)
1. [Test It Out!](#test-it-out)

## Find the Source Code
### Option 1. Go to GitHub and Search for Providers There
By convention, all providers' names start with the `terraform-provider-` prefix. Try typing this prefix in the search bar in combination with the name of the target provider — no hyphens needed. For example, `terraform provider proxmox`.

> There's a high chance the first link will be a good choice. Also, I'd look for a greater number of stars. Most of the time, popular projects have lots of them.

![Using GitHub search capabilities to find a Terraform provider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wl8tkryrx44qixbfm1ob.png)

### Option 2. Search the Registry Beforehand or Ask Someone to Do This for You
> Yeah, I know. That's kind of obvious.

Just type the name of the target provider in the search bar and pick one. Each provider's main page has a link to the source code.

![Using the Terraform Registry search bar to find a provider](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xv68ctron4ucy5djhr2o.png)

![Locating the source code repo link](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wyp2uxg0x1yuowmp7qx.png)

## Get the Binaries
Many providers' devs are kind enough to provide archives with binaries compiled for various platforms. They are located on the `Releases` page.

{% spoiler But Not Always %}
> That is the case with HashiCorp, of course.
> ![Viewing HashiCorp's release assets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hd4wwk1x2rvzsufcv3m6.png)
{% endspoiler %}

<!-- -->
> If there're no binaries, then you have to compile the provider yourself. Search for docs in the repo.

![Locating the Releases link on a GitHub repo page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97a0qxpf26h7b85q3yyl.png)

![Downloading the archives](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbu8k2zh4flf54eitn0s.png)

## Place the Binaries Somewhere Locally
Terraform expects a directory structure of one of the two layouts:

* Packed (.zip archive)
* Unpacked (binaries)

{% spoiler About the Layouts %}
From the [official documentation](https://developer.hashicorp.com/terraform/cli/config/config-file#filesystem_mirror):

> * Packed layout: `HOSTNAME/NAMESPACE/TYPE/terraform-provider-TYPE_VERSION_TARGET.zip` is the distribution zip file obtained from the provider's origin registry.
> * Unpacked layout: `HOSTNAME/NAMESPACE/TYPE/VERSION/TARGET` is a directory containing the result of extracting the provider's distribution zip file.

{% endspoiler %}

{% spoiler Packed Layout Visualized %}
```
YOUR.REGISTRY.HOSTNAME/
└── ORGANIZATION-NAME
    └── PROVIDER
        └── terraform-provider-PROVIDER_X.X.X_PLATFORM.zip
```
{% endspoiler %}

> We'll cover the first one.

There're no strict rules on where you should place a local mirror on the filesystem. Just make sure the files are accessible by other users if you're not the only one using the system.

I'm a Linux user, so according to [FHS](https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html), `/usr/libexec` is a suitable option. There will be a directory for Terraform. Providers will have a separate directory under it — `terraform/providers`.

{% spoiler /usr/libexec summary %}
From the Linux Foundation Referenced Specifications website:

> /usr/libexec includes internal binaries that are not intended to be executed directly by users or shell scripts. Applications may use a single subdirectory under /usr/libexec.

{% endspoiler %}

1. Create a proper directory layout

    ```console
    # mkdir -p /usr/libexec/terraform/providers/registry.terraform.io/Telmate/proxmox
    ```
    > Note: The path before `registry.terraform.io` is up to you, but after it the layout must be either of two types mentioned earlier.

1. Copy the archive(s) so the result looks similar to this:

    ```console
    deathroll@hellish:~$ tree /usr/libexec/terraform/
  /usr/libexec/terraform/
    └── providers
        └── registry.terraform.io
            └── Telmate
                └── proxmox
                    ├── terraform-provider-proxmox_2.9.11_linux_amd64.zip
                    └── terraform-provider-proxmox_2.9.14_linux_amd64.zip

    5 directories, 2 files
    deathroll@hellish:~$
    ```

## Configure the Terraform CLI
According to the [documentation](https://developer.hashicorp.com/terraform/cli/config/config-file#locations), the config file for the cli utility on Linux is placed in the home directory and is called `.terraformrc`.

1. Create the config file.
1. Populate it with the [following content](https://developer.hashicorp.com/terraform/cli/config/config-file#explicit-installation-method-configuration):
    > Make sure to replace the path with your own.
    ```terraform
    provider_installation {
      filesystem_mirror {
        path    = "/usr/libexec/terraform/providers"
        include = ["*/*"] # */* is a shorthand for registry.terraform.io/*/*
      }
    
      direct {
        exclude = ["*/*"]
      }
    }
    ```

    > Note: The path doesn't include the registry host name.

## Test It Out!
Now you can go to your Terraform project directory and start working on it. Everything should work as expected.

![Running Terraform without access to the registry](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1b17ed9o4tekkgfxox0z.png)