#!/usr/bin/env bash set -e SERVER=$1 ROLES=$2 BRANCH=$3 if [ -z "$SERVER" ] || [ -z "$ROLES" ]; then echo "USAGE: $0 server roles [branch]" echo echo "Installs an empty Ubuntu server in AWS with a Zulip server role." echo echo " * server is the local part of the hostname (e.g. postgres0)" echo " * roles is a comma-separated list of Puppet rules to be passed to scripts/lib/install" echo " E.g. 'zulip::profile::postgresql'" echo " * branch is used to override the default branch to install from." echo echo "Reads configuration from $HOME/.zulip-install-server.conf, which should look like:" echo echo "[repo]" echo "repo_url=git@github.com:zulip/zulip.git" echo "branch=master" echo "[aws]" echo "zone_id=Z2U988IEXAMPLE" echo "security_groups=sg-01234567" echo "image_id=ami-0dc45e3d9be6ab7b5" echo "instance_type=m4.large" echo "ssh_secret_id=prod/git/deploy" exit 1 fi set -x cd "$(dirname "$0")" source ./bootstrap-awscli zulip_install_config_file="$HOME/.zulip-install-server.conf" if [ ! -f "$zulip_install_config_file" ]; then echo "No configuration file found in $zulip_install_config_file" exit 1 fi REPO_URL=$(crudini --get "$zulip_install_config_file" repo repo_url) if [ -z "$BRANCH" ]; then BRANCH=$(crudini --get "$zulip_install_config_file" repo default_branch) fi AWS_ZONE_ID=$(crudini --get "$zulip_install_config_file" aws zone_id) SECURITY_GROUPS=$(crudini --get "$zulip_install_config_file" aws security_groups) AMI_ID=$(crudini --get "$zulip_install_config_file" aws image_id) INSTANCE_TYPE=$(crudini --get "$zulip_install_config_file" aws instance_type) SSH_SECRET_ID=$(crudini --get "$zulip_install_config_file" aws ssh_secret_id) # Verify it doesn't exist already ZONE_NAME=$($AWS route53 get-hosted-zone --id "$AWS_ZONE_ID" | jq -r '.HostedZone.Name') HOSTNAME="$SERVER.${ZONE_NAME%?}" # Remove trailing . EXISTING_RECORDS=$($AWS route53 list-resource-record-sets \ --hosted-zone-id "$AWS_ZONE_ID" \ --query "ResourceRecordSets[?Name == '$HOSTNAME.']" \ | jq '. | length') if [ "$EXISTING_RECORDS" != "0" ]; then echo "$HOSTNAME already exists!" exit 1 fi # Build up the provisioning script BOOTDATA=$(mktemp) { echo "#!/bin/bash" echo "SERVER=$SERVER" echo "HOSTNAME=$HOSTNAME" echo "ROLES=$ROLES" echo "REPO_URL=$REPO_URL" echo "BRANCH=$BRANCH" echo "SSH_SECRET_ID=$SSH_SECRET_ID" sed '/^AWS=/ r ./bootstrap-awscli' bootstrap-aws-installer } >>"$BOOTDATA" TAGS="[{Key=Name,Value=$SERVER},{Key=role,Value=\"$ROLES\"}]" INSTANCE_DATA=$($AWS ec2 run-instances \ --iam-instance-profile 'Name="EC2ProdInstance"' \ --image-id "$AMI_ID" \ --instance-type "$INSTANCE_TYPE" \ --security-group-ids "$SECURITY_GROUPS" \ --tag-specifications "ResourceType=instance,Tags=$TAGS" \ --user-data "file://$BOOTDATA") INSTANCEID=$(echo "$INSTANCE_DATA" | jq -r .Instances[0].InstanceId) # Wait for public IP assignment PUBLIC_DNS_NAME="" while [ -z "$PUBLIC_DNS_NAME" ]; do sleep 1 PUBLIC_DNS_NAME=$($AWS ec2 describe-instances --instance-ids "$INSTANCEID" \ | jq -r .Reservations[0].Instances[0].PublicDnsName) done # Add the hostname to the zone ROUTE53_CHANGES=$(mktemp) cat >"$ROUTE53_CHANGES" <>> Install started successfully! Provisioning takes 5-6min." echo " sleep 360 && ssh root@$HOSTNAME"