Hi there,
I have been using terraform for the last two weeks now. So far I have used terraform to build my AWS VPC and launch two instances in it. My trouble is that every time a do a terraform plan
, terraform tells me that it would be destroy and recreate those two instance and terraform apply
does it.
I am using the latest terraform version
$ terraform -v
Terraform v0.6.16
Here is snippet from my instances.tf
configuration file.
variable "linux-amis" {
default = {
eu-west-1 = "ami-c39604b0"
eu-central-1 = "ami-7df01e12"
}
}
resource "aws_key_pair" "web" {
key_name = "web-key"
public_key = "${file("ssh/test-key.pub")}"
}
resource "aws_instance" "web1" {
ami = "${lookup(var.linux-amis, var.region)}"
instance_type = "t2.micro"
key_name = "${aws_key_pair.web.key_name}"
security_groups = ["${aws_security_group.Standard.id}","${aws_security_group.Dmz.id}"]
subnet_id = "${aws_subnet.DmzAz1.id}"
associate_public_ip_address = "true"
connection {
user = "ec2-user"
private_key = "${file("ssh/test-key")}"
host = "${aws_instance.web1.public_ip}"
}
provisioner "file" {
source = "./html/index.html"
destination = "/tmp/index.html"
}
provisioner "remote-exec" {
inline = [
"sudo yum install httpd -y",
"sudo cp /tmp/index.html /var/www/html/index.html"
]
}
provisioner "remote-exec" {
scripts = [
"scripts/web.sh"
]
}
/*
lifecycle {
create_before_destroy = "true"
}
*/
tags {
Name = "Web-Test1"
}
}
output "web1-public-ip" {
value = "${aws_instance.web1.public_ip}"
}
resource "aws_instance" "web2" {
ami = "${lookup(var.linux-amis, var.region)}"
instance_type = "t2.micro"
key_name = "${aws_key_pair.web.key_name}"
security_groups = ["${aws_security_group.Standard.id}","${aws_security_group.Dmz.id}"]
subnet_id = "${aws_subnet.DmzAz1.id}"
associate_public_ip_address = "true"
connection {
user = "ec2-user"
private_key = "${file("ssh/test-key")}"
host = "${aws_instance.web2.public_ip}"
}
provisioner "file" {
source = "./html/index.html"
destination = "/tmp/index.html"
}
provisioner "remote-exec" {
inline = [
"sudo yum install httpd -y",
"sudo cp /tmp/index.html /var/www/html/index.html"
]
}
provisioner "remote-exec" {
scripts = [
"scripts/web.sh"
]
}
lifecycle {
create_before_destroy = "true"
}
tags {
Name = "Web-Test2"
}
}
output "web2-public-ip" {
value = "${aws_instance.web2.public_ip}"
}
I set TF_LOG=TRACE
in order to capture data for debugging.
Here is the output, it really lengthy ==> https://gist.github.com/simplyaldo/05de4a494953a4592da4c3b21e6af483
Ideally terraform should just tell me that there are no updates to be applied.
But instead terraform tells me that it needs to destroy and recreate the two ec2 instances and update a route tables when there has absolutely no changes to the instances and the route table.
Here is the output of terraform plan
-/+ aws_instance.web1
ami: "ami-c39604b0" => "ami-c39604b0"
associate_public_ip_address: "true" => "true"
availability_zone: "eu-west-1a" => "<computed>"
ebs_block_device.#: "0" => "<computed>"
ephemeral_block_device.#: "0" => "<computed>"
instance_state: "running" => "<computed>"
instance_type: "t2.micro" => "t2.micro"
key_name: "web-key" => "web-key"
placement_group: "" => "<computed>"
private_dns: "ip-172-31-1-179.core.cvent.org" => "<computed>"
private_ip: "172.31.1.179" => "<computed>"
public_dns: "" => "<computed>"
public_ip: "52.51.223.109" => "<computed>"
root_block_device.#: "1" => "<computed>"
security_groups.#: "0" => "2" (forces new resource)
security_groups.2019842352: "" => "sg-3855d95f" (forces new resource)
security_groups.3491232061: "" => "sg-0555d962" (forces new resource)
source_dest_check: "true" => "true"
subnet_id: "subnet-4279a134" => "subnet-4279a134"
tags.#: "1" => "1"
tags.Name: "Web-Test1" => "Web-Test1"
tenancy: "default" => "<computed>"
vpc_security_group_ids.#: "2" => "<computed>"
-/+ aws_instance.web2
ami: "ami-c39604b0" => "ami-c39604b0"
associate_public_ip_address: "true" => "true"
availability_zone: "eu-west-1a" => "<computed>"
ebs_block_device.#: "0" => "<computed>"
ephemeral_block_device.#: "0" => "<computed>"
instance_state: "running" => "<computed>"
instance_type: "t2.micro" => "t2.micro"
key_name: "web-key" => "web-key"
placement_group: "" => "<computed>"
private_dns: "ip-172-31-2-138.core.cvent.org" => "<computed>"
private_ip: "172.31.2.138" => "<computed>"
public_dns: "" => "<computed>"
public_ip: "52.17.29.129" => "<computed>"
root_block_device.#: "1" => "<computed>"
security_groups.#: "0" => "2" (forces new resource)
security_groups.2019842352: "" => "sg-3855d95f" (forces new resource)
security_groups.3491232061: "" => "sg-0555d962" (forces new resource)
source_dest_check: "true" => "true"
subnet_id: "subnet-4279a134" => "subnet-4279a134"
tags.#: "1" => "1"
tags.Name: "Web-Test2" => "Web-Test2"
tenancy: "default" => "<computed>"
vpc_security_group_ids.#: "2" => "<computed>"
~ aws_route_table.RouteTablePrivateAz1
route.2196669984.cidr_block: "172.21.0.0/16" => "172.21.0.0/16"
route.2196669984.gateway_id: "vgw-45516231" => "vgw-45516231"
route.2196669984.instance_id: "" => ""
route.2196669984.nat_gateway_id: "" => ""
route.2196669984.network_interface_id: "" => ""
route.2196669984.vpc_peering_connection_id: "" => ""
route.3512800776.cidr_block: "0.0.0.0/0" => ""
route.3512800776.gateway_id: "" => ""
route.3512800776.instance_id: "" => ""
route.3512800776.nat_gateway_id: "nat-0c18faa8f1f1b6ae0" => ""
route.3512800776.network_interface_id: "" => ""
route.3512800776.vpc_peering_connection_id: "" => ""
route.3722049459.cidr_block: "" => "0.0.0.0/0"
route.3722049459.gateway_id: "" => "nat-0c18faa8f1f1b6ae0"
route.3722049459.instance_id: "" => ""
route.3722049459.nat_gateway_id: "" => ""
route.3722049459.network_interface_id: "" => ""
route.3722049459.vpc_peering_connection_id: "" => ""
route.813709441.cidr_block: "10.0.0.0/8" => "10.0.0.0/8"
route.813709441.gateway_id: "vgw-45516231" => "vgw-45516231"
route.813709441.instance_id: "" => ""
route.813709441.nat_gateway_id: "" => ""
route.813709441.network_interface_id: "" => ""
route.813709441.vpc_peering_connection_id: "" => ""
steps required to reproduce the issue
terraform plan
terraform apply
Hi @simplyaldo! Thanks for opening an issue. From the plan, it looks like the security groups are forcing a new resource here. I know @catsby did a ton of work around security groups recently, so hopefully he is the best person to spot what is going on here!
Hey @simplyaldo – in v0.6.15 we added a backwards incompatible change such that Instance in a VPC need to use the vpc_security_group_ids
configuration parameter in place of security_gruops
. The former allows you to add/edit security groups without destroying the instance, while the later is reserved for instances in EC2 Classic, where destroying the instances was required to change security groups.
Here all you need to do is change this:
security_groups = ["${aws_security_group.Standard.id}","${aws_security_group.Dmz.id}"]
to this:
vpc_security_group_ids = ["${aws_security_group.Standard.id}","${aws_security_group.Dmz.id}"]
Sorry for the trouble!
@jen20 @catsby Thanks a ton, that solved my problem.
Sorry again for the surprise :/
Could be worth changing the example on https://www.terraform.io/docs/providers/aws/r/instance.html
Agree with @zachgatesak; the documentation does not make sense. If vpc_security_group_ids
is the preferred way to specify security groups, docs should say so. More importantly, the current documentation is really confusing: "The associated security groups in a non-default VPC."
The docs should also specify that using security_groups
could cause an aws_instance
to always be dropped and recreated. Currently, this is not obvious at all from the documentation.
Thanks @catsby this resolved the issue!
vpc_security_group_ids = ["${aws_security_group.tomcat.id}"] even i use this the instance is recreating for every apply
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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Most helpful comment
Hey @simplyaldo – in v0.6.15 we added a backwards incompatible change such that Instance in a VPC need to use the
vpc_security_group_ids
configuration parameter in place ofsecurity_gruops
. The former allows you to add/edit security groups without destroying the instance, while the later is reserved for instances in EC2 Classic, where destroying the instances was required to change security groups.Here all you need to do is change this:
to this:
Sorry for the trouble!