Virtually Free MC Bedrock Hosting (on AWS)

Introduction

 In this tutorial I’m going to explain how to set up a cheap Minecraft Bedrock server using the power of AWS (Amazon Web Services). Why choose AWS to host your server?

  • Better value for money – you only pay for what you use
  • More customisability – adjust pretty much anything you want

 This guide is quite comprehensive, so turn back now if you don’t have a good half an hour or more to spend.

How does this guide differ from others?

 We are going to be creating a server that is heavily focussed on the minimisation of costs. The end result will be an MC server that can be turned on via clicking a link, and then it will automatically turn off again after 15 minutes of no players being detected. The server will also post status updates via Discord, to let your friends and others know when the server is on or offline.

AWS Pricing

Before we begin, it’s important to go over the basics of AWS pricing. As mentioned earlier, you pay for what you use. In this tutorial we are going to use a few different AWS services:

  • EC2 – This is the virtual server that will host your Minecraft server. It is priced per hour, but billed per second, and the rates can be seen here.
  • Elastic IP – Typically EC2 instances will have a different IP each time they are stopped and started, using Elastic IP’s we can designate a specific IP that does NOT change when restarting the EC2 instance. Elastic IP’s only cost you money when your EC2 instance is offline, more info on their pricing can be seen via the link above for EC2 pricing.
  • API Gateway + Lambda – We will use these services to start the Minecraft server when it is stopped. We almost certainly will not be going over the free tier limits for these services.

All in all, if you follow this tutorial exactly, with daily use of your server, you can expect to be paying around £10 per month.

Getting Started

 First things first, you will need to set up an AWS account and know the basics of how it works. I’m not going over that in this tutorial, but you can see an official guide on how to do this here.

 Next, we are going to set up billing alerts. AWS can be quite complicated at first, and we want to make sure you are in control of the money you spend on AWS.

  1. Login to your admin account
  2. Search for ‘Billing and Cost Management’
  3. Navigate to the ‘Budgets’ tab
  4. Click ‘Create Budget’
  5. Now keep ‘Use a template’ selected
  6. Select ‘Monthly Cost Budget’ under the ‘Templates’ header
  7. Enter the budget you are comfortable spending each month
  8. Enter a name for the budget
  9. Enter the email address for budget alerts to be sent to
  10. Finally create the budget

 Now, you will be notified at various points of your monthly budget. First when you reach 85% of it, then when you reach 100% of it. You will also be notified if AWS predicts that you are going to reach 100% of your budget.

Setting Up The Server

Now we’re going to actually start setting up the Minecraft Server, I will break this down in to a few stages to make the process as straight forward as possible.

Create the EC2 Instance

First we want to get the actual server that will be hosting your Minecraft Bedrock Server setup and running.

  1. Search for ‘EC2’ and then navigate to the first result
  2. Now in the top right of your page, select the region that is closest to you, this will most likely be ‘Europe (Paris)’ if you live in the UK. Make a note of the region code (the smaller text e.g. ‘eu-west-3’, as this will be needed later)
  3. On your page, you should see an option to ‘Launch Instance’, click this
  4. Name the instance something appropriate, such as ‘MC Server’
  5. Select ‘Windows’ as the operating system
  6. Select ‘t3.small’ as the Instance type (or t3.medium for more performance, although this will cost more!)
  7. Now we want to create a new Key Pair, click ‘Create new Key Pair’, give it a valid name, select ‘RSA’ as the type and ‘.pem’ as the format. Save this somewhere safe as  we will need it later
  8. Leave everything under ‘Network Settings’ as it is
  9. Under ‘Configure Storage’, change ‘1 x 30 GiB’ to be ‘1 x 50 GiB’ as you will need around 50GB of storage. Also, make sure the dropdown next to this is set to ‘gp3’.
  10. Click ‘Launch Instance’ and you’ve just created your AWS EC2 instance!

Setup an Elastic IP

Now we want to give the server we just set up an IP that won’t change when the server starts and stops.

  1. Search for ‘Elastic IP’s’ and then click on the first result
  2. Click ‘Allocate Elastic IP address’ in the top right of the page
  3. Don’t touch any of the options here, just click ‘Allocate’ at the bottom of the page
  4. Now you will see the Elastic IP address you have created, select it and then at the top right of the page click ‘Actions’
  5. Click ‘Associate IP Address’, and then you will be directed to a page with more options
  6. In the ‘Instance’ box, select the EC2 instance we created in the step before, and then click the ‘Associate’ button
  7. Congratulations, our EC2 instance now has an IP address that does not change!

