Example #1
0
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)
                                         }])
Example #2
0
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
Example #3
0
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
Example #4
0
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...'
        )
Example #5
0
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()))