I terminated my EC2 instance!

Congratulations! Your rite of passage is now complete, and you are officially an adult! 🙂

As far as rites of passage go, this one, too, sucks and was just about as exciting and useful as any other one. So let’s celebrate by preventing this from happening ever again.

Does your account contain production instances? Do you love right-clicking them in the console instead of selecting and going to Action button? Do you frequently run test instances in your prod account and then remove them (plus other collateral stuff) without thinking twice?

If answer to any of this is ‘Yes’, you need protection. Not armed forces-type of protection, and certainly not Durex. You need protection from your very self.


It became quite obvious in the early days of Active Directory that anything that can be accidentally deleted will be accidentally deleted.

Therefore Microsoft came up with the lovely option of “Protect object from accidental deletion”: Set-ADObject -ProtectedFromAccidentalDeletion:$true Brilliant, and my instant favorite. Now you needed to be 100% special, and not in a Fallout way, to manage to break your AD users and groups.

AWS engineers also gave us a way from protecting our instances from ourselves in the form of Termination Protection. Go to the instance, right-click (or go to Action, do as you please) -> Instance Settings -> Change Termination Protection.

Now you won’t be able to randomly do as you please. Well, at least not until you not-so-randomly disable Termination Protection first.

Since we’re interested in doing this via PowerShell and not puny EC2 console as a common pleb, we’ll need to see the basics first.

You know what’s coming now, right? Right?
Right! An epic help page!

But this one is short, I promise. Check out Edit-EC2InstanceAttribute commandlet details.

See? I lied again. It’s huge as hell and longer than twice my weight.
But hopefully you knew better than to trust me.

Also, we learned from the help page. And that’s the important point here.

Now, I know most of you cheated and used Find on the page, but let’s sum it up for those who actually read through and forgot everything by the time they reached the end of the page:

So simple even console users could write this script.

Let’s go!

Grab all of our instances into a variable:

For each one, enable Termination Protection. Be aware that this action isn’t a Describe API event, and has significantly less tolerance for you hammering the API endpoint. You may want to limit your requests to one per second or otherwise space them apart. Add Start-Sleep 1 if you start getting Service Unavailable exceptions.

There we go. All instances, a safe distance from us and our Terminate button hammering.

Be warned, though, for the simple script is simple. A beautiful tautophrase, I agree with you, but what does it mean?

It means that we were lazy and this will protect only instances in our current region, of our current account.

To achieve protection level over 9000 we will need to run this for both all of our regions and all of our accounts.

Running this through all of our regions shouldn’t be that difficult, so let’s make the script more complex, if only by little. As for other AWS accounts, just cycle through them and fire the same thing over and over again until you run out of accounts.

But honestly, if you have more than one AWS account and no Termination Protection enabled yet, I’d advise checking how much YouTube traffic your IT guys use.

Get-EC2Region will give us the list of regions available to us, and their endpoints. We don’t care about endpoints at this point, so let’s just grab all the regions we can have our EC2 instances in:

Self-explanatory stuff. Now let’s loop through regions and do all what we did before for just one.

Works? Let’s check.

Get an instance ID of one of your instances. I’ll use my own here – i-1234567890. Best InstanceID ever.

What? Looks broken.

Let’s try another attribute.

Another.

*sigh* Yep. It’s broken alright.
Why in the world does it require you to provide an attribute you want when it lists all of them anyway? I guess I’ll report this, they are good at fixing stuff.

OK, let’s get the value only by cheating a little:

Perfect. Let’s get the Name, too, while we’re at it.

It’s a mess, yes. Just run it to get the value of the instance ‘Name’ key tag, a.k.a. Instance Name.

When we put all this to use, we end up with something like this:

Yes. Colors. Beautiful colors! I love colors. Don’t judge me!
There’s Write-Host, too. You are free to judge here. Change to Write-Output and no one will ever know.

So, did you try it? Do you now have a green-brick road in your output? Perfect! Our cause is noble and just!

A quick note if you want to use this for multiple accounts: You can use Set-AWSCredentials and -StoredCredentials parameter when calling it.

Links to Set-EC2TerminationProtection.ps1 and Get-EC2TerminateProtection.ps1 are here:
https://s3-eu-west-1.amazonaws.com/mypowershell.space/ps/Set-EC2TerminationProtection.ps1
https://s3-eu-west-1.amazonaws.com/mypowershell.space/ps/Get-EC2TerminationProtection.ps1

Scripts also available below for your copy/paste enjoyment.

Drop me an email at six@mypowershell.space [link] if you feel like it.

Have a great day and may the Force be with you!

Leave a Comment