Skip to content

Commit 9ac345f

Browse files
author
masaki.sato
committed
Add Lambda Code
1 parent 209f42f commit 9ac345f

File tree

9 files changed

+396
-0
lines changed

9 files changed

+396
-0
lines changed
+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# 特定のタグを含むEBSボリュームのスナップショットを作成する。
4+
# Python 3.6
5+
#
6+
# (参考)
7+
# https://qiita.com/HorieH/items/66bb68d12bd8fdbbd076
8+
# https://inaba-serverdesign.jp/blog/20180330/aws_ec2_create_snapshot_lambda.html
9+
# EBSボリュームが存在するリージョンでLambda関数を作成すること。
10+
#
11+
# 対象とするボリュームのタグで、
12+
# Key: <TAGKEYの文字列>, Value: <保存世代数>
13+
# を設定すること。
14+
#
15+
TAGKEY = 'Backup-Generation'
16+
17+
import boto3
18+
import collections
19+
import time
20+
from datetime import datetime as dt
21+
22+
from botocore.client import ClientError
23+
import os
24+
25+
client = boto3.client('ec2', os.environ['AWS_REGION'])
26+
27+
def lambda_handler(event, context):
28+
descriptions = create_snapshots()
29+
delete_old_snapshots(descriptions)
30+
31+
def create_snapshots():
32+
volumes = get_volumes([TAGKEY])
33+
34+
descriptions = {}
35+
36+
for v in volumes:
37+
tags = { t['Key']: t['Value'] for t in v['Tags'] }
38+
generation = int( tags.get(TAGKEY, 0) )
39+
40+
if generation < 1:
41+
continue
42+
43+
volume_id = v['VolumeId']
44+
description = volume_id if tags.get('Name') is '' else '%s(%s)' % (volume_id, tags['Name'])
45+
description = 'Auto Snapshot ' + description
46+
snapshot = _create_snapshot(volume_id, description)
47+
snapshot_id = snapshot['SnapshotId']
48+
snapshot_name = get_snapshot_name(volume_id)
49+
print(snapshot_name)
50+
_create_tags(snapshot_id,snapshot_name)
51+
print('create snapshot %s(%s)' % (snapshot['SnapshotId'], description))
52+
53+
descriptions[description] = generation
54+
55+
return descriptions
56+
57+
def get_volumes(tag_names):
58+
volumes = client.describe_volumes(
59+
Filters=[
60+
{
61+
'Name': 'tag-key',
62+
'Values': tag_names
63+
}
64+
]
65+
)['Volumes']
66+
67+
return volumes
68+
69+
def delete_old_snapshots(descriptions):
70+
snapshots_descriptions = get_snapshots_descriptions(list(descriptions.keys()))
71+
72+
for description, snapshots in snapshots_descriptions.items():
73+
delete_count = len(snapshots) - descriptions[description]
74+
75+
if delete_count <= 0:
76+
continue
77+
78+
snapshots.sort(key=lambda x:x['StartTime'])
79+
80+
old_snapshots = snapshots[0:delete_count]
81+
82+
for s in old_snapshots:
83+
_delete_snapshot(s['SnapshotId'])
84+
print('delete snapshot %s(%s)' % (s['SnapshotId'], s['Description']))
85+
86+
def get_snapshots_descriptions(descriptions):
87+
snapshots = client.describe_snapshots(
88+
Filters=[
89+
{
90+
'Name': 'description',
91+
'Values': descriptions,
92+
}
93+
]
94+
)['Snapshots']
95+
96+
groups = collections.defaultdict(lambda: [])
97+
{ groups[ s['Description'] ].append(s) for s in snapshots }
98+
99+
return groups
100+
101+
def _create_snapshot(id, description):
102+
for i in range(1, 3):
103+
try:
104+
return client.create_snapshot(VolumeId=id,Description=description)
105+
except ClientError as e:
106+
print(str(e))
107+
time.sleep(1)
108+
raise Exception('cannot create snapshot ' + description)
109+
110+
def _delete_snapshot(id):
111+
for i in range(1, 3):
112+
try:
113+
return client.delete_snapshot(SnapshotId=id)
114+
except ClientError as e:
115+
print(str(e))
116+
if e.response['Error']['Code'] == 'InvalidSnapshot.InUse':
117+
return;
118+
time.sleep(1)
119+
raise Exception('cannot delete snapshot ' + id)
120+
121+
def _create_tags(id,name):
122+
response = client.create_tags(
123+
DryRun=False,
124+
Resources=[
125+
id ,
126+
],
127+
Tags=[
128+
{
129+
'Key': 'Name',
130+
'Value': name
131+
},
132+
]
133+
)
134+
def get_snapshot_name(id):
135+
exec_time = dt.now().strftime('%Y%m%d')
136+
response = 'Seven Batch Add Volume_' + exec_time
137+
print(response)
138+
return response
139+
# EOF

EBS_CreateSnapshot/Readme.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lifecycle_managerがあるからもうつかわなそう

