- Welcome my DevOps blog./
- š°Posts/
- šļøMy Trainings/
- Terraform Trainings and Certifications/
- Terraform on AWS with SRE & IaC DevOps/
- Terraform: Loops, Meta-Arguments, Splat Operator and Functions/
Terraform: Loops, Meta-Arguments, Splat Operator and Functions
Table of Contents
Meta-arguments are a class of arguments built into the Terraform configuration language that control how Terraform creates and manages your infrastructure. You can use meta-arguments in any type of resource. You can also use most meta-arguments inĀ moduleĀ blocks.
More info: https://developer.hashicorp.com/terraform/language/meta-arguments
depends_on #
TheĀ depends_onĀ meta-argument instructs Terraform to complete all actions on the dependency object, includingĀ readĀ operations, before performing actions on the object declaring the dependency. Use theĀ depends_onĀ argument to explicitly set the order in which Terraform creates resources. Refer to theĀ depends_onĀ referenceĀ for details.
count #
By default, Terraform configures one infrastructure object for eachĀ resource,Ā module, andĀ ephemeralĀ block. Terraform also creates single instances of a module perĀ moduleĀ block. You can add theĀ countĀ argument toĀ resource,Ā module, andĀ ephemeralĀ blocks to create and manage multiple instances of each without writing a separate block for each instance. Refer to theĀ countĀ referenceĀ for details.
for_each #
By default, Terraform configures one infrastructure object for eachĀ resource,Ā module, andĀ ephemeralĀ block. You can add theĀ for_eachĀ block to yourĀ resource,Ā data,Ā module, andĀ ephemeralĀ blocks to create and manage several similar objects, such as a fixed pool of compute instances, without writing a separate block for each instance. Refer to theĀ for_eachĀ referenceĀ for details.
š File: c5-ec2instance.tf
| |
More about for_each:
lifecycle #
TheĀ lifecycleĀ block accepts a rule that customizes how Terraform performs the lifecycle stages for each resource. Support for eachĀ lifecycleĀ rule varies across Terraform configuration blocks. Refer to theĀ lifecycleĀ referenceĀ for details.
provider #
By default, Terraform determines the local name of the provider from the first word in the resource type and uses that provider’s default configuration to create the resource. You can add multipleĀ providerĀ blocks to your configuration and use theĀ providerĀ argument to a resource definition to specify which provider it should use. Refer to theĀ providerĀ referenceĀ for details.
providers #
By default, child modules inherit the default provider configurations of their parent module. You can specify an alternate provider configuration in theĀ moduleĀ block using theĀ providersĀ argument. TheĀ providersĀ argument instructs Terraform to use the reference provider configuration to create the module resources. Refer to theĀ providersĀ referenceĀ for details.
Variable List and Map #
š File: c2-variables.tf
# INFO: Redefining "instance_type" variable to use List and / or Map
# INFO: EC2 Instance Type - List
variable "instance_type_list" {
description = "EC2 Instance Type(List)"
type = list(string) # NOTE: Define list of strings variable type
default = ["t3.nano", "t3.micro"] # NOTE: (Multiple) default values
}
# INFO: EC2 Instance Type - Map
variable "instance_type_map" {
description = "EC2 Instance Type(Map)"
type = map(string) # NOTE: Define map of strings
default = {
"dev" = "t3.nano" # NOTE: Define default string for dev
"qa" = "t3.micro" # NOTE: Define default string for qa
"prod" = "t3.small" # NOTE: Define default string for prod
}
}
š File: c5-ec2instance.tf
# INFO: Create EC2 Instance
# INFO: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#example-usage
# EC2 Instance
resource "aws_instance" "myec2vm" {
ami = data.aws_ami.amzlinux2.id
# NOTE: Referencing List and Map variables
#instance_type = var.instance_type
#instance_type = var.instance_type_list[1] # NOTE: Accessing variable of a type "list"
instance_type = var.instance_type_map["dev"] # NOTE: Accessing variable of a type "map"
user_data = file("${path.module}/app1-install.sh") # NOTE: Apply User Data
key_name = var.instance_keypair # NOTE: Attach Key-Pair ID
vpc_security_group_ids = [ # NOTE: Attach INGRESS SG
aws_security_group.vpc-ssh.id,
aws_security_group.vpc-web-80.id,
aws_security_group.vpc-web-443.id,
aws_security_group.vpc-egress.id # NOTE: Attach EGRESS SG
]
count = "2" # NOTE: Add count Meta-Argument to create a number of the same resoure type
tags = {
"Name" = "Count Demo ${count.index}" # NOTE: Update the name to reflect "count.index" to iterate
"Description" = "Variable Lists, Maps and Meta-Arguments"
}
}
Drawbacks of using count in this example
- Resource Instances in this case were identified using index numbers instead of string values like actual
subnet_id - If an element was removed from the middle of the list, every instance after that element would see its
subnet_idvalue change, resulting in more remote object changes than intended - Even the
subnet_idsshould be pre-defined or we need to get them again usingfor_eachor for using variousdatasources - Using
for_eachgives the same flexibility without the extra churn
For Loops and Splat Operators in Outputs #
š File: c6-outputs.tf
# INFO: Terraform Output Values
# INFO: https://developer.hashicorp.com/terraform/language/block/output
/* Concepts Covered
1. For Loop with List
2. For Loop with Map
3. For Loop with Map Advanced
4. Legacy Splat Operator (latest) - Returns List
5. Latest Generalized Splat Operator - Returns the List
*/
# Output - For Loop with List
output "for_output_list" {
description = "For Loop with List"
value = [for instance in aws_instance.myec2vm : instance.public_dns] # NOTE: Accessing list via square brackets
}
# Output - For Loop with Map
output "for_output_map1" {
description = "For Loop with Map"
value = {
for instance in aws_instance.myec2vm : instance.id => instance.public_dns # NOTE: Accessing map via "flower" brackets. Maps are key-value.
}
}
# Output - For Loop with Map Advanced
output "for_output_map2" {
description = "FOr Loop with Map - Advanced"
value = {
for c, instance in aws_instance.myec2vm : c => instance.public_dns # NOTE: For c means for each count (like count.index)
}
}
# Output Legacy Splat Operator (Legacy) - Returns the List
/*
output "legacy_splat_instance_publicdns" {
description = "Legacy Splat Operator"
value = aws_instance.myec2vm.*.public_dns
}
*/
# Output Latest Generalized Splat Operator - Returns the List
output "latest_splat_instance_publicdns" {
description = "Generalized latest Splat Operator"
value = aws_instance.myec2vm[*].public_dns
}
» Sources « #
Terraform:
availability_zones datasource
Kalyanās GitHub Repositories:
» Disclaimer « #
This series draws heavily from Kalyan Reddy Daida’s Terraform on AWS with SRE & IaC DevOps course on Udemy.
His content was a game-changer in helping me understand Terraform.
| About the instructor | |
|---|---|
| š Website | šŗ YouTube |
| š¼ LinkedIn | šļø GitHub |