Special arguments that modify, manages, and structures multiple resources
count
- Allows you to specify a number of instances for a resource. Example: Deploying five virtual machines with the same configurations
- assigns an index to reference each instance
- reference the resource using
<type>.<name>[index]
variable "vm_count" {
type = number
default = 3
}
resource "azurerm_virtual_machine" "example" {
count = var.vm_count # once defined count, can use count.index
name = "vm-${count.index}" # avoid same name error
location = "East US"
resource_group_name = "my-resource-group"
vm_size = "Standard_D2s_v3"
os_profile {
computer_name = "vm-${count.index}"
admin_username = "adminuser"
}
# You would also need os_profile_linux_config or windows_config,
# network_interface_ids, and storage_* blocks to make this complete.
}
for_each
Lets you create multiple resources dynamically from a map or set variable. Example: Deploying three VMS with different names instead of the same
- similar to count, but pulls in values from a map or set rather than a fixed number
- each resource get a unique key as a reference instead of arbitrary index
- ideal for managing unique configurations ⇒ stable even a resource is deleted
variable "vms" {
type = map(string)
default = {
vml = "Standard_B2ms"
vm2 = "Standard_D2s_v3"
vm3 = "Standard_D4s_v3"
}
}
resource "azurerm_virtual_machine" "vm" {
for_each = var.vms # point for_each to the map/set variable
name = each.key # call the key/value by using each.key/value
location = "East US"
resource_group_name = "my-resource-group"
vm_size = each.value
...
}
depends_on
Implicitly Terraform will try its best to figure out the dependency. This “depends_on” allow us to explicitly define that a resource must be created before another.
- Ensure correct provisioning order
- prevents race conditions for deployments Example: Ensure a database is provisioned before an app server
resource "aws_db_instance" "db" {
identifier = "imydb"
engine = "mysql"
instance_class = "db.t3.micro"
allocated_storage = 20
username = "admin"
password = "SuperSecurePassword123!"
skip_final_snapshot = true
}
resource "aws_instance" "app_server" {
ami = "ami-abcdef1234567890"
instance_type = "t2.micro"
depends_on = [
aws_db_instance.db,
aws_s3_bucket.logs,
aws_iam_role.app_role
]
}
provider
Specify what provider configuration to use Example: Assign resources to use a different provider block mapped to a second region
- explicitly assigns a resource to a specific provider config
- most often used for multi-cloud or multi account deployments (e.g. dev/ prod)
- Uses the
provider = <provider_alias>
, then the resource will be deployed using that provider block
Noted: If alias isn’t provided, that block would be the default provider
example - dev/ prod in different regions
provider "aws" {
alias = "dev"
region = "us-east-1"
}
provider "aws" {
alias = "prod"
region = "us-west-1"
}
resource "aws_s3_bucket" "dev_bucket" {
provider = aws.dev
bucket = "my-dev-bucket"
}
resource "aws_s3_bucket" "prod_bucket" {
provider = aws.prod
bucket = "my-prod-bucket"
}
lifecycle
Control how Terraform manages the lifecycle of the resource Example: Protect critical infrastructure or ensure that Terraform doesn ‘t replace resources unnecessarily
- protect resources/ avoid changes
- option include
prevent_destroy
(bool):- a safe lock
- setting of the previous run is saved in the state file, when the next run when the tf file has no that resource or requires replacement, it will throw an error
create_before_destroy
(bool):- By default, when there is changes terraform destroy the object first then recreate the resource with new config
- this option changes the order
ignore_changes
(list of attributes):- ignore the changes outside terraform (e.g. after manually change the config of the terraform-created resource)
- replace_triggered_by (list of resource/ attribute)
- force a resource to be replaced (destroyed and re-created) when another resource or attribute changes, even if the resource itself hasn’t changed