count (int) - The number of identical resources to create. This doesn’t apply to all resources. For details on using variables in conjunction with count, see Using Variables with count below.
TL;DR: only use the count attribute to enable resources.
Basic example
The count attribute can be used to instantiate multiple resources with a single resource declaration. Here we instanciate 10 EC2 instances:
Eg:
resource "aws_instance" "web" {
  count         = 10
  ami           = "ami-0cdba8e998f076547"
  instance_type = "t2.micro"
}On the surface it looks useful but it suffers from a number of limitations that make it almost useless.
Pattern: enable attribute
This is pretty much the only viable use-case for the count attribute. Use count = 0 to disable a resource and count = 1 to enable it.
Even then, evaluation might fail if the resource is disabled and another resource depends on it’s outputs.
Eg:
variable "enable_elb" {
  default = 1
}
resource "aws_elb" "bar" {
  count              = "${var.enable_elb}"
  name               = "foobar-terraform-elb"
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
  listener {
    instance_port     = 8000
    instance_protocol = "http"
    lb_port           = 80
    lb_protocol       = "http"
  }
  instances                   = ["${aws_instance.web.id}"]
  cross_zone_load_balancing   = true
  idle_timeout                = 400
  connection_draining         = true
  connection_draining_timeout = 400
}Anti-pattern: avoid repetition
Forget DRY with Terraform. Copy-and-paste is your friend :slight_smile:
This is a natural usage of count. Don’t do this:
variable "users" {
  type = "list"
}
resource "aws_iam_user" "my-users" {
  count = "${length(var.users)}"
  name = "${element(var.users, count.index)}"
  path = "/"
}Let’s say I instantiace that module with:
module "my-users" {
  source = "../tf_my_users"
  users = [
    "bob",
    "alice",
    "jannet",
  ]
}This will work great on the first invocation. The problem is that each aws_iam_user is actually a different resource.
Let’s say that later that bob leaves the company.
aws_iam_user.my-users.0 "bob" => "alice"
aws_iam_user.my-users.1 "alice" => "jannet"
aws_iam_user.my-users.2 "jannet" => ""All the users get re-created, invalidating their AWS credentials. With bad luck your current AWS account might be in that list.
So in conclusion, Terraform deals with individual resources. Having them tied to a specific ordering is quite a bad idea as it makes the application of those resource inflexible.
For that use-case it’s better to copy-and-paste the IAM user. Or write a script that generates the terraform code from the list of users.