How to update EC2 instance parameters (e.g., security groups) without terminating or restarting the instance using Terraform?

I have a task to deploy infrastructure on AWS using Terraform, including VPC, availability zones (AZs), security groups, and other resources. The challenge is that I need to be able to update certain parameters of an EC2 instance, such as its attached security groups, without causing a disruption (i.e., terminating or restarting the instance).

Currently, I’m using Terraform to manage my infrastructure, but I’m not sure how to achieve this seamless update process for the EC2 instance. Is there a way to make changes to the instance’s configuration without interrupting its operations?

Some specific points I’m unsure about:

How do I define the EC2 instance resource in Terraform to enable this dynamic parameter update capability? What are the steps involved in applying changes to the EC2 instance without any disruption? Is is even possible? Are there any best practices or considerations I should be aware of to achieve this goal effectively? I’d appreciate any insights, sample Terraform code snippets, or documentation references to help me achieve this task successfully.

I have tried modifying the Terraform configuration for the EC2 instance’s security group directly and then running terraform apply. However, when I make such changes, Terraform attempts to recreate the EC2 instance, resulting in downtime for the application running on the instance.

Since I’m a Terraform newbie I was hoping that Terraform would apply only the necessary changes to the EC2 instance’s configuration, such as updating its associated security groups, without requiring a complete instance recreation.
Thanks for help!

Hi @ZAdamski,

Terraform’s AWS provider does not have any special access to EC2 beyond what the EC2 API exposes, and so typically when the provider reports that a particular change requires creating an entirely new EC2 instance that is because the same requirement exists in the underlying EC2 API.

I believe that is true for security groups in particular, so I don’t think there will be any way to directly achieve the goal you’ve stated.

However, you might be able to redefine the problem so that it can be solved. For example: Instead of changing which security groups are associated with a running instance, could you keep the same security group but change the rules associated with it? This might still require some care because you might create a brief instant when both old and new rules are in effect simultaneously, or when neither is. But that’s at least a smaller time window than waiting for an EC2 instance to boot.

If that avenue isn’t suitable then there is another more general solution: instead of managing EC2 instances directly with Terraform, you can use Terraform to manage EC2’s autoscaling service.

Despite the name, you don’t actually need to use automatic scaling rules for it to be useful; really Autoscaling is just an agent running in EC2 that monitors the lifecycle events of a set of EC2 instances and takes actions automatically in response. One common way to use it is to specify a fixed desired number of instances and then autoscaling will notice if one of the instances fails in some way and automatically replace it.

This can be a useful building block for situations like yours because you can change the template that describes how the set of instances ought to be configured and then take actions to inspire autoscaling to gradually replace the instances that were using the old template with new ones using the new template, taking care to preserve a certain minimum number of healthy instances of either template during the process.

All of what I’ve described here are more AWS things than Terraform things. You can use Terraform to configure autoscaling, for example, but you will first need to learn about the autoscaling system and decide what configuration of that system will best meet your needs.

There’s an AWS guide here that might be a useful starting point if you decide to use EC2 Autoscaling as part of the solution: