1---
2layout: "docs"
3page_title: "CLI Configuration"
4sidebar_current: "docs-commands-cli-config"
5description: "Learn to use the CLI configuration file to customize your CLI settings, including credentials, plugin caching, provider installation methods, etc."
6---
7
8# CLI Configuration File (`.terraformrc` or `terraform.rc`)
9
10The CLI configuration file configures per-user settings for CLI behaviors,
11which apply across all Terraform working directories. This is separate from
12[your infrastructure configuration](/docs/language/index.html).
13
14## Location
15
16The configuration is placed in a single file whose location depends on the
17host operating system:
18
19* On Windows, the file must be named `terraform.rc` and placed
20  in the relevant user's `%APPDATA%` directory. The physical location
21  of this directory depends on your Windows version and system configuration;
22  use `$env:APPDATA` in PowerShell to find its location on your system.
23* On all other systems, the file must be named `.terraformrc` (note
24  the leading period) and placed directly in the home directory
25  of the relevant user.
26
27On Windows, beware of Windows Explorer's default behavior of hiding filename
28extensions. Terraform will not recognize a file named `terraform.rc.txt` as a
29CLI configuration file, even though Windows Explorer may _display_ its name
30as just `terraform.rc`. Use `dir` from PowerShell or Command Prompt to
31confirm the filename.
32
33The location of the Terraform CLI configuration file can also be specified
34using the `TF_CLI_CONFIG_FILE` [environment variable](/docs/cli/config/environment-variables.html).
35
36## Configuration File Syntax
37
38The configuration file uses the same _HCL_ syntax as `.tf` files, but with
39different attributes and blocks. The following example illustrates the
40general syntax; see the following section for information on the meaning
41of each of these settings:
42
43```hcl
44plugin_cache_dir   = "$HOME/.terraform.d/plugin-cache"
45disable_checkpoint = true
46```
47
48## Available Settings
49
50The following settings can be set in the CLI configuration file:
51
52- `credentials` - configures credentials for use with Terraform Cloud or
53  Terraform Enterprise. See [Credentials](#credentials) below for more
54  information.
55
56- `credentials_helper` - configures an external helper program for the storage
57  and retrieval of credentials for Terraform Cloud or Terraform Enterprise.
58  See [Credentials Helpers](#credentials-helpers) below for more information.
59
60- `disable_checkpoint` — when set to `true`, disables
61  [upgrade and security bulletin checks](/docs/cli/commands/index.html#upgrade-and-security-bulletin-checks)
62  that require reaching out to HashiCorp-provided network services.
63
64- `disable_checkpoint_signature` — when set to `true`, allows the upgrade and
65  security bulletin checks described above but disables the use of an anonymous
66  id used to de-duplicate warning messages.
67
68- `plugin_cache_dir` — enables
69  [plugin caching](#provider-plugin-cache)
70  and specifies, as a string, the location of the plugin cache directory.
71
72- `provider_installation` - customizes the installation methods used by
73  `terraform init` when installing provider plugins. See
74  [Provider Installation](#provider-installation) below for more information.
75
76## Credentials
77
78[Terraform Cloud](/docs/cloud/index.html) provides a number of remote network
79services for use with Terraform, and
80[Terraform Enterprise](/docs/enterprise/index.html) allows hosting those
81services inside your own infrastructure. For example, these systems offer both
82[remote operations](/docs/cloud/run/cli.html) and a
83[private module registry](/docs/cloud/registry/index.html).
84
85When interacting with Terraform-specific network services, Terraform expects
86to find API tokens in CLI configuration files in `credentials` blocks:
87
88```hcl
89credentials "app.terraform.io" {
90  token = "xxxxxx.atlasv1.zzzzzzzzzzzzz"
91}
92```
93
94If you are running the Terraform CLI interactively on a computer with a web browser, you can use [the `terraform login` command](/docs/cli/commands/login.html)
95to get credentials and automatically save them in the CLI configuration. If
96not, you can manually write `credentials` blocks.
97
98You can have multiple `credentials` blocks if you regularly use services from
99multiple hosts. Many users will configure only one, for either
100Terraform Cloud (at `app.terraform.io`) or for their organization's own
101Terraform Enterprise host. Each `credentials` block contains a `token` argument
102giving the API token to use for that host.
103
104~> **Important:** If you are using Terraform Cloud or Terraform Enterprise,
105the token provided must be either a
106[user token](/docs/cloud/users-teams-organizations/users.html#api-tokens)
107or a
108[team token](/docs/cloud/users-teams-organizations/api-tokens.html#team-api-tokens);
109organization tokens cannot be used for command-line Terraform actions.
110
111-> **Note:** The credentials hostname must match the hostname in your module
112sources and/or backend configuration. If your Terraform Enterprise instance
113is available at multiple hostnames, use only one of them consistently.
114Terraform Cloud responds to API calls at both its current hostname
115`app.terraform.io`, and its historical hostname `atlas.hashicorp.com`.
116
117### Credentials Helpers
118
119If you would prefer not to store your API tokens directly in the CLI
120configuration as described in the previous section, you can optionally instruct
121Terraform to use a different credentials storage mechanism by configuring a
122special kind of plugin program called a _credentials helper_.
123
124```hcl
125credentials_helper "example" {
126  args = []
127}
128```
129
130`credentials_helper` is a configuration block that can appear at most once
131in the CLI configuration. Its label (`"example"` above) is the name of the
132credentials helper to use. The `args` argument is optional and allows passing
133additional arguments to the helper program, for example if it needs to be
134configured with the address of a remote host to access for credentials.
135
136A configured credentials helper will be consulted only to retrieve credentials
137for hosts that are _not_ explicitly configured in a `credentials` block as
138described in the previous section.
139Conversely, this means you can override the credentials returned by the helper
140for a specific hostname by writing a `credentials` block alongside the
141`credentials_helper` block.
142
143Terraform does not include any credentials helpers in the main distribution.
144To learn how to write and install your own credentials helpers to integrate
145with existing in-house credentials management systems, see
146[the guide to Credentials Helper internals](/docs/internals/credentials-helpers.html).
147
148## Provider Installation
149
150The default way to install provider plugins is from a provider registry. The
151origin registry for a provider is encoded in the provider's source address,
152like `registry.terraform.io/hashicorp/aws`. For convenience in the common case,
153Terraform allows omitting the hostname portion for providers on
154`registry.terraform.io`, so you can write shorter public provider addresses like
155`hashicorp/aws`.
156
157Downloading a plugin directly from its origin registry is not always
158appropriate, though. For example, the system where you are running Terraform
159may not be able to access an origin registry due to firewall restrictions
160within your organization or your locality.
161
162To allow using Terraform providers in these situations, there are some
163alternative options for making provider plugins available to Terraform which
164we'll describe in the following sections.
165
166### Explicit Installation Method Configuration
167
168A `provider_installation` block in the CLI configuration allows overriding
169Terraform's default installation behaviors, so you can force Terraform to use
170a local mirror for some or all of the providers you intend to use.
171
172The general structure of a `provider_installation` block is as follows:
173
174```hcl
175provider_installation {
176  filesystem_mirror {
177    path    = "/usr/share/terraform/providers"
178    include = ["example.com/*/*"]
179  }
180  direct {
181    exclude = ["example.com/*/*"]
182  }
183}
184```
185
186Each of the nested blocks inside the `provider_installation` block specifies
187one installation method. Each installation method can take both `include`
188and `exclude` patterns that specify which providers a particular installation
189method can be used for. In the example above, we specify that any provider
190whose origin registry is at `example.com` can be installed only from the
191filesystem mirror at `/usr/share/terraform/providers`, while all other
192providers can be installed only directly from their origin registries.
193
194If you set both `include` and `exclude` for a particular installation
195method, the exclusion patterns take priority. For example, including
196`registry.terraform.io/hashicorp/*` but also excluding
197`registry.terraform.io/hashicorp/dns` will make that installation method apply
198to everything in the `hashicorp` namespace with the exception of
199`hashicorp/dns`.
200
201As with provider source addresses in the main configuration, you can omit
202the `registry.terraform.io/` prefix for providers distributed through the
203public Terraform registry, even when using wildcards. For example,
204`registry.terraform.io/hashicorp/*` and `hashicorp/*` are equivalent.
205`*/*` is a shorthand for `registry.terraform.io/*/*`, not for
206`*/*/*`.
207
208The following are the two supported installation method types:
209
210* `direct`: request information about the provider directly from its origin
211  registry and download over the network from the location that registry
212  indicates. This method expects no additional arguments.
213
214* `filesystem_mirror`: consult a directory on the local disk for copies of
215  providers. This method requires the additional argument `path` to indicate
216  which directory to look in.
217
218    Terraform expects the given directory to contain a nested directory structure
219    where the path segments together provide metadata about the available
220    providers. The following two directory structures are supported:
221
222    * Packed layout: `HOSTNAME/NAMESPACE/TYPE/terraform-provider-TYPE_VERSION_TARGET.zip`
223      is the distribution zip file obtained from the provider's origin registry.
224    * Unpacked layout: `HOSTNAME/NAMESPACE/TYPE/VERSION/TARGET` is a directory
225      containing the result of extracting the provider's distribution zip file.
226
227    In both layouts, the `VERSION` is a string like `2.0.0` and the `TARGET`
228    specifies a particular target platform using a format like `darwin_amd64`,
229    `linux_arm`, `windows_amd64`, etc.
230
231    If you use the unpacked layout, Terraform will attempt to create a symbolic
232    link to the mirror directory when installing the provider, rather than
233    creating a deep copy of the directory. The packed layout prevents this
234    because Terraform must extract the zip file during installation.
235
236    You can include multiple `filesystem_mirror` blocks in order to specify
237    several different directories to search.
238
239* `network_mirror`: consult a particular HTTPS server for copies of providers,
240  regardless of which registry host they belong to. This method requires the
241  additional argument `url` to indicate the mirror base URL, which should
242  use the `https:` scheme and end with a trailing slash.
243
244    Terraform expects the given URL to be a base URL for an implementation of
245    [the provider network mirror protocol](/docs/internals/provider-network-mirror-protocol.html),
246    which is designed to be relatively easy to implement using typical static
247    website hosting mechanisms.
248
249~> **Warning:** Don't configure `network_mirror` URLs that you do not trust.
250Provider mirror servers are subject to TLS certificate checks to verify
251identity, but a network mirror with a TLS certificate can potentially serve
252modified copies of upstream providers with malicious content.
253
254Terraform will try all of the specified methods whose include and exclude
255patterns match a given provider, and select the newest version available across
256all of those methods that matches the version constraint given in each
257Terraform configuration. If you have a local mirror of a particular provider
258and intend Terraform to use that local mirror exclusively, you must either
259remove the `direct` installation method altogether or use its `exclude`
260argument to disable its use for specific providers.
261
262### Implied Local Mirror Directories
263
264If your CLI configuration does not include a `provider_installation` block at
265all, Terraform produces an _implied_ configuration. The implied configuration
266includes a selection of `filesystem_mirror` methods and then the `direct`
267method.
268
269The set of directories Terraform can select as filesystem mirrors depends on
270the operating system where you are running Terraform:
271
272* **Windows:** `%APPDATA%/terraform.d/plugins` and `%APPDATA%/HashiCorp/Terraform/plugins`
273* **Mac OS X:** `$HOME/.terraform.d/plugins/`,
274  `~/Library/Application Support/io.terraform/plugins`, and
275  `/Library/Application Support/io.terraform/plugins`
276* **Linux and other Unix-like systems**:`$HOME/.terraform.d/plugins/`, and
277  [XDG Base Directory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
278  data directories as configured, after appending `terraform/plugins`.
279  Without any XDG environment variables set, Terraform will use
280  `~/.local/share/terraform/plugins`,
281  `/usr/local/share/terraform/plugins`, and `/usr/share/terraform/plugins`.
282
283Terraform will create an implied `filesystem_mirror` method block for each of
284the directories indicated above that exists when Terraform starts up.
285In addition, if a `terraform.d/plugins` directory exists in the current working
286directory, it will be added as a filesystem mirror.
287
288In addition to the zero or more implied `filesystem_mirror` blocks, Terraform
289also creates an implied `direct` block. Terraform will scan all of the
290filesystem mirror directories to see which providers are placed there and
291automatically exclude all of those providers from the implied `direct` block.
292(This automatic `exclude` behavior applies only to _implicit_ `direct` blocks;
293if you use explicit `provider_installation` you will need to write the intended
294exclusions out yourself.)
295
296### Provider Plugin Cache
297
298By default, `terraform init` downloads plugins into a subdirectory of the
299working directory so that each working directory is self-contained. As a
300consequence, if you have multiple configurations that use the same provider
301then a separate copy of its plugin will be downloaded for each configuration.
302
303Given that provider plugins can be quite large (on the order of hundreds of
304megabytes), this default behavior can be inconvenient for those with slow
305or metered Internet connections. Therefore Terraform optionally allows the
306use of a local directory as a shared plugin cache, which then allows each
307distinct plugin binary to be downloaded only once.
308
309To enable the plugin cache, use the `plugin_cache_dir` setting in
310the CLI configuration file. For example:
311
312```hcl
313plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
314```
315
316This directory must already exist before Terraform will cache plugins;
317Terraform will not create the directory itself.
318
319Please note that on Windows it is necessary to use forward slash separators
320(`/`) rather than the conventional backslash (`\`) since the configuration
321file parser considers a backslash to begin an escape sequence.
322
323Setting this in the configuration file is the recommended approach for a
324persistent setting. Alternatively, the `TF_PLUGIN_CACHE_DIR` environment
325variable can be used to enable caching or to override an existing cache
326directory within a particular shell session:
327
328```bash
329export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"
330```
331
332When a plugin cache directory is enabled, the `terraform init` command will
333still use the configured or implied installation methods to obtain metadata
334about which plugins are available, but once a suitable version has been
335selected it will first check to see if the chosen plugin is already available
336in the cache directory. If so, Terraform will use the previously-downloaded
337copy.
338
339If the selected plugin is not already in the cache, Terraform will download
340it into the cache first and then copy it from there into the correct location
341under your current working directory. When possible Terraform will use
342symbolic links to avoid storing a separate copy of a cached plugin in multiple
343directories.
344
345The plugin cache directory _must not_ also be one of the configured or implied
346filesystem mirror directories, since the cache management logic conflicts with
347the filesystem mirror logic when operating on the same directory.
348
349Terraform will never itself delete a plugin from the plugin cache once it has
350been placed there. Over time, as plugins are upgraded, the cache directory may
351grow to contain several unused versions which you must delete manually.
352
353-> **Note:** The plugin cache directory is not guaranteed to be concurrency
354safe. The provider installer's behavior in environments with multiple `terraform
355init` calls is undefined.
356
357### Development Overrides for Provider Developers
358
359-> **Note:** Development overrides work only in Terraform v0.14 and later.
360Using a `dev_overrides` block in your CLI configuration will cause Terraform
361v0.13 to reject the configuration as invalid.
362
363Normally Terraform verifies version selections and checksums for providers
364in order to help ensure that all operations are made with the intended version
365of a provider, and that authors can gradually upgrade to newer provider versions
366in a controlled manner.
367
368These version and checksum rules are inconvenient when developing a provider
369though, because we often want to try a test configuration against a development
370build of a provider that doesn't even have an associated version number yet,
371and doesn't have an official set of checksums listed in a provider registry.
372
373As a convenience for provider development, Terraform supports a special
374additional block `dev_overrides` in `provider_installation` blocks. The contents
375of this block effectively override all of the other configured installation
376methods, so a block of this type must always appear first in the sequence:
377
378```hcl
379provider_installation {
380
381  # Use /home/developer/tmp/terraform-null as an overridden package directory
382  # for the hashicorp/null provider. This disables the version and checksum
383  # verifications for this provider and forces Terraform to look for the
384  # null provider plugin in the given directory.
385  dev_overrides {
386    "hashicorp/null" = "/home/developer/tmp/terraform-null"
387  }
388
389  # For all other providers, install them directly from their origin provider
390  # registries as normal. If you omit this, Terraform will _only_ use
391  # the dev_overrides block, and so no other providers will be available.
392  direct {}
393}
394```
395
396With development overrides in effect, the `terraform init` command will still
397attempt to select a suitable published version of your provider to install and
398record in
399[the dependency lock file](/docs/language/dependency-lock.html)
400for future use, but other commands like
401`terraform apply` will disregard the lock file's entry for `hashicorp/null` and
402will use the given directory instead. Once your new changes are included in a
403published release of the provider, you can use `terraform init -upgrade` to
404select the new version in the dependency lock file and remove your development
405override.
406
407The override path for a particular provider should be a directory similar to
408what would be included in a `.zip` file when distributing the provider. At
409minimum that includes an executable file named with a prefix like
410`terraform-provider-null`, where `null` is the provider type. If your provider
411makes use of other files in its distribution package then you can copy those
412files into the override directory too.
413
414You may wish to enable a development override only for shell sessions where
415you are actively working on provider development. If so, you can write a
416local CLI configuration file with content like the above in your development
417directory, perhaps called `dev.tfrc` for the sake of example, and then use the
418`TF_CLI_CONFIG_FILE` environment variable to instruct Terraform to use that
419localized CLI configuration instead of the default one:
420
421```
422export TF_CLI_CONFIG_FILE=/home/developer/tmp/dev.tfrc
423```
424
425Development overrides are not intended for general use as a way to have
426Terraform look for providers on the local filesystem. If you wish to put
427copies of _released_ providers in your local filesystem, see
428[Implied Local Mirror Directories](#implied-local-mirror-directories)
429or
430[Explicit Installation Method Configuration](#explicit-installation-method-configuration)
431instead.
432
433This development overrides mechanism is intended as a pragmatic way to enable
434smoother provider development. The details of how it behaves, how to
435configure it, and how it interacts with the dependency lock file may all evolve
436in future Terraform releases, including possible breaking changes. We therefore
437recommend using development overrides only temporarily during provider
438development work.
439
440## Removed Settings
441
442The following settings are supported in Terraform 0.12 and earlier but are
443no longer recommended for use:
444
445* `providers` - a configuration block that allows specifying the locations of
446  specific plugins for each named provider. This mechanism is deprecated
447  because it is unable to specify a version number and source for each provider.
448  See [Provider Installation](#provider-installation) above for the replacement
449  of this setting in Terraform 0.13 and later.
450