194 lines
4.7 KiB
Bash
Executable File
194 lines
4.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -eu -o pipefail
|
|
|
|
assertNotEmpty() {
|
|
: "${!1:? "$1 is not set."}"
|
|
}
|
|
|
|
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
readonly SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)"
|
|
export JSON="${SOURCE_DIR}/node_modules/.bin/json"
|
|
|
|
INSTANCE_TYPE="t2.micro"
|
|
BLOCK_DEVICE="DeviceName=/dev/sda1,Ebs={VolumeSize=20,DeleteOnTermination=true,VolumeType=gp2}"
|
|
SSH_KEY_NAME="id_rsa_yellowtent"
|
|
|
|
revision=$(git rev-parse HEAD)
|
|
ami_name=""
|
|
server_id=""
|
|
server_ip=""
|
|
destroy_server="yes"
|
|
deploy_env="prod"
|
|
image_id=""
|
|
|
|
args=$(getopt -o "" -l "revision:,name:,no-destroy,env:,region:" -n "$0" -- "$@")
|
|
eval set -- "${args}"
|
|
|
|
while true; do
|
|
case "$1" in
|
|
--env) deploy_env="$2"; shift 2;;
|
|
--revision) revision="$2"; shift 2;;
|
|
--name) ami_name="$2"; shift 2;;
|
|
--no-destroy) destroy_server="no"; shift 2;;
|
|
--region)
|
|
case "$2" in
|
|
"us-east-1")
|
|
image_id="ami-6edd3078"
|
|
security_group="sg-a5e17fd9"
|
|
subnet_id="subnet-b8fbc0f1"
|
|
;;
|
|
"eu-central-1")
|
|
image_id="ami-5aee2235"
|
|
security_group="sg-19f5a770" # everything open on eu-central-1
|
|
subnet_id=""
|
|
;;
|
|
*)
|
|
echo "Unknown aws region $2"
|
|
exit 1
|
|
;;
|
|
esac
|
|
export AWS_DEFAULT_REGION="$2" # used by the aws cli tool
|
|
shift 2
|
|
;;
|
|
--) break;;
|
|
*) echo "Unknown option $1"; exit 1;;
|
|
esac
|
|
done
|
|
|
|
# TODO fix this
|
|
export AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY}"
|
|
export AWS_SECRET_ACCESS_KEY="${AWS_ACCESS_SECRET}"
|
|
|
|
readonly ssh_keys="${HOME}/.ssh/id_rsa_yellowtent"
|
|
readonly SSH="ssh -o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ${ssh_keys}"
|
|
|
|
if [[ ! -f "${ssh_keys}" ]]; then
|
|
echo "caas ssh key is missing at ${ssh_keys} (pick it up from secrets repo)"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "${image_id}" ]]; then
|
|
echo "--region is required (us-east-1 or eu-central-1)"
|
|
exit 1
|
|
fi
|
|
|
|
function get_pretty_revision() {
|
|
local git_rev="$1"
|
|
local sha1=$(git rev-parse --short "${git_rev}" 2>/dev/null)
|
|
|
|
echo "${sha1}"
|
|
}
|
|
|
|
function wait_for_ssh() {
|
|
echo "=> Waiting for ssh connection"
|
|
while true; do
|
|
echo -n "."
|
|
|
|
if $SSH ubuntu@${server_ip} echo "hello"; then
|
|
echo ""
|
|
break
|
|
fi
|
|
|
|
sleep 5
|
|
done
|
|
}
|
|
|
|
now=$(date "+%Y-%m-%d-%H%M%S")
|
|
pretty_revision=$(get_pretty_revision "${revision}")
|
|
|
|
if [[ -z "${ami_name}" ]]; then
|
|
ami_name="box-${deploy_env}-${pretty_revision}-${now}"
|
|
fi
|
|
|
|
echo "=> Create EC2 instance"
|
|
id=$(aws ec2 run-instances --image-id "${image_id}" --instance-type "${INSTANCE_TYPE}" --security-group-ids "${security_group}" --block-device-mappings "${BLOCK_DEVICE}" --key-name "${SSH_KEY_NAME}" --subnet-id "${subnet_id}" --associate-public-ip-address \
|
|
| $JSON Instances \
|
|
| $JSON 0.InstanceId)
|
|
|
|
[[ -z "$id" ]] && exit 1
|
|
echo "Instance created ID $id"
|
|
|
|
echo "=> Waiting for instance to get a public IP"
|
|
while true; do
|
|
server_ip=$(aws ec2 describe-instances --instance-ids ${id} \
|
|
| $JSON Reservations.0.Instances \
|
|
| $JSON 0.PublicIpAddress)
|
|
|
|
if [[ ! -z "${server_ip}" ]]; then
|
|
echo ""
|
|
break
|
|
fi
|
|
|
|
echo -n "."
|
|
sleep 1
|
|
done
|
|
|
|
echo "Got public IP ${server_ip}"
|
|
|
|
wait_for_ssh
|
|
|
|
echo "=> Fetching cloudron-setup"
|
|
while true; do
|
|
|
|
if $SSH ubuntu@${server_ip} wget "https://cloudron.io/cloudron-setup" -O "cloudron-setup"; then
|
|
echo ""
|
|
break
|
|
fi
|
|
|
|
echo -n "."
|
|
sleep 5
|
|
done
|
|
|
|
echo "=> Running cloudron-setup"
|
|
$SSH ubuntu@${server_ip} sudo /bin/bash "cloudron-setup" --env "${deploy_env}" --provider "ami" --skip-reboot
|
|
|
|
wait_for_ssh
|
|
|
|
echo "=> Removing ssh key"
|
|
$SSH ubuntu@${server_ip} sudo rm /home/ubuntu/.ssh/authorized_keys /root/.ssh/authorized_keys
|
|
|
|
echo "=> Creating AMI"
|
|
image_id=$(aws ec2 create-image --instance-id "${id}" --name "${ami_name}" | $JSON ImageId)
|
|
[[ -z "$id" ]] && exit 1
|
|
echo "Creating AMI with Id ${image_id}"
|
|
|
|
echo "=> Waiting for AMI to be created"
|
|
while true; do
|
|
state=$(aws ec2 describe-images --image-ids ${image_id} \
|
|
| $JSON Images \
|
|
| $JSON 0.State)
|
|
|
|
if [[ "${state}" == "available" ]]; then
|
|
echo ""
|
|
break
|
|
fi
|
|
|
|
echo -n "."
|
|
sleep 5
|
|
done
|
|
|
|
if [[ "${destroy_server}" == "yes" ]]; then
|
|
echo "=> Deleting EC2 instance"
|
|
|
|
while true; do
|
|
state=$(aws ec2 terminate-instances --instance-id "${id}" \
|
|
| $JSON TerminatingInstances \
|
|
| $JSON 0.CurrentState.Name)
|
|
|
|
if [[ "${state}" == "shutting-down" ]]; then
|
|
echo ""
|
|
break
|
|
fi
|
|
|
|
echo -n "."
|
|
sleep 5
|
|
done
|
|
fi
|
|
|
|
echo ""
|
|
echo "Done."
|
|
echo ""
|
|
echo "New AMI is: ${image_id}"
|
|
echo ""
|