AWS EC2 instance (aws_instance) replaced on every Terraform run

Written by - 1 comments

Published on - Listed in AWS Cloud


Ran into a weird problem, when an AWS EC2 instance was replaced on every Terraform run.

The aws_instance resource

The EC2 instance is built using Terraform. The "aws_instance" module from Hashicorp is used in this situation and looks pretty straightforward and not too complicated:

resource "aws_instance" "onl-varnish01-t" {
  ami = "ami-02003f9f0fde924ea"
  instance_type = "t3.micro"
  subnet_id     = "subnet-xxxxxxxxxxxxxxxxxx"
  security_groups = [aws_security_group.varnish_ec2_sg.id]
  key_name      = aws_key_pair.ck2025.key_name

  tags = {
    Name = "onl-varnish01-t"
    Role = "varnish"
  }
}

But on every terraform plan I saw that the instance(s) would be destroyed and re-created from scratch. 

Note: This is using the HCP Platform (formerly known as Terraform Cloud). 

security_groups forces replacement

A deeper look into the planned changes showed multiple changes of the EC2 instance (although there was no change in the code). One change caught my eye:

The security_groups change had an additional description: Forces replacement.

After an excellent hint from Thomas Weiss, a Terraform expert I'm in contact with for this project, it turned out to be a problem with security_groups used in the resource. The documentation states:

 If you are creating Instances in a VPC, use vpc_security_group_ids instead.

Well, that's the case here. I have an existing VPC and I want to create instances using the existing VPC.

Fix with vpc_security_group_ids

According to this information, I replaced security_groups with vpc_security_group_ids:

resource "aws_instance" "onl-varnish01-t" {
  ami = "ami-02003f9f0fde924ea"
  instance_type = "t3.micro"
  subnet_id     = "subnet-xxxxxxxxxxxxxxxxxx"
  vpc_security_group_ids = [aws_security_group.varnish_ec2_sg.id]
  key_name      = aws_key_pair.ck2025.key_name

  tags = {
    Name = "onl-varnish01-t"
    Role = "varnish"
  }
}

After another terraform plan this seemed to work as it should: No changes detected (as the EC2 instances were already created in a previous run):

Now the question arises, why did I use security_groups instead of vpc_security_group_ids in the aws_instance resource?

As Terraform is rather new for me (I've known what it is for a long time, but never actually got to work with it), I used Grok AI to help me create a TF file with the relevant AWS resources. And Grok's example contained the aws_instance resource - with the security_groups option. Grok also seemed unaware that this situation might cause a replacement of the existing EC2 instance(s). When I added this hint, Grok explained this with changes in the code - which didn't happen. 

This whole situation is a pretty good real life example on AI usage: Good ideas and very helpful input (especially for previously unknown topic to the human), but always verify with an expert in that field. 


Add a comment

Show form to leave a comment

Comments (newest first)

Mike Anderson from Florida wrote on Sep 3rd, 2025:

Spot-on article! I’ve been bitten by that exact Terraform behavior before—security_groups silently locks you into replacement cycles in a VPC. This post saved me from repeating it elsewhere. And the AI caveat is a nice, timely reminder for us all.


RSS feed

Blog Tags:

  AWS   Android   Ansible   Apache   Apple   Atlassian   BSD   Backup   Bash   Bluecoat   CMS   Chef   Cloud   Coding   Consul   Containers   CouchDB   DB   DNS   Databases   Docker   ELK   Elasticsearch   Filebeat   FreeBSD   Galera   Git   GlusterFS   Grafana   Graphics   HAProxy   HTML   Hacks   Hardware   Icinga   Influx   Internet   Java   KVM   Kibana   Kodi   Kubernetes   LVM   LXC   Linux   Logstash   Mac   Macintosh   Mail   MariaDB   Minio   MongoDB   Monitoring   Multimedia   MySQL   NFS   Nagios   Network   Nginx   OSSEC   OTRS   Observability   Office   OpenSearch   PHP   Perl   Personal   PostgreSQL   PowerDNS   Proxmox   Proxy   Python   Rancher   Rant   Redis   Roundcube   SSL   Samba   Seafile   Security   Shell   SmartOS   Solaris   Surveillance   Systemd   TLS   Tomcat   Ubuntu   Unix   VMWare   VMware   Varnish   Virtualization   Windows   Wireless   Wordpress   Wyse   ZFS   Zoneminder    Linux