| --- |
| page_title: CLI Configuration |
| description: >- |
| Learn to use the CLI configuration file to customize your CLI settings, |
| including credentials, plugin caching, provider installation methods, etc. |
| --- |
| |
| # CLI Configuration File (`.terraformrc` or `terraform.rc`) |
| |
| The CLI configuration file configures per-user settings for CLI behaviors, |
| which apply across all Terraform working directories. This is separate from |
| [your infrastructure configuration](/language). |
| |
| ## Locations |
| |
| The configuration can be placed in a single file whose location depends |
| on the host operating system: |
| |
| * On Windows, the file must be named `terraform.rc` and placed |
| in the relevant user's `%APPDATA%` directory. The physical location |
| of this directory depends on your Windows version and system configuration; |
| use `$env:APPDATA` in PowerShell to find its location on your system. |
| * On all other systems, the file must be named `.terraformrc` (note |
| the leading period) and placed directly in the home directory |
| of the relevant user. |
| |
| 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](/cli/config/environment-variables). |
| Any such file should follow the naming pattern `*.tfrc`. |
| |
| ## Configuration File Syntax |
| |
| 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: |
| |
| ```hcl |
| plugin_cache_dir = "$HOME/.terraform.d/plugin-cache" |
| disable_checkpoint = true |
| ``` |
| |
| ## Available Settings |
| |
| The following settings can be set in the CLI configuration file: |
| |
| * `credentials` - configures credentials for use with Terraform Cloud or |
| Terraform Enterprise. See [Credentials](#credentials) below for more |
| information. |
| |
| * `credentials_helper` - configures an external helper program for the storage |
| and retrieval of credentials for Terraform Cloud or Terraform Enterprise. |
| See [Credentials Helpers](#credentials-helpers) below for more information. |
| |
| * `disable_checkpoint` — when set to `true`, disables |
| [upgrade and security bulletin checks](/cli/commands#upgrade-and-security-bulletin-checks) |
| that require reaching out to HashiCorp-provided network services. |
| |
| * `disable_checkpoint_signature` — when set to `true`, allows the upgrade and |
| security bulletin checks described above but disables the use of an anonymous |
| id used to de-duplicate warning messages. |
| |
| * `plugin_cache_dir` — enables |
| [plugin caching](#provider-plugin-cache) |
| and specifies, as a string, the location of the plugin cache directory. |
| |
| * `provider_installation` - customizes the installation methods used by |
| `terraform init` when installing provider plugins. See |
| [Provider Installation](#provider-installation) below for more information. |
| |
| ## Credentials |
| |
| [Terraform Cloud](https://cloud.hashicorp.com/products/terraform) provides a number of remote network |
| services for use with Terraform, and |
| [Terraform Enterprise](/enterprise) allows hosting those |
| services inside your own infrastructure. For example, these systems offer both |
| [remote operations](/cloud-docs/run/cli) and a |
| [private module registry](/cloud-docs/registry). |
| |
| When interacting with Terraform-specific network services, Terraform expects |
| to find API tokens in CLI configuration files in `credentials` blocks: |
| |
| ```hcl |
| 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` command](/cli/commands/login) |
| to 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 |
| Terraform Cloud (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 Terraform Cloud or Terraform Enterprise, |
| the token provided must be either a |
| [user token](/cloud-docs/users-teams-organizations/users#api-tokens) |
| or a |
| [team token](/cloud-docs/users-teams-organizations/api-tokens#team-api-tokens); |
| 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. |
| Terraform Cloud responds to API calls at both its current hostname |
| `app.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 prefix |
| `TF_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 equivalent](https://www.charset.org/punycode) |
| with 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 name |
| `café.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. |
| |
| ```hcl |
| 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 the |
| `credentials_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, see |
| [the guide to Credentials Helper internals](/internals/credentials-helpers). |
| |
| ### 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](https://github.com/apparentlymart/terraform-credentials-env), this priority has been effectively reversed following the |
| release of Terraform 1.2. Previously, credentials found within CLI config or set by |
| `terraform login` were preferred to `TF_TOKEN_*` variables. |
| |
| ## Provider Installation |
| |
| 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 on |
| `registry.terraform.io`, so you can write shorter public provider addresses like |
| `hashicorp/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: |
| |
| ```hcl |
| 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 `include` |
| and `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, including |
| `registry.terraform.io/hashicorp/*` but also excluding |
| `registry.terraform.io/hashicorp/dns` will make that installation method apply |
| to everything in the `hashicorp` namespace with the exception of |
| `hashicorp/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: |
| |
| * `direct`: request information about the provider directly from its origin |
| registry and download over the network from the location that registry |
| indicates. This method expects no additional arguments. |
| |
| * `filesystem_mirror`: consult a directory on the local disk for copies of |
| providers. This method requires the additional argument `path` to indicate |
| which directory to look in. |
| |
| Terraform expects the given directory to contain a nested directory structure |
| where the path segments together provide metadata about the available |
| providers. The following two directory structures are supported: |
| |
| * Packed layout: `HOSTNAME/NAMESPACE/TYPE/terraform-provider-TYPE_VERSION_TARGET.zip` |
| is the distribution zip file obtained from the provider's origin registry. |
| * Unpacked layout: `HOSTNAME/NAMESPACE/TYPE/VERSION/TARGET` is a directory |
| containing the result of extracting the provider's distribution zip file. |
| |
| In both layouts, the `VERSION` is a string like `2.0.0` and the `TARGET` |
| specifies a particular target platform using a format like `darwin_amd64`, |
| `linux_arm`, `windows_amd64`, etc. |
| |
| If you use the unpacked layout, Terraform will attempt to create a symbolic |
| link to the mirror directory when installing the provider, rather than |
| creating a deep copy of the directory. The packed layout prevents this |
| because Terraform must extract the zip file during installation. |
| |
| You can include multiple `filesystem_mirror` blocks in order to specify |
| several different directories to search. |
| |
| * `network_mirror`: consult a particular HTTPS server for copies of providers, |
| regardless of which registry host they belong to. This method requires the |
| additional argument `url` to indicate the mirror base URL, which should |
| use the `https:` scheme and end with a trailing slash. |
| |
| Terraform expects the given URL to be a base URL for an implementation of |
| [the provider network mirror protocol](/internals/provider-network-mirror-protocol), |
| which is designed to be relatively easy to implement using typical static |
| website hosting mechanisms. |
| |
| ~> **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 `exclude` |
| argument 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 `direct` |
| method. |
| |
| The set of directories Terraform can select as filesystem mirrors depends on |
| the operating system where you are running Terraform: |
| |
| * **Windows:** `%APPDATA%/terraform.d/plugins` and `%APPDATA%/HashiCorp/Terraform/plugins` |
| * **Mac OS X:** `$HOME/.terraform.d/plugins`, |
| `~/Library/Application Support/io.terraform/plugins`, and |
| `/Library/Application Support/io.terraform/plugins` |
| * **Linux and other Unix-like systems**:`$HOME/.terraform.d/plugins` and |
| `terraform/plugins` located within a valid |
| [XDG Base Directory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) |
| data directory such as `$XDG_DATA_HOME/terraform/plugins`. |
| Without any XDG environment variables set, Terraform will use |
| `~/.local/share/terraform/plugins`, |
| `/usr/local/share/terraform/plugins`, and `/usr/share/terraform/plugins`. |
| |
| 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_mirror` |
| blocks in [Explicit Installation Method Configuration](#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: |
| |
| ```hcl |
| 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: |
| |
| ```bash |
| 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 the |
| [dependency lock file](https://developer.hashicorp.com/terraform/language/files/dependency-lock) |
| for 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: |
| |
| ```hcl |
| plugin_cache_may_break_dependency_lock_file = true |
| ``` |
| |
| Alternatively, you can set the environment variable |
| `TF_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: |
| |
| ```hcl |
| 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 in |
| [the dependency lock file](/language/files/dependency-lock) |
| for future use, but other commands like |
| `terraform 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 like |
| `terraform-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 the |
| `TF_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, see |
| [Implied Local Mirror Directories](#implied-local-mirror-directories) |
| or |
| [Explicit Installation Method Configuration](#explicit-installation-method-configuration) |
| instead. |
| |
| 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. |
| |
| ## Removed Settings |
| |
| The following settings are supported in Terraform 0.12 and earlier but are |
| no longer recommended for use: |
| |
| * `providers` - a configuration block that allows specifying the locations of |
| specific plugins for each named provider. This mechanism is deprecated |
| because it is unable to specify a version number and source for each provider. |
| See [Provider Installation](#provider-installation) above for the replacement |
| of this setting in Terraform 0.13 and later. |