Friday, May 17, 2019

Lamda Function for changing route



import boto3
import socket
from botocore.vendored import requests
from botocore.exceptions import ClientError

SITE = 'https://www.amazon.com'
EIP = '18.202.107.127'
ENIs = ['eni-0f14174a11562151a','eni-0a7bd8e642929360b']
Instance_IDs = ['i-06ab2c2f619075c6b','i-08b596cb658ffe26b']
region = 'eu-west-1'
ec2=boto3.client('ec2',region)
sns = boto3.client('sns',region)

def getNetworkInterface(response):
        network_interface_id = ''
        instance_ID = ''
        for route_table in response["RouteTables"]:
                for route in route_table["Routes"]:
                        if route["DestinationCidrBlock"] == '0.0.0.0/0':
                                network_interface_id = route["NetworkInterfaceId"]
                                instance_ID = route["InstanceId"]
        return {"network_interface_id" : network_interface_id,"instance_id": instance_ID }

def Send_SMS(status):
        sns.publish(Message=('Attention! Performing failover to the standby NAT instance.\nThe probe for {0} has {1}'.format(SITE,status)),PhoneNumber='+971564168199')

def EIP_Change(Instance_Id):
        try:
                EIP_info = ec2.describe_addresses(PublicIps=[EIP])
                Allocation_Id = EIP_info["Addresses"][0]["AllocationId"]
                if "AssociationId" in EIP_info["Addresses"][0]:
                        Association_Id = EIP_info["Addresses"][0]["AssociationId"]
                        disassociate_response = ec2.disassociate_address(AssociationId=Association_Id)
                response = ec2.associate_address(AllocationId=Allocation_Id,InstanceId=Instance_Id)
        except ClientError as e:
                 print(e)
     
def Update_RTL():
        response = ec2.describe_route_tables(RouteTableIds=['rtb-0d5ddcf5212b20ae7'])
        current_ENI =  getNetworkInterface(response)
        available_ENIs = list(filter(lambda x: x != current_ENI["network_interface_id"], ENIs))
        current_Nat_Instance = current_ENI["instance_id"]
        available_Nat_Instance = list(filter(lambda x: x != current_Nat_Instance, Instance_IDs))
        available_Nat_Instance_Status = ec2.describe_instance_status(InstanceIds=[available_Nat_Instance[0]])
        if available_Nat_Instance_Status['InstanceStatuses'][0]['InstanceStatus']['Details'][0]['Status'] == 'passed' and available_Nat_Instance_Status['InstanceStatuses'][0]['InstanceStatus']['Status'] =='ok':
                print("Target instance is healthy")
                EIP_Change(available_Nat_Instance[0])
                change = ec2.replace_route(DestinationCidrBlock='0.0.0.0/0',NetworkInterfaceId=available_ENIs[0],RouteTableId='rtb-0d5ddcf5212b20ae7')
                if change['ResponseMetadata']['HTTPStatusCode'] == 200:
                         print('Routing table was updated successfully.')
                else:
                        print('Routing table update failed. Request returned HTTP status code:',change['ResponseMetadata']['HTTPStatusCode'])
        else:
                print("Failover couldn't be performed. The backup instance isn't healthy")
       
def lambda_handler(event, context):
        try:
                Web_Request_Test = requests.get(SITE,timeout=1)
        except:
                print("The heath check failed. Switching over to standby instance.")
                Update_RTL()
                Send_SMS('FAILED.')
        else:
                print("The health check succeeded. No Action will be taken.")