Skip to content

Instantly share code, notes, and snippets.

@linyows
Last active December 17, 2015 17:18
Show Gist options
  • Save linyows/5644632 to your computer and use it in GitHub Desktop.
Save linyows/5644632 to your computer and use it in GitHub Desktop.
Create snapshot of volume on AWS
#!/usr/bin/env ruby
# README
#
# Create snapshot
# ===============
#
# Create snapshot of volume. and generation management.
#
# Usage
# -----
#
# add to `/etc/cron.d/aws`:
#
# ```sh
# SHELL=/bin/bash
# PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin
# MAILTO=root
# AWS_ACCESSKEY=?????
# AWS_SECRETKEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#
# */10 * * * * /var/batches/create_snapshot.rb vol-xxxxxxx 5 "Database Volume"
# ```
#
# Author
# ------
#
# - [linyows](https://github.com/linyows)
#
# License
# -------
#
# MIT
require 'aws-sdk'
access_key = ENV['AWS_ACCESSKEY']
secret_key = ENV['AWS_SECRETKEY']
if access_key.nil? || access_key.empty? || secret_key.nil? || secret_key.empty?
puts "Empty AWS_ACCESSKEY or AWS_SECRETKEY"
exit 0
end
if ARGV.size < 2
puts "Usage: #{$0} <volume_id> <generation_count> <snapshot_description> <ec2_endpoint> <dry-run>"
exit 0
end
volume_id = ARGV[0]
generation_count = ARGV[1].to_i
description = "#{ARGV[2] + ' ' if ARGV[2]}#{Time.now.strftime('%Y/%m/%d %H:%M')}"
endpoint = ARGV[3] || 'ec2.us-east-1.amazonaws.com'
dryrun = ARGV[4] || false
AWS.config(access_key_id: access_key,
secret_access_key: secret_key,
ec2_endpoint: endpoint)
ec2 = AWS::EC2.new
if dryrun
puts "volume: #{ec2.volumes[volume_id]}, description: #{description}"
else
ec2.snapshots.create(volume: ec2.volumes[volume_id],
description: description)
end
snapshots = ec2.snapshots.filter('volume-id', volume_id)
targeted_snapshots = snapshots.each_with_object([]) { |snapshot, result|
next if snapshot.status != :completed
next unless snapshot.tags[:Name].nil?
result << snapshot
}.compact.sort_by { |snapshot|
snapshot.start_time
}.reverse
snapshots_to_del = []
targeted_snapshots.each_with_index do |snapshot, i|
snapshots_to_del << snapshot if i >= generation_count
end
snapshots_to_del.each do |snapshot|
if dryrun
puts "#{snapshot.id}: #{snapshot.start_time}"
else
begin
snapshot.delete
rescue => e
ap e
end
end
end
@linyows
Copy link
Author

linyows commented Nov 1, 2014

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
#0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:/root/.rbenv/bin:$PATH
MAILTO='[email protected]'

AWS_ACCESSKEY=
AWS_SECRETKEY=

# Snapshot: Database
05 0-23/3 * * * eval "$(rbenv init -)"; ruby /var/batches/snapshot.rb vol-75af1a0a 5 "Database Volume"
# Snapshot: Instances
10 5,17 * * * eval "$(rbenv init -)"; ruby /var/batches/snapshot.rb vol-4d081535 2 "Instance Volume"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment