AWS Lightsail windows instance snapshot automation

If you are using AWS Lightsail to host analytics related applications, or any other applications for that matter, and you happen to be using windows OS on your Lightsail instances, you may have noticed the message indicating that “Automatic snapshots are not supported for Windows instances at this time” in your management console. This is a bit inconvenient, if you are running applications that should be backed up, and snapshotting is such a convenient way to assure recoverability.

While you can take manual snapshots occasionally, it’s hard to keep up with that process. After searching and not finding any solutions online, I ended up writing a PowerShell script that leverages the AWSPowerShell cmdlets and can be scheduled on your windows server Lightsail instance using task scheduler (or used in a Lambda function to run serverless). This is a simple use case with one instance, but of course this concept can be extended to support more complex scenarios and multiple instances as needed. The script executes the following operations:

  • It creates a new snapshot using the New-LSInstanceSnapshot cmdlet
  • It retrieves all the existing snapshots for the instance using the Get-LSInstanceSnapshotList cmdlet
  • It deletes older instances using the Remove-LSInstanceSnapshot, based on a parameter to keep the snapshots from the last n number of days

The script also includes code to connect to an office365 mail account and send error emails in case of a failure.

The script:

$ErrorActionPreference = "stop"
try {
  <#
The try block will only catch errors in PS execution. 
To check for errors in the response from the AWS service, can parse the response info and check..
Also, can look at CloudWatch API for more advanced options to keep an eye on the snapshot creation and removal processes
#>

  <#These are some parameters for email authentication with office365, if the script errors, it will send an email. Password can be stored as encrypted string somewhere as needed#>
  $emailUsername = "some.email@somecompany.com"
  $emailTo = "some.other.email@somecompany.com"
  $emailassword = "TypeOrGetFromYourFavoriteEncryptionMethod"
  $cred = New-Object System.Management.Automation.PSCredential ($emailUsername,(ConvertTo-SecureString $emailassword -AsPlainText -Force))

  <#The default config of the script would remove all snapshots that are older then 5 days ago. NumberOfDaysToKeep variable value can be changed as needed#>
  $NumberOfDaysToKeep = 5
  <#The InstanceName is needed to identify which instance to snapshot as well as used for snaphot name base#>
  $InstanceName = "MyInstance123"

  <#First, issue the command to create a new snapshot, append a timestamp to snapshot name#>
  $CurrentTimestamp = Get-Date -Format "yyyyMMdd-HHmm"
  $InstanceSnapshotName = $InstanceName + "-" + $CurrentTimestamp
  <#Create a snapshot#>
  New-LSInstanceSnapshot -InstanceName $InstanceName -InstanceSnapshotName $InstanceSnapshotName

  <#Next, check if there are older instances that need to be removed, to save space..

  #Calculate actual date threashold to use to remove snapshots that are older than that#>
  $MinDate = ([datetime]::Today).AddDays($NumberOfDaysToKeep * -1)

  <#Get all instance snapshots, sort them descending by created date (can delete based on number of instances, not dates..)#>
  $CurrentSnapshots = Get-LSInstanceSnapshotList | Sort-Object -Property CreatedAt -Descending

  <#Iterate through the instances, and remove any instance that is older then the threashold min date#>
  foreach ($SnapshotItem in $CurrentSnapshots) {
    if ($SnapshotItem.CreatedAt -le $MinDate)
    {
      Remove-LSInstanceSnapshot -InstanceSnapshotName $SnapshotItem.Name -Force
    }
  }
}

catch
{
  $msg = $Error[0].Exception.Message
  <#Write the error to the console in case this is run interactively and also send an email..#>
  Write-Host $msg
  Send-MailMessage -From $emailUsername -To $emailTo -Subject "LS Snapshot script errored" -Port 587 -Body $msg -SmtpServer “smtp.office365.com” -UseSsl -Credential $cred
  exit 1
}

If you are looking for some additional information about how to setup the AWSPowerShell tools, here are some additional steps and info:

You can find all the information you need about Lightsail PowerShell setup in this guide: https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html

There are several installation methods, as described in the doc, the Install-Module option was the simplest for me to use. After installing the modules and setting the appropriate execution policy, I was able to configure my IAM user profile to be used for accessing the AWS services, such as the snapshotting services used in the script above.

The document referenced above describes in great details this process, but it boils down to running a PS cmdlet called Set-AWSCredential with your IAM user access key information.

Once that is done, you can simply execute AWS cmdlets without needing to worry about authentication on each session, it is a straightforward one-time setup.

Next, I was able to find the list and documentation for all the AWSTools cmdlets, which is here: https://docs.aws.amazon.com/powershell/latest/reference/items/Lightsail_cmdlets.html

Finally, I chose to implement the solution as a PowerShell script on the instance itself and have it run on a scheduled basis using the windows task scheduler. I have this run daily and it works great for my simple use case.  If you are looking to have this process run serverless and not on the hosted instance, and also extend to leverage across multiple instances, you can import your ps1 file into a Lambda function and use CloudWatch to schedule it as well and interrogate logs more carefully.

This entry was posted in AWS, Lightsail, PowerShell and tagged , , . Bookmark the permalink.