Set Up Security Group

The instance we created earlier will be associated with a ‘Security Group’, this keeps it protected from unwanted traffic. By default, the security group will block ALL traffic except for remote desktop connections – which we of course need to set up the server. We need to allow the Minecraft Bedrock server ports through this firewall, a bit like port forwarding when you host a server on your home network.

  1. Navigate to the EC2 page via the search bar
  2. In the sidebar, select ‘Instances’
  3. Click on the instance we created earlier
  4. Click ‘Security’
  5. Now there will be one link under ‘Security Groups’, click this
  6. Here we need to setup some rules

Inbound

  1. Select ‘Edit Inbound Rules’
  2. Add a rule for  ‘Custom TCP’, set the port range as ‘19132-19133’, finally set the source as ‘ 0.0.0.0/0’
  3. Add a rule for  ‘Custom UDP’, set the port range as ‘19132-19133’, finally set the source as ‘ 0.0.0.0/0’

You do not have to set up any outbound rules as by default, all outbound traffic is allowed.

Connect to the EC2 Instance

Now we are going to start configuring the Minecraft Server, first we need to connect to the EC2 instance we created earlier.

  1. Navigate to the ‘EC2 Instances’ page we where on earlier
  2. Right click on your instance and select ‘Start Instance’ if it isn’t already started
  3. Now right click on your instance and select ‘Connect’
  4. Select the ‘RDP Client’ tab
  5. Click ‘Download remote desktop file’
  6. Now you can double click on this file to start connecting to your instance
  7. To get the administrator password, click the ‘Get password’ link, and then provide the private key file we downloaded earlier (whilst setting up the EC2 instance)
  8. Now you should be able to login to the Windows Server operating system

Set up the Minecraft Bedrock server

In this part of the tutorial, we are going to set up all of the things needed to run the Minecraft Bedrock server, as-well as the script that is going to start this server when the EC2 instance boots up, and also shut it down when no players are detected.

Start by downloading all of the dependencies

  1. RDP into the EC2 instance using the instructions above
  2. Download Chrome so you aren’t forced into the nightmare of using Microsoft Edge
  3. Download the latest version of Python
  4. Download the latest version of the MC Bedrock Server
  5. Download the latest pre-release of NSSM (from 2017)
  6. Download `start_and_monitor_mc_server.py` from this Github Repository

We will use Python to run the script that disables the server when no-one is online, and we will use NSSM (Non Sucking Server Manager) to launch this script when the instance boots up…There are many ways to launch a script on start-up, but I found most guides online to be useless, and even AWS’s own method of doing this (user-data scripts) just don’t seem to play nice.

Move Everything Into Place

  1. Extract the bedrock server files to the Desktop, and rename the folder to ‘server’. For the Python script to work, it should be able to reach the bedrock server executable via the following path: C:\Users\Administrator\Desktop\server\bedrock_server
  2. Now move the ‘NSSM.exe’ to the Desktop folder
  3. Now move the python script we downloaded in step 6 above, to the Desktop folder

Configure the Minecraft Server

Now you will want to configure the Minecraft Bedrock server to your liking, using the server.properties file. There are loads of guides online for how to do this, alternatively go to the MC Bedrock Server website linked above and view their setup guide.

Setup Windows Firewall

At this point you will need to allow the MC Bedrock Server application through the windows firewall.

  1. In the Windows search bar type ‘Firewall’, and open the Firewall settings
  2. Click ‘Allow an app through firewall’
  3. Click ‘Allow another app…’
  4. Navigate to the ‘server’ directory we setup earlier and select the Bedrock server executable
  5. Save and exit the firewall settings
Configure the Python Script
  1. Open the python script file we downloaded earlier ‘start_and_monitor_mc_server.py’ by right clicking it and opening it with Python Idle
  2. At the top click ‘Run’ and then ‘Run Module’, alternatively press F5
  3. At this point you shouldn’t see any errors, and the bedrock server should have started. If you did see any errors, try opening a command prompt and entering the following two commands py -m pip install discord-webhook and py -m pip install mcstats
  4. Now close the minecraft server that has started, and also close all of the open Python files so that we are ready for the next step

