Create a Terraform CLI configuration file | Terraform | HashiCorp Developer (original) (raw)

This topic describes how create a configuration file to customize the behavior of the Terraform CLI.

The CLI configuration file configures per-user settings for CLI behaviors, which apply across all Terraform working directories. This is separate fromyour infrastructure configuration. You can define custom configurations in file called .terraformrc or terraform.rcdepending on the host operating system as explained below.

The configuration can be placed in a single file whose location depends on the host operating system:

On Windows, beware of Windows Explorer's default behavior of hiding filename extensions. Terraform will not recognize a file named terraform.rc.txt as a CLI configuration file, even though Windows Explorer may display its name as just terraform.rc. Use dir from PowerShell or Command Prompt to confirm the filename.

The location of the Terraform CLI configuration file can also be specified using the TF_CLI_CONFIG_FILE environment variable. Any such file should follow the naming pattern *.tfrc.

The configuration file uses the same HCL syntax as .tf files, but with different attributes and blocks. The following example illustrates the general syntax; see the following section for information on the meaning of each of these settings:

plugin_cache_dir   = "$HOME/.terraform.d/plugin-cache"
disable_checkpoint = true

The following settings can be set in the CLI configuration file:

HCP Terraform provides a number of remote network services for use with Terraform, andTerraform Enterprise allows hosting those services inside your own infrastructure. For example, these systems offer bothremote operations and aprivate module registry.

When interacting with Terraform-specific network services, Terraform expects to find API tokens in CLI configuration files in credentials blocks:

credentials "app.terraform.io" {
  token = "xxxxxx.atlasv1.zzzzzzzzzzzzz"
}

If you are running the Terraform CLI interactively on a computer with a web browser, you can use the terraform login commandto get credentials and automatically save them in the CLI configuration. If not, you can manually write credentials blocks.

You can have multiple credentials blocks if you regularly use services from multiple hosts. Many users will configure only one, for either HCP Terraform (at app.terraform.io) or for their organization's own Terraform Enterprise host. Each credentials block contains a token argument giving the API token to use for that host.

Important: If you are using HCP Terraform or Terraform Enterprise, the token provided must be either auser tokenor ateam token; organization tokens cannot be used for command-line Terraform actions.

Note: The credentials hostname must match the hostname in your module sources and/or backend configuration. If your Terraform Enterprise instance is available at multiple hostnames, use only one of them consistently. HCP Terraform responds to API calls at both its current hostnameapp.terraform.io, and its historical hostname atlas.hashicorp.com.

Environment Variable Credentials

Note: Environment variable credentials are supported in Terraform v1.2.0 and later.

If you would prefer not to store your API tokens directly in the CLI configuration, you may use a host-specific environment variable. Environment variable names should have the prefixTF_TOKEN_ added to the domain name, with periods encoded as underscores. For example, the value of a variable named TF_TOKEN_app_terraform_io will be used as a bearer authorization token when the CLI makes service requests to the hostname app.terraform.io.

You must convert domain names containing non-ASCII characters to their punycode equivalentwith an ACE prefix. For example, token credentials for 例えば.com must be set in a variable called TF_TOKEN_xn--r8j3dr99h_com.

Hyphens are also valid within host names but usually invalid as variable names and may be encoded as double underscores. For example, you can set a token for the domain namecafé.fr as TF_TOKEN_xn--caf-dma.fr, TF_TOKEN_xn--caf-dma_fr, or TF_TOKEN_xn____caf__dma_fr. If multiple variables evaluate to the same hostname, Terraform will choose the one defined last in the operating system's variable table.

Credentials Helpers

You can configure a credentials_helper to instruct Terraform to use a different credentials storage mechanism.

credentials_helper "example" {
  args = []
}

credentials_helper is a configuration block that can appear at most once in the CLI configuration. Its label ("example" above) is the name of the credentials helper to use. The args argument is optional and allows passing additional arguments to the helper program, for example if it needs to be configured with the address of a remote host to access for credentials.

A configured credentials helper will be consulted only to retrieve credentials for hosts that are not explicitly configured in a credentials block as described in the previous section. Conversely, this means you can override the credentials returned by the helper for a specific hostname by writing a credentials block alongside thecredentials_helper block.

Terraform does not include any credentials helpers in the main distribution. To learn how to write and install your own credentials helpers to integrate with existing in-house credentials management systems, seethe guide to Credentials Helper internals.

Credentials Source Priority Order

Credentials found in an environment variable for a particular service host as described above will be preferred over those in CLI config as set by terraform login. If neither are set, any configured credentials helper will be consulted.

Note: For users of terraform-credentials-helper, this priority has been effectively reversed following the release of Terraform 1.2. Previously, credentials found within CLI config or set byterraform login were preferred to TF_TOKEN_* variables.

The default way to install provider plugins is from a provider registry. The origin registry for a provider is encoded in the provider's source address, like registry.terraform.io/hashicorp/aws. For convenience in the common case, Terraform allows omitting the hostname portion for providers onregistry.terraform.io, so you can write shorter public provider addresses likehashicorp/aws.

