def create_resources(event): """ This method is called from the lambda handler entry point. The following actions are performed: - validate the AMI-ID - deploys the ```sched_evt1``` lambda function. :param event: :return: None """ stackname = event['ResourceProperties']['StackName'] logger.info('Creating resources for stackname: ' + stackname) r = event['ResourceProperties'] logger.info('Dump all the parameters') logger.info(r) debug = r['Debug'] ScalingParameter = r['ScalingParameter'] ScalingPeriod = r['ScalingPeriod'] ScaleUpThreshold = r['ScaleUpThreshold'] ScaleDownThreshold = r['ScaleDownThreshold'] MinInstancesASG = r['MinInstancesASG'] MaximumInstancesASG = r['MaximumInstancesASG'] VpcId = r['VpcId'] FWInstanceType = r['FWInstanceType'] BootstrapS3Bucket = r['BootstrapS3Bucket'] SubnetIDTrust = r['SubnetIDTrust'] SubnetIDUntrust = r['SubnetIDUntrust'] SubnetIDMgmt = r['SubnetIDMgmt'] TrustSecurityGroup = r['TrustSecurityGroup'] UntrustSecurityGroup = r['UntrustSecurityGroup'] MgmtSecurityGroup = r['MgmtSecurityGroup'] VPCSecurityGroup = r['VPCSecurityGroup'] ELBName = r['ELBName'] ELBTargetGroupName = r['ELBTargetGroupName'] SSHLocation = r['SSHLocation'] ImageID = r['ImageID'] KeyName = r['KeyName'] LambdaENISNSTopic = r['LambdaENISNSTopic'] Region = r['Region'] LambdaExecutionRole = r['LambdaExecutionRole'] PanS3KeyTpl = r['PanS3KeyTpl'] FirewallBootstrapRole = r['FirewallBootstrapRole'] ASGNotifierRole = r['ASGNotifierRole'] ASGNotifierRolePolicy = r['ASGNotifierRolePolicy'] KeyPANWFirewall = r['KeyPANWFirewall'] KeyPANWPanorama = r['KeyPANWPanorama'] SubnetIDNATGW = r['SubnetIDNATGW'] SubnetIDLambda = r['SubnetIDLambda'] KeyDeLicense = r['KeyDeLicense'] LambdaENIQueue = r['LambdaENIQueue'] NetworkLoadBalancerQueue = r['NetworkLoadBalancerQueue'] SubnetIDTrust = str(lib.fix_unicode(SubnetIDTrust)) SubnetIDTrust = lib.fix_subnets(SubnetIDTrust) SubnetIDUntrust = str(lib.fix_unicode(SubnetIDUntrust)) SubnetIDUntrust = lib.fix_subnets(SubnetIDUntrust) SubnetIDMgmt = str(lib.fix_unicode(SubnetIDMgmt)) SubnetIDMgmt = lib.fix_subnets(SubnetIDMgmt) SubnetIDLambda = str(lib.fix_unicode(SubnetIDLambda)) SubnetIDLambda = lib.fix_subnets(SubnetIDLambda) SubnetIDNATGW = str(lib.fix_unicode(SubnetIDNATGW)) SubnetIDNATGW = lib.fix_subnets(SubnetIDNATGW) logger.info( 'Creating Sched Lambda funcion (VIP Monitoring) for stackname: ' + stackname) r = event['ResourceProperties'] lambda_exec_role_name = r['LambdaExecutionRole'] LambdaS3Bucket = r['LambdaS3Bucket'] if LambdaS3Bucket == "panw-aws-autoscale-v20": LambdaS3Bucket = LambdaS3Bucket + "-" + Region logger.info( '-------------------------------------------------------------------------------' ) logger.info('Lambda Template S3 Bucket: ' + LambdaS3Bucket + ' S3Key is : ' + PanS3KeyTpl) logger.info( '-------------------------------------------------------------------------------' ) event_rule_name = get_event_rule_name(stackname) logger.info('Creating event rule: ' + event_rule_name) response = events_client.put_rule(Name=event_rule_name, ScheduleExpression='rate(1 minute)', State='ENABLED') events_source_arn = response.get('RuleArn') logger.info('Getting IAM role') lambda_exec_role_arn = iam.get_role( RoleName=lambda_exec_role_name).get('Role').get('Arn') lambda_func_name = lib.get_sched_func_name(stackname, ELBTargetGroupName) logger.info('creating lambda function: ' + lambda_func_name) logger.info('SubnetIDLambda: {}'.format(SubnetIDLambda)) subnetids = SubnetIDLambda.split(",") response = lambda_client.create_function( FunctionName=lambda_func_name, Runtime='python2.7', Role=lambda_exec_role_arn, Handler='sched_evt1.lambda_handler', Code={ 'S3Bucket': LambdaS3Bucket, 'S3Key': PanS3KeyTpl }, MemorySize=256, Timeout=120, VpcConfig={ 'SubnetIds': subnetids, 'SecurityGroupIds': [VPCSecurityGroup] }) logger.info('Lambda function sched_evt created...') sched_evt_lambda_arn = response.get('FunctionArn') response = lambda_client.add_permission( FunctionName=sched_evt_lambda_arn, StatementId=lib.get_lambda_statement_id(stackname, ELBTargetGroupName), Action='lambda:InvokeFunction', Principal='events.amazonaws.com', SourceArn=events_source_arn) c = read_s3_object(BootstrapS3Bucket, "config/init-cfg.txt") dict = lib.get_values_from_init_cfg(c) logger.info('Init CFG bootstrap file Panorama settings: ') logger.info(dict) pip = dict['panorama-server'] pdg = dict['dgname'] ptpl = dict['tplname'] Input = { 'ScalingParameter': ScalingParameter, 'ScalingPeriod': ScalingPeriod, 'StackName': stackname, 'VpcId': VpcId, 'FWInstanceType': FWInstanceType, 'BootstrapS3Bucket': BootstrapS3Bucket, 'SubnetIDTrust': SubnetIDTrust, 'SubnetIDUntrust': SubnetIDUntrust, 'SubnetIDMgmt': SubnetIDMgmt, 'TrustSecurityGroup': TrustSecurityGroup, 'UntrustSecurityGroup': UntrustSecurityGroup, 'MgmtSecurityGroup': MgmtSecurityGroup, 'VPCSecurityGroup': VPCSecurityGroup, 'MaximumInstancesASG': MaximumInstancesASG, 'ELBName': ELBName, 'ELBTargetGroupName': ELBTargetGroupName, 'SSHLocation': SSHLocation, 'ImageID': ImageID, 'ScaleUpThreshold': ScaleUpThreshold, 'ScaleDownThreshold': ScaleDownThreshold, 'KeyName': KeyName, 'LambdaENISNSTopic': LambdaENISNSTopic, 'MinInstancesASG': MinInstancesASG, 'Region': Region, 'FirewallBootstrapRole': FirewallBootstrapRole, 'LambdaExecutionRole': LambdaExecutionRole, 'ASGNotifierRole': ASGNotifierRole, 'ASGNotifierRolePolicy': ASGNotifierRolePolicy, 'LambdaS3Bucket': LambdaS3Bucket, 'PanS3KeyTpl': PanS3KeyTpl, 'KeyPANWFirewall': KeyPANWFirewall, 'KeyPANWPanorama': KeyPANWPanorama, 'SubnetIDNATGW': SubnetIDNATGW, 'SubnetIDLambda': SubnetIDLambda, 'PIP': pip, 'PDG': pdg, 'PTPL': ptpl, 'Hostname': dict['hostname'], 'KeyDeLicense': KeyDeLicense, 'LambdaENIQueue': LambdaENIQueue, 'NetworkLoadBalancerQueue': NetworkLoadBalancerQueue, 'Debug': debug } stack_metadata = { 'SGM': MgmtSecurityGroup, 'SGU': UntrustSecurityGroup, 'SGT': TrustSecurityGroup, 'SGV': VPCSecurityGroup, 'IamLambda': LambdaExecutionRole, 'StackName': stackname, 'Region': Region, 'LambdaS3Bucket': LambdaS3Bucket, 'PanS3KeyTpl': PanS3KeyTpl, 'ScalingParameter': ScalingParameter, 'SubnetIDNATGW': SubnetIDNATGW, 'PIP': pip, 'PDG': pdg, 'PTPL': ptpl, 'Hostname': dict['hostname'], 'Debug': debug } lib.set_queue_attributes(LambdaENIQueue, 345600) lib.set_queue_attributes(NetworkLoadBalancerQueue, 345600) logger.info( "Send initial message onto the queue: {}".format(LambdaENIQueue)) lib.send_message_to_queue(LambdaENIQueue, json.dumps(stack_metadata)) logger.info('Event put targets') target_id_name = get_target_id_name(stackname) response = events_client.put_targets(Rule=event_rule_name, Targets=[{ 'Id': target_id_name, 'Arn': sched_evt_lambda_arn, 'Input': json.dumps(Input) }])
def update_resources(event): """ Method to handle any updates to the CFT templates. :param event: CFT input parameters :return: None """ global asg_name global untrust global PanS3KeyTpl global LambdaS3Bucket global KeyPANWPanorama global KeyPANWFirewall global ScalingParameter global Namespace global ilb_ip_address global ilb_name global elb_name global SubnetIDLambda global sgv global Arn stackname = event['ResourceProperties']['StackName'] logger.info('Updating resources for stackname: ' + stackname) Arn = event['StackId'] r = event['ResourceProperties'] oldr = event['OldResourceProperties'] logger.info('Dump all the new parameters') logger.info(r) logger.info('Dump all the OLD parameters') logger.info(oldr) LambdaExecutionRole = r['LambdaExecutionRole'] LambdaS3Bucket = r['LambdaS3Bucket'] PanS3KeyTpl = r['PanS3KeyTpl'] KeyPANWFirewall = r['KeyPANWFirewall'] KeyPANWPanorama = r['KeyPANWPanorama'] KeyDeLicense = r['KeyDeLicense'] elb_name = r['ELBName'] ELBTargetGroupName = r['ELBTargetGroupName'] sgv = r['VPCSecurityGroup'] ScalingParameter = r['ScalingParameter'] MaximumInstancesASG = r['MaximumInstancesASG'] MinInstancesASG = r['MinInstancesASG'] ScaleUpThreshold = r['ScaleUpThreshold'] ScaleDownThreshold = r['ScaleDownThreshold'] ScalingPeriod = r['ScalingPeriod'] BootstrapS3Bucket = r['BootstrapS3Bucket'] LambdaENIQueue = r['LambdaENIQueue'] NetworkLoadBalancerQueue = r['NetworkLoadBalancerQueue'] ASGNotifierRole = str(r['ASGNotifierRole']) LambdaENISNSTopic = str(r['LambdaENISNSTopic']) SubnetIDTrust = r['SubnetIDTrust'] SubnetIDUntrust = r['SubnetIDUntrust'] SubnetIDMgmt = r['SubnetIDMgmt'] SubnetIDTrust = str(lib.fix_unicode(SubnetIDTrust)) SubnetIDTrust = lib.fix_subnets(SubnetIDTrust) SubnetIDUntrust = str(lib.fix_unicode(SubnetIDUntrust)) SubnetIDUntrust = lib.fix_subnets(SubnetIDUntrust) SubnetIDMgmt = str(lib.fix_unicode(SubnetIDMgmt)) SubnetIDMgmt = lib.fix_subnets(SubnetIDMgmt) logger.info('Purging LambdaENIqueue: {}'.format(LambdaENIQueue)) lib.purge_stack_queue(LambdaENIQueue) logger.info('Purging NLB queue: {}'.format(NetworkLoadBalancerQueue)) lib.purge_stack_queue(NetworkLoadBalancerQueue) if remove_sched_func(stackname, ELBTargetGroupName) == False: logger.error('Failed to delete Sched Lambda Func (VIP Monitoring)') return create_resources(event) if LambdaS3Bucket == "panw-aws-autoscale-v20": region = r['Region'] LambdaS3Bucket = LambdaS3Bucket + "-" + region logger.info( '-------------------------------------------------------------------------------' ) logger.info('Lambda Template S3 Bucket: ' + LambdaS3Bucket + ' S3Key is : ' + PanS3KeyTpl) logger.info( '-------------------------------------------------------------------------------' ) lambda_func_name = r['FwInit'] try: lambda_client.update_function_code(FunctionName=lambda_func_name, S3Bucket=LambdaS3Bucket, S3Key=PanS3KeyTpl) logger.info('Updated FwInit Lambda Function Code Successfully') except Exception as e: logger.error('Update Resource for FwInit Lambda Failed') logger.error("[Update Resource FwInit Lambda]: {}".format(e)) return False lambda_func_name = r['InitLambda'] try: lambda_client.update_function_code(FunctionName=lambda_func_name, S3Bucket=LambdaS3Bucket, S3Key=PanS3KeyTpl) logger.info('Updated Init Lambda Function Code Successfully') except Exception as e: logger.error('Update Resource for Init Lambda Failed') logger.error("[Update Resource Init Lambda]: {}".format(e)) return False fw_azs = lib.getAzs(SubnetIDTrust) for i in fw_azs: search = lib.get_asg_name(stackname, ELBTargetGroupName, i) response = asg.describe_auto_scaling_groups( AutoScalingGroupNames=[search]) if len(response['AutoScalingGroups']) == 0: logger.warning('ASG for az {} is not found'.format(i)) if len(response['AutoScalingGroups']) > 1: logger.error('Multiple ASGs for az {} is found'.format(i)) asg_response = response['AutoScalingGroups'][0] logger.info('Update Resource: ASG Name: ' + asg_response['AutoScalingGroupName']) asg_name = asg_response['AutoScalingGroupName'] asg.update_auto_scaling_group(AutoScalingGroupName=asg_name, MinSize=int(MinInstancesASG), MaxSize=int(MaximumInstancesASG), DesiredCapacity=int(MinInstancesASG), DefaultCooldown=int(ScalingPeriod)) update_alarm(stackname, asg_name, event) logger.info('Updating Life Cycle Hook for ASG: ' + asg_name) hookname = asg_name + '-life-cycle-launch' mgmt = lib.choose_subnet(SubnetIDMgmt, i) untrust = lib.choose_subnet(SubnetIDUntrust, i) trust = lib.choose_subnet(SubnetIDTrust, i) metadata = { 'MGMT': mgmt, 'UNTRUST': untrust, 'TRUST': trust, 'KeyPANWFirewall': KeyPANWFirewall, 'KeyPANWPanorama': KeyPANWPanorama, 'KeyDeLicense': KeyDeLicense, 'LambdaENIQueue': LambdaENIQueue, 'AvailZone': i } try: asg.put_lifecycle_hook( LifecycleHookName=hookname, AutoScalingGroupName=asg_name, LifecycleTransition="autoscaling:EC2_INSTANCE_LAUNCHING", RoleARN=ASGNotifierRole, NotificationTargetARN=LambdaENISNSTopic, DefaultResult="ABANDON", HeartbeatTimeout=300, NotificationMetadata=json.dumps(metadata)) except Exception as e: logger.error("[ASG LifeCycle Hook Launch. ROLLBACK]: {}".format(e)) return False hookname = asg_name + '-life-cycle-terminate' try: asg.put_lifecycle_hook( LifecycleHookName=hookname, AutoScalingGroupName=asg_name, LifecycleTransition="autoscaling:EC2_INSTANCE_TERMINATING", RoleARN=ASGNotifierRole, NotificationTargetARN=LambdaENISNSTopic, DefaultResult="CONTINUE", HeartbeatTimeout=300, NotificationMetadata=json.dumps(metadata)) except Exception as e: logger.error( "[ASG LifeCycle Hook Terminate. ROLLBACK]: {}".format(e)) logger.info('Done Updating Resources...') return
def update_resources(event): global asg_name global untrust global PanS3KeyTpl global PanS3BucketTpl global KeyPANWPanorama global KeyPANWFirewall global ScalingParameter global Namespace global NATGateway global ilb_ip_address global ilb_name global elb_name global SubnetIDLambda global sgv global Arn stackname = event['ResourceProperties']['StackName'] logger.info('Updating resources for stackname: ' + stackname) Arn = event['StackId'] r = event['ResourceProperties'] oldr = event['OldResourceProperties'] logger.info('Dump all the new parameters') logger.info(r) logger.info('Dump all the OLD parameters') logger.info(oldr) LambdaExecutionRole = r['LambdaExecutionRole'] stackname = r['StackName'] PanS3BucketTpl = r['PanS3BucketTpl'] PanS3KeyTpl = r['PanS3KeyTpl'] KeyPANWFirewall = r['KeyPANWFirewall'] KeyPANWPanorama = r['KeyPANWPanorama'] ScalingParameter = r['ScalingParameter'] NATGateway = r['NATGateway'] elb_name = r['ELBName'] ilb_name = r['ILBName'] SubnetIDLambda = r['SubnetIDLambda'] sgv = r['VPCSecurityGroup'] ScalingParameter = r['ScalingParameter'] MaximumInstancesASG = r['MaximumInstancesASG'] MinInstancesASG = r['MinInstancesASG'] ScaleUpThreshold = r['ScaleUpThreshold'] ScaleDownThreshold = r['ScaleDownThreshold'] ScalingPeriod = r['ScalingPeriod'] SubnetIDUntrust = r['SubnetIDUntrust'] MasterS3Bucket = r['MasterS3Bucket'] LambdaENIQueue = r['LambdaENIQueue'] SubnetIDLambda = str(lib.fix_unicode(SubnetIDLambda)) SubnetIDLambda = lib.fix_subnets(SubnetIDLambda) SubnetIDUntrust = str(lib.fix_unicode(SubnetIDUntrust)) SubnetIDUntrust = lib.fix_subnets(SubnetIDUntrust) logger.info('Purging queue: {}'.format(LambdaENIQueue)) lib.purge_stack_queue(LambdaENIQueue) if remove_sched_func(stackname) == False: logger.error('Failed to delete Sched Lambda Func (VIP Monitoring)') return create_resources(event) if PanS3BucketTpl == "panw-aws": region = r['Region'] PanS3BucketTpl = PanS3BucketTpl + "-" + region PanS3KeyTpl = r['Version'] else: PanS3KeyTpl = r['PanS3KeyTpl'] logger.info('Lambda Template S3 Bucket: ' + PanS3BucketTpl + ' S3Key is : ' + PanS3KeyTpl) lambda_func_name = r['AddENILambda'] try: lambda_client.update_function_code(FunctionName=lambda_func_name, S3Bucket=PanS3BucketTpl, S3Key=PanS3KeyTpl) logger.info('Updated AddENI Lambda Function Code Successfully') except Exception as e: logger.error('Update Resource for AddENI Lambda Failed') logger.error("[Update Resource AddENI Lambda]: {}".format(e)) return False lambda_func_name = r['InitLambda'] try: lambda_client.update_function_code(FunctionName=lambda_func_name, S3Bucket=PanS3BucketTpl, S3Key=PanS3KeyTpl) logger.info('Updated Init Lambda Function Code Successfully') except Exception as e: logger.error('Update Resource for Init Lambda Failed') logger.error("[Update Resource Init Lambda]: {}".format(e)) return False c = read_s3_object(MasterS3Bucket, "config/init-cfg.txt") dict = lib.get_values_from_init_cfg(c) logger.info('Init CFG bootstrap file Panorama settings: ') logger.info(dict) PIP = dict['panorama-server'] PDG = dict['dgname'] PTPL = dict['tplname'] Hostname = dict['hostname'] asg_response = asg.describe_auto_scaling_groups() for i in asg_response['AutoScalingGroups']: for lbn in i['LoadBalancerNames']: if lbn == elb_name: AZ = i['AvailabilityZones'] logger.info('Update Resource: ASG Name: ' + i['AutoScalingGroupName']) asg_name = i['AutoScalingGroupName'] asg.update_auto_scaling_group( AutoScalingGroupName=asg_name, MinSize=int(MinInstancesASG), MaxSize=int(MaximumInstancesASG), DesiredCapacity=int(MinInstancesASG), DefaultCooldown=int(ScalingPeriod)) search = lib.get_asg_name1(stackname) ip = lib.substring_after(asg_name, search) ilb_ip_address = ip.replace("-", ".") logger.info('Update Resource: ASG Name: ' + i['AutoScalingGroupName'] + ' ILB-IP Address: ' + ilb_ip_address) update_alarm(stackname, asg_name, event) for ec2i in i['Instances']: try: instanceId = str(ec2i['InstanceId']) logger.info('Updating instance: ' + instanceId + ' HealthStatus: ' + ec2i['HealthStatus']) logger.info(ec2i) cw = lib.get_lambda_cloud_watch_func_name( stackname, asg_name, instanceId) Namespace = lib.get_cw_name_space(stackname, asg_name) logger.info('Cloud Watch Lambda Function Name: ' + cw) eni_response = ec2_client.describe_network_interfaces( Filters=[{ 'Name': "attachment.instance-id", 'Values': [instanceId] }, { 'Name': "attachment.device-index", 'Values': ["1"] }]) logger.info(eni_response) eniId = "" for eni in eni_response['NetworkInterfaces']: eniId = eni['NetworkInterfaceId'] if eniId == "": logger.error( 'Mgmt ENI ID not found for instance: ' + instanceId) continue logger.info('Eni ID (eth1) for instance : ' + instanceId + ' is: ' + eniId) untrust = lib.choose_subnet(SubnetIDUntrust, AZ[0]) #untrust="None" #if NATGateway == "Yes": # lambda_response=lambda_client.get_function(FunctionName=cw) # logger.info(lambda_response) # untrust=lambda_response['Configuration']['VpcConfig']['SubnetIds'] if lib.delete_cw_metrics_lambda( stackname, asg_name, instanceId, None) == False: logger.error('Failed to delete Lambda Function: ' + cw + ' for instance: ' + instanceId) continue logger.info( 'Delete CW Metrics function successfully: ' + cw) Input = { 'EC2InstanceId': instanceId, 'StackName': stackname, 'ASGName': asg_name, 'FWIP': "xxx", 'FWPIP': "xxx", 'KeyPANWFirewall': KeyPANWFirewall, 'KeyPANWPanorama': KeyPANWPanorama, 'ScalingParameter': ScalingParameter, 'Namespace': Namespace, 'ELBName': elb_name, 'ILBName': ilb_name, 'ILBIPAddress': ilb_ip_address, 'UntrustSubnet': untrust, 'Arn': Arn, 'PanS3BucketTpl': PanS3BucketTpl, 'PanS3KeyTpl': PanS3KeyTpl, 'PIP': PIP, 'PDG': PDG, 'PTPL': PTPL, 'Hostname': Hostname } for retry in range(1, 5): if lib.create_cw_metrics_lambda( Input, LambdaExecutionRole, eniId, NATGateway, SubnetIDLambda, sgv) == True: logger.info( 'Re-created Lambda function for instance: ' + instanceId) break if retry == 4: logger.error( 'Timeout in re-creation of Lambda function for instance: ' + instanceId) break time.sleep(1) except Exception as e: logger.error( "[Error in Update Resource CW Lambda ASG Loop]: {}" .format(e)) continue logger.info('Done Updating Resources...') return
def lambda_handler(event, context): """ .. note:: This function is the entry point for the ```init``` Lambda function. This function performs the following actions: - invokes ```create | delete | update_resources()``` based on the action required. - creates the ```sched_evt1``` lambda function and configures the same. - validates that the PAN FW AMI-ID specified as input is valid and supported. :param event: Encodes all the input variables to the lambda function, when the function is invoked. Essentially AWS Lambda uses this parameter to pass in event data to the handler function. :type event: dict :param context: AWS Lambda uses this parameter to provide runtime information to your handler. :type context: LambdaContext :return: None """ global logger logger.info('got event{}'.format(event)) try: r = event['ResourceProperties'] lfunc = r['InitLambda'] lresponse = lambda_client.get_function(FunctionName=lfunc) logger.info(json.dumps(lresponse)) LambdaS3Bucket = r['LambdaS3Bucket'] PanS3KeyTpl = r['PanS3KeyTpl'] if LambdaS3Bucket != "panw-aws-autoscale-v20": logger.info( '-------------------------------------------------------------------------------' ) logger.info('Customer is using their own lambada S3 bucket: ' + LambdaS3Bucket) logger.info( '-------------------------------------------------------------------------------' ) stackname = r['StackName'] region = r['Region'] SubnetIDNATGW = r['SubnetIDNATGW'] SubnetIDLambda = r['SubnetIDLambda'] LambdaS3Bucket = "panw-aws-autoscale-v20-" + region get_sha(LambdaS3Bucket, PanS3KeyTpl, lresponse['Configuration']['CodeSha256']) except Exception as e: logger.error("[CodeSha256]: {}".format(e)) ami_id = event['ResourceProperties']['ImageID'] status = "SUCCESS" try: if event['RequestType'] == 'Delete': delete_resources(event) logger.info( '[INFO]: Sending delete response to S3 URL for stack deletion to proceed' ) elif event['RequestType'] == 'Create': try: logger.info('Validate Ami-Id: {}'.format(ami_id)) if not validate_ami_id(event): # Check to ensure that the AMI-ID specified is valid. send_response( event, context, "FAILURE: We do not support AMI-ID: {}".format(ami_id)) return except Exception as e: logger.error( "Failed to determine validity of the AMI specified: {}". format(e)) send_response( event, context, "FAILURE: validating AMI-ID {}. Unable to proceed".format( ami_id)) return logger.info( 'Successfully validated that the Ami is a valid PAN FW AMI') try: SubnetIDLambda = str(lib.fix_unicode(SubnetIDLambda)) SubnetIDLambda = lib.fix_subnets(SubnetIDLambda) SubnetIDNATGW = str(lib.fix_unicode(SubnetIDNATGW)) SubnetIDNATGW = lib.fix_subnets(SubnetIDNATGW) llen = len(SubnetIDLambda.split(',')) nlen = len(SubnetIDNATGW.split(',')) print('Length of Lambda Subnets: ' + str(llen)) print('Length of NATGW Subnets: ' + str(nlen)) if llen == 0 or nlen == 0: logger.error( '[ERROR]: Either Lambda or NATGW Subnets were not passed...' ) send_response( event, context, "FAILURE: Either Lambda or NATGW Subnets were not passed" ) return if llen > 2 or nlen > 2: logger.error( '[ERROR]: Either Lambda or NATGW Subnets are more than 2 AZs' ) send_response( event, context, "FAILURE: Either Lambda or NATGW Subnets are more than 2 AZs" ) return except Exception as e: logger.error("[StackNameLenCheck]: {}".format(e)) try: logger.info('Length of stackname is: ' + str(len(stackname))) if len(stackname) > 128: logger.error( '[ERROR]: We dont support Stack Name more than 128 characters long...' ) send_response( event, context, "FAILURE: We dont support Stack Name more than 128 characters long" ) return except Exception as e: logger.error("[StackNameLenCheck]: {}".format(e)) logger.info('Create nlb table') lib.create_nlb_table(stackname, region) logger.info('Create firewall table') lib.create_firewall_table(stackname, region) create_resources(event) logger.info( '[INFO]: Sending Create response to S3 URL for stack creation to proceed' ) elif event['RequestType'] == 'Update': update_resources(event) logger.info('[INFO]: Sending Update response to S3 URL for stack.') except Exception as e: logger.error('[ERROR]: Got ERROR in Init Lamnda handler...') logger.error("[Error in Init Lambda Handler]: {}".format(e)) if (send_response(event, context, status)) == 'false': logger.info( '[ERROR]: Got ERROR in sending response to S3 URL for custom resource...' )
def lambda_handler(event, context): """ .. note:: This function is the entry point for the ```sched_event1``` Lambda function. This function performs the following actions: firewall_asg_update(event, context) firewall_init_config(event, context) network_load_balancer_update(event, context) | invokes ```check_and_send_message_to_queue()``` | desc: Checks the messages on the queue to ensure its up to date | and for any changes as the case maybe. | invokes ```firewall_asg_update()``` | desc: monitor firewall asg and create asg if not exist | invokes ```firewall_init_config()``` | desc: monitor firewall in INIT state and move it to COMMIT if | firewall auto commit is done | invokes ```network_load_balancer_update()``` | desc: update firewall nat rules based on info in firewall table | nlb table :param event: Encodes all the input variables to the lambda function, when the function is invoked. Essentially AWS Lambda uses this parameter to pass in event data to the handler function. :type event: dict :param context: AWS Lambda uses this parameter to provide runtime information to your handler. :type context: LambdaContext :return: None """ global stackname global ilb_tag global elb_name global ELBTargetGroupName global region global sg_mgmt global sg_untrust global sg_trust global sg_vpc global keyname global iamprofilebs global s3master global subnetmgmt global subnetuntrust global subnettrust global imageID global ScalingPeriod global ScaleUpThreshold global ScaleDownThreshold global ScalingParameter global instanceType global gcontext global MinInstancesASG global MaximumInstancesASG global LambdaExecutionRole global LambdaENISNSTopic global ASGNotifierRolePolicy global ASGNotifierRole global LambdaS3Bucket global PanS3KeyTpl global KeyPANWFirewall global KeyPANWPanorama global SubnetIDNATGW global SubnetIDLambda global PIP global PDG global PTPL global Hostname global logger global KeyDeLicense global LambdaENIQueue global NetworkLoadBalancerQueue global fw_azs global trust_def_gw gcontext = context #print("First operation remaining (MS):", context.get_remaining_time_in_millis()) #print('Parameters {}...'.format(event)) stackname=event['StackName'] elb_name=event['ELBName'] ELBTargetGroupName=event['ELBTargetGroupName'] sg_mgmt=event['MgmtSecurityGroup'] sg_trust=event['TrustSecurityGroup'] sg_untrust=event['UntrustSecurityGroup'] sg_vpc=event['VPCSecurityGroup'] keyname=event['KeyName'] s3master=event['BootstrapS3Bucket'] subnetmgmt=event['SubnetIDMgmt'] subnettrust=event['SubnetIDTrust'] subnetuntrust=event['SubnetIDUntrust'] imageID=event['ImageID'] instanceType=event['FWInstanceType'] region=event['Region'] iamprofilebs=str(event['FirewallBootstrapRole']) LambdaENISNSTopic=str(event['LambdaENISNSTopic']) LambdaExecutionRole=str(event['LambdaExecutionRole']) ASGNotifierRole=str(event['ASGNotifierRole']) ASGNotifierRolePolicy=str(event['ASGNotifierRolePolicy']) LambdaS3Bucket=event['LambdaS3Bucket'] PanS3KeyTpl=event['PanS3KeyTpl'] KeyPANWFirewall=event['KeyPANWFirewall'] KeyPANWPanorama=event['KeyPANWPanorama'] SubnetIDNATGW=event['SubnetIDNATGW'] SubnetIDLambda=event['SubnetIDLambda'] PIP=event['PIP'] PDG=event['PDG'] PTPL=event['PTPL'] Hostname=event['Hostname'] KeyDeLicense=event['KeyDeLicense'] LambdaENIQueue=event['LambdaENIQueue'] NetworkLoadBalancerQueue=event['NetworkLoadBalancerQueue'] logger = logging.getLogger() debug = event['Debug'] if debug == 'Yes': logger.setLevel(logging.INFO) logger.info('got event{}'.format(event)) subnetuntrust=str(lib.fix_unicode(subnetuntrust)) subnetuntrust=lib.fix_subnets(subnetuntrust) subnetmgmt=str(lib.fix_unicode(subnetmgmt)) subnetmgmt=lib.fix_subnets(subnetmgmt) subnettrust=str(lib.fix_unicode(subnettrust)) subnettrust=lib.fix_subnets(subnettrust) SubnetIDNATGW=str(lib.fix_unicode(SubnetIDNATGW)) SubnetIDNATGW=lib.fix_subnets(SubnetIDNATGW) SubnetIDLambda=str(lib.fix_unicode(SubnetIDLambda)) SubnetIDLambda=lib.fix_subnets(SubnetIDLambda) logger.info('StackName:' + event['StackName']) logger.info('ELB Name: ' + elb_name) logger.info('Mgmt Security Group ID : ' + sg_mgmt) logger.info('KeyName is :' + keyname) logger.info('S3 Master Bucket :' + s3master) logger.info('iamprofilebs: ' + iamprofilebs) logger.info('Subnet Mgmt List: ' + subnetmgmt) logger.info('Subnet Untrust List: ' + subnetuntrust) logger.info('Subnet Trust List: ' + subnettrust) if PIP != "": logger.info('Panorama IP is: ' + PIP) ScalingPeriod = int(event['ScalingPeriod']) ScaleUpThreshold = float(event['ScaleUpThreshold']) ScaleDownThreshold = float(event['ScaleDownThreshold']) ScalingParameter = event['ScalingParameter'] MinInstancesASG = int(event['MinInstancesASG']) MaximumInstancesASG = int(event['MaximumInstancesASG']) stack_metadata= { 'SGM': sg_mgmt, 'SGU': sg_untrust, 'SGT': sg_trust, 'SGV': sg_vpc, 'IamLambda': LambdaExecutionRole, 'StackName': stackname, 'LambdaS3Bucket': LambdaS3Bucket, 'PanS3KeyTpl': PanS3KeyTpl, 'ScalingParameter': ScalingParameter, 'SubnetIDNATGW': SubnetIDNATGW, 'PIP': PIP, 'PDG': PDG, 'PTPL': PTPL, 'Hostname': Hostname, "Debug":debug } check_and_send_message_to_queue(LambdaENIQueue, json.dumps(stack_metadata)) logger.info('First Time remaining (MS):' + str(context.get_remaining_time_in_millis())) try: fw_azs = lib.getAzs(subnettrust) trust_def_gw = [] for i in fw_azs: trust_subnet_id=lib.choose_subnet(subnettrust, i) subnet=ec2.Subnet(trust_subnet_id) subnet_str,gw=lib.get_subnet_and_gw(subnet.cidr_block) trust_def_gw.append(gw) #logger.info("Trust subnet default gw[{}]: {}".format(i, trust_def_gw[i])) except Exception as e: logger.exception("Get az and trust default gw error]: {}".format(e)) firewall_asg_update(event, context) firewall_init_config(event, context) network_load_balancer_update(event, context) logger.info('DONE: Last Operations: Time remaining (MS):' + str(context.get_remaining_time_in_millis()))