Security Group

Deploying Infrastructure in Terraform



Infrastructure management has changed a lot over the years. Historically, your traditional systems administrator would manage a rack full of servers. In a lot of cases, the initial setup would require manual intervention at the console.

That has changed. Using tools like Terraform, you can now provision infrastructure automatically (some might say automagically) with the click of a button or by running a script.

In this article, I’ll demonstrate how to use Terraform to provision infrastructure on AWS.

Our objectives

  1. Create a ‘tf’ file which will hold all of our relevant configuration information
  2. Define which provider we will be using in the Terraform config.
  3. Define security group rules and names.
  4. Define the EC2 instances we want to create.
  5. Run Terraform to plan and apply our configuration.

Create ‘tf’ file

Now, you’ll have to create a ‘tf’ file which will hold all relevant Terraform config. You could split this out into multiple files but to keep things simple we’ll be working within the confines of one file at this point. In my local working copy, I’ve chosen to create a directory under the Terraform directory structure with the name ‘test’ and gone on to create a ‘’ file which we can use going forward.

Define provider within config

Terraform has a number of ‘providers’ it will work with (see resources section at the end for a link to this). We will be using the AWS provider in this example. Depending on which provider you choose to use, the basic concepts are the same, but you may find that some naming conventions for certain features are slightly different. The documentation on Terraform’s site covers this in quite a lot of detail, so you shouldn’t have any issues.

To define the provider within your ‘’ file, simply add the following:

provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region = "eu-west-1"

You’ll note in the above block that for ‘access_key’ and ‘secret_key’ we are referring to two preset variables. These can be set within another file, or you can have Terraform prompt you for them when it runs. We’re choosing to do the latter for security purposes. You’ll need to create a ‘’ file so Terraform understands what to do when these variables are referenced. Simply populate it with the following:

variable "access_key" {}
variable "secret_key" {}
variable "region" {
	default = "eu-west-1"

Make sure this file is saved in the same directory as your ‘’ file.

Define Security Group rules

Next, we want to tell Terraform to create a Security Group within AWS EC2, and populate it with rules to allow traffic on specific ports. For the purposes of this article, we’ll use the scenario of one web server listening on TCP ports 80 (HTTP), and 22 (SSH). We also want to make sure the instance can connect outbound on any port, so we’re including an egress section below as well.

resource "aws_security_group" "web-node" {
	name = "web-node"
	description = "Web Security Group"

	ingress {
		from_port = 80
		to_port = 80
		protocol = "tcp"
		cidr_blocks = [""]

	ingress {
		from_port = 22
		to_port = 22
		protocol = "tcp"
		cidr_blocks = [""]

	egress {
		from_port = 0
		to_port = 0
		protocol = "-1"
		cidr_blocks = [""]

If you’re in any doubt, simply add the above section underneath the provider config we added earlier to ‘’.

Define our instances

Now, we want to create a section to define the instances we wish to create within EC2. Again, all you’ll need to do is add this section below the previous security group configuration you made in ‘’.

resource "aws_instance" "web-node" {
	ami = "ami-b8134dcb"
	instance_type = "t2.micro"
	key_name = "terraform-test"
	security_groups = ["${}"]

In the above stanza, you’ll want to define the AMI you wish to spawn your instance from. I’ve chosen to ‘subscribe’ to the Debian 8 AMI mentioned above in the EU-Ireland region. However, this same AMI will have a different ID for you if you’re in a different region, and you’ll have to subscribe to it first before utilising it. So please bear this in mind. I’ve also told the resource which SSH key to use (which you’re able to create within your AWS EC2 console). The security group ID is automatically calculated by utilising a variable which will be set during the creation process. Terraform is clever like that! 😉

Run Terraform!

Finally, we’re ready to run Terraform, but I’d always suggest first running a ‘terraform plan’ which allows you to see the changes Terraform plans to make. It’s important you choose to run this first, as it means you can prevent it from doing any damage to existing infrastructure!

So, without further ado, let’s run Terraform and see what we get back…
# ./terraform plan

The output is rather extensive, so I won’t include it here, but you should see a lot of planned actions with something similar to the following output at the end:

If this is the case, then let’s proceed to apply our configuration!

# ./terraform apply

Again, the output is extensive so I won’t include it here, but if everything has gone to plan, you should see the following:

And there you have it. You’ll note that there is now a security group in AWS EC2 with the name you specified within your Terraform config, along with the rules you specified. Also, you’ll see the new EC2 instance that has been created.


We have only scratched the surface of what is possible with Terraform, but I feel a simple introduction is the best! In other configurations, I have previously used Terraform to automatically create DNS records in Route 53 for newly created resources, and have also used it to create multiple instances at a time. A demonstration of this can be found at GitHub (see Resources section).


  1. The Terraform provider list can be found here:
  2. Terraform AWS provider documentation can be found here:
  3. Terraform has extensive documentation available here:
  4. Use this link to search for and ‘subscribe’ to AMIs:
  5. A more complicated demonstration of Terraform can be found here:

Keith Rogers is an IT professional with over 10 years’ experience in modern development practices. Currently he works for a broadcasting organization in the DevOps space with a focus on automation. Keith is a regular contributor at Fixate IO.


Click on a tab to select how you'd like to leave your comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Skip to toolbar