(Optional) Link To Discord

The script above has the ability to give a Discord server notifications of your servers status (whether it is online or not). By default this is turned off, but follow the steps below to turn it on.

  1. Create a new discord server or open the one you currently own
  2. Go into the Discord server settings and create a Webhook URL for the channel you want updates to be sent to
  3. Now open the python script file we downloaded earlier ‘start_and_monitor_mc_server.py’ by right clicking it and opening it with Python Idle.
  4. Find the variable ‘DISCORD_WEBHOOK_URL’ and between the empty quotation marks, paste the Discord webhook URL you have just copied
  5. Now save the file, and then run it by pressing F5, or alternatively navigating to the ‘Run’ menu and clicking ‘Run Module’
  6. Now a message will have been sent to your Discord server, and you will need to copy the message ID. Right click onto the message, and select ‘Copy Message ID’. If this option does not appear, you will need to enable Developer Mode on discord.
  7. You will now see two Python Idle windows, and the MC server window that has been started. Close every app/window except for the one containing the Python code itself
  8. Find the variable ‘WEBHOOK_MESSAGE_ID’ at the top of the code, and again, paste the message ID you copied above in-between the speech marks to the right of this variable
  9. If you re-run the Python script, you should now see the Discord message in your server has updated to reflect the status of the server

Configure NSSM

Important: Please make sure you have configured the MC server to your liking before running this step, as it could make changes to the configuration difficult later on – essentially the server will restart within 15 minutes of no players being detected, so whenever you want to make configuration changes to the MC server, you will only have a 15 minute window unless you log into the MC server and stay in-game whilst you make changes to the configuration files.

At this point, all we need to do is make sure that the server launches the Python script when it boots up. The Python script will then launch the MC Server and continue to monitor it’s player count, and then shut down after 15 minutes of no players being detected.

  1. First, find out where we installed Python earlier. We need to get a path to the python.exe file. This will most likely be inside of your C:\ folder, where you will see a folder that looks like “PythonXX”. So the file path for Python will look something like C:\Python39\python.exe.Alternatively you may find it in the %temp%\local folder
  2. Open command prompt and type: CD desktop
  3. Now type the following command: nssm install "mcmanager" "PATH_TO_PYTHON.EXE" "PATH_TO_PYTHON_SCRIPT"

In step 3, you should replace the following:

  • PATH_TO_PYTHON.EXE – replace with the path you found in step 2
  • PATH_TO_PYTHON_SCRIPT – replace this with the path to the python script you have been altering. If you have followed this guide exactly, this path will be: C:\Users\Administrator\Desktop\start_and_monitor_mc_server.py
Now that NSSM has been set up, the server will turn off after 15 minutes of no players being online. This can be incredibly annoying when trying to configure your MC server or other things. To stop the server from shutting down automatically, you will want to search for “services” in the bottom left windows bar, open “Service Manager” and then search for the name of the service created – in our example it will be “mcmanager”, finally right click it and select “Stop Service”. This will stop the Python script from running, but NOT the MC Bedrock Server. When you have made the changes you want to make, you should shut down the server so that it restarts the service correctly the next time it boots up.

Test The Server

Congratulations, at this point your server should be all set up and ready to go! You can now test it by going back to the AWS web console and navigating to theEC2 instances page. Restart the instance, and then after waiting about a minute, you should be able to connect to the Minecraft Server by typing the IPV4 address we found earlier (or alternatively look at the Instances Public IP/IPV4 address on the AWS instances page). If you opted to set up Discord, you should now also see the Discord status message updating as the server status also updates.

Setting Up How The Server Starts

At this point, you will have a working server that will stop itself when it is running, however only you will be able to restart it by going to the EC2 Instances page in AWS and selecting “Start Instance”. If you are happy to do this and are fed up of reading this absolute behemoth of text, I don’t blame you and you can stop reading here!

Otherwise, we will now set up a way for your friends to also start the server when they want to go on and play. We will do this by creating an API (a URL your friends can visit in their browser) and then linking this to an AWS Lambda, which is basically just a piece of code that we will use to turn your server on.

Setting Up Permissions

