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