Skip to content

Commit

Permalink
repo update
Browse files Browse the repository at this point in the history
  • Loading branch information
Varun Chandak committed Feb 3, 2019
1 parent c7aff5b commit 6ab401d
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
71 changes: 71 additions & 0 deletions README.md
@@ -0,0 +1,71 @@
# AMI Backups and Retention using AWS Lambda

---
#### NOTE: AMI and Instance Names and Name Tags must be between 3 and 128 characters long, and may contain letters, numbers, '(', ')', '.', '-', '/' and '_' only. Not following this nomenclature will lead to failure of the lambda function.
---

Here, we are using 2 AWS Lambda functions viz., **createAMI** and **deleteAMI**, which will create AMIs and delete AMIs, respectively. Both these functions are explained in detail below. **<u>Please note that both the lambda functions cover all the regions.</u>**

## createAMI

**Table of details:**

| Name | Value |
| --------------------------- | ----------------- |
| Name of the Lambda Function | createAMI |
| Timeout | 5 min |
| Role Permissions | `ec2:*` |
| Runtime | `python2.7` |
| File Name | `createAMI.py` |
| Schedule | `rate(5 minutes)` |

**Documentation:**

The lambda function make use of tags on EC2 intances which provides all the information required to create an AMI. The table below explains the tags required.

| Tag Name | Format | Default Value |
| --------- | ------------ | ------------- |
| AMIBackup | Yes/No | No |
| AMITime | HH:MM | 15:00 |
| Reboot | Yes/No | No |
| Retention | Whole Number | 7 |

In the above table:

- `AMIBackup`: It is used to specify which Instance has to be backed up.
- `AMITime`: It is used to specify the time when the AMI has to be created.
- `Reboot`: It is used to specify if the instance has to be rebooted when creating the AMI.
- `Retention`: It is used to specify the AMI retention period in **days**.

---

## deleteAMI

**Table of details:**

| Name | Value |
| --------------------------- | --------------------- |
| Name of the Lambda Function | deleteAMI |
| Timeout | 5 min |
| Role Permissions | `ec2:*` |
| Runtime | `python2.7` |
| File Name | `deleteAMI.py` |
| Schedule | `cron(00 15 * * ? *)` |

**Documentation:**

The lambda function make use of tags on EC2 intances which provides all the information required to delete an AMI. The tags are copied from the instance to AMI via **createAMI** function. The table below explains the tags required.

| Tag Name | Format | Default Value |
| --------- | ------------ | -------------------- |
| AMIBackup | Yes/No | Copied from Instance |
| AMITime | HH:MM | Copied from Instance |
| Reboot | Yes/No | Copied from Instance |
| Retention | Whole Number | Copied from Instance |

In the above table(s):

* `AMIBackup`: It is used to specify which Instance has to be backed up. **deleteAMI** will only get triggered if this tag is present with `Yes` value.
* `AMITime`: It is used to specify the time when the AMI has to be created.
* `Reboot`: It is used to specify if the instance has to be rebooted when creating the AMI.
* `Retention`: It is used to specify the AMI retention period in **days**.
57 changes: 57 additions & 0 deletions createAMI.py
@@ -0,0 +1,57 @@
def lambda_handler(event, context):
# TODO implement
import boto3
import datetime

client = boto3.client('ec2')
regions = [region['RegionName'] for region in client.describe_regions()['Regions']]
for regionnaire in regions:
print regionnaire
ec2 = boto3.client("ec2", region_name=regionnaire)
instances_list = ec2.describe_instances()
nowtime = datetime.datetime.now().strftime('%d%m%Y-%H-%M')
for reservation in instances_list['Reservations']:
for instance in reservation['Instances']:
ami = False
reboot = False
retention = 7
# UTC Time for IST Zone
timeToCreate = "18:30"
instanceName = "Unnamed"
if instance.get("Tags",None) != None:
tags = instance["Tags"]
for tag in tags:
if(tag["Key"] == "AMIBackup" and tag["Value"] == "Yes"):
ami = True
if(tag["Key"] == "Reboot" and tag["Value"] == "Yes"):
reboot = True
if(tag["Key"] == "AMITime"):
timeToCreate = tag["Value"]
if(tag["Key"] == "Retention"):
retention = tag["Value"]
if(tag["Key"] == "Name"):
instanceName = tag["Value"]
if(ami==True):
timeToCreate = datetime.datetime.strptime(timeToCreate,"%H:%M")
currTimeStr = datetime.datetime.now().strftime("%H:%M")
currTime = datetime.datetime.strptime(currTimeStr,"%H:%M")
delta = currTime - timeToCreate
deltaMinutes = abs(delta.total_seconds())
if(deltaMinutes < 900):
createImageResponse = ec2.create_image(
InstanceId = instance['InstanceId'],
NoReboot=(not reboot),
DryRun=False,
Description= instanceName + "-" + str(nowtime),
Name= instanceName + "-" + str(nowtime)
)
imageId = createImageResponse["ImageId"]
print imageId
final_tags = []
for tag in tags:
if not (tag['Key']=="Name"):
final_tags.append(tag)
if not (tag['Key'].startswith("aws:") or tag['Value'].startswith("aws:")):
final_tags.append(tag)
ec2.create_tags(Resources=[imageId],Tags=final_tags)
return 'createAMI run successfully'
31 changes: 31 additions & 0 deletions deleteAMI.py
@@ -0,0 +1,31 @@
def lambda_handler(event, context):
import boto3
import datetime
import time

client = boto3.client('ec2')
regions = [region['RegionName'] for region in client.describe_regions()['Regions']]
for regionnaire in regions:
print regionnaire
ec2 = boto3.client("ec2", region_name=regionnaire)
response = ec2.describe_images(Owners=['self'],DryRun=False)
for i in range(len(response['Images'])):
ami = False
retention = 7
creationDate = response["Images"][i]["CreationDate"][:10]
AMIdate = datetime.datetime.strptime(creationDate, '%Y-%m-%d')
timeStampNow = datetime.datetime.now()
if response['Images'][i].get("Tags",None) != None :
tags = response['Images'][i]['Tags']
for tag in tags:
if(tag["Key"] == "AMIBackup" and tag["Value"] == "Yes"):
ami = True
if(tag["Key"] == "Retention"):
retention = tag["Value"]
if(ami==True):
if (timeStampNow - AMIdate).days >= int(retention):
print str("Deleting AMI: ") + response["Images"][i]["ImageId"]
deregisterImageResponse = client.deregister_image(ImageId=response['Images'][i]['ImageId'])
time.sleep(1)
for k in range(len(response['Images'][i]['BlockDeviceMappings'])):
deleteSnapshotResponse = client.delete_snapshot(SnapshotId=response['Images'][i]['BlockDeviceMappings'][k]['Ebs']['SnapshotId'])

0 comments on commit 6ab401d

Please sign in to comment.