In normal usage, terraform init
downloads & installs the plugins for any providers used in the configuration automatically in the .terraform
directory. It’s sometimes desirable to disable this behavior, either because you wanna do away with the re-download every time on your dev system, or because you’re running Terraform in a CI/CD pipeline where it’s sensible to download the plugins just once & reuse them for every build. This not only avoids the overhead of re-downloading every time, it also allows systems admins to control which plugins are available to Terraform runs.
There are several ways to achieve this with Terraform, each one subtly different than the other. This article explores them all.
Plugin Directory
Create a directory anywhere on your system, manually download the plugin archives from releases.hashicorp.com & place them in that directory. Make sure you download the correct plugin archive for your OS & architecture. Extract the archives so they look like this:
ls ~/terraform-plugins
terraform-provider-aws-v1.0.0-x3
terraform-provider-rundeck-v2.3.0-x3
terraform-provider-mysql-v1.2.0-x3
Terraform infers the version of each plugin by looking at the version info at the end of the names above. If multiple versions of a plugin are installed, Terraform will pick the latest one that matches the version constraints in your config. Now when you run terraform init
, you should run it as follows:
terraform init -plugin-dir=~/terraform-plugins
~/terraform.d/plugins
The above approach completely disables plugin downloads. If the plugin directory doesn’t have something needed by your config, the build fails. But what if you wanna bypass downloading plugins just for performance reasons? Place the plugins in directory which Terraform can search but it’s still free to download the ones it doesn’t find in there. That’s exactly what this next approach does.
Create the directory ~/terraform.d/plugins/OS_ARCH & place your plugins there. ~/terraform.d/plugins/linux_amd64
for example. When terraform init
runs, it’ll first search that directory & then go out & download whatever it doesn’t find. If you wanna disable automatic download here too, use the -get-plugins=false
flag.
Terraform Bundle
— Terraform Bundle — GitHub
terraform-bundle
is a helper program to create “bundle archives”, which are zip files that contain both a particular version of Terraform and a number of provider plugins.
Write a Terraform bundle config file & run terraform-bundle
on a system that can download plugins. This will give you an archive which you can move onto your automation server & extract to get all the plugins required by your main Terraform config. The Terraform bundle config looks like this:
terraform {
# Version of Terraform to include in the bundle.
# An exact version number is required.
version = "0.13.0"
}
# Define which provider plugins are to be included.
providers {
# Include the newest "aws" provider version in the 1.0 series.
aws = {
versions = ["~> 1.0"]
}
}
Including multiple versions of the same provider allows several configurations running on the same system to share an installation of the bundle and to choose a version using version constraints within the main Terraform configuration.
— Usage — Terraform Bundle — GitHub
After the config file is ready, run:
terraform-bundle package terraform-plugins.hcl
By default, the tool will target the OS & CPU architecture where the tool is being run. To override this, use the -os
& -arch
options:
terraform-bundle package -os=linux -arch=amd64 terraform-plugins.hcl