Are you looking to create a basic AWS instance web server? Maybe you’re learning AWS, trying to get an understanding on Terraform or actually trying to get a pieceof your infrastructure setup. Whatever your reason for needing a simple AWS web server setup, that’s what we’ll be covering today.
Today we’ll walk through (in detail) how to create the simplest possible EC2 web server on AWS using Terraform. We’ll cover all of the fiddly AWS details like AMI’s and user data scripts.
By the end of this article you’ll know how to create a simple Apache based web server on AWS EC2 written in Terraform.
Right, let’s get straight into it!
If you’re in a rush and you’re just looking for a snippet to copy, here it is…
But if you’re not in such a rush, and you actually want to understand the code that you’re copy/pasting then read on.
In part one, we’ll go through our configuration, and what we’ve written and why — there’s a surprising amount going on when you dig into it.
In part two, we’ll go through how to execute the snippet and what you should see in AWS when it executes.
Sound good? Let’s get to it…
Part 1: The Terraform Configuration
Before we start flying through the article—depending on what you know already—reading one (or all) of the following articles might help.
- What is Terraform? A Simple Definition.
- Infrastructure As Code: An Ultimate Guide.
- Your personal AWS setup (and how to not get hacked)
- Should You Commit the Terraform .tfstate File to Git?
- The Ultimate Terraform Workflow: Setup Terraform (And Remote State) With Github Actions
Let’s start with the Terraform configuration of our instance…
1.1. The Terraform Instance
Okay so the first thing we’ll look at is the Terraform’ed instance resource. You’ll notice in the above example I’ve removed a lot of code (which mainly was the
user_data property). We’ll cover what the
user_data property does soon, but for now let’s focus on the EC2 instance block.
What we’ve created here is an
aws_instance resource block. This resource block is specific to AWS. You can only execute this resource when you’ve installed the AWS provider (so make sure you have that setup first).
You’ll also see that we’re passing
ami-06ce3edf0cff21f07 as the
ami property. The AMI property stands for Amazon Machine Image (AMI), which is the underlying base machine that our EC2 is created upon.
For our example I hardcoded the latest AMI, which is fine if you running the example as an experiment. But, hardcoding AMI’s is to be avoided if you want to eventually run this configuration in production. Instead you’ll want to dynamically grab your AMI using the
aws_ami resource block.
Ans last up in our configuration is the
instance_type, which is set to the cheapest instance that is available on AWS, the
t2.micro. Feel free to change the instance size if you want or need greater performance.
That should hopefully cover enough to get you going with the AWS instance resource configuration block, let’s move onto the
user_data script that we mentioned earlier…
1.2. The EC2 “User Data” Script
The “user data” script. What is this cryptic looking thing? Let’s take a look…
Firstly, our underlying EC2 image itself doesn’t have apache (our web server of choice) installed on it. So we’ll need to add that ourselves. But rather than do it manually, we want our instance to automatically start itself once it’s deployed, and that’s done by usage of the “user data” script. In our script we install Apache, create a basic web page and then start apache.
The sharp-eyed amongst you will have noticed we removed the
EOF characters that were present in the original snippet. These characters simply allow us to put multiline strings into terraform configurations, in our case, that’s our putting our bash script into user data.
Let’s start dissecting our script, starting from the top. At the top of our script is the line
#!/bin/bash. This odd looking character collection is a shebang. This tells our interpreter that we want to execute our script using bash.
Next up we are “elevating our permissions” to the root user with
sudo su (
su stands for switch user) so we can perform our apache installation. Now, with the right permissions we can install
yum, the package manager which is installed on the AWS AMI).
Now we have apache installed, but no website files to serve, so let’s fix that. We create our website as a small HTML string, and outputting it to the
/var/www directory—which is the default location for files on an apache web server.
Now we’ve got everything setup, the last thing we’ll need to do is start our web server. We start our server using the global binary
systemctl which we installed with
yum in the last step.
1.3. The Terraform Output Block
Below our resource configuration we have a Terraform output. Outputs are easy ways to expose values that can be consumed in other configurations, or in our case just make an easy way to see a simple output when we run our
terraform apply command.
In the output block we are giving a name to our output (like you would name a variable). In our case our name is
DNS and we’re pointing our variable to a returned values of our instance, in our case the public DNS entry.
Every resource in Terraform documents the values that they “output”—here’s the output values of an EC2 instance in Terraform. But in our case the output block is optional, so feel free to omit it if you don’t feel you need it.
Part 2: Creating Your Instance
Okay hopefully by now you should have a good handle on the what and why of our setup. Now let’s move onto the practicalities of executing it, and what you should see in AWS when you’ve executed your configuration.
Before we do jump into the details of the setup there are few things you’ll need to have installed and setup.
- The Terraform CLI installed
- The AWS Provider configured in Terraform
- An AWS account (with credentials)
Once you’ve got those setup, you’ll be good to go.
2.1 Plan Terraform
Plan your terraform configuration by copying in the EC2 resource from above, and execute a
You might notice that Terraform creates a lot of values here that we explicitly define. That’s because the instance resource also creates a lot of other resources implicitly. Because we didn’t define things like subnets, security groups and mounted volumes AWS takes a best guess at what we want to set these values to, using things like default resources.
2.2 Apply Terraform
When you’ve checked that your
terraform plan didn’t output anything unexpected, go ahead and execute a
terraform apply to launch your instance. Note the URL at the bottom, which is thanks to our output block.
2.3 View Your Website!
Lastly, you can just grab that outputted URL and go to your browser to see if it has worked as expected. And there you have it, a super simple web server, launched on EC2 in AWS with Apache.
Destroy What You Made (Optional)
Before you go, I should also remind you that if you don’t want an unexpected AWS bill, you should also destroy your infrastructure. The small instances cost about $10 dollars per month, but that’s money you can put elsewhere!
To destroy your instance you can execute
terraform destroy, which will tear down the stack you just created.
Your Simple EC2 Instance!
And that concludes our walk through of how to create a super simple EC2 instance on AWS with Apache. This setup can be used to create a basic website, or in my case you can use it for experimenting with different AWS features, such as exploring how load balancing works, or DNS failover.
I hope this article helped point you in the right direction with the different nuances of the setup, sometimes it can be quite overwhelming with the amount of prior knowledge that you need to do something as simple as launching an EC2. Stick with your learning though, it does eventually get clearer the more you experiment.
Speak soon Cloud Native friends!
What are you intending to build on your EC2?