mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	The previous steps for standing up a new host were somewhat manual. This further scripts the process, by using the AWS CLI to start the instance, and pass it a "user data" script to provision itself upon boot. This results in a hands-off provisioning process which completes in 5min. Additional settings are required for `~/.zulip-install-server.conf`. It is not suited for all roles, as it assumes one instance type and security group value. Additionally, not all of the post-provision process is currently automated -- Nagios SSH key verification, for instance, is still a manual step. There are also additional steps for database or frontend servers. Regardless, this is a move toward automated provisioning.
		
			
				
	
	
		
			121 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/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 list of puppet rules to be passed to scripts/lib/install"
 | 
						|
    echo "   E.g. 'zulip::base,zulip::apt_repository,zulip::postgres_common'"
 | 
						|
    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" <<EOF
 | 
						|
{
 | 
						|
    "Comment": "Add the $HOSTNAME CNAME record",
 | 
						|
    "Changes": [
 | 
						|
        {
 | 
						|
            "Action": "CREATE",
 | 
						|
            "ResourceRecordSet": {
 | 
						|
                "Name": "$HOSTNAME",
 | 
						|
                "Type": "CNAME",
 | 
						|
                "TTL": 300,
 | 
						|
                "ResourceRecords": [{"Value": "$PUBLIC_DNS_NAME"}]
 | 
						|
            }
 | 
						|
        }
 | 
						|
    ]
 | 
						|
}
 | 
						|
EOF
 | 
						|
$AWS route53 change-resource-record-sets --hosted-zone-id "$AWS_ZONE_ID" --change-batch "file://$ROUTE53_CHANGES"
 | 
						|
rm "$ROUTE53_CHANGES"
 | 
						|
 | 
						|
set +x
 | 
						|
echo
 | 
						|
echo
 | 
						|
echo ">>> Install started successfully!  Provisioning takes 5-6min."
 | 
						|
echo "    sleep 360 && ssh root@$HOSTNAME"
 |