Skip to content

Instantly share code, notes, and snippets.

@Rimbo
Created March 12, 2023 23:20
Show Gist options
  • Save Rimbo/388508c334d25eeabea2e43610d204f6 to your computer and use it in GitHub Desktop.
Save Rimbo/388508c334d25eeabea2e43610d204f6 to your computer and use it in GitHub Desktop.
Suppose you want your own self-hosted Minecraft server on EC2 because you want to save money; you have a Route 53 DNS that needs updating, too...
#
# AWS EC2 Minecraft Server Functions!
# These functions will work for any EC2 you want to start and stop on-demand.
# Save even MORE money with a spot instance.
#
# You will need:
# 1. An AWS account.
# 2. A domain/DNS for the host, preferably in Route 53.
# 3. An EC2 with the minecraft server installed on it (possibly launched on boot?)
# 4. A configured IAM role with the following permissions on the above resources:
# - ec2.describe-instances
# - ec2.start-instances
# - ec2.stop-instances
# - budgets.describe-budgets
# - route53.change-record-resource-sets
# - route53.get-change
#
# 5. Set these variables.
#
INSTANCE_ID= # AWS Instance ID
HOST_DNS= # DNS name of minecraft server
ZONEID= # DNS Zone ID
ACCOUNT_ID= # Your account ID (for billing updates)
# 6. If you don't have ~/.aws/config set for this IAM profile, also set these:
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=
# AWS_DEFAULT_REGION=
#
# Status and this month's billing
#
minecraft-status() {
server_status=$(aws ec2 describe-instances --instance-ids ${INSTANCE_ID} | jq -r .Reservations[].Instances[].State.Name)
budget_status=$(aws budgets describe-budgets --account-id ${ACCOUNT_ID})
actual_spend=$(echo ${budget_status} | jq -r .Budgets[].CalculatedSpend.ActualSpend.Amount)
future_spend=$(echo ${budget_status} | jq -r .Budgets[].CalculatedSpend.ForecastedSpend.Amount)
echo "Minecraft host is currently: ${server_status}."
echo "Current monthly spend is: \$${actual_spend}."
echo "Expected monthly spend is: \$${future_spend}."
}
#
# Bring up the server and update DNS
#
minecraft-up() {
echo "Launching the server."
aws ec2 start-instances --instance-ids ${INSTANCE_ID}
echo -n "Waiting for it to be alive..."
while [ $(aws ec2 describe-instances --instance-ids ${INSTANCE_ID} | jq -r .Reservations[].Instances[].State.Name) != "running" ] ; do
sleep 5
echo -n '.'
done
echo "And we're awake."
server_ip=$(aws ec2 describe-instances --instance-ids ${INSTANCE_ID} | jq -r .Reservations[].Instances[].PublicIpAddress)
echo "Server IP: ${server_ip}"
cat <<EOF > /tmp/changeset.json
{
"Comment": "Update record to reflect new IP address of minecraft server",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "${HOST_DNS}",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "${server_ip}"
}
]
}
}
]
}
EOF
echo "Updating DNS record."
long_changeid=$(aws route53 change-resource-record-sets --hosted-zone-id ${ZONEID} --change-batch file:///tmp/changeset.json | jq -r .ChangeInfo.Id)
changeid=$(echo $long_changeid |sed -e 's/\/change\///')
echo "Change ID: ${changeid}"
echo -n "Waiting for DNS update..."
while [ $(aws route53 get-change --id ${changeid} | jq -r .ChangeInfo.Status) != 'INSYNC' ] ; do
sleep 5
echo -n '.'
done
echo "updated."
echo "You may now connect to the host with ssh."
}
#
# Shut down the server.
#
minecraft-down() {
echo "Stopping the server."
aws ec2 stop-instances --instance-ids ${INSTANCE_ID}
echo -n "Waiting for it to be down..."
while [ $(aws ec2 describe-instances --instance-ids ${INSTANCE_ID} | jq -r .Reservations[].Instances[].State.Name) != "stopped" ] ; do sleep 5 ; echo -n '.' ; done
echo "And we're dead."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment