Mastering Loops and Conditionals in Terraform

🎉This article, will explain in detail how to implement conditional logic within your Terraform configurations to control resource deployments based on input variables or specific criteria🎉

🎃Synopsis:

🎈 Understand how to implement conditional logic within your Terraform configurations to control resource deployments based on input variables or specific criteria.


🎃Conditionals:

🎈In addition to loops, Terraform allows you to control the deployment of resources conditionally based on input variables or other criteria. Conditional logic helps you manage different environments or configurations dynamically.

count parameter Used for conditional resources

for_each and for expressions Used for conditional resources and inline blocks within a resource

if string directive Used for conditionals within a string


🎃Conditionals with the count Parameter:

🎈If you set count to 1 on a resource, you get one copy of that resource; if you set count to 0, that resource is not created at all.

🎈Terraform supports conditional expressions of the format. This ternary syntax, which may be familiar to you from other programming languages, will evaluate the Boolean logic in CONDITION, and if the result is true, it will return TRUE_VAL, and if the result is false, it’ll return FALSE_VAL.

<CONDITION> ? <TRUE_VAL> : <FALSE_VAL>
 resource "aws_autoscaling_schedule" "scale_out_during_business_hours" {
  count = var.enable_autoscaling ? 1 : 0
  scheduled_action_name  = "${var.cluster_name}-scale-out-during-business-hours"
  min_size = 2              
  max_size = 10              
  desired_capacity  = 10      
  recurrence = "0 9 * * *"             
  autoscaling_group_name = aws_autoscaling_group.example.name
 }

🎃If-else-statements with the count parameter:

🎈Several IAM users with read-only access to EC2. Imagine that you wanted to give one of these users, neo, access to Cloudwatch as well but allow the person applying the Terraform configurations to decide whether neo is assigned only read access or both read and write access.

IAM Policy that allows read-only access to CloudWatch

resource "aws_iam_policy" "cloudwatch_read_only" {
  name = "cloudwatch-read-only"  
  policy = data.aws_iam_policy_document.cloudwatch_read_only.json
 }

 data "aws_iam_policy_document" "cloudwatch_read_only" {
 statement {
    effect = "Allow"   
    actions  = [   
        "cloudwatch:Describe*",
        "cloudwatch:Get*",
        "cloudwatch:List*"
     ]  
    resources = ["*"]
  }
 }

IAM Policy that allows full (read and write) access to CloudWatch

 resource "aws_iam_policy" "cloudwatch_full_access" {
  name = "cloudwatch-full-access"   
  policy = data.aws_iam_policy_document.cloudwatch_full_access.json
 }
 data "aws_iam_policy_document" "cloudwatch_full_access" {
 statement {
    effect = "Allow"    
    actions  = ["cloudwatch:*"]  
    resources = ["*"]
  }
 }

you can use the count parameter and a conditional expression on each of the resources:

 resource "aws_iam_user_policy_attachment" "neo_cloudwatch_full_access" {
  count = var.give_neo_cloudwatch_full_access ? 1 : 0
  user = aws_iam_user.example[0].name      
  policy_arn = aws_iam_policy.cloudwatch_full_access.arn
 }
 resource "aws_iam_user_policy_attachment" "neo_cloudwatch_read_only" {
  count = var.give_neo_cloudwatch_full_access ? 0 : 1
  user = aws_iam_user.example[0].name      
  policy_arn = aws_iam_policy.cloudwatch_read_only.arn
 }

🎃Conditionals with for_each and for Expressions:

🎈If you pass a for_each expression an empty collection, the result will be zero copies of the resource, inline block, or module where you have the for_each; if you pass it a nonempty collection, it will create one or more copies of the resource, inline block, or module. The answer is to combine the for_each expression with the for expression.

dynamic "tag" {
    for_each = {
         for key, value in var.custom_tags:
         key => upper(value)
         if key != "Name"
    }
 content {
      key = tag.key                
      value  = tag.value              
      propagate_at_launch = true
    }
  }

🕵🏻I also want to express that your feedback is always welcome. As I strive to provide accurate information and insights, I acknowledge that there’s always room for improvement. If you notice any mistakes or have suggestions for enhancement, I sincerely invite you to share them with me.

🤩 Thanks for being patient and following me. Keep supporting 🙏

Clap👏 if you liked the blog.

For more exercises — please follow me below ✅!

vjraghavanv.hashnode.dev

#aws #terraform #cloudcomputing #IaC #DevOps #tools #operations #30daytfchallenge #HUG #hashicorp #HUGYDE #IaC #developers #awsugmdu #awsugncr #automatewithraghavan

0
Subscribe to my newsletter

Read articles from vijayaraghavan vashudevan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

vijayaraghavan vashudevan
vijayaraghavan vashudevan

I'm Vijay, a seasoned professional with over 13 years of expertise. Currently, I work as a Quality Automation Specialist at NatWest Group. In addition to my employment, I am an "AWS Community Builder" in the Serverless Category and have served as a volunteer in AWS UG NCR Delhi and AWS UG MDU, a Pynt Ambassador (Pynt is an API Security Testing tool), and a Browserstack Champion. Actively share my knowledge and thoughts on a variety of topics, including AWS, DevOps, and testing, via blog posts on platforms such as dev.to and Medium. I always like participating in intriguing discussions and actively contributing to the community as a speaker at various events. This amazing experience provides me joy and fulfillment! 🙂