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:
- Copy the CA cert to
/etc/pki/ca-trust/source/anchors/
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
.