mephisto.abstractions.architects.ec2.prepare_ec2_servers
View Source
#!/usr/bin/env python3 # Copyright (c) Meta Platforms and its affiliates. # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import mephisto.abstractions.architects.ec2.ec2_helpers as ec2_helpers from mephisto.abstractions.architects.ec2.ec2_helpers import ( DEFAULT_FALLBACK_FILE, FALLBACK_INSTANCE_TYPE, ) import boto3 # type: ignore import os import json from typing import Dict, Any DEFAULT_KEY_PAIR_NAME = "mephisto-server-key" def update_details( open_file, new_data: Dict[str, Any], ): """ Overwrite the contents of the open file with the given data. """ open_file.seek(0) open_file.truncate(0) json.dump(new_data, open_file, sort_keys=True, indent=4) def launch_ec2_fallback( iam_profile: str, # Iam role name, should be saved in aws credentials domain_name: str, ssh_ip_block: str, access_logs_key: str, key_pair_name: str = DEFAULT_KEY_PAIR_NAME, server_details_file: str = DEFAULT_FALLBACK_FILE, instance_type: str = FALLBACK_INSTANCE_TYPE, ) -> Dict[str, Any]: """ This function is used to set up a mephisto vpc and fallback server for the AWS setup. At the moment it requires that you already have a domain registered, and it is up to you to delegate the domain to the amazon nameservers created by this function. This function will request the ssl certificate from amazon At the moment, it only works on the us-east region. Feel free to open a PR to extend this functionality if you need another region! """ assert not domain_name.startswith("www."), ( "You should provide a domain name without www, like 'example.com', " "or 'crowdsourcing.example.com'" ) key_pair_name = DEFAULT_KEY_PAIR_NAME if key_pair_name is None else key_pair_name server_details_file = ( DEFAULT_FALLBACK_FILE if server_details_file is None else server_details_file ) instance_type = FALLBACK_INSTANCE_TYPE if instance_type is None else instance_type session = boto3.Session(profile_name=iam_profile, region_name="us-east-2") try: with open(server_details_file, "r") as saved_details_file: existing_details = json.load(saved_details_file) except: existing_details = {"domain": domain_name, "cidr": ssh_ip_block} with open(server_details_file, "w+") as saved_details_file: # Get a ssl certificate for the domain cert_details = existing_details.get("cert_details") if cert_details is None: print("Getting a certificate for the given domain...") cert_details = ec2_helpers.get_certificate(session, domain_name) existing_details["cert_details"] = cert_details update_details(saved_details_file, existing_details) else: print("Using existing certificate") # Create a hosted zone for the given domain hosted_zone_id = existing_details.get("hosted_zone_id") if hosted_zone_id is None: print("Creating hosted zone for the given domain...") hosted_zone_id = ec2_helpers.create_hosted_zone(session, domain_name) existing_details["hosted_zone_id"] = hosted_zone_id update_details(saved_details_file, existing_details) else: print(f"Using existing hosted zone {hosted_zone_id}") # Create the VPC to hold the servers vpc_details = existing_details.get("vpc_details") if vpc_details is None: print("Initializing VPC...") vpc_details = ec2_helpers.create_mephisto_vpc(session) existing_details["vpc_details"] = vpc_details update_details(saved_details_file, existing_details) else: print(f"Using existing vpc {vpc_details['vpc_id']}") # Set up a security group for everything security_group_id = existing_details.get("security_group_id") if security_group_id is None: print("Creating security group...") security_group_id = ec2_helpers.create_security_group( session, vpc_details["vpc_id"], ssh_ip_block ) existing_details["security_group_id"] = security_group_id update_details(saved_details_file, existing_details) else: print(f"Using existing security group {security_group_id}") # Create a keypair for the server key_pair_filename = existing_details.get("key_pair_filename") if key_pair_filename is None: print(f"Generating keypair named {key_pair_name}") key_pair_filename = ec2_helpers.create_key_pair(session, key_pair_name) existing_details["key_pair_filename"] = key_pair_filename existing_details["key_pair_name"] = key_pair_name update_details(saved_details_file, existing_details) else: print(f"Using existing keypair at {key_pair_filename}") # Create the instance running the fallback server instance_id = existing_details.get("instance_id") if instance_id is None: print("Creating a new instance for fallback server...") instance_id = ec2_helpers.create_instance( session, key_pair_name, security_group_id, vpc_details["subnet_1_id"], "mephisto-default-fallover", instance_type=instance_type, ) existing_details["instance_id"] = instance_id update_details(saved_details_file, existing_details) else: print(f"Using existing instance {instance_id}") # Create load balancer balancer_arn = existing_details.get("balancer_arn") if balancer_arn is None: print("Creating load balancer...") balancer_arn = ec2_helpers.create_load_balancer( session, [vpc_details["subnet_1_id"], vpc_details["subnet_2_id"]], security_group_id, vpc_details["vpc_id"], ) print("Registering to hosted zone") ec2_helpers.register_zone_records( session, existing_details["hosted_zone_id"], domain_name, balancer_arn, cert_details["Name"], cert_details["Value"], ) existing_details["balancer_arn"] = balancer_arn update_details(saved_details_file, existing_details) else: print(f"Using existing balancer {balancer_arn}") # Create the target group for the fallback instance target_group_arn = existing_details.get("target_group_arn") if target_group_arn is None: print("Creating target group...") target_group_arn = ec2_helpers.create_target_group( session, vpc_details["vpc_id"], instance_id ) existing_details["target_group_arn"] = target_group_arn update_details(saved_details_file, existing_details) else: print(f"Using existing target group {target_group_arn}") # Create listener in balancer to direct to target group listener_arn = existing_details.get("listener_arn") if listener_arn is None: print("Creating listener for load balancer...") listener_arn = ec2_helpers.configure_base_balancer( session, balancer_arn, cert_details["arn"], target_group_arn, ) existing_details["listener_arn"] = listener_arn update_details(saved_details_file, existing_details) else: print(f"Using existing listener {listener_arn}") # Finally, deploy the fallback server contents: ec2_helpers.deploy_fallback_server( session, instance_id, key_pair_name, access_logs_key ) existing_details["access_logs_key"] = access_logs_key update_details(saved_details_file, existing_details) return existing_details # TODO(CLEAN) Hydrize def main(): iam_role_name = input("Please enter local profile name for IAM role\n>> ") ec2_helpers.setup_ec2_credentials(iam_role_name) domain_name = input("Please provide the domain name you will be using\n>> ") ssh_ip_block = input("Provide the CIDR IP block for ssh access\n>> ") access_logs_key = input( "Please provide a key password to use for accessing server logs\n>> " ) launch_ec2_fallback(iam_role_name, domain_name, ssh_ip_block, access_logs_key) if __name__ == "__main__": main()
View Source
def update_details( open_file, new_data: Dict[str, Any], ): """ Overwrite the contents of the open file with the given data. """ open_file.seek(0) open_file.truncate(0) json.dump(new_data, open_file, sort_keys=True, indent=4)
Overwrite the contents of the open file with the given data.
#  
def
launch_ec2_fallback(
iam_profile: str,
domain_name: str,
ssh_ip_block: str,
access_logs_key: str,
key_pair_name: str = 'mephisto-server-key',
server_details_file: str = '/Users/jju/mephisto/mephisto/abstractions/architects/ec2/servers/fallback.json',
instance_type: str = 't2.nano'
) -> Dict[str, Any]:
View Source
def launch_ec2_fallback( iam_profile: str, # Iam role name, should be saved in aws credentials domain_name: str, ssh_ip_block: str, access_logs_key: str, key_pair_name: str = DEFAULT_KEY_PAIR_NAME, server_details_file: str = DEFAULT_FALLBACK_FILE, instance_type: str = FALLBACK_INSTANCE_TYPE, ) -> Dict[str, Any]: """ This function is used to set up a mephisto vpc and fallback server for the AWS setup. At the moment it requires that you already have a domain registered, and it is up to you to delegate the domain to the amazon nameservers created by this function. This function will request the ssl certificate from amazon At the moment, it only works on the us-east region. Feel free to open a PR to extend this functionality if you need another region! """ assert not domain_name.startswith("www."), ( "You should provide a domain name without www, like 'example.com', " "or 'crowdsourcing.example.com'" ) key_pair_name = DEFAULT_KEY_PAIR_NAME if key_pair_name is None else key_pair_name server_details_file = ( DEFAULT_FALLBACK_FILE if server_details_file is None else server_details_file ) instance_type = FALLBACK_INSTANCE_TYPE if instance_type is None else instance_type session = boto3.Session(profile_name=iam_profile, region_name="us-east-2") try: with open(server_details_file, "r") as saved_details_file: existing_details = json.load(saved_details_file) except: existing_details = {"domain": domain_name, "cidr": ssh_ip_block} with open(server_details_file, "w+") as saved_details_file: # Get a ssl certificate for the domain cert_details = existing_details.get("cert_details") if cert_details is None: print("Getting a certificate for the given domain...") cert_details = ec2_helpers.get_certificate(session, domain_name) existing_details["cert_details"] = cert_details update_details(saved_details_file, existing_details) else: print("Using existing certificate") # Create a hosted zone for the given domain hosted_zone_id = existing_details.get("hosted_zone_id") if hosted_zone_id is None: print("Creating hosted zone for the given domain...") hosted_zone_id = ec2_helpers.create_hosted_zone(session, domain_name) existing_details["hosted_zone_id"] = hosted_zone_id update_details(saved_details_file, existing_details) else: print(f"Using existing hosted zone {hosted_zone_id}") # Create the VPC to hold the servers vpc_details = existing_details.get("vpc_details") if vpc_details is None: print("Initializing VPC...") vpc_details = ec2_helpers.create_mephisto_vpc(session) existing_details["vpc_details"] = vpc_details update_details(saved_details_file, existing_details) else: print(f"Using existing vpc {vpc_details['vpc_id']}") # Set up a security group for everything security_group_id = existing_details.get("security_group_id") if security_group_id is None: print("Creating security group...") security_group_id = ec2_helpers.create_security_group( session, vpc_details["vpc_id"], ssh_ip_block ) existing_details["security_group_id"] = security_group_id update_details(saved_details_file, existing_details) else: print(f"Using existing security group {security_group_id}") # Create a keypair for the server key_pair_filename = existing_details.get("key_pair_filename") if key_pair_filename is None: print(f"Generating keypair named {key_pair_name}") key_pair_filename = ec2_helpers.create_key_pair(session, key_pair_name) existing_details["key_pair_filename"] = key_pair_filename existing_details["key_pair_name"] = key_pair_name update_details(saved_details_file, existing_details) else: print(f"Using existing keypair at {key_pair_filename}") # Create the instance running the fallback server instance_id = existing_details.get("instance_id") if instance_id is None: print("Creating a new instance for fallback server...") instance_id = ec2_helpers.create_instance( session, key_pair_name, security_group_id, vpc_details["subnet_1_id"], "mephisto-default-fallover", instance_type=instance_type, ) existing_details["instance_id"] = instance_id update_details(saved_details_file, existing_details) else: print(f"Using existing instance {instance_id}") # Create load balancer balancer_arn = existing_details.get("balancer_arn") if balancer_arn is None: print("Creating load balancer...") balancer_arn = ec2_helpers.create_load_balancer( session, [vpc_details["subnet_1_id"], vpc_details["subnet_2_id"]], security_group_id, vpc_details["vpc_id"], ) print("Registering to hosted zone") ec2_helpers.register_zone_records( session, existing_details["hosted_zone_id"], domain_name, balancer_arn, cert_details["Name"], cert_details["Value"], ) existing_details["balancer_arn"] = balancer_arn update_details(saved_details_file, existing_details) else: print(f"Using existing balancer {balancer_arn}") # Create the target group for the fallback instance target_group_arn = existing_details.get("target_group_arn") if target_group_arn is None: print("Creating target group...") target_group_arn = ec2_helpers.create_target_group( session, vpc_details["vpc_id"], instance_id ) existing_details["target_group_arn"] = target_group_arn update_details(saved_details_file, existing_details) else: print(f"Using existing target group {target_group_arn}") # Create listener in balancer to direct to target group listener_arn = existing_details.get("listener_arn") if listener_arn is None: print("Creating listener for load balancer...") listener_arn = ec2_helpers.configure_base_balancer( session, balancer_arn, cert_details["arn"], target_group_arn, ) existing_details["listener_arn"] = listener_arn update_details(saved_details_file, existing_details) else: print(f"Using existing listener {listener_arn}") # Finally, deploy the fallback server contents: ec2_helpers.deploy_fallback_server( session, instance_id, key_pair_name, access_logs_key ) existing_details["access_logs_key"] = access_logs_key update_details(saved_details_file, existing_details) return existing_details
This function is used to set up a mephisto vpc and fallback server for the AWS setup. At the moment it requires that you already have a domain registered, and it is up to you to delegate the domain to the amazon nameservers created by this function. This function will request the ssl certificate from amazon
At the moment, it only works on the us-east region. Feel free to open a PR to extend this functionality if you need another region!
View Source
def main(): iam_role_name = input("Please enter local profile name for IAM role\n>> ") ec2_helpers.setup_ec2_credentials(iam_role_name) domain_name = input("Please provide the domain name you will be using\n>> ") ssh_ip_block = input("Provide the CIDR IP block for ssh access\n>> ") access_logs_key = input( "Please provide a key password to use for accessing server logs\n>> " ) launch_ec2_fallback(iam_role_name, domain_name, ssh_ip_block, access_logs_key)