When someone hits your API to start the server, it will then trigger the Lambda that will run code to start the server. The problem is, we need to give that Lambda permission to actually start the server.

First we need to create a policy, which is basically a group of permissions. Then we need to create a role which is the thing that we will attach to our Lambda to give it permission to actually start our server.

Create a Policy

  1. Search for ‘IAM’ in the AWS console, and then hover over the IAM option and select ‘Policies’
  2. Click ‘Create Policy’
  3. Choose ‘EC2’ as the service
  4. Under ‘Actions Allowed’ search for ‘StartInstances’, then select this
  5. Now we have specified that this policy relates to allowing a service to start an instance, but we need to specify which instance that is
  6. Under ‘Resources’ select ‘Specific’ and then next to the ‘instance’, click ‘Add ARNs to restrict access’
    1. The window that pops up will have the title ‘Specify ARN(s)’
    2. Select ‘Visual’ to load the visual editor
    3. Under ‘Resources In’ select ‘This account’
    4. Under ‘Resource region’ you will want to input the region you created your EC2 instance in. You can do this by opening a new tab and navigating to the EC2 instances page, then in the top right you can see the name of the region you selected, and a code for it that will be separated by dashes, in this tutorial the instance location is Europe (Paris) and the code for this is “eu-west-3”, so under ‘Resource Region’ we will put “eu-west-3”.
    5. Under ‘Resource Instance’ we need to put the ARN of our EC2 instance. On the EC2 instances page this will be displayed as the “Instance ID”, just copy all of this and paste it into this box. It will look something like “i-bunchofnumbersandletters”
    6. Finally click “Add ARN”
  7. Now we will be back on the create policy page. Click ‘Next’
  8. Add a name to the policy that will distinguish it from the hundreds of default policies already created. E.g. “StartMCBedrock”
  9. Finally click ‘Create Policy’

Create a Role

Now we need to create a Role that we can later attach to our Lambda function.

  1. Search for ‘IAM’ in the AWS console, and then however over the IAM option and select ‘Roles’
  2. Click ‘Create Role’
  3. Select ‘AWS Service’
  4. Select ‘Lambda’ as the Service or use case
  5. Click ‘Next’
  6. Now search for the policy you created earlier, e.g. “StartMCBedrock” and select this
  7. Click ‘Next’
  8. Give the Role a name that you will remember, e.g. “MCBedrockLambda”

Congratulations, you have now set up the permissions for the Lambda that we will create in the next step.

Setting Up The Lambda

At this point, we want to create the Lambda function that will start our server when it is run. A Lambda is just a piece of code that runs when some trigger is activated, in our case we will be using an API later on to trigger our Lambda to run.

  1. Search for “Lambda” in the AWS console and click the first result
  2. Click ‘Create function’
  3. Select ‘Author from scratch’
  4. Enter a name for the function e.g. ‘StartBedrockServer’, and select the runtime as ‘Python 3.12’
  5. Under ‘Permissions’ click ‘Change default execution role’
  6. Select ‘Use an existing role’
  7. Now find and select the role you created earlier, in our example it was “MCBedrockLambda”
  8. Click ‘Create Function’
  9. Now navigate back to the Lambda functions page, and select the function you just created

Now you will see a screen with the details of your lambda function, and if you scroll down you will see a section with some code and a file “lambda_function.py”. Replace all of the contents of this file with the code from the ‘lambda.py’ file in this Github Repository.

You will then need to replace the following:

  • REGION_CODE_HERE – replace this with the code of the region your EC2 instance is hosted in
  • INSTANCE_ID_HERE – replace this with the ID of your EC2 instance (starts with “i-“)

You should already have the above two codes from the ‘Create a Policy’ section completed earlier.

Now you must save this code by clicking “Deploy”

Setting Up API Gateway

The final part of this tutorial (nearly there) is to set up the API that will trigger the Lambda we just set up, this is essentially just a URL you or any of your friends can load in a browser, and then the server will start.

  1. Search for ‘API Gateway’ in the AWS console and select the first option
  2. Click ‘Create API’
  3. Under ‘HTTP API’ click ‘Build’
  4. Under ‘Integrations’ select ‘Lambda’ from the dropdown
  5. Select the Lambda function you created earlier
  6. Set the API name to anything you want
  7. Click ‘Next’ and then click ‘Next’ again
  8. Click ‘Add Stage’ and give it a reasonable name e.g. ‘production’
  9. Click ‘Next’ and then click ‘Create’
  10. Now you should be on the API ‘Routes’ page
  11. In the left sidebar, select ‘Stages’ and then click ‘Create’
  12. Click the ‘Deploy’ button towards the top right of the page, then select the stage we created in step 8, and click ‘Deploy to Stage’

