def get_vpc_subnets(self, subnet_ids=[]): try: vpc = self.connect_vpc() subnets = vpc.get_all_subnets(subnet_ids) return subnets except boto.exception.EC2ResponseError: logger.exception('Error looking up subnet_ids: {0}'.format( subnet_ids )) return None
def get_vpc_subnets(self, subnet_ids=None): if subnet_ids is None: subnet_ids = [] try: vpc = self.connect_vpc() subnets = vpc.get_all_subnets(subnet_ids) return subnets except boto.exception.EC2ResponseError: logger.info('Error looking up subnet_ids: {0}'.format(subnet_ids)) return None
def provision_master(self, cluster_component, cluster_instance): """ Provision a master instance in EC2. The master instance is a special instance with the following features: - Public IP - /home shared over NFS @param cluster_component - parent cluster of each instance @param cluster_instance - instance id of the owning cluster @return - boto.ec2.instance.Instances provisioned """ vpc = boto.vpc.VPCConnection() subnet = vpc.get_all_subnets(subnet_ids=__default_subnet__)[0] cidr_block = subnet.cidr_block vpc.close() user_data = "#cloud-config\n" user_data += "runcmd:\n" user_data += " - echo '/home %s(rw,root_squash,sync)' > /etc/exports\n" % ( cidr_block, ) user_data += " - systemctl start nfs-server\n" user_data += " - systemctl enable nfs-server\n" user_data += self.cloud_init_yum_repos() user_data += self.cloud_init_current_user() net_if = boto.ec2.networkinterface.NetworkInterfaceSpecification( subnet_id=__default_subnet__, groups=[ __default_security_group__, ], associate_public_ip_address=True) net_ifs = boto.ec2.networkinterface.NetworkInterfaceCollection(net_if) new_reservation = self._conn.run_instances( image_id=self._ami, min_count=1, max_count=1, instance_type=__default_instance_type__, network_interfaces=net_ifs, tenancy='default', user_data=user_data) instance = new_reservation.instances[0] instance.add_tag('parent_component', cluster_component) instance.add_tag('parent_instance', cluster_instance) instance.add_tag('master', 'self') return instance
def provision_vpc(env, vpc): dryRun = True if env != "test": dryRun = False print "Availability zones: " + str(vpc.get_all_zones()) existing_vpcs = [v for v in vpc.get_all_vpcs() if v.id == my_vpc['id']] existing_subnets = [s.id for s in vpc.get_all_subnets()] print "Info: Existing VPCs: " + str(vpc.get_all_vpcs()) print "Info: Existing Subnets: " + str(existing_subnets) #print my_vpc['id'] vpc_to_prov = existing_vpcs[0] if existing_vpcs else None if not vpc_to_prov: print "Starting new VPC provisioning process.." new_vpc = vpc.create_vpc(my_vpc['cidr_block'], dry_run=dryRun) print "New VPC provisioned, please update its ID: " + str(new_vpc.id) provision_subnets(env, vpc, new_vpc.id, existing_subnets) else: print "vpc already exists, nothing to do here, moving on to subnets.." provision_subnets(env, vpc, my_vpc['id'], existing_subnets)
def provision_vpc(env, vpc): dryRun = True if env != "test": dryRun = False print "Availability zones: " + str( vpc.get_all_zones() ) existing_vpcs = [v for v in vpc.get_all_vpcs() if v.id == my_vpc['id'] ] existing_subnets = [s.id for s in vpc.get_all_subnets() ] print "Info: Existing VPCs: " + str(vpc.get_all_vpcs()) print "Info: Existing Subnets: " + str(existing_subnets) #print my_vpc['id'] vpc_to_prov = existing_vpcs[0] if existing_vpcs else None if not vpc_to_prov: print "Starting new VPC provisioning process.." new_vpc = vpc.create_vpc(my_vpc['cidr_block'], dry_run = dryRun) print "New VPC provisioned, please update its ID: " +str(new_vpc.id) provision_subnets(env, vpc, new_vpc.id, existing_subnets) else: print "vpc already exists, nothing to do here, moving on to subnets.." provision_subnets(env, vpc, my_vpc['id'], existing_subnets)
def create_instance_args(): """ Looks up security group, subnet and returns arguments to pass into ec2.run_instances() including user data """ vpc = boto.vpc.connect_to_region(args.region) subnet = vpc.get_all_subnets(filters={ 'tag:aws:cloudformation:stack-name': stack_name, 'tag:play': args.play }) if len(subnet) < 1: # # try scheme for non-cloudformation builds # subnet = vpc.get_all_subnets( filters={ 'tag:play': args.play, 'tag:environment': args.environment, 'tag:deployment': args.deployment }) if len(subnet) < 1: sys.stderr.write( "ERROR: Expected at least one subnet, got {} for {}-{}-{}\n". format(len(subnet), args.environment, args.deployment, args.play)) sys.exit(1) subnet_id = subnet[0].id vpc_id = subnet[0].vpc_id security_group_id = get_instance_sec_group(vpc_id) if args.identity: config_secure = 'true' with open(args.identity) as f: identity_contents = f.read() else: config_secure = 'false' identity_contents = "dummy" user_data = """#!/bin/bash set -x set -e exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 base_dir="/var/tmp/edx-cfg" extra_vars="$base_dir/extra-vars-$$.yml" secure_identity="$base_dir/secure-identity" git_ssh="$base_dir/git_ssh.sh" configuration_version="{configuration_version}" configuration_secure_version="{configuration_secure_version}" configuration_private_version="{configuration_private_version}" configuration_internal_version="{configuration_internal_version}" environment="{environment}" deployment="{deployment}" play="{play}" cluster="{play}" config_secure={config_secure} git_repo_name="configuration" git_repo="https://github.com/edx/$git_repo_name" git_repo_secure="{configuration_secure_repo}" git_repo_secure_name=$(basename $git_repo_secure .git) git_repo_private="{configuration_private_repo}" git_repo_private_name=$(basename $git_repo_private .git) git_repo_internal="{configuration_internal_repo}" git_repo_internal_name=$(basename $git_repo_internal .git) secure_vars_file={secure_vars_file} environment_deployment_secure_vars="$base_dir/$git_repo_secure_name/ansible/vars/{environment}-{deployment}.yml" deployment_secure_vars="$base_dir/$git_repo_secure_name/ansible/vars/{deployment}.yml" environment_deployment_internal_vars="$base_dir/$git_repo_internal_name/ansible/vars/{environment}-{deployment}.yml" deployment_internal_vars="$base_dir/$git_repo_internal_name/ansible/vars/{deployment}.yml" instance_id=\\ $(curl http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null) instance_ip=\\ $(curl http://169.254.169.254/latest/meta-data/local-ipv4 2>/dev/null) instance_type=\\ $(curl http://169.254.169.254/latest/meta-data/instance-type 2>/dev/null) playbook_dir="$base_dir/{playbook_dir}" if $config_secure; then git_cmd="env GIT_SSH=$git_ssh git" else git_cmd="git" fi ANSIBLE_ENABLE_SQS=true SQS_NAME={queue_name} SQS_REGION={region} SQS_MSG_PREFIX="[ $instance_id $instance_ip $environment-$deployment $play ]" PYTHONUNBUFFERED=1 HIPCHAT_TOKEN={hipchat_token} HIPCHAT_ROOM={hipchat_room} HIPCHAT_MSG_PREFIX="$environment-$deployment-$play: " HIPCHAT_FROM="ansible-$instance_id" HIPCHAT_MSG_COLOR=$(echo -e "yellow\\ngreen\\npurple\\ngray" | shuf | head -1) DATADOG_API_KEY={datadog_api_key} # environment for ansible export ANSIBLE_ENABLE_SQS SQS_NAME SQS_REGION SQS_MSG_PREFIX PYTHONUNBUFFERED export HIPCHAT_TOKEN HIPCHAT_ROOM HIPCHAT_MSG_PREFIX HIPCHAT_FROM export HIPCHAT_MSG_COLOR DATADOG_API_KEY #################################### Lifted from ansible-bootstrap.sh if [[ -z "$ANSIBLE_REPO" ]]; then ANSIBLE_REPO="https://github.com/edx/ansible.git" fi if [[ -z "$ANSIBLE_VERSION" ]]; then ANSIBLE_VERSION="master" fi if [[ -z "$CONFIGURATION_REPO" ]]; then CONFIGURATION_REPO="https://github.com/edx/configuration.git" fi if [[ -z "$CONFIGURATION_VERSION" ]]; then CONFIGURATION_VERSION="master" fi if [[ -z "$UPGRADE_OS" ]]; then UPGRADE_OS=false fi # # Bootstrapping constants # VIRTUAL_ENV_VERSION="15.0.2" PIP_VERSION="8.1.2" SETUPTOOLS_VERSION="24.0.3" EDX_PPA="deb http://ppa.edx.org precise main" EDX_PPA_KEY_SERVER="hkp://pgp.mit.edu:80" EDX_PPA_KEY_ID="B41E5E3969464050" cat << EOF ****************************************************************************** Running the abbey with the following arguments: ANSIBLE_REPO="$ANSIBLE_REPO" ANSIBLE_VERSION="$ANSIBLE_VERSION" CONFIGURATION_REPO="$CONFIGURATION_REPO" CONFIGURATION_VERSION="$CONFIGURATION_VERSION" ****************************************************************************** EOF if [[ $(id -u) -ne 0 ]] ;then echo "Please run as root"; exit 1; fi if grep -q 'Precise Pangolin' /etc/os-release then SHORT_DIST="precise" elif grep -q 'Trusty Tahr' /etc/os-release then SHORT_DIST="trusty" elif grep -q 'Xenial Xerus' /etc/os-release then SHORT_DIST="xenial" else cat << EOF This script is only known to work on Ubuntu Precise, Trusty and Xenial, exiting. If you are interested in helping make installation possible on other platforms, let us know. EOF exit 1; fi EDX_PPA="deb http://ppa.edx.org $SHORT_DIST main" # Upgrade the OS apt-get update -y apt-key update -y if [ "$UPGRADE_OS" = true ]; then echo "Upgrading the OS..." apt-get upgrade -y fi # Required for add-apt-repository apt-get install -y software-properties-common python-software-properties # Add git PPA add-apt-repository -y ppa:git-core/ppa # For older distributions we need to install a PPA for Python 2.7.10 if [[ "precise" = "$SHORT_DIST" || "trusty" = "$SHORT_DIST" ]]; then # Add python PPA apt-key adv --keyserver "$EDX_PPA_KEY_SERVER" --recv-keys "$EDX_PPA_KEY_ID" add-apt-repository -y "$EDX_PPA" fi # Install python 2.7 latest, git and other common requirements # NOTE: This will install the latest version of python 2.7 and # which may differ from what is pinned in virtualenvironments apt-get update -y apt-get install -y python2.7 python2.7-dev python-pip python-apt python-yaml python-jinja2 build-essential sudo git-core libmysqlclient-dev libffi-dev libssl-dev # Workaround for a 16.04 bug, need to upgrade to latest and then # potentially downgrade to the preferred version. # https://github.com/pypa/pip/issues/3862 if [[ "xenial" = "$SHORT_DIST" ]]; then pip install --upgrade pip pip install --upgrade pip=="$PIP_VERSION" else pip install --upgrade pip=="$PIP_VERSION" fi # pip moves to /usr/local/bin when upgraded hash -r #pip may have moved from /usr/bin/ to /usr/local/bin/. This clears bash's path cache. PATH=/usr/local/bin:$PATH pip install setuptools=="$SETUPTOOLS_VERSION" pip install virtualenv=="$VIRTUAL_ENV_VERSION" ##################### END Lifted from ansible-bootstrap.sh # python3 is required for certain other things # (currently xqwatcher so it can run python2 and 3 grader code, # but potentially more in the future). It's not available on Ubuntu 12.04, # but in those cases we don't need it anyways. if [[ -n "$(apt-cache search --names-only '^python3-pip$')" ]]; then /usr/bin/apt-get update /usr/bin/apt-get install -y python3-pip python3-dev fi # this is missing on 14.04 (base package on 12.04) # we need to do this on any build, since the above apt-get # only runs on a build from scratch /usr/bin/apt-get install -y python-httplib2 --force-yes rm -rf $base_dir mkdir -p $base_dir cd $base_dir cat << EOF > $git_ssh #!/bin/sh exec /usr/bin/ssh -o StrictHostKeyChecking=no -i "$secure_identity" "\$@" EOF chmod 755 $git_ssh if $config_secure; then cat << EOF > $secure_identity {identity_contents} EOF fi cat << EOF >> $extra_vars --- # extra vars passed into # abbey.py including versions # of all the repositories {extra_vars_yml} # abbey will always run fake migrations # this is so that the application can come # up healthy fake_migrations: true disable_edx_services: true COMMON_TAG_EC2_INSTANCE: true # abbey should never take instances in # and out of elbs elb_pre_post: false EOF chmod 400 $secure_identity $git_cmd clone $git_repo $git_repo_name cd $git_repo_name $git_cmd checkout $configuration_version cd $base_dir if $config_secure; then $git_cmd clone $git_repo_secure $git_repo_secure_name cd $git_repo_secure_name $git_cmd checkout $configuration_secure_version cd $base_dir fi if [[ ! -z $git_repo_private ]]; then $git_cmd clone $git_repo_private $git_repo_private_name cd $git_repo_private_name $git_cmd checkout $configuration_private_version cd $base_dir fi if [[ ! -z $git_repo_internal ]]; then $git_cmd clone $git_repo_internal $git_repo_internal_name cd $git_repo_internal_name $git_cmd checkout $configuration_internal_version cd $base_dir fi cd $base_dir/$git_repo_name sudo pip install -r pre-requirements.txt sudo pip install -r requirements.txt cd $playbook_dir if [[ -r "$deployment_internal_vars" ]]; then extra_args_opts+=" -e@$deployment_internal_vars" fi if [[ -r "$environment_deployment_internal_vars" ]]; then extra_args_opts+=" -e@$environment_deployment_internal_vars" fi if [[ -r "$deployment_secure_vars" ]]; then extra_args_opts+=" -e@$deployment_secure_vars" fi if [[ -r "$environment_deployment_secure_vars" ]]; then extra_args_opts+=" -e@$environment_deployment_secure_vars" fi if $secure_vars_file; then extra_args_opts+=" -e@$secure_vars_file" fi extra_args_opts+=" -e@$extra_vars" ansible-playbook -vvvv -c local -i "localhost," $play.yml $extra_args_opts ansible-playbook -vvvv -c local -i "localhost," stop_all_edx_services.yml $extra_args_opts rm -rf $base_dir """.format( hipchat_token=args.hipchat_api_token, hipchat_room=args.ansible_hipchat_room_id, configuration_version=args.configuration_version, configuration_secure_version=args.configuration_secure_version, configuration_secure_repo=args.configuration_secure_repo, configuration_private_version=args.configuration_private_version, configuration_private_repo=args.configuration_private_repo, configuration_internal_version=args.configuration_internal_version, configuration_internal_repo=args.configuration_internal_repo, environment=args.environment, deployment=args.deployment, play=args.play, playbook_dir=args.playbook_dir, config_secure=config_secure, identity_contents=identity_contents, queue_name=run_id, extra_vars_yml=extra_vars_yml, secure_vars_file=secure_vars_file, cache_id=args.cache_id, datadog_api_key=args.datadog_api_key, region=args.region) mapping = BlockDeviceMapping() root_vol = BlockDeviceType(size=args.root_vol_size, volume_type='gp2') mapping['/dev/sda1'] = root_vol ec2_args = { 'security_group_ids': [security_group_id], 'subnet_id': subnet_id, 'key_name': args.keypair, 'image_id': base_ami, 'instance_type': args.instance_type, 'instance_profile_name': args.role_name, 'user_data': user_data, 'block_device_map': mapping, } return ec2_args
def create_instance_args(): """ Looks up security group, subnet and returns arguments to pass into ec2.run_instances() including user data """ vpc = boto.vpc.connect_to_region(args.region) subnet = vpc.get_all_subnets( filters={ 'tag:aws:cloudformation:stack-name': stack_name, 'tag:play': args.play} ) if len(subnet) < 1: # # try scheme for non-cloudformation builds # subnet = vpc.get_all_subnets( filters={ 'tag:play': args.play, 'tag:environment': args.environment, 'tag:deployment': args.deployment} ) if len(subnet) < 1: sys.stderr.write("ERROR: Expected at least one subnet, got {} for {}-{}-{}\n".format( len(subnet), args.environment, args.deployment, args.play)) sys.exit(1) subnet_id = subnet[0].id vpc_id = subnet[0].vpc_id security_group_id = get_instance_sec_group(vpc_id) if args.identity: config_secure = 'true' with open(args.identity) as f: identity_contents = f.read() else: config_secure = 'false' identity_contents = "dummy" user_data = """#!/bin/bash set -x set -e exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 base_dir="/var/tmp/edx-cfg" extra_vars="$base_dir/extra-vars-$$.yml" secure_identity="$base_dir/secure-identity" git_ssh="$base_dir/git_ssh.sh" configuration_version="{configuration_version}" configuration_secure_version="{configuration_secure_version}" configuration_private_version="{configuration_private_version}" environment="{environment}" deployment="{deployment}" play="{play}" cluster="{play}" config_secure={config_secure} git_repo_name="configuration" git_repo="https://github.com/edx/$git_repo_name" git_repo_secure="{configuration_secure_repo}" git_repo_secure_name=$(basename $git_repo_secure .git) git_repo_private="{configuration_private_repo}" git_repo_private_name=$(basename $git_repo_private .git) secure_vars_file={secure_vars_file} environment_deployment_secure_vars="$base_dir/$git_repo_secure_name/ansible/vars/{environment}-{deployment}.yml" deployment_secure_vars="$base_dir/$git_repo_secure_name/ansible/vars/{deployment}.yml" instance_id=\\ $(curl http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null) instance_ip=\\ $(curl http://169.254.169.254/latest/meta-data/local-ipv4 2>/dev/null) instance_type=\\ $(curl http://169.254.169.254/latest/meta-data/instance-type 2>/dev/null) playbook_dir="$base_dir/{playbook_dir}" if $config_secure; then git_cmd="env GIT_SSH=$git_ssh git" else git_cmd="git" fi ANSIBLE_ENABLE_SQS=true SQS_NAME={queue_name} SQS_REGION={region} SQS_MSG_PREFIX="[ $instance_id $instance_ip $environment-$deployment $play ]" PYTHONUNBUFFERED=1 HIPCHAT_TOKEN={hipchat_token} HIPCHAT_ROOM={hipchat_room} HIPCHAT_MSG_PREFIX="$environment-$deployment-$play: " HIPCHAT_FROM="ansible-$instance_id" HIPCHAT_MSG_COLOR=$(echo -e "yellow\\ngreen\\npurple\\ngray" | shuf | head -1) DATADOG_API_KEY={datadog_api_key} # environment for ansible export ANSIBLE_ENABLE_SQS SQS_NAME SQS_REGION SQS_MSG_PREFIX PYTHONUNBUFFERED export HIPCHAT_TOKEN HIPCHAT_ROOM HIPCHAT_MSG_PREFIX HIPCHAT_FROM export HIPCHAT_MSG_COLOR DATADOG_API_KEY if [[ ! -x /usr/bin/git || ! -x /usr/bin/pip ]]; then echo "Installing pkg dependencies" /usr/bin/apt-get update /usr/bin/apt-get install -y git python-pip python-apt \\ git-core build-essential python-dev libxml2-dev \\ libxslt-dev curl libmysqlclient-dev --force-yes fi # this is missing on 14.04 (base package on 12.04) # we need to do this on any build, since the above apt-get # only runs on a build from scratch /usr/bin/apt-get install -y python-httplib2 --force-yes # upgrade setuptools early to avoid no distributin errors pip install --upgrade setuptools==18.3.2 rm -rf $base_dir mkdir -p $base_dir cd $base_dir cat << EOF > $git_ssh #!/bin/sh exec /usr/bin/ssh -o StrictHostKeyChecking=no -i "$secure_identity" "\$@" EOF chmod 755 $git_ssh if $config_secure; then cat << EOF > $secure_identity {identity_contents} EOF fi cat << EOF >> $extra_vars --- # extra vars passed into # abbey.py including versions # of all the repositories {extra_vars_yml} # abbey will always run fake migrations # this is so that the application can come # up healthy fake_migrations: true disable_edx_services: true COMMON_TAG_EC2_INSTANCE: true # abbey should never take instances in # and out of elbs elb_pre_post: false EOF chmod 400 $secure_identity $git_cmd clone $git_repo $git_repo_name cd $git_repo_name $git_cmd checkout $configuration_version cd $base_dir if $config_secure; then $git_cmd clone $git_repo_secure $git_repo_secure_name cd $git_repo_secure_name $git_cmd checkout $configuration_secure_version cd $base_dir fi if [[ ! -z $git_repo_private ]]; then $git_cmd clone $git_repo_private $git_repo_private_name cd $git_repo_private_name $git_cmd checkout $configuration_private_version cd $base_dir fi cd $base_dir/$git_repo_name sudo pip install -r pre-requirements.txt sudo pip install -r requirements.txt cd $playbook_dir if [[ -r "$deployment_secure_vars" ]]; then extra_args_opts+=" -e@$deployment_secure_vars" fi if [[ -r "$environment_deployment_secure_vars" ]]; then extra_args_opts+=" -e@$environment_deployment_secure_vars" fi if $secure_vars_file; then extra_args_opts+=" -e@$secure_vars_file" fi extra_args_opts+=" -e@$extra_vars" ansible-playbook -vvvv -c local -i "localhost," $play.yml $extra_args_opts ansible-playbook -vvvv -c local -i "localhost," stop_all_edx_services.yml $extra_args_opts rm -rf $base_dir """.format( hipchat_token=args.hipchat_api_token, hipchat_room=args.ansible_hipchat_room_id, configuration_version=args.configuration_version, configuration_secure_version=args.configuration_secure_version, configuration_secure_repo=args.configuration_secure_repo, configuration_private_version=args.configuration_private_version, configuration_private_repo=args.configuration_private_repo, environment=args.environment, deployment=args.deployment, play=args.play, playbook_dir=args.playbook_dir, config_secure=config_secure, identity_contents=identity_contents, queue_name=run_id, extra_vars_yml=extra_vars_yml, secure_vars_file=secure_vars_file, cache_id=args.cache_id, datadog_api_key=args.datadog_api_key, region=args.region) mapping = BlockDeviceMapping() root_vol = BlockDeviceType(size=args.root_vol_size, volume_type='gp2') mapping['/dev/sda1'] = root_vol ec2_args = { 'security_group_ids': [security_group_id], 'subnet_id': subnet_id, 'key_name': args.keypair, 'image_id': base_ami, 'instance_type': args.instance_type, 'instance_profile_name': args.role_name, 'user_data': user_data, 'block_device_map': mapping, } return ec2_args
def create_instance_args(): """ Looks up security group, subnet and returns arguments to pass into ec2.run_instances() including user data """ vpc = boto.vpc.connect_to_region(args.region) subnet = vpc.get_all_subnets( filters={ 'tag:aws:cloudformation:stack-name': stack_name, 'tag:play': args.play} ) if len(subnet) < 1: # # try scheme for non-cloudformation builds # subnet = vpc.get_all_subnets( filters={ 'tag:play': args.play, 'tag:environment': args.environment, 'tag:deployment': args.deployment} ) if len(subnet) < 1: sys.stderr.write("ERROR: Expected at least one subnet, got {} for {}-{}-{}\n".format( len(subnet), args.environment, args.deployment, args.play)) sys.exit(1) subnet_id = subnet[0].id vpc_id = subnet[0].vpc_id security_group_id = get_instance_sec_group(vpc_id) if args.identity: config_secure = 'true' with open(args.identity) as f: identity_contents = f.read() else: config_secure = 'false' identity_contents = "dummy" user_data = """#!/bin/bash set -x set -e exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 base_dir="/var/tmp/edx-cfg" extra_vars="$base_dir/extra-vars-$$.yml" secure_identity="$base_dir/secure-identity" git_ssh="$base_dir/git_ssh.sh" configuration_version="{configuration_version}" configuration_secure_version="{configuration_secure_version}" configuration_private_version="{configuration_private_version}" configuration_internal_version="{configuration_internal_version}" environment="{environment}" deployment="{deployment}" play="{play}" cluster="{play}" config_secure={config_secure} git_repo_name="configuration" git_repo="https://github.com/edx/$git_repo_name" git_repo_secure="{configuration_secure_repo}" git_repo_secure_name=$(basename $git_repo_secure .git) git_repo_private="{configuration_private_repo}" git_repo_private_name=$(basename $git_repo_private .git) git_repo_internal="{configuration_internal_repo}" git_repo_internal_name=$(basename $git_repo_internal .git) secure_vars_file={secure_vars_file} environment_deployment_secure_vars="$base_dir/$git_repo_secure_name/ansible/vars/{environment}-{deployment}.yml" deployment_secure_vars="$base_dir/$git_repo_secure_name/ansible/vars/{deployment}.yml" environment_deployment_internal_vars="$base_dir/$git_repo_internal_name/ansible/vars/{environment}-{deployment}.yml" deployment_internal_vars="$base_dir/$git_repo_internal_name/ansible/vars/{deployment}.yml" instance_id=\\ $(curl http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null) instance_ip=\\ $(curl http://169.254.169.254/latest/meta-data/local-ipv4 2>/dev/null) instance_type=\\ $(curl http://169.254.169.254/latest/meta-data/instance-type 2>/dev/null) playbook_dir="$base_dir/{playbook_dir}" if $config_secure; then git_cmd="env GIT_SSH=$git_ssh git" else git_cmd="git" fi ANSIBLE_ENABLE_SQS=true SQS_NAME={queue_name} SQS_REGION={region} SQS_MSG_PREFIX="[ $instance_id $instance_ip $environment-$deployment $play ]" PYTHONUNBUFFERED=1 HIPCHAT_TOKEN={hipchat_token} HIPCHAT_ROOM={hipchat_room} HIPCHAT_MSG_PREFIX="$environment-$deployment-$play: " HIPCHAT_FROM="ansible-$instance_id" HIPCHAT_MSG_COLOR=$(echo -e "yellow\\ngreen\\npurple\\ngray" | shuf | head -1) DATADOG_API_KEY={datadog_api_key} # environment for ansible export ANSIBLE_ENABLE_SQS SQS_NAME SQS_REGION SQS_MSG_PREFIX PYTHONUNBUFFERED export HIPCHAT_TOKEN HIPCHAT_ROOM HIPCHAT_MSG_PREFIX HIPCHAT_FROM export HIPCHAT_MSG_COLOR DATADOG_API_KEY #################################### Lifted from ansible-bootstrap.sh if [[ -z "$ANSIBLE_REPO" ]]; then ANSIBLE_REPO="https://github.com/edx/ansible.git" fi if [[ -z "$ANSIBLE_VERSION" ]]; then ANSIBLE_VERSION="master" fi if [[ -z "$CONFIGURATION_REPO" ]]; then CONFIGURATION_REPO="https://github.com/edx/configuration.git" fi if [[ -z "$CONFIGURATION_VERSION" ]]; then CONFIGURATION_VERSION="master" fi if [[ -z "$UPGRADE_OS" ]]; then UPGRADE_OS=false fi # # Bootstrapping constants # VIRTUAL_ENV_VERSION="15.0.2" PIP_VERSION="8.1.2" SETUPTOOLS_VERSION="24.0.3" EDX_PPA_KEY_SERVER="keyserver.ubuntu.com" EDX_PPA_KEY_ID="B41E5E3969464050" cat << EOF ****************************************************************************** Running the abbey with the following arguments: ANSIBLE_REPO="$ANSIBLE_REPO" ANSIBLE_VERSION="$ANSIBLE_VERSION" CONFIGURATION_REPO="$CONFIGURATION_REPO" CONFIGURATION_VERSION="$CONFIGURATION_VERSION" ****************************************************************************** EOF if [[ $(id -u) -ne 0 ]] ;then echo "Please run as root"; exit 1; fi if grep -q 'Trusty Tahr' /etc/os-release then SHORT_DIST="trusty" elif grep -q 'Xenial Xerus' /etc/os-release then SHORT_DIST="xenial" else cat << EOF This script is only known to work on Ubuntu Trusty and Xenial, exiting. If you are interested in helping make installation possible on other platforms, let us know. EOF exit 1; fi EDX_PPA="deb http://ppa.edx.org $SHORT_DIST main" # Upgrade the OS apt-get update -y apt-key update -y if [ "$UPGRADE_OS" = true ]; then echo "Upgrading the OS..." apt-get upgrade -y fi # Required for add-apt-repository apt-get install -y software-properties-common python-software-properties # Add git PPA add-apt-repository -y ppa:git-core/ppa # For older distributions we need to install a PPA for Python 2.7.10 if [[ "trusty" = "$SHORT_DIST" ]]; then # Add python PPA apt-key adv --keyserver "$EDX_PPA_KEY_SERVER" --recv-keys "$EDX_PPA_KEY_ID" add-apt-repository -y "$EDX_PPA" fi # Install python 2.7 latest, git and other common requirements # NOTE: This will install the latest version of python 2.7 and # which may differ from what is pinned in virtualenvironments apt-get update -y apt-get install -y python2.7 python2.7-dev python-pip python-apt python-yaml python-jinja2 build-essential sudo git-core libmysqlclient-dev libffi-dev libssl-dev # Workaround for a 16.04 bug, need to upgrade to latest and then # potentially downgrade to the preferred version. # https://github.com/pypa/pip/issues/3862 if [[ "xenial" = "$SHORT_DIST" ]]; then pip install --upgrade pip pip install --upgrade pip=="$PIP_VERSION" else pip install --upgrade pip=="$PIP_VERSION" fi # pip moves to /usr/local/bin when upgraded hash -r #pip may have moved from /usr/bin/ to /usr/local/bin/. This clears bash's path cache. PATH=/usr/local/bin:$PATH pip install setuptools=="$SETUPTOOLS_VERSION" pip install virtualenv=="$VIRTUAL_ENV_VERSION" ##################### END Lifted from ansible-bootstrap.sh # python3 is required for certain other things # (currently xqwatcher so it can run python2 and 3 grader code, # but potentially more in the future). /usr/bin/apt-get install -y python3-pip python3-dev # this is missing on 14.04 (base package on 12.04) # we need to do this on any build, since the above apt-get # only runs on a build from scratch /usr/bin/apt-get install -y python-httplib2 --force-yes rm -rf $base_dir mkdir -p $base_dir cd $base_dir cat << EOF > $git_ssh #!/bin/sh exec /usr/bin/ssh -o StrictHostKeyChecking=no -i "$secure_identity" "\$@" EOF chmod 755 $git_ssh if $config_secure; then cat << EOF > $secure_identity {identity_contents} EOF fi cat << EOF >> $extra_vars --- # extra vars passed into # abbey.py including versions # of all the repositories {extra_vars_yml} # abbey will always run fake migrations # this is so that the application can come # up healthy fake_migrations: true disable_edx_services: true COMMON_TAG_EC2_INSTANCE: true # abbey should never take instances in # and out of elbs elb_pre_post: false EOF chmod 400 $secure_identity $git_cmd clone $git_repo $git_repo_name cd $git_repo_name $git_cmd checkout $configuration_version cd $base_dir if $config_secure; then $git_cmd clone $git_repo_secure $git_repo_secure_name cd $git_repo_secure_name $git_cmd checkout $configuration_secure_version cd $base_dir fi if [[ ! -z $git_repo_private ]]; then $git_cmd clone $git_repo_private $git_repo_private_name cd $git_repo_private_name $git_cmd checkout $configuration_private_version cd $base_dir fi if [[ ! -z $git_repo_internal ]]; then $git_cmd clone $git_repo_internal $git_repo_internal_name cd $git_repo_internal_name $git_cmd checkout $configuration_internal_version cd $base_dir fi cd $base_dir/$git_repo_name sudo pip install -r pre-requirements.txt sudo pip install -r requirements.txt cd $playbook_dir if [[ -r "$deployment_internal_vars" ]]; then extra_args_opts+=" -e@$deployment_internal_vars" fi if [[ -r "$environment_deployment_internal_vars" ]]; then extra_args_opts+=" -e@$environment_deployment_internal_vars" fi if [[ -r "$deployment_secure_vars" ]]; then extra_args_opts+=" -e@$deployment_secure_vars" fi if [[ -r "$environment_deployment_secure_vars" ]]; then extra_args_opts+=" -e@$environment_deployment_secure_vars" fi if $secure_vars_file; then extra_args_opts+=" -e@$secure_vars_file" fi extra_args_opts+=" -e@$extra_vars" ansible-playbook -vvvv -c local -i "localhost," $play.yml $extra_args_opts ansible-playbook -vvvv -c local -i "localhost," stop_all_edx_services.yml $extra_args_opts rm -rf $base_dir """.format( hipchat_token=args.hipchat_api_token, hipchat_room=args.ansible_hipchat_room_id, configuration_version=args.configuration_version, configuration_secure_version=args.configuration_secure_version, configuration_secure_repo=args.configuration_secure_repo, configuration_private_version=args.configuration_private_version, configuration_private_repo=args.configuration_private_repo, configuration_internal_version=args.configuration_internal_version, configuration_internal_repo=args.configuration_internal_repo, environment=args.environment, deployment=args.deployment, play=args.play, playbook_dir=args.playbook_dir, config_secure=config_secure, identity_contents=identity_contents, queue_name=run_id, extra_vars_yml=extra_vars_yml, secure_vars_file=secure_vars_file, cache_id=args.cache_id, datadog_api_key=args.datadog_api_key, region=args.region) mapping = BlockDeviceMapping() root_vol = BlockDeviceType(size=args.root_vol_size, volume_type='gp2') mapping['/dev/sda1'] = root_vol ec2_args = { 'security_group_ids': [security_group_id], 'subnet_id': subnet_id, 'key_name': args.keypair, 'image_id': base_ami, 'instance_type': args.instance_type, 'instance_profile_name': args.role_name, 'user_data': user_data, 'block_device_map': mapping, } return ec2_args