今回はLambda(サーバレス)を使用してEC2のインスタンス、EBSのスナップショット、
EIP、ELB/ALB/RDS/S3/CloudFrontをterminate/delete(削除)する方法をブログします。
■Lambdaとは
インスタンスベースの仮想サーバー(EC2、ElastiChache、Redshiftなど)を使わずにアプリケーションを開発するアーキテクチャで、毎回サーバを構築する必要がありません!なのでコスト削減に期待できます。
■Lambdaを使ってみる
AWSのインスタンス情報は基本jsonで返ってきます。今回は以下のコマンドで確認します。
1 2 3 |
#IAMの設定を事前にしときましょう $ aws ec2 describe-instances $ aws ec2 describe-snapshots |
AWS SDK For Python (Boto3)で書いてます。
・IAMにLambdaのロールを追加する
以下の3つの権限をぶち込んでください。
・Lambdaのコンソールを開き、新しく作成する
・Configure Function
・Dashboard
・スクリプトの紹介
やりたいことはKeyが「nodelete」Valueが「true」以外のものはインスタンスterminate(削除)します。空白のものも消えます。つまり、上記のタグにしとけば消えることはありません。あとはこのスクリプトをかましてcloud watchで3ヶ月に一回とかイベント設定すればOK。
- delete-cloudfront.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# coding: utf-8 # RDS delete import boto3 # nodelete,trueを変数化 ND = 'nodelete' TR = 'true' def lambda_handler(event, context): #if __name__ == '__main__': client = boto3.client('cloudfront', "ap-northeast-1") resp = client.list_distributions() #print resp all_list = [] del_list = [] for cf in resp['DistributionList']['Items']: #print cf['Id'] all_list.append(cf['Id']) #print all_list resp2 = client.list_tags_for_resource( Resource = "arn:aws:cloudfront::xxxxxxxxxxxxxxxxx:distribution/" + cf['Id'] ) #print resp2 for tag in resp2['Tags']['Items']: #print tag if tag['Key'] == ND and tag['Value'] == TR: del_list.append(cf['Id']) #print(del_list) diffset = set(all_list) - set(del_list) #print(diffset) targetlist = list(diffset) #print(targetlist) for target in targetlist: #print target response = client.delete_distribution( Id=target ) |
- delete-eip.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# coding: utf-8 #EC2に紐付いていないEIPを開放 import boto3 def lambda_handler(event, context): #if __name__ == '__main__': #EC2 client = boto3.client('ec2', "ap-northeast-1") resp = client.describe_addresses() #print(resp) for addresses in resp['Addresses']: #print(addresses['AllocationId']) if not 'InstanceId' in addresses: #print(addresses['AllocationId']) client.release_address( AllocationId=addresses['AllocationId'] ) |
- delete-elb-alb.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# coding: utf-8 #ELB delete import boto3 # nodelete,trueを変数化 ND = 'nodelete' TR = 'true' def lambda_handler(event, context): #if __name__ == '__main__': #EC2の場合 client = boto3.client('elb') #loadbalancersの情報を変数化 resp = client.describe_load_balancers() all_list1 = [] del_list1 = [] #loadbalancerNameでtagを出力 #print resp for elb in resp['LoadBalancerDescriptions']: all_list1.append(elb['LoadBalancerName']) #print(all_list) resp2 = client.describe_tags( LoadBalancerNames=[elb['LoadBalancerName']] ) #print(resp2) for tag in resp2['TagDescriptions']: #tagがnodelete以外を出力 for k in tag['Tags']: #print k if k['Key'] == ND and k['Value'] == TR: del_list1.append(elb['LoadBalancerName']) #print(del_list) diffset1 = set(all_list1) - set(del_list1) #print(diffset) targetlist1 = list(diffset1) #print(targetlist1) response = client.delete_load_balancer( LoadBalancerName=targetlist1 ) #ALB delete def lambda_handler(event, context): #if __name__ == '__main__': client = boto3.client('elbv2') #loadbalancersの情報を変数化 resp = client.describe_load_balancers() all_list2 = [] del_list2 = [] #loadbalancerNameでtagを出力 #print resp for alb in resp['LoadBalancers']: all_list2.append(alb['LoadBalancerArn']) #print(all_list2) resp2 = client.describe_tags( ResourceArns=[alb['LoadBalancerArn']] ) #print(resp2) for tag in resp2['TagDescriptions']: #tagがnodelete以外を出力 for a in tag['Tags']: #print a if a['Key'] == ND and a['Value'] == TR: del_list2.append(alb['LoadBalancerArn']) #print(del_list) diffset2 = set(all_list2) - set(del_list2) #print(diffset2) targetlist2 = list(diffset2) #print(targetlist2) response = client.delete_load_balancer( LoadBalancerArn=targetlist2 ) |
- delete-rds-snapshot.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# coding: utf-8 # RDS delete import boto3 # nodelete,trueを変数化 ND = 'nodelete' TR = 'true' def lambda_handler(event, context): #if __name__ == '__main__': client = boto3.client('rds', "ap-northeast-1") resp = client.describe_db_snapshots() #print resp all_list = [] del_list = [] for rds in resp['DBSnapshots']: all_list.append(rds['DBSnapshotIdentifier']) #print(all_list) resp2 = client.list_tags_for_resource( ResourceName="arn:aws:rds:ap-northeast-1:xxxxxxxxxxxx:snapshot:" + rds['DBSnapshotIdentifier'] ) #print resp2 for tag in resp2['TagList']: #print tag if tag['Key'] == ND and tag['Value'] == TR: del_list.append(rds['DBSnapshotIdentifier']) #print(del_list) diffset = set(all_list) - set(del_list) #print(diffset) targetlist = list(diffset) #print(targetlist) for target in targetlist: #print target response = client.delete_db_snapshot( DBSnapshotIdentifier=target, SkipFinalSnapshot=True ) |
- delete-rds.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# coding: utf-8 # RDS delete import boto3 # nodelete,trueを変数化 ND = 'nodelete' TR = 'true' #def lambda_handler(event, context): if __name__ == '__main__': client = boto3.client('rds', "ap-northeast-1") resp = client.describe_db_instances() all_list = [] del_list = [] for rds in resp['DBInstances']: all_list.append(rds['DBInstanceIdentifier']) #print(all_list) resp2 = client.list_tags_for_resource( ResourceName="arn:aws:rds:ap-northeast-1:xxxxxxxxxx:db:" + rds['DBInstanceIdentifier'] ) #print resp2 #タグ判別による出力 for tag in resp2['TagList']: #print tag if tag['Key'] == ND and tag['Value'] == TR: del_list.append(rds['DBInstanceIdentifier']) #print(del_list) diffset = set(all_list) - set(del_list) #print(diffset) targetlist = list(diffset) #print(targetlist) for target in targetlist: print target #print type(target) response = client.delete_db_instance( DBInstanceIdentifier=target, SkipFinalSnapshot=True, ) |
- delete-s3.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# coding: utf-8 # RDS delete import boto3 # nodelete,trueを変数化 ND = 'nodelete' TR = 'true' def lambda_handler(event, context): #if __name__ == '__main__': client = boto3.client('s3', "ap-northeast-1") resp = client.list_buckets() #print resp all_list = [] del_list = [] for s3 in resp['Buckets']: #print s3 all_list.append(s3['Name']) #print(all_list) try: resp2 = client.get_bucket_tagging( Bucket=s3['Name'] ) except: None #print s3['Name'] for tag in resp2['TagSet']: #print tag if tag['Key'] == ND and tag['Value'] == TR: del_list.append(s3['Name']) #print(del_list) diffset = set(all_list) - set(del_list) #print(diffset) targetlist = list(diffset) #print(targetlist) for target in targetlist: #print target # #print type(target) response = client.delete_bucket( Bucket=target ) |
- delete-security-groups.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# coding: utf-8 #EC2 SecurityGroups delete import boto3 # nodelete,trueを変数化 ND = 'nodelete' TR = 'true' def lambda_handler(event, context): #if __name__ == '__main__': #EC2上 ec2 = boto3.client('ec2') resp = ec2.describe_security_groups() all_list = [] del_list = [] #print (resp) for securitygroups in resp['SecurityGroups']: for groupid in securitygroups['GroupId']: all_list.append(securitygroups['GroupId']) #print(all_list) if 'Tags' in securitygroups: for tag in securitygroups['Tags']: #print(tag) if tag['Key'] == ND and tag['Value'] == TR: del_list.append(securitygroups['GroupId']) #print(del_list) diffset = set(all_list) - set(del_list) #print(diffset) targetlist = list(diffset) #print(targetlist) resp = ec2.delete_security_group( GroupId=targetlist ) |
- terminate-ebs-snapshot-delete.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
##スナップショットのTagsでKeyが「nodelete」Valueが「true」以外削除 # coding: utf-8 #EC2 snapshot delete import boto3 # nodelete,trueを変数化 ND = 'nodelete' TR = 'true' def lambda_handler(event, context): #if __name__ == '__main__': #EC2上 ec2 = boto3.client('ec2') resp = ec2.describe_snapshots() all_list = [] del_list = [] #print (resp) for snapshots in resp['Snapshots']: for snapshotid in snapshots['SnapshotId']: all_list.append(snapshots['SnapshotId']) #print(all_list) if 'Tags' in snapshots: for tag in snapshots['Tags']: #print(tag) if tag['Key'] == ND and tag['Value'] == TR: del_list.append(snapshots['SnapshotId']) #print(del_list) diffset = set(all_list) - set(del_list) #print(diffset) targetlist = list(diffset) #print(targetlist) resp = ec2.delete_snapshot( GroupId=targetlist ) |
- terminate-ec2-instances.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#Keyがnodelete、Valueがtrue以外は削除 # coding: utf-8 # EC2 terminate import boto3 #nodelete,trueを変数化 ND = 'nodelete' TR = 'true' def lambda_handler(event, context): #if __name__ == '__main__': #EC2上で client = boto3.client('ec2') resp = client.describe_instances() all_list = [] del_list = [] for reservation in resp['Reservations']: for instance in reservation['Instances']: all_list.append(instance['InstanceId']) #print(all_list) if 'Tags' in instance: #nodelete以外は削除 for tag in instance['Tags']: if tag['Key'] == ND and tag['Value'] == TR: del_list.append(instance['InstanceId']) #print(del_list) diffset = set(all_list) - set(del_list) #print(diffset) targetlist = list(diffset) #print(targetlist) ec2.terminate_instances( InstanceIds=targetlist ) |
■実際にテスト
今回はインスタンスをterminateするスクリプトでやってみます。実際にまずは削除プログラムをコメントアウトして、インスタンスIDがタグ判別で出力されるかやってみましょう。
■定期実行
Cloud Watchからイベントでルールの新規作成をします。スケジュールを選択肢し、
ターゲットの追加で先程のLambdaを以下のように追加します。追加するとLambdaのマネジメントコンソールからTriggerに反映されているはずです。
■まとめ
Pythonの基本勉強しよう。
やっぱコードとか実際に課題にそって作るのが一番覚えると思う!参考書は逆引きな感じで。
※ちなみにEC2から実行する場合は(もともとインスタンスにPythonが入っているので)
以下のようにしないとあかん。
・boto3のインストール
1 |
$ sudo pip install boto3 |
・Pythonスクリプトの変更
1 2 3 |
#def lambda_handler(event, context): #Lambdaの場合 if __name__ == '__main__': #EC2の場合 client = boto3.client('rds', "ap-northeast-1") #リージョンの追加 |
参考:
http://boto3.readthedocs.io/en/latest/index.html
http://qiita.com/Yuki_BB3/items/bf713a5141ea59b741dc
http://qiita.com/Yuki_BB3/items/7885e06f82bebfa8a3bb
0件のコメント