The Simplest Possible EC2 Web Server Setup Using Terraform (On AWS)
Tags: aws, devops, terraform
Published: 2020-04-27 05:57:19

---
title: The Simplest Possible EC2 Web Server Setup Using Terraform (On AWS)
published: true
date: 2020-04-27 05:53:08 UTC
tags: aws, devops, terraform
canonical_url: https://www.thedevcoach.co.uk/aws-ec2-instance-apache-terraform/
---

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.

![](https://i1.wp.com/www.thedevcoach.co.uk/wp-content/uploads/2020/04/EC2-Simple-Apache-1.png?fit=760%2C463&ssl=1)

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…

<script src="https://gist.github.com/loujaybee/c571ee63b73877b8087b6bec182e8559.js"></script>

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.](https://www.thedevcoach.co.uk/what-is-terraform/)
- [Infrastructure As Code: An Ultimate Guide](https://www.thedevcoach.co.uk/infrastructure-as-code-ultimate-guide/).
- [Your personal AWS setup (and how to not get hacked)](https://www.thedevcoach.co.uk/how-to-setup-an-aws-to-experiment-and-learn/)
- [Should You Commit the Terraform .tfstate File to Git?](https://www.thedevcoach.co.uk/commit-terraform-tfstate-git/)
- [The Ultimate Terraform Workflow: Setup Terraform (And Remote State) With Github Actions](https://www.thedevcoach.co.uk/setup-terraform-aws-github-actions/)

Let’s start with the Terraform configuration of our instance…

### 1.1. The Terraform Instance

<script src="https://gist.github.com/loujaybee/5de7477112bf8e4965223fa942fa1500.js"></script>

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](https://www.terraform.io/docs/providers/aws/index.html) (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](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) (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](https://www.terraform.io/docs/providers/aws/r/ami.html) 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

<script src="https://gist.github.com/loujaybee/79fe045b8b30155ae0509685039911bb.js"></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` and `EOF` characters that were present in the original snippet. These characters simply allow us to put [multiline strings into terraform configurations](https://www.terraform.io/docs/configuration-0-11/syntax.html), 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](https://en.wikipedia.org/wiki/Shebang_(Unix)). This tells our interpreter that we want to execute our script using [bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell)).

Next up we are “elevating our permissions” to the [root user](https://en.wikipedia.org/wiki/Superuser) with `sudo su` (`su` stands for switch user) so we can perform our apache installation. Now, with the right permissions we can install `httpd` (using `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

<script src="https://gist.github.com/loujaybee/1ff0d721fddfcd0d6aff35fc4e45d706.js"></script>

Below our resource configuration we have a [Terraform output](https://www.terraform.io/docs/configuration/outputs.html). 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](https://www.terraform.io/docs/providers/aws/r/instance.html#attributes-reference). 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](https://learn.hashicorp.com/terraform/getting-started/install.html) CLI installed
- The [AWS Provider](https://www.terraform.io/docs/providers/aws/index.html) configured in Terraform
- An [AWS account](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-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 `terraform plan`.

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](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html).

 ![Terraform Plan Instance](https://i1.wp.com/www.thedevcoach.co.uk/wp-content/uploads/2020/04/terraformplaninstance.png?resize=760%2C480&ssl=1)

Terraform Plan Instance

### 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.

 ![Terraform Apply Instance](https://i1.wp.com/www.thedevcoach.co.uk/wp-content/uploads/2020/04/terraformapplyinstance.png?resize=760%2C369&ssl=1)

Terraform Apply Instance

### 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.

 ![Basic Web Server Output](https://i2.wp.com/www.thedevcoach.co.uk/wp-content/uploads/2020/04/basicWebServer.png?resize=760%2C391&ssl=1)

Basic Web Server Output

## 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?_**  

---

The post [The Simplest Possible EC2 Web Server Setup Using Terraform (On AWS)](https://www.thedevcoach.co.uk/aws-ec2-instance-apache-terraform/) appeared first on [The Dev Coach](https://www.thedevcoach.co.uk).

Lou is the editor of [The Cloud Native Software Engineering Newsletter](https://newsletter.thedevcoach.co.uk) a Newsletter dedicated to making Cloud Software Engineering more accessible and easy to understand. Every month you’ll get a digest of the best content for Cloud Native Software Engineers right in your inbox.