def deploy_web_servers()

in static/Reliability/300_Testing_for_Resiliency_of_EC2_RDS_and_S3/Code/Python/WebAppLambda/deploy_web_lambda.py [0:0]


def deploy_web_servers(event):
    logger.debug("Running function deploy_web_servers")
    try:
        region = event['region_name']
        cfn_region = event['cfn_region']
        bucket = event['cfn_bucket']
        key_prefix = event['folder']
    except Exception:
        region = os.environ.get('AWS_REGION', AWS_REGION)
        cfn_region = os.environ.get('AWS_REGION', AWS_REGION)
        bucket = "aws-well-architected-labs-ohio",
        key_prefix = "/"
    # Create CloudFormation client
    client = boto3.client('cloudformation', region)

    # Get the S3 bucket the boot script is in, and the object to retrieve and the image to display
    boot_bucket = event['boot_bucket']
    boot_prefix = event['boot_prefix']
    if 'boot_object' in event:
      boot_object = event['boot_object']
    else:
      boot_object = None
    websiteimage = event['websiteimage']

    # Get the outputs of the VPC stack
    vpc_stack = event['vpc']['stackname']
    try:
        stack_response = client.describe_stacks(StackName=vpc_stack)
        stack_list = stack_response['Stacks']
        if (len(stack_list) < 1):
            logger.debug("Cannot find stack named " + vpc_stack + ", so cannot parse outputs as inputs")
            sys.exit(1)
    except Exception:
        logger.debug("Cannot find stack named " + vpc_stack + ", so cannot parse outputs as inputs")
        sys.exit(1)
    vpc_outputs = stack_list[0]['Outputs']

    try:
        workshop_name = event['workshop']
    except Exception:
        logger.debug("Unexpected error!\n Stack Trace:", traceback.format_exc())
        workshop_name = 'UnknownWorkshop'

    # Create the list of subnets to pass
    igw_subnets = find_in_outputs(vpc_outputs, 'IGWSubnets')
    private_subnets = find_in_outputs(vpc_outputs, 'PrivateSubnets')

    # Get the VPC
    vpcid = find_in_outputs(vpc_outputs, 'VPC')

    # Get the list of security groups to pass
    elb_sg = find_in_outputs(vpc_outputs, 'WebELBSecurityGroup')
    web_sg = find_in_outputs(vpc_outputs, 'WebSecurityGroup')
    bastion_sg = find_in_outputs(vpc_outputs, 'BastionSecurityGroup')
    webserver_sg_list = web_sg + ',' + bastion_sg

    # Run in zones a, b, and c
    azs = region + "a," + region + "b," + region + "c"

    # Get the latest AMI
    latest_ami = find_latest_ami_name(region, "HVM64")

    # Get the outputs of the RDS stack
    rds_stack = event['rds']['stackname']
    try:
        stack_response = client.describe_stacks(StackName=rds_stack)
        stack_list = stack_response['Stacks']
        if (len(stack_list) < 1):
            logger.debug("Cannot find stack named " + rds_stack + ", so cannot parse outputs as inputs")
            sys.exit(1)
    except Exception:
        logger.debug("Cannot find stack named " + rds_stack + ", so cannot parse outputs as inputs")
        sys.exit(1)
    try:
        workshop_name = event['workshop']
    except Exception:
        workshop_name = 'UnknownWorkshop'

    rds_outputs = stack_list[0]['Outputs']

    # Get the hostname of the RDS host
    rds_host = find_in_outputs(rds_outputs, 'DBAddress')

    rds_password = get_password_from_ssm(workshop_name, region)

    # Prepare the stack parameters
    webserver_parameters = []
    webserver_parameters.append({'ParameterKey': 'VPCID', 'ParameterValue': vpcid, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'WebServerSecurityGroups', 'ParameterValue': webserver_sg_list, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'WebLoadBalancerSG', 'ParameterValue': elb_sg, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'WebLoadBalancerSubnets', 'ParameterValue': igw_subnets, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'WebServerSubnets', 'ParameterValue': private_subnets, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'WebServerInstanceType', 'ParameterValue': 't2.micro', 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'WebServerAMI', 'ParameterValue': latest_ami, 'UsePreviousValue': False})
    webserver_parameters.append({'ParameterKey': 'AvailabilityZones', 'ParameterValue': azs, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'BootBucketRegion', 'ParameterValue': cfn_region, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'BootBucket', 'ParameterValue': boot_bucket, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'BootPrefix', 'ParameterValue': boot_prefix, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'WebSiteImage', 'ParameterValue': websiteimage, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'RDSHostName', 'ParameterValue': rds_host, 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'RDSUser', 'ParameterValue': 'admin', 'UsePreviousValue': True})
    webserver_parameters.append({'ParameterKey': 'RDSPassword', 'ParameterValue': rds_password, 'UsePreviousValue': False})
    
    # If Boot Object is supplied then use it, otherwise CloudFormation template will use Parameter default
    if boot_object is not None: 
      webserver_parameters.append({'ParameterKey': 'BootObject', 'ParameterValue': boot_object, 'UsePreviousValue': True})
    
    stack_tags = []

    stack_tags.append({'Key': 'Workshop', 'Value': 'AWSWellArchitectedReliability' + workshop_name})
    capabilities = []
    capabilities.append('CAPABILITY_NAMED_IAM')
    web_template_s3_url = "https://s3." + cfn_region + ".amazonaws.com/" + bucket + "/" + key_prefix + "web_server_autoscaling.json"
    client.create_stack(
        StackName=stackname,
        TemplateURL=web_template_s3_url,
        Parameters=webserver_parameters,
        DisableRollback=False,
        TimeoutInMinutes=10,
        Capabilities=capabilities,
        Tags=stack_tags
    )
    return_dict = {'stackname': stackname}
    return return_dict