Day 59: An introduction to snapshots in AWS

Welcome to Day 59 of the “100 Days of DevOps with PowerShell”! For background on our goals in this series, see Announcing the “100 Days of Devops with PowerShell” Series here at SCC.

One of the many advantages of hosting of your infrastructure in a virtual environment is the ability to use snapshots to create copies of your environment at a specific time.  This is particularly important in the DevOps world where snapshots provide the ability to restore your environment to a known state.  This saves an enormous amount of time and resources because instead of provisioning a new environment you revert  to the known clean state through snapshots.  Essentially snapshots are just a copy of a volume done at a specific time and in AWS, snapshots can be used not only for restoring the state of an instance, but they can also play a major part in your backup and disaster recovery plans.  Once a snapshot has been created it can be copied to another availability zone or region, where if required it can be used to restore an instance.

Using on-premise virtualization solutions like VMware vSphere or Hyper-V, snapshots of VMs can be easily created through the respective consoles.  In AWS, it is also possible, but it is perhaps not as intuitive.  Therefore in this post we are going to look at the basics of how to create a snapshot and how to access the properties required to create a snapshot via PowerShell.

Provisioning the test instance.

As we have done in previous posts we’re going to provision a new instance, using an example that you may well be familiar with:

#Deploy an instance and apply a tag to it.
$ami = Get-EC2ImageByName -Names 'WINDOWS_2012R2_BASE'
$reservation = New-EC2Instance -ImageId $ami[0].ImageId -KeyName 'SCCDemo-key-pair' -InstanceType 't1.micro' -MinCount 1 -MaxCount 1
Start-Sleep -Seconds 30

#create the tag object
$instanceID = $reservation.runninginstance.instanceID
$Tag = New-Object amazon.EC2.Model.Tag
$Tag.Key = 'Name'
$Tag.Value = 'SRV01'

#apply the tag to the instance
New-EC2Tag -ResourceID $instanceID -Tag $tag

In the example above we’re also applying a tag, so we can name the instance and later easily retrieve the details about the instance using its tags.

Creating a snapshot

Assuming we know the volume ID of the instance creating a snapshot is very straight forward:

#creating a snapshot
New-EC2Snapshot -VolumeId $volumeId -Description 'Backup of important instance'

However, how do we find the volume ID of an instance?  Looking through the details of the instance below there’s no mention of a volume ID:

FindingVolumeId

To find the volume ID, we need to into Volumes in the AWS console and then enter the instance ID:

FindingVolumeId_2

However, with PowerShell there is simpler way and we’ll hopefully demonstrate here that if you are going to be spending any significant amount of time managing snapshots in AWS, then PowerShell is the way to do it.  In the example below we are going to get the details of instance we want to work with by querying its tags.  Remember we assigned the Name tag with a value of SRV01 to the instance, so we’ll use that to retrieve the details we need from the instance:

function Get-EC2InstanceTag
{

Param (
      [string][Parameter(Mandatory=$True)]$Tag,
      [string][Parameter(Mandatory=$True)]$Value
      )

Get-EC2Instance | Select-Object -ExpandProperty RunningInstance | Where-Object {$_.Tag.Key -eq $tag -and $_.Tag.Value -eq $value}

}

$instance = Get-ec2InstanceTag -Tag Name -Value SRV01

Listing out the properties of the instance, again there’s no mention of a volume, but we do see BlockDeviceMappings:

InstanceProperties

Examining the properties of BlockDeviceMappings, we see more details about the volume.  If you remember from Day 54, when we created a new volume we needed to create two objects: Amazon.EC2.Model.EbsBlockDevice and Amazon.EC2.Model.BlockDeviceMapping, so it makes sense that we need use BlockDeviceMapping to find more details about the volume:

BlockDeviceMappings

Therefore to create a new snapshot, having already retrieved properties of the instance into the variable $instance, we can do the following:

$volumeId = $instance.BlockDeviceMappings.ebs.VolumeId
$snapshot = New-EC2Snapshot -VolumeId $volumeId -Description "Backup of SRV01 [$($instance.instanceId)]"

Once the new snapshot has been initiated, you can check the progress of it:

snapshot_status

The snapshot should complete after a few minutes, but rather than running $snapshot continuously you could include the following snippet at the end of you script to create the snapshot and it will tell you once it’s complete and how long it took!

$start = $snapshot.StartTime

While ($snapshot.status -ne 'completed')
{
  $snapshot = Get-EC2Snapshot -SnapshotId $snapshot.snapshotId
  Start-Sleep -Seconds 10
}

$end = Get-Date

$duration = New-TimeSpan -Start $start -End $end
Write-Output ("Completed in {0:mm} minutes {0:ss} seconds" -f $duration)

Conclusion

This is been a basic introduction in how to create snapshots using PowerShell in AWS.  In later posts we’ve going to build upon what we’ve done here and look at how we can use snapshots to restore volumes, increase the size of volumes and finally how we can leverage snapshots as part of the daily backup procedures in our cloud infrastructure.

Previous Installments

To see the previous installments in this series, visit “100 Days of DevOps with PowerShell”.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.