EC2_StartStop/EC2_Start.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# -*- coding: utf-8 -*-
2+
import boto3
3+
4+
def lambda_handler(event, context):
5+
# Enter the region your instances are in, e.g. 'us-east-1'
6+
region = event['Region']
7+
# Enter your instances from CloudWatch constant
8+
instances = event['Instances']
9+
ec2 = boto3.client('ec2', region_name=region)
10+
11+
available_instances = []
12+
13+
# get stopped instances
14+
try:
15+
response = ec2.describe_instances(
16+
Filters=[
17+
{
18+
'Name': 'instance-state-name',
19+
'Values': ['stopped']
20+
},
21+
],
22+
InstanceIds=instances
23+
)
24+
stopped_instances = [v['Instances'][0]['InstanceId'] for v in response['Reservations']]
25+
except Exception as e:
26+
print('failed get stopped instances: ' + str(instances))
27+
print(e)
28+
raise e
29+
30+
# started your instances
31+
try:
32+
if stopped_instances:
33+
ec2.start_instances(InstanceIds=stopped_instances)
34+
print('started your instances: ' + str(instances))
35+
else:
36+
print('There are no stopped instances')
37+
except Exception as e:
38+
print('failed started your instances: ' + str(instances))
39+
print(e)
40+
raise e

EC2_StartStop/EC2_Stop.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# -*- coding: utf-8 -*-
2+
import boto3
3+
4+
def lambda_handler(event, context):
5+
# Enter the region your instances are in, e.g. 'us-east-1'
6+
region = event['Region']
7+
# Enter your instances from CloudWatch constant
8+
instances = event['Instances']
9+
ec2 = boto3.client('ec2', region_name=region)
10+
11+
stopped_instances = []
12+
13+
# get available instances
14+
try:
15+
response = ec2.describe_instances(
16+
Filters=[
17+
{
18+
'Name': 'instance-state-name',
19+
'Values': ['running']
20+
},
21+
],
22+
InstanceIds=instances
23+
)
24+
available_instances = [v['Instances'][0]['InstanceId'] for v in response['Reservations']]
25+
except Exception as e:
26+
print('failed get available instances: ' + str(instances))
27+
print(e)
28+
raise e
29+
30+
# stopped your instances
31+
try:
32+
if available_instances:
33+
ec2.stop_instances(InstanceIds=available_instances)
34+
print('stopped your instances: ' + str(instances))
35+
else:
36+
print('There are no instances running')
37+
except Exception as e:
38+
print('failed stopped your instances: ' + str(instances))
39+
print(e)
40+
raise e

EC2_StartStop/Readme.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CloudwatchEventで下記のように定数を指定しておく
2+
3+
{"Region": "ap-northeast-1", "Instances": ["i-08922ebf858160ee0","i-088aff367c751032d"]}

RDS_StartStop/Readme.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CloudwatchEventで下記のように定数を指定しておく
2+
3+
{"Region": "ap-northeast-1", "Db_Instance": "seven-db"}
4+

RDS_StartStop/Start_RDS.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# -*- coding: utf-8 -*-
2+
import boto3
3+
4+
def lambda_handler(event, context):
5+
# Enter the region your instances are in, e.g. 'us-east-1'
6+
region = event['Region']
7+
# Enter your instances from CloudWatch constant
8+
db_instance = event['Db_Instance']
9+
rds = boto3.client('rds', region_name=region)
10+
db_status = False
11+
12+
# check db instance state
13+
try:
14+
response = rds.describe_db_instances(
15+
Filters=[
16+
{'Name': 'db-instance-id',
17+
'Values': [db_instance]
18+
},
19+
]
20+
)
21+
if response['DBInstances'][0]['DBInstanceStatus'] == 'available': db_status = True
22+
except Exception as e:
23+
print('failed check db instance state: ' + str(db_instance))
24+
print(e)
25+
raise e
26+
27+
# started your db instance
28+
try:
29+
if not db_status:
30+
rds.start_db_instance(DBInstanceIdentifier=db_instance)
31+
print('started your db instance: ' + str(db_instance))
32+
else:
33+
print('DB is running')
34+
except Exception as e:
35+
print('failed started your db instance: ' + str(db_instance))
36+
print(e)
37+
raise e

RDS_StartStop/Stop_RDS.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# -*- coding: utf-8 -*-
2+
import boto3
3+
4+
def lambda_handler(event, context):
5+
# Enter the region your instances are in, e.g. 'us-east-1'
6+
region = event['Region']
7+
# Enter your instances from CloudWatch constant
8+
db_instance = event['Db_Instance']
9+
rds = boto3.client('rds', region_name=region)
10+
db_status = False
11+
12+
# check db instance state
13+
try:
14+
response = rds.describe_db_instances(
15+
Filters=[
16+
{'Name': 'db-instance-id',
17+
'Values': [db_instance]
18+
},
19+
]
20+
)
21+
if response['DBInstances'][0]['DBInstanceStatus'] == 'available': db_status = True
22+
except Exception as e:
23+
print('failed check db instance state: ' + str(db_instance))
24+
print(e)
25+
raise e
26+
27+
# stop your db instance
28+
try:
29+
if db_status:
30+
rds.stop_db_instance(DBInstanceIdentifier=db_instance)
31+
print('stop your db instance: ' + str(db_instance))
32+
else:
33+
print('DB is stopped')
34+
except Exception as e:
35+
print('failed stop your db instance: ' + str(db_instance))
36+
print(e)
37+
raise e

0 commit comments

Comments
 (0)