You will now be on the ‘Stages’ page and you will see an ‘Invoke URL’, this is the base URL of your API and will look something like https://xxxx.execute-api.eu-west-3.amazonaws.com/STAGE_NAME

This link will NOT work as it is, it is just the base URL of your endpoint. You will need to add /NAME_OF_ROUTE to the end of it. This is usually the name of your Lambda by default, but you can find out by clicking on ‘Routes’ in the left sidebar.

If you’ve copied the naming from this tutorial, the URL to start your server will look something like https://xxxx.execute-api.eu-west-3.amazonaws.com/production/StartBedrockServer

(Optional) Make It Cheaper!

Well done for reaching the end of the tutorial. This is an optional ‘upgrade’ to make things even cheaper. Currently we have the server setup using an Elastic IP,  which keeps the server IP the same when it reboots, however AWS charges us to use this service. We can achieve the same result as an Elastic IP with something called Dynamic DNS, and there are quite a few DynDNS providers that offer free tiers.

Dynamic DNS is essentially a way to get a hostname or IP address that remains the same, but then redirects traffic to an IP address of your choosing – in this case we will update the Dynamic DNS provider each time the server boots (in the script we made earlier) so that the IP for players connecting to the server will always remain the same, even though the server instances IP address actually changes.

Option One: NoIP

This blog is not sponsored by NoIP, and you can actually just search for “Free Dynamic DNS” to get any other provider. At the time of writing, NoIP offers a free tier with the caveat of having to confirm your account is still active every month.

  1. Create a new NoIP account and set up one of their free hostnames
  2. Follow this guide to get an update URL to update the IP address associated with your NoIP hostname
  3. Now open up the Python script we edited earlier, and paste the update URL from step two in-between the empty speech marks after the variable DYNAMIC_DNS_URL
  4. Save the script file, and shutdown the EC2 instance
  5. Finally, load up the AWS web console, navigate to “Elastic IP”, select the Elastic IP that is present and click “Disassociate”, then select the Elastic IP again and click “Release IP address”.

Option Two: cPanel

If you already host your own website or have access to a cPanel instance, this step may be easier than using a dynamic DNS Service.

  1. Go to your cPanel instance and navigate to “Dynamic DNS”
  2. Click “Create” and create a subdomain that you want players to connect to when they join your server
  3. Now copy the URL to the side of the subdomain you just created, this is the URL that is used to update the dynamic DNS IP. You can test this URL by loading it into your browser, and checking to see that the cPanel page has updated to your computers IP
    • If this step does not work, you may need to copy the HOSTNAME and PORT of the cPanel instance from your web browsers URL bar. And then copy the part of the URL besides the IP you created in cPanel that looks like /cpanelwebcall/somerandomstringhere. The whole URL should look something like https://cpanelhostname.com:cpanelport/cpanelwebcall/somerandomstuffhere
  4. Now open up the Python script we edited earlier, and paste the update URL from step 3 in-between the empty speech marks after the variable DYNAMIC_DNS_URL
  5. Save the script file, and shutdown the EC2 instance
  6. Finally, load up the AWS web console, navigate to “Elastic IP”, select the Elastic IP that is present and click “Disassociate”, then select the Elastic IP again and click “Release IP address”.

Congratulations!

Congratulations on reaching it this far. By now you will have a Minecraft server that you can start with the URL obtained above, a discord status bot that will update you with the servers status, and a MC Server that will shut down within 15 minutes of all players leaving the server.

Oh, if you find yourself needing a bit more power after setting all of this up, don’t redo it all! The beauty of AWS is configurability. Go to the EC2 Instances page, stop your instance and then right click it and select “Instance Settings” then “Change Instance Type” and you can make it more/less powerful without any fuss, remember this will also affect the price!

This is my first ever tutorial of this length, so please feel free to send me some feedback! Just don’t ask me to add photos, doing that in WordPress is an absolute pain!

Posted in Tutorial
Write a comment