Downloading a plugin directly from its origin registry is not always appropriate, though. For example, the system where you are running Terraform may not be able to access an origin registry due to firewall restrictions within your organization or your locality.

To allow using Terraform providers in these situations, there are some alternative options for making provider plugins available to Terraform which we'll describe in the following sections.

Explicit Installation Method Configuration

A provider_installation block in the CLI configuration allows overriding Terraform's default installation behaviors, so you can force Terraform to use a local mirror for some or all of the providers you intend to use.

The general structure of a provider_installation block is as follows:

provider_installation {
  filesystem_mirror {
    path    = "/usr/share/terraform/providers"
    include = ["example.com/*/*"]
  }
  direct {
    exclude = ["example.com/*/*"]
  }
}

Each of the nested blocks inside the provider_installation block specifies one installation method. Each installation method can take both includeand exclude patterns that specify which providers a particular installation method can be used for. In the example above, we specify that any provider whose origin registry is at example.com can be installed only from the filesystem mirror at /usr/share/terraform/providers, while all other providers can be installed only directly from their origin registries.

If you set both include and exclude for a particular installation method, the exclusion patterns take priority. For example, includingregistry.terraform.io/hashicorp/* but also excludingregistry.terraform.io/hashicorp/dns will make that installation method apply to everything in the hashicorp namespace with the exception ofhashicorp/dns.

As with provider source addresses in the main configuration, you can omit the registry.terraform.io/ prefix for providers distributed through the public Terraform registry, even when using wildcards. For example,registry.terraform.io/hashicorp/* and hashicorp/* are equivalent.*/* is a shorthand for registry.terraform.io/*/*, not for*/*/*.

The following are the two supported installation method types:

Warning: Don't configure network_mirror URLs that you do not trust. Provider mirror servers are subject to TLS certificate checks to verify identity, but a network mirror with a TLS certificate can potentially serve modified copies of upstream providers with malicious content.

Terraform will try all of the specified methods whose include and exclude patterns match a given provider, and select the newest version available across all of those methods that matches the version constraint given in each Terraform configuration. If you have a local mirror of a particular provider and intend Terraform to use that local mirror exclusively, you must either remove the direct installation method altogether or use its excludeargument to disable its use for specific providers.

Implied Local Mirror Directories

If your CLI configuration does not include a provider_installation block at all, Terraform produces an implied configuration. The implied configuration includes a selection of filesystem_mirror methods and then the directmethod.

The set of directories Terraform can select as filesystem mirrors depends on the operating system where you are running Terraform:

If a terraform.d/plugins directory exists in the current working directory then Terraform will also include that directory, regardless of your operating system. This behavior changes when you use the -chdir option with the init command. In that case, Terraform checks for the terraform.d/plugins directory in the launch directory and not in the directory you specified with -chdir.

Terraform will check each of the paths above to see if it exists, and if so treat it as a filesystem mirror. The directory structure inside each one must therefore match one of the two structures described for filesystem_mirrorblocks in Explicit Installation Method Configuration.

In addition to the zero or more implied filesystem_mirror blocks, Terraform also creates an implied direct block. Terraform will scan all of the filesystem mirror directories to see which providers are placed there and automatically exclude all of those providers from the implied direct block. (This automatic exclude behavior applies only to implicit direct blocks; if you use explicit provider_installation you will need to write the intended exclusions out yourself.)

Provider Plugin Cache

By default, terraform init downloads plugins into a subdirectory of the working directory so that each working directory is self-contained. As a consequence, if you have multiple configurations that use the same provider then a separate copy of its plugin will be downloaded for each configuration.

Given that provider plugins can be quite large (on the order of hundreds of megabytes), this default behavior can be inconvenient for those with slow or metered Internet connections. Therefore Terraform optionally allows the use of a local directory as a shared plugin cache, which then allows each distinct plugin binary to be downloaded only once.

To enable the plugin cache, use the plugin_cache_dir setting in the CLI configuration file. For example:

plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"

This directory must already exist before Terraform will cache plugins; Terraform will not create the directory itself.

Please note that on Windows it is necessary to use forward slash separators (/) rather than the conventional backslash (\) since the configuration file parser considers a backslash to begin an escape sequence.

Setting this in the configuration file is the recommended approach for a persistent setting. Alternatively, the TF_PLUGIN_CACHE_DIR environment variable can be used to enable caching or to override an existing cache directory within a particular shell session:

export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"

When a plugin cache directory is enabled, the terraform init command will still use the configured or implied installation methods to obtain metadata about which plugins are available, but once a suitable version has been selected it will first check to see if the chosen plugin is already available in the cache directory. If so, Terraform will use the previously-downloaded copy.

If the selected plugin is not already in the cache, Terraform will download it into the cache first and then copy it from there into the correct location under your current working directory. When possible Terraform will use symbolic links to avoid storing a separate copy of a cached plugin in multiple directories.

The plugin cache directory must not also be one of the configured or implied filesystem mirror directories, since the cache management logic conflicts with the filesystem mirror logic when operating on the same directory.

Terraform will never itself delete a plugin from the plugin cache once it has been placed there. Over time, as plugins are upgraded, the cache directory may grow to contain several unused versions which you must delete manually.

Note: The plugin cache directory is not guaranteed to be concurrency safe. The provider installer's behavior in environments with multiple terraform init calls is undefined.

Allowing the Provider Plugin Cache to break the dependency lock file

Note: The option described in is for unusual and exceptional situations only. Do not set this option unless you are sure you need it and you fully understand the consequences of enabling it.

By default Terraform will use packages from the global cache directory only if they match at least one of the checksums recorded in thedependency lock filefor that provider. This ensures that Terraform can always generate a complete and correct dependency lock file entry the first time you use a new provider in a particular configuration.

However, we know that in some special situations teams have been unable to use the dependency lock file as intended, and so they don't include it in their version control as recommended and instead let Terraform re-generate it each time it installs providers.

For those teams that don't preserve the dependency lock file in their version control systems between runs, Terraform allows an additional CLI Configuration setting which tells Terraform to always treat a package in the cache directory as valid even if there isn't already an entry in the dependency lock file to confirm it:

plugin_cache_may_break_dependency_lock_file = true

Alternatively, you can set the environment variableTF_PLUGIN_CACHE_MAY_BREAK_DEPENDENCY_LOCK_FILE to any value other than the empty string or 0, which is equivalent to the above setting.

Setting this option gives Terraform CLI permission to create an incomplete dependency lock file entry for a provider if that would allow Terraform to use the cache to install that provider. In that situation the dependency lock file will be valid for use on the current system but may not be valid for use on another computer with a different operating system or CPU architecture, because it will include only a checksum of the package in the global cache.

We recommend that most users leave this option unset, in which case Terraform will always install a provider from upstream the first time you use it with a particular configuration, but can then re-use the cache entry on later runs once the dependency lock file records valid checksums for the provider package.

Note: The Terraform team intends to improve the dependency lock file mechanism in future versions so that it will be usable in more situations. At that time this option will become silently ignored. If your workflow relies on the use of this option, please open a GitHub issue to share details about your situation so that we can consider how to support it without breaking the dependency lock file.

Development Overrides for Provider Developers

Note: Development overrides work only in Terraform v0.14 and later. Using a dev_overrides block in your CLI configuration will cause Terraform v0.13 to reject the configuration as invalid.

Normally Terraform verifies version selections and checksums for providers in order to help ensure that all operations are made with the intended version of a provider, and that authors can gradually upgrade to newer provider versions in a controlled manner.

These version and checksum rules are inconvenient when developing a provider though, because we often want to try a test configuration against a development build of a provider that doesn't even have an associated version number yet, and doesn't have an official set of checksums listed in a provider registry.

As a convenience for provider development, Terraform supports a special additional block dev_overrides in provider_installation blocks. The contents of this block effectively override all of the other configured installation methods, so a block of this type must always appear first in the sequence:

provider_installation {

  # Use /home/developer/tmp/terraform-null as an overridden package directory
  # for the hashicorp/null provider. This disables the version and checksum
  # verifications for this provider and forces Terraform to look for the
  # null provider plugin in the given directory.
  dev_overrides {
    "hashicorp/null" = "/home/developer/tmp/terraform-null"
  }

  # For all other providers, install them directly from their origin provider
  # registries as normal. If you omit this, Terraform will _only_ use
  # the dev_overrides block, and so no other providers will be available.
  direct {}
}

With development overrides in effect, the terraform init command will still attempt to select a suitable published version of your provider to install and record inthe dependency lock filefor future use, but other commands liketerraform apply will disregard the lock file's entry for hashicorp/null and will use the given directory instead. Once your new changes are included in a published release of the provider, you can use terraform init -upgrade to select the new version in the dependency lock file and remove your development override.

The override path for a particular provider should be a directory similar to what would be included in a .zip file when distributing the provider. At minimum that includes an executable file named with a prefix liketerraform-provider-null, where null is the provider type. If your provider makes use of other files in its distribution package then you can copy those files into the override directory too.

You may wish to enable a development override only for shell sessions where you are actively working on provider development. If so, you can write a local CLI configuration file with content like the above in your development directory, perhaps called dev.tfrc for the sake of example, and then use theTF_CLI_CONFIG_FILE environment variable to instruct Terraform to use that localized CLI configuration instead of the default one:

export TF_CLI_CONFIG_FILE=/home/developer/tmp/dev.tfrc

Development overrides are not intended for general use as a way to have Terraform look for providers on the local filesystem. If you wish to put copies of released providers in your local filesystem, seeImplied Local Mirror DirectoriesorExplicit Installation Method Configurationinstead.

This development overrides mechanism is intended as a pragmatic way to enable smoother provider development. The details of how it behaves, how to configure it, and how it interacts with the dependency lock file may all evolve in future Terraform releases, including possible breaking changes. We therefore recommend using development overrides only temporarily during provider development work.

The following settings are supported in Terraform 0.12 and earlier but are no longer recommended for use: