diff --git a/website/docs/configuration/override.html.md b/website/docs/configuration/override.html.md index 0d497f6e15..523a2c2b44 100644 --- a/website/docs/configuration/override.html.md +++ b/website/docs/configuration/override.html.md @@ -1,47 +1,55 @@ --- layout: "docs" -page_title: "Overrides" +page_title: "Override Files" sidebar_current: "docs-config-override" description: |- - Terraform loads all configuration files within a directory and appends them together. Terraform also has a concept of overrides, a way to create files that are loaded last and merged into your configuration, rather than appended. + Override files allow additional settings to be merged into existing + configuration objects. --- -# Overrides +# Override Files -Terraform loads all configuration files within a directory and -appends them together. Terraform also has a concept of _overrides_, -a way to create files that are loaded last and _merged_ into your -configuration, rather than appended. +Terraform normally loads all of the `.tf` and `.tf.json` files within a +directory and expects each one to define a distinct set of configuration +objects. If two files attempt to define the same object, Terraform returns +an error. -Overrides have a few use cases: +In some rare cases, it is convenient to be able to override specific portions +of an existing configuration object in a separate file. For example, a +human-edited configuration file in the Terraform language native syntax +could be partially overridden using a programmatically-generated file +in JSON syntax. - * Machines (tools) can create overrides to modify Terraform - behavior without having to edit the Terraform configuration - tailored to human readability. +For these rare situations, Terraform has special handling of any configuration +file whose name ends in `_override.tf` or `_override.tf.json`. This special +handling also applies to a file named literally `override.tf` or +`override.tf.json`. - * Temporary modifications can be made to Terraform configurations - without having to modify the configuration itself. +Terraform initially skips these _override files_ when loading configuration, +and then afterwards processes each one in turn (in lexicographical order). For +each top-level block defined in an override file, Terraform attempts to find +an already-defined object corresponding to that block and then merges the +override block contents into the existing object. -Overrides names must be `override` or end in `_override`, excluding -the extension. Examples of valid override files are `override.tf`, -`override.tf.json`, `temp_override.tf`. - -Override files are loaded last in alphabetical order. - -Override files can be in Terraform syntax or JSON, just like non-override -Terraform configurations. +Use override files only in special circumstances. Over-use of override files +hurts readability, since a reader looking only at the original files cannot +easily see that some portions of those files have been overridden without +consulting all of the override files that are present. When using override +files, use comments in the original files to warn future readers about which +override files apply changes to each block. ## Example -If you have a Terraform configuration `example.tf` with the contents: +If you have a Terraform configuration `example.tf` with the following contents: ```hcl resource "aws_instance" "web" { - ami = "ami-408c7f28" + instance_type = "t2.micro" + ami = "ami-408c7f28" } ``` -And you created a file `override.tf` with the contents: +...and you created a file `override.tf` containing the following: ```hcl resource "aws_instance" "web" { @@ -49,6 +57,98 @@ resource "aws_instance" "web" { } ``` -Then the AMI for the one resource will be replaced with "foo". Note -that the override syntax can be Terraform syntax or JSON. You can -mix and match syntaxes without issue. +Terraform will merge the latter into the former, behaving as if the original +configuration had been as follows: + +```hcl +resource "aws_instance" "web" { + instance_type = "t2.micro" + ami = "foo" +} +``` + +## Merging Behavior + +The merging behavior is slightly different for each block type, and some +special constructs within certain blocks are merged in a special way. + +The general rule, which applies in most cases, is: + +* A top-level block in an override file merges with a block in a normal + configuration file that has the same block header. The block _header_ is the + block type and any quoted labels that follow it. + +* Within a top-level block, an attribute argument within an override block + replaces any argument of the same name in the original block. + +* Within a top-level block, any nested blocks within an override block replace + _all_ blocks of the same type in the original block. Any block types that + do not appear in the override block remain from the original block. + +* The contents of nested configuration blocks are not merged. + +* The resulting _merged block_ must still comply with any validation rules + that apply to the given block type. + +If more than one override file defines the same top-level block, the overriding +effect is compounded, with later blocks taking precedence over earlier blocks. +Overrides are processed in order first by filename (in lexicographical order) +and then by position in each file. + +The following sections describe the special merging behaviors that apply to +specific arguments within certain top-level block types. + +### Merging `resource` and `data` blocks + +Within a `resource` block, the contents of any `lifecycle` nested block are +merged on an argument-by-argument basis. For example, if an override block +sets only the `create_before_destroy` argument then any `ignore_changes` +argument in the original block will be preserved. + +If an overriding `resource` block contains one or more `provisioner` blocks +then any `provisioner` blocks in the original block are ignored. + +If an overriding `resource` block contains a `connection` block then it +completely overrides any `connection` block present in the original block. + +The `depends_on` meta-argument may not be used in override blocks, and will +produce an error. + +### Merging `variable` blocks + +The arguments within a `variable` block are merged in the standard way +described above, but some special considerations apply due to the interactions +between the `type` and `default` arguments. + +If the original block defines a `default` value and an override block changes +the variable's `type`, Terraform attempts to convert the default value to +the overridden type, producing an error if this conversion is not possible. + +Conversely, if the original block defines a `type` and an override block changes +the `default`, the overridden default value must be compatible with the +original type specification. + +### Merging `output` blocks + +The `depends_on` meta-argument may not be used in override blocks, and will +produce an error. + +### Merging `locals` blocks + +Each `locals` block defines a number of named values. Overrides are applied +on a value-by-value basis, ignoring which `locals` block they are defined in. + +### Merging `terraform` blocks + +The settings within `terraform` blocks are considered individually when +merging. + +If the `required_providers` argument is set, its value is merged on an +element-by-element basis, which allows an override block to adjust the +constraint for a single provider without affecting the constraints for +other providers. + +In both the `required_version` and `required_providers` settings, each override +constraint entirely replaces the constraints for the same component in the +original block. If both the base block and the override block both set +`required_version` then the constraints in the base block are entirely ignored.