Last active
July 4, 2018 21:00
-
-
Save moziauddin/92e8fa7ecc40c3602b088f5b7c16a95d to your computer and use it in GitHub Desktop.
AWS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#------------------------------------------------------------------------------------------------------ | |
# Copy files using S3 while adding a Key with Date | |
mo@linux-jzir:~> export AWS_DATE=`date +"%Y-%m-%d"` | |
mo@linux-jzir:~> echo $AWS_DATE | |
2018-06-18 | |
mo@linux-jzir:~> aws s3 cp initscript.sh s3://nxlbackup/NAQS/dailycopy/`date +"%Y-%m-%d"`/ --profile s3user | |
#------------------------------------------------------------------------------------------------------ | |
# EBS-Snapshot-Backup-Script-Retention-Tag.sh | |
import logging | |
from datetime import date | |
import boto3 | |
from dateutil.relativedelta import relativedelta | |
VERSION = '1.0.1' | |
logger = logging.getLogger() | |
logger.setLevel(logging.INFO) | |
ec2 = boto3.resource('ec2') | |
client = boto3.client('ec2') | |
def lambda_handler(event, context): | |
logger.info('Start ebs-backup v{}'.format(VERSION)) | |
backup() | |
expire() | |
def backup(): | |
instances = ec2.instances.filter(Filters=[{'Name': 'tag-key', | |
'Values': ['LambdaBackupConfiguration']}]) | |
for instance in instances: | |
try: | |
backup_instance(instance) | |
except: | |
logging.exception('Error creating snapshot for {}'.format(instance.id)) | |
def backup_instance(instance): | |
instance_tags = dict(map(lambda x: (x['Key'], x['Value']), instance.tags or [])) | |
instance_name = instance_tags.get('Name', '[unnamed]') | |
backup_cfg_str = instance_tags['LambdaBackupConfiguration'] | |
backup_cfg = parse_config(instance, instance_name, backup_cfg_str) | |
backup_label, retention = calc_retention(backup_cfg) | |
if not backup_label: | |
logger.info('Skip backup of instance {} ({}); LambdaBackupConfiguration is {}' | |
.format(instance.id, instance_name, backup_cfg_str)) | |
return | |
delete_date_fmt = (date.today() + retention).strftime('%Y-%m-%d') | |
logger.info('Work on instance {} ({}); Create {} backups to be deleted on {}' | |
.format(instance.id, instance_name, backup_label, delete_date_fmt)) | |
snapshot_ids = [] | |
for device_mapping in instance.block_device_mappings: | |
volume_id = device_mapping['Ebs']['VolumeId'] | |
device_name = device_mapping['DeviceName'] | |
logger.info('Create snapshot of volume {} (mounted at {})'.format(volume_id, device_name)) | |
snapshot = client.create_snapshot(VolumeId=volume_id, Description='Backup of {} {}' | |
.format(instance_name, device_name)) | |
snapshot_ids.append(snapshot['SnapshotId']) | |
if snapshot_ids: | |
logger.info('Create tags for snapshots {}'.format(snapshot_ids)) | |
tags = { | |
'Name': 'lambda-backup', | |
'BackupLabel': backup_label, | |
'InstanceId': instance.instance_id, | |
'InstanceName': instance_name, | |
'DeleteOn': delete_date_fmt | |
} | |
tag_list = list(map(lambda kv: {'Key': kv[0], 'Value': kv[1]}, list(tags.items()))) | |
client.create_tags(Resources=snapshot_ids, Tags=tag_list) | |
def parse_config(instance, instance_name, config): | |
try: | |
backup_configuration = list(map(int, config.split(','))) | |
if any(i < 0 for i in backup_configuration): | |
raise ValueError('Values must be >= 0') | |
return backup_configuration | |
except: | |
raise ValueError('Syntax error in LambdaBackupConfiguration of {} ({}): {}' | |
.format(instance.id, instance_name, config)) | |
def calc_retention(backup_configuration): | |
today = date.today() | |
r_daily, r_weekly, r_monthly, r_yearly = backup_configuration | |
if today.day == 1: | |
if today.month == 1 and r_yearly > 0: | |
return 'yearly', relativedelta(years=r_yearly) | |
if r_monthly > 0: | |
return 'monthly', relativedelta(months=r_monthly) | |
if today.weekday() == 6 and r_weekly > 0: | |
return 'weekly', relativedelta(weeks=r_weekly) | |
if r_daily > 0: | |
return 'daily', relativedelta(days=r_daily) | |
return None, None | |
def expire(): | |
delete_fmt = date.today().strftime('%Y-%m-%d') | |
snapshots = ec2.snapshots.filter(OwnerIds=['self'], | |
Filters=[{'Name': 'tag:DeleteOn', 'Values': [delete_fmt]}]) | |
for snapshot in snapshots: | |
logger.info('Remove snapshot {} (of volume {}) created at {}' | |
.format(snapshot.id, snapshot.volume_id, snapshot.start_time)) | |
snapshot.delete() | |
#------------------------------------------------------------------------------------------------------ | |
# Swap volumes of ebs backed instances on AWS | |
# SwapVolumesEC2Inshance.sh | |
#!/bin/bash | |
# Set variables below | |
export awsInstanceId=*instance-id-value* | |
export snapId=*snapshot-name* | |
export tagEnvSwap=dev | |
export tagAppSwap=*app-name* | |
echo "Create New Volume" | |
echo "-----------------------------------------------------------------------" | |
export awsAZone=`aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=$awsInstanceId | jq '.Volumes[0].AvailabilityZone' | sed -e 's/"//g'` | |
echo "Create New Volume" | |
echo "-----------------------------------------------------------------------" | |
export awsNewVolId=`aws ec2 create-volume --availability-zone $awsAZone --snapshot-id $snapId --volume-type gp2 --size 80 --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=tagEnvSwap-tagAppSwap},{Key=app,Value=$tagAppSwap},{Key=env,Value=$tagEnvSwap}]' | jq '.VolumeId' | sed -e 's/"//g'` | |
echo "Getting Old Volume Information" | |
echo "-----------------------------------------------------------------------" | |
export awsOldVolId=`aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=$awsInstanceId | jq '.Volumes[0].Attachments[0].VolumeId' | sed -e 's/"//g'` | |
echo "Stopping Instance" | |
echo "-----------------------------------------------------------------------" | |
aws ec2 stop-instances --instance-ids $awsInstanceId | |
aws ec2 wait instance-stopped --instance-ids $awsInstanceId | |
echo "Detaching Old Volume" | |
echo "-----------------------------------------------------------------------" | |
aws ec2 detach-volume --volume-id $awsOldVolId | |
echo "Ataching New Volume" | |
echo "-----------------------------------------------------------------------" | |
aws ec2 attach-volume --volume-id $awsNewVolId --instance-id $awsInstanceId --device /dev/sda1 | |
echo "Starting the instance" | |
echo "-----------------------------------------------------------------------" | |
aws ec2 start-instances --instance-ids $awsInstanceId | |
aws ec2 wait instance-running --instance-ids $awsInstanceId | |
echo "Final Output" | |
echo "-----------------------------------------------------------------------" | |
echo "The old volume $awsOldVolId was swapped with new volume $awsNewVolId for instance $awsInstanceId" | |
#------------------------------------------------------------------------------------------------------ | |
#Add DNS Entry in Route53 dynamically | |
#add-dns-entry-dynamiclly.sh | |
#!/bin/bash -eo pipefail | |
## Allows for creation of "Basic" DNS records in a Route53 hosted zone | |
function main() { | |
record_name=$1 | |
record_value=$2 | |
[[ -z $record_name ]] && echo "record_name is: $record_name" && exit 1 | |
[[ -z $record_value ]] && echo "record_value is: $record_value" && exit 1 | |
## set some defaults if variables haven't been overridden on script execute | |
zone_name=${zone_name:-$ROUTE53_DEFAULT_HOSTED_ZONE_NAME} | |
action=${action:-CREATE} | |
record_type=${record_type:-A} | |
ttl=${ttl:-300} | |
wait_for_sync=${wait_for_sync:-false} | |
change_id=$(submit_resource_record_change_set) || exit 1 | |
echo "Record change submitted! Change Id: $change_id" | |
if $wait_for_sync; then | |
echo -n "Waiting for all Route53 DNS to be in sync..." | |
until [[ $(get_change_status $change_id) == "INSYNC" ]]; do | |
echo -n "." | |
sleep 5 | |
done | |
echo "!" | |
echo "Your record change has now propogated." | |
fi | |
echo 'Thank you for using "The Cloud".' | |
} | |
function change_batch() { | |
jq -c -n "{\"Changes\": [{\"Action\": \"$action\", \"ResourceRecordSet\": {\"Name\": \"$record_name\", \"Type\": \"$record_type\", \"TTL\": $ttl, \"ResourceRecords\": [{\"Value\": \"$record_value\"} ] } } ] }" | |
} | |
function get_change_status() { | |
aws route53 get-change --id $1 | jq -r '.ChangeInfo.Status' | |
} | |
function hosted_zone_id() { | |
aws route53 list-hosted-zones | jq -r ".HostedZones[] | select(.Name == \"${zone_name}\") | .Id" | cut -d'/' -f3 | |
} | |
function submit_resource_record_change_set() { | |
aws route53 change-resource-record-sets --hosted-zone-id $(hosted_zone_id) --change-batch $(change_batch) | jq -r '.ChangeInfo.Id' | cut -d'/' -f3 | |
} | |
function usage() { | |
echo "usage: $0 <record_name> <record_value>" | |
echo "" | |
echo "possible env config settings and their defaults:" | |
echo " - action=CREATE" | |
echo " - ttl=300" | |
echo " - record_type=A" | |
echo " - wait_for_sync=false" | |
echo "" | |
} | |
main $1 $2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment