Switch branches/tags
7986-subnet-locking 11625c alexis/f-bb-ssh-module-example allthingsclowd-patch-1 armchairlinguist/doc-module-version-current armchairlinguist/remote-backend-copyedit aws-tfver-header azurerm-backend-proxy azurerm-fix14160 azurerm-website azurerm_os_profile_optional b-0.12-replacediff b-apply-graph-complex b-aws-cloudfront-behaviour-precedence b-aws-db-option-id b-aws-elb-subnet b-command-tests-timeout b-configs-resource-name-diags b-console-newlines b-cty-type-unification b-dme-txt-quotes b-eni-device-idx-test b-fix-build-ldflag b-get-ok-exists-non-empty-state b-graph-noise b-main-help-consistency b-makefile-travis b-mapwriter-overwrites b-module-ref-crash b-more-aws-test-fixes b-nested-sets-change-fix b-nested-sets b-ns1-map-elem b-remove-map-with-resource-elem b-resource-test-expecterror b-resourcediff-forcenew-newremoved-values b-sdk-envdefault b-set-diff-panic b-statemgr-build-vendor b-v0.12-planfile b-validate-func-type-map b/expecterror-and-checks backend/azurerm/client-cert before-provider-split build-with-tfdev catsby-patch-1 catsby-patch-2 cd/add-archiving-policy cd/document-consul-value-limit cdoherty/link-to-graphs-video cfa299 core-remove-version-constant-from-providers deps/azure-helpers-030 dev/stephweatherford/9694 doc-design-patterns doc-issue-template-1 doc-issue-template doc-vs-pulumi docs-add-diff-customization docs-guide-k8s docs-hashicorp-providers docs-terraform-block-validation docs-ux ecosystem/oracle-provider f-allow-env-var-plugin-dir f-aws-asg-attachment-instances f-cbd-during-plan f-cmd-fmt-red-null f-cmd-fmt-reduce-diff f-config-extra-valid f-core-acc-test-planonly f-create-on-init f-custom-diff f-debug-trace f-diags-with-var-vals f-diff-cty f-hcl2-commandtests f-hcl2-config-extras f-hcl2-context-old f-hcl2-context f-hcl2-coretests f-hcl2-diff f-hcl2-disable-kw-deprecation f-hcl2-docs f-hcl2-evaluate f-hcl2-planfile-misses f-hcl2-planstate f-hcl2-planstatetypes f-hcl2-providerresolver f-hcl2-steps/config-reorg f-hcl2-validate f-hcl2-variable-types f-hcl2 f-import-state-testing-id-func f-k8s-replication-controller f-k8s-service-account f-langserver f-locals-link-variable-interpolation f-more-rsrc-validation f-outputs-in-plan f-provider-plugin-lock f-provider-schema-api f-provider-schema-init f-provider-test-instances f-provider-version-match f-remove-tf-push f-resource-diff-getokexists-computed f-resource-state-upgrade f-return-retryerror-when-nil f-schema-disallow-forcenew-computed f-schema-versions f-svchost-disco f-testing-taint f-updatePluginPathDoc f-v0.12-cmdvars f-v0.12-upgrade f-validate-list-no-duplicates f-validation-no-zero-values f-validation-stringmatch f-zcl-prototype f-zipmap-tuples go-1.11.3 go1.11rc1-vendor-experiment h-tfe-backend jbardin/backend-hash jbardin/destroy-chained-outputs jbardin/import-aliased-provider jbardin/null-from-output jbardin/requires-new jbardin/resource-test-shim make-limit-test-in-ci master mildwonkey/f-plan-json mildwonkey/remote-state-provider nov18_guide_links oct18_remote_operations oct18_remote_state opc-p-instance-fqdn paddy_diff_nested_checkKey paddy_fix_run_api_links paddy_networkip_testfail paddy_9051_forwarding_rule_idempotent paultyng-patch-1 plugin-proto-version5 pr-8180 proto-test-harness provider/aws-codestar provider/kubernetes/pod radeksimko/wip run-api-links split-website-prototype stable-website unused-vendored-libs update-core-workflow-guide-for-new-run-details-ui v0.11 v0.12-alpha v0.12-alpha1-changelog v0.12-dev-before-rebase v0.12-dev-tomerge v0.12-dev-tomerge2 v0.12-dev-tomerge3 v0.12-dev v0.12-fix-tests-20181109 v0.12-fix-tests v0.12-upgrade-guide-pre-tweaks v011 vendor-checkpoint-with-timeout vendor-github vendor-hcl2-update vendor-tfe website-header with-go-modules
Nothing to show
Find file History

README.md

terraform-bundle

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.

Normally terraform init will download and install the plugins necessary to work with a particular configuration, but sometimes Terraform is deployed in a network that, for one reason or another, cannot access the official plugin repository for automatic download.

In some cases, this can be solved by installing provider plugins into the user plugins directory. However, this doesn't always meet the needs of automated deployments.

terraform-bundle provides an alternative, by allowing the auto-download process to be run out-of-band on a separate machine that does have access to the repository. The result is a zip file that can be extracted onto the target system to install both the desired Terraform version and a selection of providers, thus avoiding the need for on-the-fly plugin installation.

Building

To build terraform-bundle from source, set up a Terraform development environment per Terraform's own README and then install this tool from within it:

$ go install ./tools/terraform-bundle

This will install terraform-bundle in $GOPATH/bin, which is assumed by the rest of this README to be in PATH.

Usage

terraform-bundle uses a simple configuration file to define what should be included in a bundle. This is designed so that it can be checked into version control and used by an automated build and deploy process.

The configuration file format works as follows:

terraform {
  # Version of Terraform to include in the bundle. An exact version number
  # is required.
  version = "0.10.0"
}

# Define which provider plugins are to be included
providers {
  # Include the newest "aws" provider version in the 1.0 series.
  aws = ["~> 1.0"]

  # Include both the newest 1.0 and 2.0 versions of the "google" provider.
  # Each item in these lists allows a distinct version to be added. If the
  # two expressions match different versions then _both_ are included in
  # the bundle archive.
  google = ["~> 1.0", "~> 2.0"]

  # Include a custom plugin to the bundle. Will search for the plugin in the
  # plugins directory, and package it with the bundle archive. Plugin must have
  # a name of the form: terraform-provider-*, and must be build with the operating
  # system and architecture that terraform enterprise is running, e.g. linux and amd64
  customplugin = ["0.1"]
}

The terraform block defines which version of Terraform will be included in the bundle. An exact version is required here.

The providers block defines zero or more providers to include in the bundle along with core Terraform. Each attribute in this block is a provider name, and its value is a list of version constraints. For each given constraint, terraform-bundle will find the newest available version matching the constraint and include it in the bundle.

It is allowed to specify multiple constraints for the same provider, in which case multiple versions can be included in the resulting bundle. Each constraint string given results in a separate plugin in the bundle, unless two constraints resolve to the same concrete plugin.

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. This avoids the need to upgrade all configurations to newer versions in lockstep.

After creating the configuration file, e.g. terraform-bundle.hcl, a bundle zip file can be produced as follows:

$ terraform-bundle package terraform-bundle.hcl

By default the bundle package will target the operating system and CPU architecture where the tool is being run. To override this, use the -os and -arch options. For example, to build a bundle for on-premises Terraform Enterprise:

$ terraform-bundle package -os=linux -arch=amd64 terraform-bundle.hcl

The bundle file is assigned a name that includes the core Terraform version number, a timestamp to the nearest hour of when the bundle was built, and the target OS and CPU architecture. It is recommended to refer to a bundle using this composite version number so that bundle archives can be easily distinguished from official release archives and from each other when multiple bundles contain the same core Terraform version.

To include custom plugins in the bundle file, create a local directory "./plugins" and put all the plugins you want to include there. Optionally, you can use the -plugin-dir flag to specify a location where to find the plugins. To be recognized as a valid plugin, the file must have a name of the form terraform-provider-<NAME>-v<VERSION>. In addition, ensure that the plugin is built using the same operating system and architecture used for Terraform Enterprise. Typically this will be linux and amd64.

Provider Resolution Behavior

Terraform's provider resolution behavior is such that if a given constraint can be resolved by any plugin already installed on the system it will use the newest matching plugin and not attempt automatic installation.

Therefore if automatic installation is not desired, it is important to ensure that version constraints within Terraform configurations do not exclude all of the versions available from the bundle. If a suitable version cannot be found in the bundle, Terraform will attempt to satisfy that dependency by automatic installation from the official repository. If you want terraform init to explicitly fail instead of contacting the repository, pass the -get-plugins=false option.

For full details about provider resolution, see How Terraform Works: Plugin Discovery.

The downloaded provider archives are verified using the same signature check that is used for auto-installed plugins, using Hashicorp's release key. At this time, the core Terraform archive itself is not verified in this way; that may change in a future version of this tool.

Installing a Bundle in On-premises Terraform Enterprise

If using a private install of Terraform Enterprise in an "air-gapped" environment, this tool can produce a custom Terraform version package, which includes a set of provider plugins along with core Terraform.

To create a suitable bundle, use the -os and -arch options as described above to produce a bundle targeting linux_amd64. You can then place this archive on an HTTP server reachable by the Terraform Enterprise hosts and install it as per Administration: Managing Terraform Versions.

After clicking the "Add Terraform Version" button:

  1. In the "Version" field, enter the generated bundle version from the bundle filename, which will be of the form N.N.N-bundleYYYYMMDDHH.
  2. In the "URL" field, enter the URL where the generated bundle archive can be found.
  3. In the "SHA256 Checksum" field, enter the SHA256 hash of the file, which can be found by running sha256sum <FILE> or shasum -a256 <FILE>.

The new bundle version can then be selected as the Terraform version for any workspace. When selected, configurations that require only plugins included in the bundle will run without trying to auto-install.

Note that the above does not apply to Terraform Pro, or to Terraform Premium when not running a private install. In these packages, Terraform versions are managed centrally across all organizations and so custom bundles are not supported.

For more information on the available Terraform Enterprise packages, see the Terraform product site.