pythonでEC2のリソースチェックする(AWS APIを利用) on CentOS
前提
- aws cliをインストール(Installing the AWS CLI)して、aws configureは設定しておく。
- aws configureしておく。(What Is the AWS Command Line Interface?)
- vagrantを使ってのインストールは前回の(ココ)を参照
やること
1. boto3のインストール
# インストール $ pip install boto3 # バージョン確認 $ pip freeze | grep boto3 boto3==1.14.12
すべてのインスタンスの起動、停止
ec2_status.py
#!/usr/bin/env python3 import sys import logging import boto3 import botocore from ec2.check import EC2_Instance_Check # ログレベル設定 logging.basicConfig(level=logging.INFO) ''' # ログ群 logging.critical('critical') logging.error('error') logging.warning('warning') logging.info('info') logging.debug('debug') ''' class RDS_Instance_Check: rds = None def __init__(self): self.rds = boto3.client('rds') def get_tags_for_db(self, db): try: logging.debug("get_tags_for_db start") instance_arn = db['DBInstanceArn'] instance_tags = self.rds.list_tags_for_resource(ResourceName=instance_arn) return instance_tags['TagList'] except: raise def start_db_instances(self, target_tag): try: dbs = self.rds.describe_db_instances() except Exception as e: print(e) return { 'status': 2 } for db in dbs['DBInstances']: db_tags = get_tags_for_db(db) tag = next(iter(filter(lambda tag: tag['Key'] == target_tag and tag['Value'] == 'True', db_tags)), None) if tag and db['DBInstanceStatus'] == 'stopped': response = rds.start_db_instance(DBInstanceIdentifier=db["DBInstanceIdentifier"]) print(db['DBInstanceIdentifier']) raise def lambda_start_handler(self, event, context): target_tag = "AutoStart" start_db_instances(target_tag) return { 'status': 0 } def stop_db_instances(self, target_tag): """ stop instances """ try: dbs = rds.describe_db_instances() except Exception as e: print(e) return { 'status': 2 } for db in dbs['DBInstances']: db_tags = get_tags_for_db(db) tag = next(iter(filter(lambda tag: tag['Key'] == target_tag and tag['Value'] == 'True', db_tags)), None) if tag and db['DBInstanceStatus'] == 'available': response = rds.stop_db_instance(DBInstanceIdentifier=db["DBInstanceIdentifier"]) print(db['DBInstanceIdentifier']) def lambda_stop_handler(self, event, context): target_tag = "AutoStop" stop_db_instances(target_tag) return { 'status': 0 } if __name__ == '__main__': args = sys.argv # print (boto3.Session().get_credentials().access_key) # print boto3.Session().get_credentials().secret_key inscheck = EC2_Instance_Check() # 停止しているInstanceをすべて起動する # inscheck.start_first_instances(inscheck.ListInstances) # inscheck.start_all_instances() # 指定するIDのインスタンスをすべて停止する # inscheck.stop_instances(inscheck.ListInstances, inscheck.CODE_STOPPING) # 起動しているInstanceをすべてTerminateする inscheck.stop_all_instances(inscheck.CODE_TERMINATED)
check.py
#!/usr/bin/env python3 import sys import logging import boto3 import botocore import time # ログレベル設定 logging.basicConfig(level=logging.DEBUG) ''' # ログ群 logging.critical('critical') logging.error('error') logging.warning('warning') logging.info('info') logging.debug('debug') ''' class EC2_Instance_Check: CODE_PENDING = 0 CODE_RUNNING = 16 CODE_SHUTTING_DOWN = 32 CODE_TERMINATED = 48 CODE_STOPPING = 64 CODE_STOPED = 80 FIRST_FTP_SRV_ID = 'i-0c4b0ba37630791a0' FIRST_STORAGE_SRV_ID = FIRST_FTP_SRV_ID FIRST_BASTION_SRV_ID = FIRST_FTP_SRV_ID ListInstances=[ FIRST_FTP_SRV_ID ,FIRST_STORAGE_SRV_ID ,FIRST_BASTION_SRV_ID ] RETRY_VALUE = 3 WAIT_TIME = 2 def start_first_instances(self, instanceList): try: logging.debug("start_first_instances start") ec2 = boto3.client('ec2') for instance_id in instanceList: # Instance起動 response = ec2.start_instances(InstanceIds=[instance_id]) logging.info(" ==> instance start:%s", response) # リスト順に1インスタンスずつ完全起動を繰り返す。 # 10回はリトライする for i in range(self.RETRY_VALUE): time.sleep(self.WAIT_TIME) instance_statuses = ec2.describe_instance_status(InstanceIds=[instance_id]) if instance_statuses['InstanceStatuses'][0]['InstanceState']['Code'] == self.CODE_RUNNING: logging.info(" ==> instance launched") break; except botocore.exceptions.ClientError as e: code = e.response['Error']['Code'] status_code = e.response['ResponseMetadata']['HTTPStatusCode'] message = e.response['Error']['Message'] if e.response['ResponseMetadata']['HTTPStatusCode'] == 400: logging.error("%s, %s", code, message) else: # まだ未発見のエラー logging.error("%s, %s, %s",status_code, code, message) raise Exception(e) except Exception as e: # まだ未発見のエラー logging.error("!! Undiscovered Error !!") raise Exception(e) def start_all_instances(self): try: logging.debug("=== start_all_instances start") # ec2 = boto3.client('ec2').describe_instances() ec2 = boto3.client('ec2') res = ec2.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values':['stopping','stopped']}]); if 0 == len(res['Reservations']): logging.info("Nothing instance") return False instances = res['Reservations'][0]['Instances'] for instance in instances: state = instance.get('State') keyname = instance.get('KeyName') logging.debug(" ==> KeyName:%s, Status: %s", keyname, state) code = state.get('Code') if code == self.CODE_STOPED: instance_id = instance.get('InstanceId') # Instance起動 ec2.start_instances(InstanceIds=[instance_id]) logging.info(" ==> instance start:%s", instance_id) logging.info("=== start_all_instances Success") return True except botocore.exceptions.ClientError as e: code = e.response['Error']['Code'] status_code = e.response['ResponseMetadata']['HTTPStatusCode'] message = e.response['Error']['Message'] if e.response['ResponseMetadata']['HTTPStatusCode'] == 400: logging.error("%s, %s", code, message) else: # まだ未発見のエラー logging.error("%s, %s, %s",status_code, code, message) raise Exception(e) except Exception as e: # まだ未発見のエラー logging.error("!! Undiscovered Error !!") raise Exception(e) def stop_instances(self, instanceList, destStatus): try: logging.info("start_stop_instances start") ec2 = boto3.client('ec2') for instanceId in instanceList: # Instance停止 try: # boto3 new method 使えない。。。response = ec2.instances.filter(InstanceIds=instanceId).stop() response = ec2.stop_instances(InstanceIds=[instanceId]) logging.info(" ==> response:%s", response) # リスト順に1インスタンスずつ完全停止を繰り返す。 # 10回はリトライする for i in range(self.RETRY_VALUE): time.sleep(self.WAIT_TIME) # boto3 new method 使えない。。status = ec2.meta.client.describe_instance_status(InstanceIds=[instanceId]) status = ec2.describe_instance_status(InstanceIds=[instanceId]) if len(status['InstanceStatuses']) != 0: code = status['InstanceStatuses'][0]['InstanceState']['Code'] name = status['InstanceStatuses'][0]['InstanceState']['Name'] if code == self.CODE_STOPPING or code == self.CODE_STOPED : logging.info(" ==> instance stopped: %s", code) break else: code = status['ResponseMetadata']['HTTPStatusCode'] if code == 200: logging.info(" ==> instance stopping: %s", code) break logging.info("not enough %s, %s, %s, %s", i, instanceId, name) except Exception as e: logging.info('instance:%s is no existed', instanceId) continue except botocore.exceptions.ClientError as e: code = e.response['Error']['Code'] status_code = e.response['ResponseMetadata']['HTTPStatusCode'] message = e.response['Error']['Message'] if e.response['ResponseMetadata']['HTTPStatusCode'] == 400: logging.error("%s, %s", code, message) else: # まだ未発見のエラー logging.error("%s, %s, %s",status_code, code, message) raise Exception(e) except Exception as e: # まだ未発見のエラーがあるかも raise Exception(e) def stop_all_instances(self, destStatus): try: logging.debug("=== stop_all_instances start") # ec2 = boto3.client('ec2').describe_instances() ec2 = boto3.client('ec2') res = ec2.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values':['pending','running','stopping','stopped']}]); if 0 == len(res['Reservations']): logging.info("Nothing instance") return False instances = res['Reservations'][0]['Instances'] for instance in instances: state = instance.get('State') keyname = instance.get('KeyName') logging.debug(" ==> KeyName:%s, Status: %s", keyname, state) code = state.get('Code') instance_id = instance.get('InstanceId') if destStatus == self.CODE_TERMINATED: ec2.terminate_instances(InstanceIds=[instance_id]) logging.info("=== terminate_all_instances Success") else: ec2.stop_instances(InstanceIds=[instance_id]) logging.info("=== stop_all_instances Success") return True except botocore.exceptions.ClientError as e: code = e.response['Error']['Code'] status_code = e.response['ResponseMetadata']['HTTPStatusCode'] message = e.response['Error']['Message'] if e.response['ResponseMetadata']['HTTPStatusCode'] == 400: logging.error("%s, %s", code, message) else: # まだ未発見のエラー logging.error("%s, %s, %s",status_code, code, message) raise Exception(e) except Exception as e: # まだ未発見のエラー logging.error("!! Undiscovered Error !!") raise Exception(e)RDSの起動、停止
#!/usr/bin/env python3 import sys import logging import boto3 import botocore import ec2.EC2_Instance_Check as EC2_Instance_Check # ログレベル設定 logging.basicConfig(level=logging.DEBUG) ''' # ログ群 logging.critical('critical') logging.error('error') logging.warning('warning') logging.info('info') logging.debug('debug') ''' class RDS_Instance_Check: rds = None def __init__(self): self.rds = boto3.client('rds') def get_tags_for_db(self, db): try: logging.debug("get_tags_for_db start") instance_arn = db['DBInstanceArn'] instance_tags = self.rds.list_tags_for_resource(ResourceName=instance_arn) return instance_tags['TagList'] except: raise def start_db_instances(self, target_tag): try: dbs = self.rds.describe_db_instances() except Exception as e: print(e) return { 'status': 2 } for db in dbs['DBInstances']: db_tags = get_tags_for_db(db) tag = next(iter(filter(lambda tag: tag['Key'] == target_tag and tag['Value'] == 'True', db_tags)), None) if tag and db['DBInstanceStatus'] == 'stopped': response = rds.start_db_instance(DBInstanceIdentifier=db["DBInstanceIdentifier"]) print(db['DBInstanceIdentifier']) raise def lambda_start_handler(self, event, context): target_tag = "AutoStart" start_db_instances(target_tag) return { 'status': 0 } def stop_db_instances(self, target_tag): """ stop instances """ try: dbs = rds.describe_db_instances() except Exception as e: print(e) return { 'status': 2 } for db in dbs['DBInstances']: db_tags = get_tags_for_db(db) tag = next(iter(filter(lambda tag: tag['Key'] == target_tag and tag['Value'] == 'True', db_tags)), None) if tag and db['DBInstanceStatus'] == 'available': response = rds.stop_db_instance(DBInstanceIdentifier=db["DBInstanceIdentifier"]) print(db['DBInstanceIdentifier']) def lambda_stop_handler(self, event, context): target_tag = "AutoStop" stop_db_instances(target_tag) return { 'status': 0 } if __name__ == '__main__': args = sys.argv # print (boto3.Session().get_credentials().access_key) # print boto3.Session().get_credentials().secret_key inscheck = EC2_Instance_Check() # 停止しているInstanceをすべて起動させる inscheck.start_first_instances() inscheck.start_all_instances() # 起動しているInstanceをすべて停止させる inscheck.stop_all_instances(inscheck.CODE_TERMINATED)
参考:
コメント
コメントを投稿