How should I define this output?

I have the following aws_instance definition which works fine. Most annoying is the fact that I can’t get the right syntax to output the public_ip for each instance produced… Here is what I’ve got:

  1 resource "aws_instance" "nginx" {
  2   for_each = aws_subnet.archer-public
  3   ami           = var.AMIS[var.AWS_REGION]
  4   instance_type = "t2.micro"
  7   subnet_id = each.value.id
 10   vpc_security_group_ids = [aws_security_group.allow-ssh.id]
 13   key_name = aws_key_pair.archerkeypair.key_name
 15   monitoring = true
 19   tags = {
 20     Name  = "archer-nginx}"
 21   }
 24 }
 25
 26 output "nginx public_ip" {
 27   value = aws_instance.nginx[0].public_ip   <==== this doesn't work!
 28 }
 29

How can I properly specify the syntax to print out the public_ip of each EC2 instance created? I’ve tried:
aws_instance.nginx[0].public_ip
aws_instance.nginx[ * ].public_ip
aws_instance.nginx.*.public_ip

… I can’t get it right…

Hi @jjtdepaul,

When you use for_each, the aws_instance.nginx reference produces a map whose keys are the same as the keys in your aws_subnet.archer-public. Since I can’t see what the keys of that are I can’t show a fully-working example, but if you want to return a particular instance’s IP address then you’ll need to use its key to identify it:

output "nginx public_ip" {
  value = aws_instance.nginx["nginx"].public_ip
}

Another option is to collect all of the IP addresses together into a single map, again using the same keys as from aws_subnet.archer-public and aws_instance.nginx:

output "nginx_public_ips" {
  value = { for k, inst in aws_instance.nginx : k => inst.public_ip }
}

This second example is using a for expression to derive a simpler map (a map of strings) from the map of objects that the resource "aws_instance" "nginx" block naturally produces.

Here is my aws_instance.nginx map from terraform console (I’ve trimmed a bunch of attributes for brevity):

> aws_instance.nginx
{
  "pub_a" = {
    "ami" = "ami-fef48b86"
    "arn" = "arn:aws:ec2:us-west-2:361879417564:instance/i-030ab0a27fb7bb5af"
    "associate_public_ip_address" = true
    "availability_zone" = "us-west-2a"
    "public_ip" = "52.36.188.142"
    "vpc_security_group_ids" = [
      "sg-013eb859d4dddc22c",
    ]
  }
  "pub_b" = {
    "ami" = "ami-fef48b86"
    "arn" = "arn:aws:ec2:us-west-2:361879417564:instance/i-0e43b21b421cf9c7c"
    "associate_public_ip_address" = true
    "availability_zone" = "us-west-2b"
    "public_ip" = "34.208.120.98"
    "vpc_security_group_ids" = [
      "sg-013eb859d4dddc22c",
    ]
  }
  "pub_c" = {
    "ami" = "ami-fef48b86"
    "arn" = "arn:aws:ec2:us-west-2:361879417564:instance/i-015bdaa2539111c92"
    "associate_public_ip_address" = true
    "availability_zone" = "us-west-2c"
    "public_ip" = "54.189.126.117"
    "vpc_security_group_ids" = [
      "sg-013eb859d4dddc22c",
    ]
  }
}

Here is the construct that finally worked for me:

 1 output "nginx" {
  2   value = {
  3     for instance in aws_instance.nginx:
  4     instance.id => instance.public_ip
  5   }
  6 }

Not sure why but I couldn’t get your 2nd example to work for me… I kept getting this error:

Error: Extra characters after expression