AWS Networking for Developers
This post is co-authored with Mark Stephens, Partner Solutions Architect, AWS
If you’re a developer and are new to AWS, there is a good chance you have not had the need to set up or configure many networks. As a developer that has a need to work with infrastructure, you might end up running into some concepts that you aren’t familiar with and can take some time to understand. Within the AWS console we give you full control to set up your environment securely, which means understanding some key concepts will be important to setup that infrastructure in the best way possible for your use case. We’ll introduce you to key network infrastructure concepts in this post to help get you started down the right path.
The following diagram illustrates the AWS networking concepts we’ll discuss in this blog post:
AWS networking concepts
The first AWS networking concept you should be familiar with is Amazon Virtual Private Cloud (Amazon VPC). Amazon VPC allows you to provision logically isolated sections of the AWS Cloud where you can launch AWS resources in a virtual network that you define. You can think of a VPC as the high-level container for your infrastructure.
Subnets and routing
Within a VPC, there is another construct called a subnet, or a logical grouping of IP addresses that are a subsection of a larger network. You can create private and public subnets. The only difference between the two is that a private subnet does not have an Internet gateway. For example, you do not want someone to gain access to your database server, so you’d put that in a private subnet. Your Web server does need Internet connectivity, so you’d place it in a public subnet. Subnets live in an Availability Zone. If you want your infrastructure to be highly available, you will want to have subnets in multiple Availability Zones. The subnet size determines how many hosts can live in that subnet.
Routes and route tables decide which subnets and applications can reach the Internet or can connect back to your on-premises systems. We recommend that you layer your architecture and isolate your database tier in a private subnet. You can use subnets and network address translation (NAT) instances to ensure they have Internet access but are not vulnerable to outside attacks. This is similar to what network teams do on premises with demilitarized zones (DMZs) and firewalls. Using different route tables to create private and public subnets helps ensure that our API hosts communicate with our database but not with any bad actors.
Each subnet is assigned a route table which defines whether or not that subnet can reach things like VPNs or the internet. The route table has a list of IP destinations that specify where the traffic should go. You specify the IP destinations by using classless inter-domain routing (CIDR) notation; for example, 0.0.0.0/0 means all traffic goes to that IP address range, often to an Internet gateway. We’ll discuss CIDR ranges in more detail later in this post. Let’s say you want to create a VPN connection and send traffic back to your on-premises data center. You would create a virtual private gateway and attach it to your VPC. You would then create a VPN connection and a customer gateway. After you download the configuration for your customer gateway from the list of common options and apply it to your device, you would have a connection to AWS. The next step would be to choose which subnets should be allowed to use that VPN connection. In the route table for these subnets, you would create a route for your on-premises IP range (for example, 10.0.0.0/8). What’s important is that you can create different levels of access based on subnets. Individual subnets can have Internet access only, access to the Internet and VPN, or even access to other network resources like VPC peering or Amazon S3 endpoints.
Subnets are important because they define what type of network access an instance has and which Availability Zone the instances live in. Network access control lists (ACLs) are another concept specific to a subnet. Network ACLs are a broad-stroke security feature that you can use in addition to security groups (virtual firewalls that control traffic) to define which IP addresses and ports are allowed in and out of a subnet. Many customers put instances with the same security requirements and level of trust in the same subnet, since it’s easier to segment applications in different subnets.
If you want to segment your development, staging and production environments you can use subnets or VPCs to segment them. VPCs have a higher level of segmentation, but you may have to recreate infrastructure like bastion hosts, security groups and VPNs. Subnets offer segmentation as long as security groups are properly managed.
Often, choosing subnet sizes and VPC sizes can be a challenge for developers who aren’t used to working with IP addresses and subnets. Choosing CIDR ranges and subnet sizes is an arcane but necessary art. Let’s start with a few basics.
IP addressing 101
A CIDR range is a way of notating which IP address space is being used. An IP address is 32 bits long, split into four 8-bit octets like x.x.x.x. Subnets differentiate between the network part of the address and the host part of the address. Devices that route packets in the network are only aware of where sets of addresses (the network) are. In subnet notation, we use a 1 to define network and a 0 to define host. A common subnet is a /24, which means that the network will keep track of the first 24 bits (or 3 octets). This can also be notated as 255.255.255.0, or you can think of it as network.network.network.host. For example, 10.1.2.3/24 means 10.1.2 is the network, and the host was assigned the .3 address. Since 2 to the 8th power is 256, there are 256 addresses for the hosts. The network uses a few addresses—on premises, it’s typically 2 (first and last), and on AWS it’s 5 (first 4, last). Subnet calculators are really useful if doing lots of binary math isn’t your thing, or until you get the hang of it.
There are also public and private addresses. An Internet standard (RFC 1918) defined three private IP address ranges that would never be used on the Internet and are reserved for private use: 10.0.0.0/8, 192.168.0.0/16, and 172.16.0.0/12. Many organizations choose to use the 10.0.0.0/8 space since it’s the largest (it starts with a 10). Since we’ll need to divide the 10.x.x.x space up further we’ll need to split it into subnetworks. This is where we need to think strategically. We have to figure out how many different networks we’ll need, and how many hosts are in each network.
Designing subnet space
The first goal of IP addressing is to prevent any overlapping address space. If every new VPC uses the same 172.16.0.0/16 or 10.0.0.0/16 space, life becomes very difficult when those resources need to talk to one another, share any resources, or connect to a shared service. The second goal is to not run out of addresses for any given application in a subnet. You will want to use RFC 1918 space (10.x.x.x, 192.168.x.x, 172.16.x.x/12) in your VPC. As well, you don’t want to overlap with your on-premises networks.
If you have lots of unused address space, the primary goal of not overlapping address ranges will be simple to achieve. Otherwise, the art is finding a balance between subnet and network sizes so applications don’t run out of IP address space, and the organization doesn’t run out of network address space to use. If you’ve either been allocated a small address space or know that address space is limited, you’ll need to do some binary math, which we’ll illustrate here.
Securing your instances
Security groups are virtual firewalls at the instance level. You can use security groups to set rules on inbound and outbound connections. Security groups track the state of connections, and remember where a connection came from. For example, if we allow all outbound traffic but deny inbound traffic, the only packets allowed into your instance are inbound replies from the outbound connections. An example security group for Secure Shell (SSH) might allow TCP port 22 and a source IP of 188.8.131.52/24. Security group changes happen immediately. By default, security groups allow all outbound traffic and deny inbound traffic.
You can use network ACLs in addition to security groups. Network ACLs allow you to define a security policy for an entire subnet. Network ACLs use an ordered list of IP address and protocol information such as TCP or UDP port numbers to allow or deny traffic. Network ACLs are stateless, which means they don’t remember what traffic has come in or gone out. Each network ACL has rules for inbound and outbound traffic. By default, network ACLs allow all traffic. For example, if you wanted to block all traffic to or from 192.168.1.0/24 you would put a DENY statement higher in the list than the ALLOW traffic statement in both the inbound and outbound directions.
CIDR ranges are something you also use with security groups and network ACLs. For example, on a security group, you can limit the range of IPs that can access an Amazon EC2 host. A CIDR range of 192.168.70.0/24 will allow or deny IPs in the range 192.168.70.0 – 192.168.70.255. CIDR ranges are a powerful way to control access to your company’s public IP range.
Let’s talk about private subnets. An instance in a private subnet can generally reach the Internet but the Internet can’t directly reach the instance. When you have a host in a private subnet and you want access to the Internet, you use something called a NAT gateway. Since the private subnet does not have an Internet gateway associated with that subnet, you need a way to get out. The sole responsibility of the NAT gateway is to translate packets from a private subnet into public traffic and then back again to that private address. It’s best practice to put instances like databases that only connect to other internal instances in a private subnet for security.
What’s great is that we can automate what we’ve discussed in this blog post, because AWS builds automation into its services. Many people call this “infrastructure as code.” By using AWS services such as AWS CloudFormation and AWS OpsWorks, or solutions like Chef or Puppet, you can fully automate the build of your stack and infrastructure. This includes your VPC, subnets, security groups, Amazon EC2 servers, and databases. Using automation to deploy infrastructure reduces error, saves time, and makes it easier to track changes like code commits. How many times have you set up your server only to forget how you set up that tedious bit months later? With automation, you have code that describes your setup.
Since your setup is now code, you can version your CloudFormation, Chef, or Puppet scripts just like your code. Want to test out a new setup? Just modify your infrastructure scripts and spin up a new version of your infrastructure. Something in the new setup not working right? Just revert back to the previous version. It’s all in version control alongside your application code.
You can also use your code control system to keep track of who made changes and why. Curious why that security group rule was added? Now you can check the commit history and comments for that change. AWS also offers the AWS CloudTrail service for monitoring your deployments, and the AWS API call history produced by CloudTrail enables security analysis, resource change tracking, and compliance auditing.
The AWS Quick Start team recently published an AWS CloudFormation template that automates building a VPC infrastructure, based on some of the concepts we discussed in this blog post. This configurable infrastructure includes multiple Availability Zones, public and private subnets, and managed NAT gateways (or NAT instances, when the deployment region doesn’t support NAT gateways). You can use the Quick Start as a baseline for your own AWS environment, scale it up or down by adding or removing subnets and Availability Zones, and create additional private subnets with network ACLs. For more information, see Building a Modular and Scalable Virtual Network Architecture with Amazon VPC.
Automation and the larger philosophy behind it is called DevOps, and you can read more about it on our DevOps page.
Now that you have set up your infrastructure, you’ll want to monitor performance and security measures such as vulnerabilities or weaknesses. There are many AWS partners that can help with these challenges. For example, Alert Logic, an AWS Security Competency Partner, has a product called Cloud Insight that will monitor your infrastructure and deliver continuous vulnerability and configuration management insight. Cloud Insight is available in AWS Marketplace. Dome9 is another APN Partner and AWS Security Competency Partner that will monitor and manage your security groups, and their products are also available in AWS Marketplace.
These products can help you shift from being reactive to proactive about the security and operation of your infrastructure.
We hope that this blog post provided some insights into the network that sits below your applications. If you have any questions or would like to see additional topics or details on networking in the cloud, we’d like to hear from you.