How to Dynamically Retrieve EC2 Instances IDs/Private IPs from ASG in Terraform to Trigger Ansible Tower Jobs?

Hello,

I am developing a Terraform module to automate the provisioning of EC2 instances using AWS Auto Scaling Groups (ASG) and to trigger Ansible Tower jobs for each dynamically created instance. The Ansible jobs enable compilance for the instances.

Problem

I am facing an issue where, during the Terraform plan, I get the following error:

Error: Invalid count argument
   on ../main.tf line 9, in resource "null_resource" "asg_instance_provisioning":
    9: count = length(data.aws_instances.auto_scaling_instances.ids)
   The "count" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created.

# Current Setup:

1. ASG Configuration: I am using the aws_autoscaling_group resource to create EC2 instances dynamically. The ASG assigns a tag with the group name to the instances.

2. Data Block to Fetch Instances: I’m using the following data block to fetch the EC2 instance details:

data "aws_instances" "asg_instances" {
  filter {
    name   = "tag:aws:autoscaling:groupName"
    values = [aws_autoscaling_group.ec2_asg.name]
  }
  depends_on = [aws_autoscaling_group.ec2_asg]
}

3. Local Variables for Ansible Tower: I generate custom names for the instances:

locals {
  vm_name                 = [for id in data.aws_instances.asg_instances.ids : lower(format("vm-%s", id))]
  vm_computer_name        = [for name in local.vm_name : substr(name, 0, 64)]
  vm_computer_object_name = [for name in local.vm_computer_name : substr(name, 0, 15)]
}

4 : Null Resource for Ansible Tower Jobs: The null_resource triggers the Ansible Tower job to register EC2 instances:

resource "null_resource" "asg_instance_provisioning" {
  count = length(data.aws_instances.auto_scaling_instances.ids)

  triggers = {
    auth_token     = var.auth_token
    inventory_id   = var.inventory_id
    instance_ip    = data.aws_instances.auto_scaling_instances.private_ips[count.index]
    instance_name  = lower(local.instance_names[count.index])
    domain_name    = lower(var.domain_name)
  }

  provisioner "local-exec" {
    environment = {
      AUTH_TOKEN = self.triggers.auth_token
    }
    command = "cli-tool job launch --token $AUTH_TOKEN --inventory ${self.triggers.inventory_id} --job-template=123 --extra-vars 'instance_ip=${self.triggers.instance_ip} domain=${self.triggers.domain_name} instance_name=${self.triggers.instance_name}'"
  }
}

Issue:

Terraform throws the error during the plan phase because the count value relies on attributes that aren’t available until the apply phase. This is because there isn’t a native Terraform attribute from the ASG resource to directly get the EC2 instance IDs and private IPs at the planning stage.

Question

How can I dynamically retrieve the EC2 instance IDs and private IPs from the Auto Scaling Group in a way that can be used during the plan phase, allowing the null_resource to trigger Ansible Tower jobs?

I’m looking for any workaround or alternate approach to handle this. I need to ensure that my null_resource triggers the Ansible jobs for all the EC2 instances created by ASG without running into this issue.

Any help or suggestions would be greatly appreciated!