Using Meta-Arguments
1. Using depends_on Meta-Argument
| Property | Description | Usage |
|---|---|---|
| depends_on | Ensures that a resource is created or destroyed before another resource. | depends_on = [aws_instance.web, aws_instance.db] |
Example: Using depends_on to enforce resource order
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
depends_on = [aws_instance.db]
}
resource "aws_instance" "db" {
ami = "ami-87654321"
instance_type = "t2.micro"
}
Note:
depends_on is not recommended for most use cases as it can lead to complex dependency graphs and reduce Terraform's ability to safely execute operations in parallel.
2. Using count Meta-Argument
The count meta-argument is used to create multiple instances of a resource or module based on a numeric value.
| Property | Description | Values |
|---|---|---|
| count | Defines the number of instances to create | number |
Example: Creating Multiple Instances
resource "aws_instance" "web" {
count = 3
ami = "ami-12345678"
instance_type = "t2.micro"
}
Example: Using count with a Variable
variable "instance_count" {
type = number
default = 2
}
resource "aws_instance" "web" {
count = var.instance_count
ami = "ami-12345678"
instance_type = "t2.micro"
}
Note: When using
count, each instance has a unique index starting from 0, accessible via count.index.
Warning: Changing the value of
count will cause Terraform to destroy and recreate resources, potentially leading to data loss.
Key Points
countcreates multiple instances of a resource or module.- Each instance is accessible via
count.index. - Changing the value of
counttriggers a full recreation of resources.
3. Using for_each Meta-Argument
The for_each meta-argument allows you to create multiple instances of a resource or module based on a map or set of strings. It's particularly useful for creating multiple similar resources with different configurations.
| Property | Description | Example |
|---|---|---|
| for_each | Map or set of strings to iterate over. Each key-value pair creates a new instance. | for_each = { env1 = "prod", env2 = "staging" } |
Example: Creating Multiple S3 Buckets
resource "aws_s3_bucket" "bucket" {
for_each = {
prod = "production"
staging = "staging"
}
bucket = "my-app-${each.key}"
tags = {
Environment = each.value
}
}
Note: When using
for_each, the resource instances are created in the order of keys in the map. If you're using a set, the order is not guaranteed.
Example: Using for_each with Modules
module "web_server" {
for_each = {
us_west = { region = "us-west-2", instance_type = "t3.micro" }
us_east = { region = "us-east-1", instance_type = "t3.small" }
}
source = "./web_server_module"
region = each.value.region
instance_type = each.value.instance_type
}
Key Points
for_eachcreates multiple instances of a resource or module.- It accepts a map or set of strings as input.
- Each instance can be accessed using
each.keyandeach.value. - Resources created with
for_eachare managed as a list, not a single resource.
4. Using provider Meta-Argument
| Property | Description | Values | Notes |
|---|---|---|---|
| provider | Specifies the provider to use for a resource or data source | aws, google, azurerm, etc. |
Required for all resources and data sources |
| version | Specifies the version of the provider to use | >= 3.0.0, = 4.0.0 |
Ensures consistent provider behavior across environments |
| alias | Allows multiple instances of the same provider with different configurations | alias = "us_west" |
Useful for managing multiple regions or accounts |
Example: Using provider alias
provider "aws" {
alias = "us_west"
region = "us-west-2"
}
resource "aws_instance" "web" {
provider = aws.us_west
ami = "ami-12345678"
instance_type = "t2.micro"
}
Note: The
provider meta-argument is used to associate a resource or data source with a specific provider configuration. When using aliases, the provider attribute must reference the alias name.
5. Using lifecycle Meta-Argument
| Property | Description | Values | Notes |
|---|---|---|---|
| create_before_destroy | Controls the order of operations during updates | true or false |
If true, creates new resource before destroying old one. Default is false. |
| prevent_destroy | Prevents destruction of the resource | true or false |
If true, Terraform will block destruction of the resource. Useful for critical resources like databases. |
| ignore_changes | Specifies attributes to ignore during updates | List of attribute paths or [all] |
Can be used to ignore changes made outside of Terraform. Example: ["tags", "labels"]. |
Example: Using lifecycle with prevent_destroy
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-unique-bucket-name"
lifecycle {
prevent_destroy = true
}
}
Example: Using lifecycle with ignore_changes
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
lifecycle {
ignore_changes = [tags]
}
}
Note: The
ignore_changes option is useful when external tools or manual changes update attributes that you don't want Terraform to manage.
6. Understanding create_before_destroy
| Property | Description | Values | Notes |
|---|---|---|---|
| create_before_destroy | Controls the lifecycle behavior of a resource during updates | true or false |
When set to true, Terraform will create the new resource before destroying the old one. Default is false. |
Example: Using create_before_destroy
resource "aws_instance" "web" {
create_before_destroy = true
ami = "ami-12345678"
instance_type = "t2.micro"
}
Note: Enabling
create_before_destroy can cause downtime in some cases, particularly when updating resources that do not support in-place updates.7. Understanding prevent_destroy
| Argument | Description | Values | Notes |
|---|---|---|---|
| prevent_destroy | Prevents destruction of the resource during a terraform destroy operation | false | true |
Defaults to false. When set to true, Terraform will block destruction of the resource. |
Example: Using prevent_destroy
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-unique-bucket-name"
prevent_destroy = true
}
Note: Setting
prevent_destroy to true does not prevent the resource from being removed from state, but it prevents Terraform from destroying the resource in the cloud.
8. Understanding ignore_changes
| Argument | Description | Values | Notes |
|---|---|---|---|
| ignore_changes | Prevents Terraform from managing changes to specified attributes | list(string) |
Useful for external modifications to resources |
Example: ignore_changes in a resource block
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
lifecycle {
ignore_changes = [
tags,
ami
]
}
}
Note:
ignore_changes does not prevent Terraform from detecting changes in the configuration itself, only in the resource state.9. Using precondition and postcondition
| Argument | Description | Required | Example |
|---|---|---|---|
| precondition | Defines a condition that must be true before a resource is created or updated. | No | |
| postcondition | Defines a condition that must be true after a resource is created or updated. | No | |
Example: Using precondition and postcondition in a resource
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
precondition {
condition = self.instance_type != "t3.micro"
error_message = "t3.micro is not allowed for this deployment."
}
postcondition {
condition = self.private_ip != null
error_message = "Private IP must be assigned after creation."
}
}
Note: Precondition and postcondition checks are evaluated during
terraform plan and terraform apply. They do not run during terraform destroy.10. Using replace_triggered_by
| Argument | Description | Usage |
|---|---|---|
| replace_triggered_by | Triggers replacement of a resource when another resource's attribute changes. | replace_triggered_by = [aws_instance.old_instance] |
Example: Triggering Resource Replacement
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "t2.micro"
# Replace this instance when the AMI ID changes
replace_triggered_by = [aws_ami.example]
}
resource "aws_ami" "example" {
name = "custom-ami"
virtualization_type = "hvm"
architecture = "x86_64"
root_device_type = "ebs"
}
Note: The
replace_triggered_by meta-argument is useful for managing dependencies between resources where a change in one should cause a replacement of another.