Skip to content

Instantly share code, notes, and snippets.

@phainamikaze
Last active May 23, 2024 11:37
Show Gist options
  • Save phainamikaze/dbdd5471d63d5c47ef2623cdb45144fe to your computer and use it in GitHub Desktop.
Save phainamikaze/dbdd5471d63d5c47ef2623cdb45144fe to your computer and use it in GitHub Desktop.
lightsail-backup
const AWS = require('aws-sdk');
exports.handler = async (event, context) => {
console.log(JSON.stringify(event))
// ================================
// Define your backups
// ================================
const instanceName = event.instanceName || process.env['instanceName'];
const backupDaysMax = event.days || process.env['days']; // keep at least 7 daily backups
const backupWeeksMax = event.weeks || process.env['weeks']; // keep at least 4 weekly backups
const backupMonthsMax = event.months || process.env['months']; // keep at least 3 monthly backups
// ================================
// Unique short tag for snapshots
// ================================
const labelTag = process.env['labelTag']+"_"+ instanceName +"_";
// Set it differently in your Lambdas for different instances. For "ABC" label it would be ABCKW8TAG6 the name of the backups
// ================================
// Create an AWS lightsail client
// ================================
var lightsail = new AWS.Lightsail(
{
apiVersion: '2016-11-28',
region: process.env['region']
}
);
// ================================
// Dates calculations for the name
// ================================
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = now - start;
var oneDay = 1000 * 60 * 60 * 24;
var kw = Math.floor(diff / oneDay / 7) + 1;
var day = Math.floor(diff / oneDay)
console.log('KW of year: ' + kw);
console.log('day of year:' + day);
console.log('day of month:' + now.getDate());
console.log('day of week:' + now.getDay());
console.log('month:' + now.getMonth());
var backupDaysNR = now.getDay() % backupDaysMax;
var backupWeeksNR = kw % backupWeeksMax;
var backupMonatsNR = now.getMonth() % backupMonthsMax;
console.log('backupDaysNR:' + backupDaysNR);
console.log('backupWeeksNR:' + backupWeeksNR);
console.log('backupMonatsNR:' + backupMonatsNR);
const newDaySnapshot = async (instanceName, backupDaysNR) => {
var params = {
instanceName: instanceName,
instanceSnapshotName: labelTag + backupDaysNR
};
try{
await lightsail.createInstanceSnapshot(params).promise()
return 'ok'
}catch(err){
return err
}
}
const deleteOldSnapshot = async (data) =>{
var backupDaysTillNow;
var saveBackup;
var backupDate;
for (var i = 0; i < data.instanceSnapshots.length; i++) { // BROWSE THROUGH SNAPSHOTS
var backupFromInstance = data.instanceSnapshots[i].fromInstanceName;
backupDate = new Date(data.instanceSnapshots[i].createdAt);
backupDaysTillNow = Math.floor((now - backupDate) / oneDay);
saveBackup = false;
if (backupFromInstance == instanceName) {
// DO NOT DELETE LAST backupDaysMax DAYS BACKUPS
if (backupDaysTillNow <= backupDaysMax) { saveBackup = true; }
// DO NOT DELETE LAST backupWeeksMax WEEKS BACKUPS
if (backupDaysTillNow > backupDaysMax && backupDaysTillNow <= backupWeeksMax * 7 && backupDate.getDay() == 0) { saveBackup = true; }
// DO NOT DELETE LAST backupWeeksMax MONTHS BACKUPS
if (backupDaysTillNow > backupWeeksMax * 7 && backupDaysTillNow <= backupMonthsMax * 30 && backupDate.getDate() < 8 && backupDate.getDay() == 0) { saveBackup = true; }
if (saveBackup) {
// WE KEEP THESE BACKUPS
console.log(`keep ${backupDate.getDate()} ${data.instanceSnapshots[i].createdAt} ${data.instanceSnapshots[i].name}`);
} else {
if(data.instanceSnapshots[i].name.startsWith(process.env['labelTag']) ) {
// WE DELETED THESE BACKUPS
var paramsDelete = {
"instanceSnapshotName": data.instanceSnapshots[i].name
}
try{
await lightsail.deleteInstanceSnapshot(paramsDelete).promise()
console.log(`Deleted ${paramsDelete.instanceSnapshotName}`);
}catch(err){
console.log(err)
}
}else{
console.log(`keep ${backupDate.getDate()} ${data.instanceSnapshots[i].createdAt} ${data.instanceSnapshots[i].name}`);
}
}
} else {
console.log('Will ignore this backup because it belongs to an instance other than ' + instanceName);
}
}
// IF WE HAVE MORE BACKUPS WE SHOULD NAVIGATE TO THE NEXT PAGE AND USE RECURSION
console.log('\n\r=============== TOKEN =============== ');
console.log(data.nextPageToken);
if (typeof data.nextPageToken != 'undefined') {
var params = {
pageToken: data.nextPageToken
};
try{
const data = await lightsail.getInstanceSnapshots(params).promise()
await deleteOldSnapshot(data)
}catch(err){
console.log(err)
}
}
}
// ================================
// CREATE A NEW SNAPSHOT
// ================================
var params = {
"instanceSnapshotName": labelTag + "KW" + kw + "TAG" + backupDaysNR
}
try{
const {instanceSnapshot} = await lightsail.getInstanceSnapshot(params).promise()
console.log('Today Already backup, snapshot name is ' + instanceSnapshot.name);
}catch(err){
console.log('no backup, we do it new');
await newDaySnapshot(instanceName, "KW" + kw + "TAG" + backupDaysNR)
}
// ================================
// DELETING OLD SNAPSHOTS
// ================================
var params = {};
try{
const data = await lightsail.getInstanceSnapshots(params).promise()
await deleteOldSnapshot(data)
}catch(err){
console.log(err, err.stack);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment