Skip to content

Month: August 2021

How to locally host a Terraform plugin offline

I recently had to run a Terraform build in an air gapped network (no internet access) and these are the steps I took to locally host the Terraform provider I needed (vsphere). This was tested on Terraform v1.0.4 on CentOS 7.9 servers.

Local file mirror

Start by download the latest version of the desired plugin from https://releases.hashicorp.com/.

In this example I wanted the vsphere provider (terraform-provider-vsphere_2.0.2_linux_amd64.zip) so I grabbed it from https://releases.hashicorp.com/terraform-provider-vsphere/

Unzip the executable to the following directory on your Terraform machine: ~/.terraform.d/plugins/registry.terraform.io/hashicorp/vsphere/2.0.2/linux_amd64

For example: mkdir -p ~/.terraform.d/plugins/registry.terraform.io/hashicorp/vsphere/2.0.2/linux_amd64

unzip terraform-provider-vsphere_2.0.2_linux_amd64.zip -d ~/.terraform.d/plugins/registry.terraform.io/hashicorp/vsphere/2.0.2/linux_amd64

Keep in mind, your file path will be different depending on which provider you use, so please adjust accordingly!

Further information available here: https://www.terraform.io/docs/cli/config/config-file.html#implied-local-mirror-directories

Network mirror

This method is a bit tricky if you are using a self-signed certificate because Terraform enforces strict TLS checking. There is no command line option that I could find that allows you to turn off TLS enforcement.

To start, use an internet connected machine and run the terraform providers mirror command as described here (https://www.terraform.io/docs/cli/commands/providers/mirror.html). Then dump the resultant files to the local apache/nginx webserver in your offline environment.

Web Server Configuration

I had to mess around quite a bit with the self signed certificate creation on my apache server in order for it to work.

To generate my self signed cert, I executed:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout self.key -out self.crt -config /etc/ssl/openssl.cnf

I had to make sure my basicConstraints setting in my SSL.cnf file was set to basicConstraints = CA:TRUE. In case it helps anyone, here’s an example of the openssl.cnf file I used:

[req]
default_bits = 2048
prompt = no
distinguished_name = dn
req_extensions = req_ext
x509_extensions = v3_req

[dn]
C = US
ST = MD
L = Annapolis
O = MyOrg
CN = yum01.mydomain.net

[req_ext]
subjectAltName = @alt_names
basicConstraints = CA:TRUE

[v3_req]
subjectAltName = @alt_names
basicConstraints = CA:TRUE

[alt_names]
DNS.1 = yum01.mydomain.net
IP.1 = 192.168.1.20

Then copy the cert and key to the /etc/pki/tls locations referenced by your /etc/httpd/conf.d/ssl.conf file (again, using apache as the example here).

For example:

SSLCertificateFile /etc/pki/tls/certs/self.crt

SSLCertificateKeyFile /etc/pki/tls/private/self.key

Terraform CLI configuration

Make sure to add your web server’s self signed certificate to your Terraform servers trust store. This stackoverflow thread shows you how to do that (https://stackoverflow.com/questions/22509271/import-self-signed-certificate-in-redhat) on CentOS/Red Hat with the following steps:

  1. Copy the CA cert to /etc/pki/ca-trust/source/anchors/
  2. update-ca-trust extract

Create a .terraformrc file to the HOME directory of your Terraform machine, if it doesn’t already exist, with the following inside:

provider_installation {
  network_mirror {
    url = "https://fileserver.yourdomain.com/terraform/"
  }
}

In my case, the top level directory /terraform/ contained the registry.terraform.io folder.

That should be it! Try it out by going to your terraform directory and running terraform init.