Jonty Behr • 17 Feb 2018
Laravel Forge is a great tool if you need to launch servers on a regular basis. It's a huge time-saver and its nice being able to get a fully up-to-date server working in a matter of minutes, including most of the necessary services likes Nginx, Redis, MySql/Postgres and more. We've been using Forge to provision our Digital Ocean servers for a while, but I recently needed to get a new VPS up and running on AWS. Mettle already runs quite a few services on AWS and we're relatively familiar with it, but there are a few gotchas when using Forge to launch an instance.
A few weeks after this article was published, an update was released to Forge which allows you to select which VPC you would like to launch your AWS servers into.
There is still a lot of relevant information below, so I'll leave it here for posterity.
There are two options for using Forge in conjunction with your AWS account - you can either:
There are pros and cons to each method, as we'll discuss below.
If you have already created the server in AWS, then you'll want to use the Custom VPS option. You'll need a fresh Ubuntu 16.04 install, and you'll also need to have a root account with a password. Note that if you're using AWS, the root account is disabled by default, so you'll have to enable the root account, and set up a password for it. This is not ideal, and I'd strongly recommend disabling the root account once everything is set up.
Once, you've enabled your root account, head over to Forge, select the Custom VPS option and enter the relevant data.
After you click the Create Server button, Forge will ask you to log into your server and run their Provisioning Script as the root user. This script will create the forge user on your server and install all the necessary software and services. Once that is complete, head back to your Forge account and check that Forge can connect to your server.
If you get a green connection, then you're good to go!
If you're having problems connecting to your server, chances are its an AWS firewall issue. You need to ensure that you have whitelisted the Forge IP addresses for SSH access. See the section below on AWS firewall rules for more information.
Don't forget to disable the root account on your instance!
Because I like to automate things as much as possible, I wanted to see if I could use Forge to create the server for me.
In order to get up and running, you first need to create an IAM user in AWS. Sometimes I wonder if IAM should be called IAMC for I Am Confused. Or maybe even IAMFC (I'll leave you to work that one out). However, once you get to grips with it, its actually a pretty cool tool; lets just say its insanely powerful, but very confusing at first (and second and third) glance. Anyway, I wasn't sure what permissions Forge actually needed, and I stumbled on a great post from my friend and colleague Tanner Hearne who had the same question a while back. The article mentions that you need to give AmazonEC2FullAccess and AmazonVPCFullAccess, but in the end I tried with only AmazonEC2FullAccess and everything appears to work fine. As Tanner mentions, you can restrict the EC2 access to specific instance (or instances) if you wish, but I won't cover that part in this article. Go ahead and create the IAM user with Programmatic access, which creates an access key ID and secret access key for the AWS API. Make sure to store the key and secret securely.
The next step is to set up AWS as a Server Provider inside Forge. You'll only need to do this once (unless you want to link more than one AWS account, in which case you'll do it once for each AWS account). Head over to My Account (you get there by clicking your login name at the top right in Forge), and then select Server Providers, and then Amazon. Enter anything relevant for the Profile Name (I called mine forge), and then enter your IAM key and secret.
Click the Add Credentials button, and Forge will check that it has the correct API access.
Once you've done that, navigate to your Forge dashboard and select AWS from the Create Server section. For the credentials, you'll select the Server Provider profile name that you just set up above, and then complete the rest of the details.
Forge will then start creating your server on AWS and a few minutes later your new server should be up and running.
Awesome sauce! But wait...you wanted the server to be inside a specific VPC, and Forge has created the server in its own VPC. Now what?
The short answer is no, you can't use Forge to create server inside a specific VPC. We use VPCs extensively in AWS to segregate separate services and its a pity that Forge doesn't support this. I contacted Taylor, and he suggested that I use the Custom VPS option - i.e. first create your server inside your VPC and then link it to Forge. As we used to say in South Africa: "Ja well no fine" (ref).
I tried a different route. Since I had just created a server via Forge (albeit in the wrong VPC), I headed over to my AWS account and took a snapshot of the server to create a new AMI. Once that had completed, I used the AMI to launch a new instance inside my VPC. After it had finished provisioning, I copied the IP address for the new server, headed over to Forge, selected my server and inside the Meta section, I changed the IP Address from the original server to the new server's IP address.
After that, I went to the Forge dashboard and tested that the connection for the new server and it worked perfectly! Or so I thought.
When I tried to do a Git deployment via
Forge to the new server, it kept failing. I SSH'd into the server and took a look at both the
/home/forge/.ssh/authorized_keys file and
/root/.ssh/authorized_keys file, and noticed that the latter had some extraneous entries in it. It seems like AWS will automatically
append to the
/root/.ssh/authorized_keys file with some extra entries preventing logging in with anything other than the ubuntu user.
Please login as the user "ubuntu" rather than the user "root".
I suspect that AWS did this automatically when it launched the AMI. You can cross reference the Meta page on Forge to make sure that you have the correct SSH keys in those 2 files. Once I removed the extra data and saved the file, everything worked as expected. Nice!
At this point in time, I don't really like either method of provisioning a server inside an AWS VPC. Notwithstanding that there are manual steps involved in either option, I still feel that there are still advantages (with either method) versus doing the whole shebang yourself. I hope that Forge improves this process in the not-too-distant future; it would be super nice if you could optionally select from your existing VPC's on the Forge launch page, or choose to create a new VPC if you want.
One thing that I noticed is that if Forge creates your server, the default AWS security group will allow access to everything (i.e. all ports and IP addresses are wide open). This is not cool. And we want to be cool.
Generally, I prefer to only open HTTP (80) and HTTPS (443) to all IP addresses, and then I limit SSH (22) to a single IP address (our VPN). If you're using Forge or Envoyer, then you'll also want to
allow their IP addresses access to SSH, so make sure to also add
184.108.40.206 (at the time of writing).
I usually create my AWS security groups like this:
Unless you have a good reason, all other ports should not be whitelisted. Of course, if you need to allow other services access to your server, then you can create additional security groups and/or rules.
So there you have it. Hopefully this helps you to launch your AWS instances from Forge. However, if you want to launch a server inside a VPC, you'll need to do a bit of work yourself. It sounds a bit complicated, but should really only take a few minutes.