Terraform version:
Terraform v0.11.8
+ provider.aws v1.33.0
Terraform Apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ aws_eip_association.stage-eip-assoc
id: <computed>
allocation_id: "eipalloc-some-specific-id"
instance_id: "${aws_instance.stage.id}"
network_interface_id: <computed>
private_ip_address: <computed>
public_ip: <computed>
+ aws_instance.stage
id: <computed>
ami: "ami-some-ami"
arn: <computed>
associate_public_ip_address: <computed>
availability_zone: <computed>
cpu_core_count: <computed>
cpu_threads_per_core: <computed>
ebs_block_device.#: <computed>
ephemeral_block_device.#: <computed>
get_password_data: "false"
instance_state: <computed>
instance_type: "t2.micro"
ipv6_address_count: <computed>
ipv6_addresses.#: <computed>
key_name: <computed>
network_interface.#: <computed>
network_interface_id: <computed>
password_data: <computed>
placement_group: <computed>
primary_network_interface_id: <computed>
private_dns: <computed>
private_ip: <computed>
public_dns: <computed>
public_ip: <computed>
root_block_device.#: <computed>
security_groups.#: <computed>
source_dest_check: "true"
subnet_id: <computed>
tenancy: <computed>
volume_tags.%: <computed>
vpc_security_group_ids.#: <computed>
Plan: 2 to add, 0 to change, 0 to destroy.
My config:
provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}
resource "aws_instance" "stage" {
ami = "ami-some-ami"
instance_type = "t2.micro"
provisioner "local-exec" {
command = "echo ${aws_instance.stage.public_ip} > ip_address.txt"
}
}
resource "aws_eip_association" "stage-eip-assoc" {
instance_id = "${aws_instance.stage.id}"
allocation_id = "eipalloc-some-specific-id"
}
# Output variables.
output "ip" {
value = "${aws_instance.stage.public_ip}"
}
Steps to reproduce
Already have Elastic IP created on AWS, then include it via its allocation_id to associate with AWS instance that is to be created.
Then output public IP of instance.
It does output me some different IP than it is assigned. I did not even find such IP anywhere on my AWS instances. Though it does assign correct EIP on created instance.
Update:
What is interesting too, is that if I run terraform apply again, it will output correct IP. I guess it returns correct IP when EIP is already assigned on EC2 instance. Though if it is being assigned on creation, then it probably outputs default IP that instance would get if no EIP would be associated?
P.S sorry, but I accidentally removed pre format of issue, and now it gives me empty message as init message (instead of your preformated one).
Hi @oerp-odoo 👋 This is an ordering problem. Here's what should be happening with that configuration:
public_ip)The problem is that the output referencing aws_instance.stage.public_ip will read the public_ip attribute of the aws_instance as it was saved in the Terraform state, before the EIP association ever happened. As you surmised, re-running the output will show the "correct" public_ip the next run because Terraform will refresh the details of the EC2 instance and the EC2 API will report back that its public_ip is the EIP IP.
To ensure your configuration outputs the EIP the first run, you will need to reference the aws_eip_association:
output "ip" {
value = "${aws_eip_association.stage-eip-assoc.public_ip}"
}
I also run into this issue, and I think it would be helpful to fix. Because of this it doesn't seem possible to standardized a workflow for knowing that a public ip is actually correct. you have to consider edge cases if an eip is used.
There is public ip data that actually doesn't exist anymore under the aws_instance.
This can mess with terraform inventory if later provisioning is occuring with something like Ansible and you require a standard method for knowing a public IP of an instance.
+1 to a fix for this problem, azure and google cloud handle the static ip association and subsequent output just fine. It's exclusive to AWS as far as I can tell. The terraform plugin should probably be forcing an update after an association, and I'm having to write some really dirty workaround logic
Thank you for using Terraform and for opening up this question, @oerp-odoo. Issues on GitHub are intended to be related to bugs or feature requests with the provider codebase. A solution has been provided in this thread. Please use https://discuss.hashicorp.com/c/terraform-providers if additional feedback is needed, for community discussions, and questions around Terraform.
If you believe that your issue was miscategorized as a question or closed in error, please create a new issue using one of the following provided templates: bug report or feature request. Please make sure to provide us with the appropriate information so we can best determine how to assist with the given issue.
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!
Most helpful comment
I also run into this issue, and I think it would be helpful to fix. Because of this it doesn't seem possible to standardized a workflow for knowing that a public ip is actually correct. you have to consider edge cases if an eip is used.
There is public ip data that actually doesn't exist anymore under the aws_instance.
This can mess with terraform inventory if later provisioning is occuring with something like Ansible and you require a standard method for knowing a public IP of an instance.