Introduction
This blog talks about the mythical beast called AWS Security groups and how to implement them using terraform. By the end of this blog, you would be able to do describe security groups, how you can implement them using AWS console, and also via terraform. Once you understand what security groups are, implementing them using AWS console or Terraform is a fairly simple exercise.
If you are new to terraform please have a look at the Terraform – getting started blog entry first.
This blog entry is divided into the following sections
What are AWS Security Groups
AWS Security Group as the name alludes has to do with security. It is a virtual firewall for your AWS service and controls inbound and outbound traffic. Security groups are based on simple rules. These rules defined based on three things
- Protocol
- Port
- IP address range
Security groups are like a ring around your AWS EC2 service. As soon as you change the security group the inbound and outbound traffic is impacted. For example, look at the two requirements below
- Allow SSH access via port 21 enabled on an EC2 instance but not enable HTTP access.
- Allow certain EC2 instances which are in another security group to access your EC2 instances in a security group.
The beauty of security groups is that they filter the traffic before it hits your services and hence are non-intrusive. It also means AWS takes care of shielding your services so they are not impacted(Of course you need to set it up in the first place!)
Provisioning Security Groups using AWS Console
In this section, we will do the following.
- Configure the default security group.
- Create a new security group.
Configure the default security group
By default, there is always one security group available for you and that is called as default. As an example, we only want http on port 80 traffic being allowed inside the security group. Do that follow the steps below
Step 1 – Login to your aws account.
Step 2 – Navigate to Services->EC2

Step 3 – Click on Security Groups

Step 4 – Click on default security group

Your security group id may be different.
Step 5 – Click on Edit Inbound Rules

Step 6 – Click on Add Rule – Allow HTTP traffic
The problem statement in the real world will be something like this “Only HTTP traffic from all IP addresses allowed”
Element Name | Value | What does it achieve? |
---|---|---|
Type | HTTP | Sets the Protocol. It means we only want HTTP traffic inside our security group |
Port | 80 | Port is automatically set for HTTP traffic |
Source | Anywhere | We want traffic to be allowed from all possible IP addresses. |

Step 7 – Add another rule – Allow SSH traffic
The problem statement in the real world would be something like this “Only HTTP traffic from all IP addresses allowed and allow SSH traffic from certain IP address or addresses”
Add the following rule as well.
Element Name | Value | What does it achieve? |
---|---|---|
Type | SSH | Sets the Protocol. It means we only want SSH traffic inside our security group |
Port | 22 | Port is automatically set for SSH traffic. |
Source | My IP Address | We want traffic to be allowed from only My IP addresses. |

Now you have configured your default security group which
- Allows HTTP traffic from all IP addresses
- Allows SSH traffic from one specific IP address
Now let’s create a new Security group.
Create a new security group
Step 1 – Navigate to security groups as mentioned above
Step 2 – Click on “Create security group”

Step 3 – Add the Basic details

Step 4 – Add the rules

The created group should look like this

Phew that was such a long number of steps. Now let’s see how terraform does it. BTW – We are not doing this always. 🙂
Provisioning AWS Security Groups using Terraform
Now that you have seen how it is done in a console. In terraform it takes a few lines to add a security group. Create a file – let’s call it security_groups.tf (You can call it anything). See code below
region = "eu-west-2"
}
resource "aws_security_group" "cw_sg_ssh" {
name = "cw-blog-2-sg-using-terraform"
#Incoming traffic
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["11.xx.xx.xx/32"]
}
#Outgoing traffic
egress {
from_port = 0
protocol = "-1"
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}
Open a terminal session and navigate to the directory which has your terraform code and execute the following command. Enter yes when prompted!
Once the apply is completed. Open your aws console and navigate to security groups you should see the freshly minted security group.

Code Analysis
- Line 1 – Defines who is going to provide you with infrastructure APIs which terraform is going to use. So in our case, it is aws. There is a list of providers available on this link.
- Line 2 – Defines in which region of the provider you want terraform to provision the infrastructure. In our case, we chose EU/London which is identified by the code eu-west-2. The list of regions for AWS is available on this link.
- Line 5 – Defines the resource we want to create. In this case, we want to create a resource of type aws_security_group.
- resource – Tells terraform that we want to provision an AWS resource.
- resource_type – Tells terraform that what type of resource we want to provision. In this case, it is aws_security_group
- name – Gives a name to the resource. In our case it is cw_sg_ssh. This is how we will search for this resource in our terraform scripts.
- This is a recurring pattern of <resosurce> <resource type><name>
- Line 6 – Gives the security group a name. Which is seen in the AWS console.
- Line 9-13 – Defines Incoming traffic rule for HTTP
- Line 10 – Defines port on which traffic is received. In this case port 80.
- Line 11 – Defines port on which traffic is directed inside the security group. In this case port 80.
- Line 12 – Defines the protocol. In this case TCP
- Line 13 – Defines the IP address range for HTTP traffic. This case all IP addresses.
- Line 16-20 – Defines Incoming traffic rule for SSH
- Line 10 – Defines port on which traffic is received. In this case port 22.
- Line 11 – Defines port on which traffic is directed inside the security group. In this case port 22.
- Line 12 – Defines the protocol. In this case TCP
- Line 13 – Defines the IP address range for SSH traffic. This case only from one specific IP address.
In case you are struggling to understand how CIDR blocks work. They are an easy concept to grasp. Head over to this link to get a quick understanding. They help you define IP address ranges without too much fuss. If still don’t get it – wait for a post in the Terraform blog series. It is on its way!
If you now add an EC2 instance to your security group it will allow HTTP traffic from all IP addresses and will allow SSH traffic from only your IP address. We will see how they both work together in the next blog entry. So stay tuned!
This brings us to the end of this long post. Hope you find it useful. If you like it please do share it and spread the knowledge around.
1 thought on “Terraform – AWS Security Groups”