Terraform override scenarios

Override files in Terraform are used to partially override existing configuration objects in separate files. Here are few key pointers to be noted:

  1. Override files are named with a suffix of _override.tf or _override.tf.json, and Terraform processes them after loading the regular configuration files.
  2. For each top-level block defined in an override file, Terraform merges the contents of the block into the corresponding object in the regular configuration files.
  3. Use override files sparingly and only in special circumstances, as overusing them can hurt the readability and maintainability of your code.
  4. When using override files, use comments in the original files to indicate which override files apply changes to each block.
  5. Override files can be used to override any Terraform object, including resources, modules, and data sources.

Here are a few scenarios considered when you override the existing configuration. The second column has a sample override file configuration for AWS VPC and you can see what will happen if this is applied to the Original configuration file.

FeatureSample Override file configurationOriginal file configurationFinal result
Top-level blockresource “aws_vpc” “vpc-new” {
    cidr_block = “172.16.0.0/16”
    enable_dns_hostnames = “true”
}
resource “aws_vpc” “vpc-new” {
    cidr_block = “10.0.0.0/16”
    enable_dns_hostnames = “false”
}
Merges with same block header;
Replaces attribute arguments
resource “aws_vpc” “vpc-new” {
    cidr_block = “172.16.0.0/16”
    enable_dns_hostnames = “true”
}
Blocks with attributes
defined
resource “aws_vpc” “vpc-new” {
    cidr_block = “172.16.0.0/16”
}
resource “aws_vpc” “vpc-new” {
    cidr_block = var.cidrblk
    enable_dns_hostnames = “false”
}
Replaces or merges attribute arguments
resource “aws_vpc” “vpc-new” {
    cidr_block = “172.16.0.0/16”
   enable_dns_hostnames = “false”
}
Nested blocksresource “aws_vpc” “vpc-new” {
    cidr_block = “172.16.0.0/16”
}
resource “aws_vpc” “vpc-new” {
    cidr_block = “192.168.0.0/16”
    lifecycle {
    create_before_destroy = true
  }
}
> +/- create replacement and then destroy but applies to the configuration provided in Override file; 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.
    
Lifecycle blockresource “aws_vpc” “vpc-new” {
    cidr_block = “192.168.0.0/16”
    lifecycle {
    ignore_changes = [ cidr_block, tags]
  } 
}
resource “aws_vpc” “vpc-new” {
    cidr_block = “10.0.0.0/16”
    enable_dns_hostnames = “false”
          lifecycle {
    create_before_destroy = true
  }
}
Merged arg by arg;  Ignores the relevant attributes using ignore_changes and make no changes
Lifecycle block-ignore changes
in the
original file
resource “aws_vpc” “vpc-new” {
    cidr_block = “192.168.0.0/16”
    lifecycle {
    create_before_destroy = true
  }
}
resource “aws_vpc” “vpc-new” {
    cidr_block = “10.0.0.0/16”
    lifecycle {
   ignore_changes = [ cidr_block, tags]
  }
}
If an override block sets only the create_before_destroy argument then any ignore_changes argument in the original block will be preserved.
Lifecycle blockresource “aws_vpc” “vpc-new” {
    cidr_block = “192.168.0.0/16”
          lifecycle {
    create_before_destroy = true
  }
}
resource “aws_vpc” “vpc-new” {
    cidr_block = var.cidrblk
    enable_dns_hostnames = “false”
          lifecycle {
    create_before_destroy = false
  }
}
Creates replacement and destroys the resource with cidr block of “192.168.0.0/16”
Provisioner and connection blockprovisioner “file” {
  source      = “conf/newapp.conf”
  destination = “/etc/newapp.conf”

  connection {
    type     = “ssh”
    user     = “root”
    password = “${var.root_password}”
    host     = “${var.host}”
  }
}
provisioner “file” {
  source      = “conf/myapp.conf”
  destination = “/etc/myapp.conf”

  connection {
    type     = “ssh”
    user     = “root”
    password = “${var.root_password}”
    host     = “${var.host}”
  }
}
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.
variable argumentvariable “cidrblk” {
    type = string
    default = “192.168.0.0/16”
}
variable “cidrblk” {
    type = string
    default = “10.0.0.0/16”
}
Value considered is 192.168.0.0/16; Variable argument overrides
Changes in variable type than the default value variable “xyz” {
  description = “Testing”
  type        = bool
}
variable “xyz” {
  description = “Testing”
  type        = string
  default = “yes”
}
Changes in variable type (here ‘boolean’) takes precedence than the default value
changes in default value should be compatiblevariable “enabledns” {
    type = bool
}
variable “enabledns” {
    type = string
    default = “false”
}
default = “false” will be considered since it is compatible with the bool type
Changes in variable type & default value variable “enabledns” {
    type = bool
    default = true
}
variable “enabledns” {
    type = string
    default = “false”
}
Changes in variable type default = true will be considered
required_providersterraform {
  required_providers {
    aws = {
      version = “~> 4.12.0”
    }
    random = {
      version = “>= 2.1.2”
    }
  }
}
terraform {
  required_providers {
    aws = {
      version = “~> 2.13.0”
    }
    random = {
      version = “>= 2.1.2”
    }
  }
}
value merged element by element
terraform {
  required_providers {
    aws = {
      version = “~> 4.12.0”
    }
    random = {
      version = “>= 2.1.2”
    }
  }
}
required_versionrequired_version = “~> 1.2.3”required_version = “~> 0.12.29”
The base block is ignored
required_version = “~> 1.2.3”
Varied Backendscloudbackendcloud takes precedence
Varied Backendsbackendcloudbackend takes precedence
    

error: Content is protected !!