10

AWS Cloud Networking

Cloud computing is one of the major trends in computing today and has been for many years. Public cloud providers have transformed the start-up industry and what it means to launch a service from scratch. We no longer need to build our own infrastructure; we can pay public cloud providers to rent a portion of their resources for our infrastructure needs. Nowadays, walking around any technology conferences or meetups, we will be hard-pressed to find a person who has not learned about, used, or built services based in the cloud. Cloud computing is here, and we better get used to working with it.

There are several cloud computing service models, roughly divided into Software-as-a-Service (SaaS)(https://en.wikipedia.org/wiki/Software_as_a_service), Platform-as-a-Service (PaaS) (https://en.wikipedia.org/wiki/Cloud_computing#Platform_as_a_service_(PaaS)), and Infrastructure-as-a-Service (IaaS) (https://en.wikipedia.org/wiki/Infrastructure_as_a_service). Each service model offers a different level of abstraction from the user's perspective. For us, networking is part of the Infrastructure-as-a-Service offering and the focus of this chapter.

Amazon Web Services (AWShttps://aws.amazon.com/) was the first company to offer IaaS public cloud services and was the clear leader in the space by market share in 2019. If we define the term Software-Defined Networking (SDN) as a group of software services working together to create network constructs – IP addresses, access lists, load balancers, Network Address Translation (NAT) – we can make the argument that AWS is the world's largest implementer of SDN. They utilize the massive scale of their global network, data centers, and servers to offer an amazing array of networking services.

If you are interested in learning about Amazon's scale and networking, I would highly recommend taking a look at James Hamilton's AWS re:Invent 2014 talk: https://www.youtube.com/watch?v=JIQETrFC_SQ. It is a rare insider's view of the scale and innovation at AWS.

In this chapter, we will discuss the networking services offered by the AWS cloud services and how we can use Python to work with them:

  • AWS setup and networking overview
  • Virtual private cloud
  • Direct Connect and VPN
  • Networking scaling services
  • Other AWS network services

Let's begin by looking at how to set up AWS.

AWS setup

If you do not already have an AWS account and wish to follow along with these examples, please log on to https://aws.amazon.com/ and sign up. The process is pretty straightforward and simple; you will need a credit card and some way to verify your identity, such as a mobile phone that can accept text messages.

A good thing about AWS when we are just getting started is that they offer a number of services in a free tier (https://aws.amazon.com/free/), where you can use the services for free up to a certain level. For example, we will be using the Elastic Compute Cloud (EC2) service in this chapter; the free tier for EC2 is the first 750 hours per month for its t2.micro instance for the first 12 months.

I recommend always starting with the free tier and gradually increasing your tier when the need arises. Please check the AWS site for the latest offerings:

Figure 1: AWS free tier

Once you have an account, you can sign in via the AWS console (https://console.aws.amazon.com/) and take a look at the different services offered by AWS.

The console is where we can configure all the services and look at our monthly bills:

Figure 2: The AWS console

Now that we have set up our account, let's take a look at using the AWS CLI tool as well as the Python SDK to manage our AWS resources.

The AWS CLI and Python SDK

Besides the console, we can also manage AWS services via the command line interface (CLI) and various SDKs. The AWS CLI is a Python package that can be installed via PIP (https://docs.aws.amazon.com/cli/latest/userguide/installing.html). Let's install it on our Ubuntu host:

(venv) $ pip install awscli
(venv) $ aws --version
aws-cli/1.16.259 Python/3.6.8 Linux/5.0.0-27-generic botocore/1.12.249

Once the AWS CLI is installed, for easier and more secure access, we will create a user and configure the AWS CLI with the user credentials. Let's go back to the AWS console and select Identity and Access Management (IAM) for user and access management:

Figure 3: AWS IAM

We can choose Users on the left panel to create a user:

Figure 4: AWS IAM users

Select Programmatic access and assign the user to the default administrator group:

Figure 5: AWS IAM add user

The last step will show an Access key ID and a Secret access key. Copy them into a text file and keep it in a safe place:

Figure 6: AWS IAM user security credentials

We will complete the AWS CLI authentication credential setup via aws configure in the Terminal. We will go over AWS Regions in the upcoming section. We will use us-east-1 for now since that is the Region with the most services. We can always come back to the settings later to change the Region:

$ aws configure
AWS Access Key ID [None]: <key>
AWS Secret Access Key [None]: <secret> 
Default region name [None]: us-east-1 
Default output format [None]: json

We will also install the AWS Python SDK, Boto3 (https://boto3.readthedocs.io/en/latest/):

(venv) $ pip install boto3
# verification
(venv) $ python
Python 3.6.8 (default, Oct 7 2019, 12:59:55) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import boto3
>>> exit()

We are now ready to move on to the subsequent sections, starting with an introduction to AWS cloud networking services.

AWS network overview

When we discuss AWS services, we need to start at the top, with Regions and Availability Zones (AZs). They have big implications for all of our services. At the time of writing this book, AWS listed 22 geographic regions and 69 AZs around the world. In the words of AWS Global Cloud Infrastructure, (https://aws.amazon.com/about-aws/global-infrastructure/):

"The AWS Cloud infrastructure is built around Regions and Availability Zones (AZs). AWS Regions provide multiple, physically separated and isolated Availability Zones which are connected with low latency, high throughput, and highly redundant networking."

For a nice visualization of AWS Regions that can be filtered by AZ, Region, and so on, please check out: https://www.infrastructure.aws/.

Some of the services AWS offers are global (such as the IAM user we created), but most of the services are Region-based. The Regions are geographic footprints, such as US-East, US-West, EU-London, Asia-Pacific-Tokyo, and so on. What this means for us is that we should build our infrastructure in a region that is closest to our intended users. This will reduce the latency of the service for our customers. If our users are on the East Coast of the United States, we should pick US East (N. Virginia) or US East (Ohio) as our Region if the service is Regional-based:

Figure 7: AWS Regions

Besides user latency, AWS Regions also have both service and cost implications. Users who are new to AWS might find it surprising that not all services are offered in all Regions. The services we will look at in this chapter are offered in most Regions, but some newer services might only be offered in selected Regions.

In the example that follows, we can see that "Alexa for Business" and "Amazon Chime" are only offered in the Northern Virginia Region in the United States:

Figure 8: AWS services per Region

Besides service availability, the cost of an offering might be slightly different between Regions. For example, for the EC2 service we will look at in this chapter, the cost for an a1.medium instance is USD $0.0255 per hour in US East (N. Virginia); the same instance costs 14% more, at USD $0.0291 per hour, in EU (Frankfurt):

Figure 9: AWS EC2 US East price

Figure 10: AWS EC2 EU price

When in doubt, choose US East (N. Virginia); it is the oldest Region and most likely the cheapest, with the most service offerings.

Not all Regions are available to all users. For example, GovCloud and the China Region are not available to users in the United States by default. You can list the Regions available to you via aws ec2 describe-regions:

$ aws ec2 describe-regions
{
    "Regions": [
        {
            "Endpoint": "ec2.eu-north-1.amazonaws.com",
            "RegionName": "eu-north-1",
            "OptInStatus": "opt-in-not-required"
        },
        {
            "Endpoint": "ec2.ap-south-1.amazonaws.com",
            "RegionName": "ap-south-1",
            "OptInStatus": "opt-in-not-required"
        },
<skip>

As stated by Amazon, all Regions are completely independent of one another, therefore most resources are not replicated across Regions. This means if we have multiple Regions offering the same service, say US-East and US-West, and need the services to back up each other, we will need to replicate the necessary resources ourselves.

We can choose our desired Region in the AWS console, in the top-right corner, with the drop-down menu:

Figure 11: AWS Regions

We can only view the services available within the Region on the portal. For example, if we have EC2 instances in the US East Region and we select the US West Region, none of our EC2 instances will show up. I have made this mistake a few times and wondered where all of my instances went!

The number after the Regions in the preceding AWS Regions screenshot represents the number of AZs in each Region. AZs are labeled using a combination of the Region and an alphabetical letter, such as us-east-1a, us-east-1b, and so on. Each Region has multiple AZs – typically three. Each AZ is in its own isolated infrastructure with a redundant power supply, intra-data center networking, and facilities. All AZs in a Region are connected through low-latency fiber routes that are typically within 100 km of each other within the same Region:

Figure 12: AWS Regions and availability zones

Unlike Regions, many of the resources we build in AWS can be copied across AZs automatically. For example, we can configure our managed relational database (Amazon RDS) to be replicated across AZs. The concept of AZs is very important when it comes to service redundancy, and its constraints are important to us for the network services we will build.

AWS independently maps AZs to identifiers for each account. For example, my availability zone, us-east-1a, might not be the same as us-east-1a for another account, even though they are both labeled as us-east-1a.

We can check the AZs in a Region in the AWS CLI:

$ aws ec2 describe-availability-zones --region us-east-1
{
    "AvailabilityZones": [
        {
            "State": "available",
            "Messages": [],
            "RegionName": "us-east-1",
            "ZoneName": "us-east-1a",
            "ZoneId": "use1-az2"
        },
        {
            "State": "available",
            "Messages": [],
            "RegionName": "us-east-1",
            "ZoneName": "us-east-1b",
            "ZoneId": "use1-az4"
        },
<skip>

Why do we care about Regions and AZs so much? As we will see in the coming few sections, AWS networking services are usually bound by the Region and AZ. A Virtual private cloud (VPC), for example, needs to reside entirely in one Region, and each subnet needs to reside entirely in one AZ. On the other hand, NAT gateways are AZ-bound, so we will need to create one per AZ if we need redundancy.

We will go over both services in more detail, but their use cases are offered here as examples of how Regions and AZs are the basis of the AWS network services offering:

Figure 13: VPCs and AZs per Region

AWS edge locations are part of the AWS CloudFront content delivery network in 73 cities across 33 countries as of October 2019. These edge locations are used to distribute content with low latency to customers. The edge nodes have a smaller footprint than the full data center Amazon builds for the Region and AZs. Sometimes, people mistake the edge locations' point-of-presence for full AWS Regions. If the footprint is listed as an edge location only, AWS services such as EC2 or S3 will not be offered. We will revisit edge locations in the AWS CloudFront CDN services section.

AWS transit centers are one of the least documented aspects of AWS networks. They were mentioned in James Hamilton's 2014 AWS re:Invent keynote (www.youtube.com/watch?v=JIQETrFC_SQ) as the aggregation points for different AZs in the Region. To be fair, we do not know if the transit center still exists and functions the same way after all these years. However, it is fair to make an educated guess about the placement of the transit center and its correlation with the AWS Direct Connect service that we will look at later in this chapter.

James Hamilton, a VP and distinguished engineer from AWS, is one of the most influential technologists at AWS. If there is anybody who I would consider authoritative when it comes to AWS networking, it would be him. You can read more about his ideas on his blog, Perspectives, at: https://perspectives.mvdirona.com/.

It is impossible to cover all of the services related to AWS in one chapter. There are some relevant services not directly related to networking that we do not have the space to cover, but we should be familiar with:

  • The IAM ervice, https://aws.amazon.com/iam/, is the service that enables us to manage access to AWS services and resources securely.
  • Amazon Resource Names (ARNs), https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html, uniquely identify AWS resources across all of AWS. These resource names are important when we need to identify a service, such as DynamoDB and API Gateway, that needs access to our VPC resources.
  • Amazon Elastic Compute Clod (EC2), https://aws.amazon.com/ec2/, is the service that enables us to obtain and provision compute capacities, such as Linux and Windows instances, via AWS interfaces. We will use EC2 instances throughout this chapter in our examples.

For the sake of learning, we will exclude the AWS GovCloud (US) and China Regions, neither of which uses the AWS global infrastructure, and each has its own unique features and limitations.

This was a relatively long introduction to AWS network services, but an important one. These concepts and terms will be referred to in the rest of the chapters. In the upcoming section, we will take a look at the most import concept (in my opinion) in AWS networking: VPC.

Virtual private cloud

Amazon VPC enables customers to launch AWS resources in a virtual network dedicated to the customer's account. It is truly a customizable network that allows you to define your own IP address range, add and delete subnets, create routes, add VPN gateways, associate security policies, connect EC2 instances to your own data center, and much more.

In the early days when VPC was not available, all EC2 instances in an AZ were on a single, flat network that was shared among all customers. How comfortable would the customer be with putting their information in the cloud? Not very, I'd imagine. Between the launch of EC2 in 2007 and the launch of VPC in 2009, VPC functions were some of the most requested features of AWS.

The packets leaving your EC2 host in a VPC are intercepted by the Hypervisor. The Hypervisor will check the packets against a mapping service that understands your VPC construct. Then, the packets are encapsulated with the real AWS servers' source and destination addresses. The encapsulation and mapping service enables the flexibility of VPC, but also some of the limitations (multicast, sniffing) of VPC. This is, after all, a virtual network.

Since December 2013, all EC2 instances are VPC-only; you can no longer create an EC2 instance that is non-VPC (EC2-Classic), nor would you want to. If we use a launch wizard to create our EC2 instance, it will automatically be put into a default VPC with a virtual internet gateway for public access. In my opinion, only the most basic use cases should use the default VPC. In most cases, we should define our own non-default, customized VPC.

Let's create the following VPC using the AWS console in us-east-1:

Figure 14: Our first VPC in US-East-1

If you recall, VPC is AWS Region-bound, and the subnets are AZ-based. Our first VPC will be based in us-east-1; the three subnets will be allocated to two different AZs in us-east-1a and us-east-1b.

Using the AWS console to create the VPC and subnets is pretty straightforward, and AWS provides a number of good tutorials online. I have listed the steps with the associated locations of each on the VPC dashboard:

Figure 15: Steps for creating the VPC, subnet, and other features

The first two steps are point-and-click processes that most network engineers can work through, even without prior experience. By default, the VPC only contains the local route, 10.0.0.0/16. Now, we will create an internet gateway and associate it with the VPC:

Figure 16: AWS internet gateway-to-VPC assignment

We can then create a custom route table with a default route pointing to the internet gateway, which will allow for internet access. We will associate this route table with our subnet in us-east-1a, 10.0.0.0/24, thus allowing the VPC to have internet access:

Figure 17: Route table

Let's use the Boto3 Python SDK to see what we have created; I used the tag mastering_python_networking_demo as the tag for the VPC, which we can use as the filter:

#!/usr/bin/env python3

import json, boto3

region = 'us-east-1'
vpc_name = 'mastering_python_networking_demo'

ec2 = boto3.resource('ec2', region_name=region)
client = boto3.client('ec2')

filters = [{'Name':'tag:Name', 'Values':[vpc_name]}]

vpcs = list(ec2.vpcs.filter(Filters=filters))
for vpc in vpcs:
    response = client.describe_vpcs(
                 VpcIds=[vpc.id,]
                )
    print(json.dumps(response, sort_keys=True, indent=4))

This script will allow us to programmatically query the Region for the VPC we created:

(venv) $ python Chapter10_1_query_vpc.py
{
    "ResponseMetadata": {
        <skip>
        "HTTPStatusCode": 200,
        "RequestId": "9416b03f-<skip> ",
        "RetryAttempts": 0
    },
    "Vpcs": [
        {
            "CidrBlock": "10.0.0.0/16",
            "CidrBlockAssociationSet": [
                {
                    "AssociationId": "vpc-cidr-assoc-<skip>",
                    "CidrBlock": "10.0.0.0/16",
                    "CidrBlockState": {
                        "State": "associated"
                    }
                }
            ],
            "DhcpOptionsId": "dopt-<skip>",
            "InstanceTenancy": "default",
            "IsDefault": false,
            "OwnerId": "<skip>",
            "State": "available",
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "mastering_python_networking_demo"
                }
            ],
            "VpcId": "vpc-<skip>"
        }
    ]
}

The Boto3 VPC API documentation can be found at: https://boto3.readthedocs.io/en/latest/reference/services/ec2.html#vpc.

If we created EC2 instances and put them in different subnets as-is, the hosts would be able to reach each other across subnets. You may be wondering how the subnets can reach one another within the VPC since we only created an internet gateway in subnet 1a. In a physical network, the network needs to connect to a router to reach beyond its own local network.

It is not so different in VPC, except it is an implicit router with a default routing table of the local network, which in our example is 10.0.0.0/16. This implicit router was created when we created our VPC. Any subnet that is not associated with a custom routing table is associated with the main table.

Route tables and route targets

Routing is one of the most important topics in network engineering. It is worth looking at how it is done in AWS VPC more closely. We've already seen that we had an implicit router and a main routing table when we created the VPC. In the last example, we created an internet gateway, a custom routing table with a default route pointing to the internet gateway using the route target, and we associated the custom routing table with a subnet.

So far, only the concept of the route target is where VPC is a bit different than traditional networking. We can roughly equate the route target with next hop in traditional routing.

In summary:

  • Each VPC has an implicit router
  • Each VPC has the main routing table with the local route populated
  • You can create custom-routing tables
  • Each subnet can follow a custom-routing table or the default main routing table
  • The route table route target can be an internet gateway, NAT gateway, VPC peers, and so on

We can use Boto3 to look at the custom route tables and associations with the subnets:

#!/usr/bin/env python3

import json, boto3

region = 'us-east-1'
vpc_name = 'mastering_python_networking_demo'

ec2 = boto3.resource('ec2', region_name=region)
client = boto3.client('ec2')

response = client.describe_route_tables()
print(json.dumps(response['RouteTables'][0], sort_keys=True, indent=4))

The main routing table is implicit and not returned by the API. Since we only have one custom route table, this is what we will see:

(venv) $ python Chapter10_2_query_route_tables.py
{
    "Associations": [
        <skip>
    ],
    "OwnerId": "<skip>",
    "PropagatingVgws": [],
    "RouteTableId": "rtb-<skip>",
    "Routes": [
        {
            "DestinationCidrBlock": "10.0.0.0/16",
            "GatewayId": "local",
            "Origin": "CreateRouteTable",
            "State": "active"
        },
        {
            "DestinationCidrBlock": "0.0.0.0/0",
            "GatewayId": "igw-041f287c",
            "Origin": "CreateRoute",
            "State": "active"
        }
    ],
    "Tags": [
        {
            "Key": "Name",
            "Value": "public_internet_gateway"
        }
    ],
    "VpcId": "vpc-<skip>"
}

We already created the first public subnet. We will create two more subnets that are private, us-east-1b and us-east-1c, following the same steps. The end result will be three subnets: a 10.0.0.0/24 public subnet in us-east-1a, and 10.0.1.0/24 and 10.0.2.0/24 private subnets in us-east-1b and us-east-1c, respectively.

We now have a working VPC with three subnets: one public and two private. So far, we have used the AWS CLI and the Boto3 library to interact with AWS VPC. Let's take a look at another automation tool from AWS, CloudFormation.

Automation with CloudFormation

AWS CloudFormation(https://aws.amazon.com/cloudformation/) is one way in which we can use a text file to describe and launch the resource that we need. We can use CloudFormation to provision another VPC in the us-west-1 Region:

Figure 18: VPC for us-west-1

The CloudFormation template can be in YAML or JSON; we will use YAML for our first template for provisioning, Chapter10_3_cloud_formation.yml:

AWSTemplateFormatVersion: '2010-09-09'
Description: Create VPC in us-west-1
Resources:
  myVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: '10.1.0.0/16'
      EnableDnsSupport: 'false'
      EnableDnsHostnames: 'false'
      Tags:
        - Key: Name
        - Value: 'mastering_python_networking_demo_2'

We can execute the template via the AWS CLI. Notice that we specify the us-west-1 region in our execution:

(venv) $ aws --region us-west-1 cloudformation create-stack --stack-name 'mpn- ch10-demo' --template-body file://Chapter10_3_cloud_formation.yml
{
"StackId": "arn:aws:cloudformation:us-west-1:<skip>:stack/mpn-ch10- demo/<skip>"
}

We can verify the status via the AWS CLI:

(venv) $ aws --region us-west-1 cloudformation describe-stacks --stack-name mpn-ch10-demo
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:us-west-1:<skip>:stack/mpn-ch10-demo/bbf5abf0-8aba-11e8-911f-500cadc9fefe",
            "StackName": "mpn-ch10-demo",
            "Description": "Create VPC in us-west-1",
            "CreationTime": "2018-07-18T18:45:25.690Z",
            "LastUpdatedTime": "2018-07-18T19:09:59.779Z",
            "RollbackConfiguration": {},
            "StackStatus": "UPDATE_ROLLBACK_COMPLETE",
            "DisableRollback": false,
            "NotificationARNs": [],
            "Tags": [],
            "EnableTerminationProtection": false,
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

The last CloudFormation template created a VPC without any subnet. Let's delete that VPC and use the following template, Chapter10_4_cloud_formation_full.yml, to create both the VPC as well as the subnet. Notice that we will not have the VPC-ID before VPC creation, so we will use a special variable to reference the VPC-ID in the subnet creation. This same technique can be used for other resources, such as the routing table and internet gateway:

AWSTemplateFormatVersion: '2010-09-09'
Description: Create subnet in us-west-1
Resources:
  myVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: '10.1.0.0/16'
      EnableDnsSupport: 'false'
      EnableDnsHostnames: 'false'
      Tags:
        - Key: Name
          Value: 'mastering_python_networking_demo_2'

  mySubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref myVPC
      CidrBlock: '10.1.0.0/24'
      AvailabilityZone: 'us-west-1a'
      Tags:
        - Key: Name
          Value: 'mpn_demo_subnet_1'

We can execute and verify the creation of the resources as follows:

(venv) $ aws --region us-west-1 cloudformation create-stack --stack-name mpn-ch10-demo-2 --template-body file://Chapter10_4_cloud_formation_full.yml
{
"StackId": "arn:aws:cloudformation:us-west-1:<skip>:stack/mpn-ch10- demo-2/<skip>"
}
$ aws --region us-west-1 cloudformation describe-stacks --stack-name mpn- ch10-demo-2
{
"Stacks": [
{
"StackStatus": "CREATE_COMPLETE",
...
"StackName": "mpn-ch10-demo-2", "DisableRollback": false
}
]
}

We can verify the VPC and subnet information from the AWS console. Remember to pick the right Region from the drop-down menu in the top right-hand corner:

Figure 19: VPC in us-west-1

We can also take a look at the subnet:

Figure 20: Subnet in us-west-1

We now have two VPCs on the two coasts of the United States. They are currently behaving like two islands, each by themselves. This may or may not be your desired state of operation. If you would like the two VPCs to be connected, you can use VPC peering (https://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide/vpc-peering-basics.html) to allow direct communication.

There are a few VPC peering limitations, such as no overlapping IPv4 or IPv6 CIDR blocks being allowed. There are also additional limitations for inter-region VPC peering. Make sure you look over the documentation.

VPC peering is not limited to the same account. You can connect VPCs across different accounts, as long as the request was accepted and the other aspects (security, routing, DNS name) are taken care of.

In the coming section, we will take a look at VPC security groups and network access control lists.

Security groups and network ACLs

AWS Security Groups and Network ACLs can be found under the Security section of your VPC:

Figure 21: VPC security

A security group is a stateful virtual firewall that controls inbound and outbound access to resources. Most of the time, we use a security group as a way to limit public access to our EC2 instance. The current limitation is 500 security groups in each VPC. Each security group can contain up to 50 inbound and 50 outbound rules.

You can use the following sample script, Chapter10_5_security_group.py, to create a security group and two simple ingress rules:

#!/usr/bin/env python3

import boto3

ec2 = boto3.client('ec2')

response = ec2.describe_vpcs()
vpc_id = response.get('Vpcs', [{}])[0].get('VpcId', '')

# Query for security group id
response = ec2.create_security_group(GroupName='mpn_security_group',
                                     Description='mpn_demo_sg',
                                     VpcId=vpc_id)
security_group_id = response['GroupId']
data = ec2.authorize_security_group_ingress(
    GroupId=security_group_id,
    IpPermissions=[
        {'IpProtocol': 'tcp',
         'FromPort': 80,
         'ToPort': 80,
         'IpRanges': [{'CidrIp': '0.0.0.0/0'}]},
        {'IpProtocol': 'tcp',
         'FromPort': 22,
         'ToPort': 22,
         'IpRanges': [{'CidrIp': '0.0.0.0/0'}]}
    ])
print('Ingress Successfully Set %s' % data)

# Describe security group
#response = ec2.describe_security_groups(GroupIds=[security_group_id])
print(security_group_id)

We can execute the script and receive confirmation of the creation of the security group, which can be associated with other AWS resources:

(venv) $ python Chapter10_5_security_group.py
Ingress Successfully Set {'ResponseMetadata': {'RequestId': '<skip>', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'AmazonEC2', 'content- type': 'text/xml;charset=UTF-8', 'date': 'Wed, 18 Jul 2018 20:51:55 GMT',
'content-length': '259'}, 'RetryAttempts': 0}} sg-<skip>

Network access control lists (ACLs) are an additional layer of security that is stateless. Each subnet in the VPC is associated with a network ACL. Since an ACL is stateless, you will need to specify both inbound and outbound rules.

The important differences between security groups and ACLs are as follows:

  • Security groups operate at the network interface level, whereas ACLs operate at the subnet level.
  • For a security group, we can only specify allow rules and not deny rules, whereas ACLs support both allow and deny rules.
  • A security group is stateful so return traffic is automatically allowed; return traffic in ACLs needs to be specifically allowed.

Let's take a look at one of the coolest features of AWS networking: Elastic IP. When I initially learned about Elastic IPs, I was blown away by their ability to assign and reassign IP addresses dynamically.

Elastic IP

An Elastic IP (EIP) is a way to use a public IPv4 address that's reachable from the internet.

IPv6 is not currently supported in EIP as of late 2019.

An EIP can be dynamically assigned to an EC2 instance, network interface, or other resources. A few characteristics of an EIP are as follows:

  • An EIP is associated with the account and is region-specific. For example, an EIP in us-east-1 can only be associated with resources in us-east-1.
  • You can disassociate an EIP from a resource, and re-associate it with a different resource. This flexibility can sometimes be used to ensure high availability. For example, you can migrate from a smaller EC2 instance to a larger EC2 instance by reassigning the same IP address from the small EC2 instance to the larger one.
  • There is a small hourly charge associated with EIPs.

You can request an EIP from the portal. After assignment, you can associate it with the desired resources:

Figure 22: Elastic IP

Unfortunately, EIPs are limited by default to five per Region to discourage waste (https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html). However, this number can be increased via a ticket to AWS Support if needed.

In the coming section, we will look at how we can use NAT gateways to allow communication for private subnets with the internet.

NAT gateways

To allow the hosts in our EC2 public subnet to be accessed from the internet, we can allocate an EIP and associate it with the network interface of the EC2 host. However, at the time of writing this book, there is a limit of five Elastic IPs per EC2-VPC (https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Appendix_Limits.html#vpc-limits-eips). Sometimes, it would be nice to allow the host in a private subnet outbound access when needed, without creating a permanent one-to-one mapping between the EIP and the EC2 host.

This is where a NAT gateway can help, by allowing the hosts in the private subnet temporary outbound access by performing NAT. This operation is similar to port address translation (PAT), which we normally perform on the corporate firewall. To use an NAT gateway, we can perform the following steps:

  1. Create an NAT gateway in a subnet with access to the internet gateway via the AWS CLI, Boto3 library, or AWS console. The NAT gateway will need to be assigned an EIP.
  2. Point the default route in the private subnet to the NAT gateway.
  3. The NAT gateway will follow the default route to the internet gateway for external access.

This operation can be illustrated in the following diagram:

Figure 23: NAT gateway operations

One of the most common questions about NAT gateways typically involves which subnet the NAT gateway should reside in. The rule of thumb is to remember that the NAT gateway needs public access. Therefore, it should be created in the subnet with public internet access with an available EIP assigned to it:

Figure 24: NAT gateway creation

In the coming section, we will take a look at how to connect our shiny virtual network in AWS to our physical network.

Direct Connect and VPN

Up to this point, our VPC has been a self-contained network that resides in the AWS network. It is flexible and functional, but to access the resources inside of the VPC, we will need to access them with their internet-facing services such as SSH and HTTPS.

In this section, we will look at the two ways in which AWS allows us to connect to the VPC from our private network: an IPSec VPN gateway and Direct Connect.

VPN gateways

The first way to connect our on-premise network to VPC is with traditional IPSec VPN connections. We will need a publicly accessible device that can establish VPN connections to AWS's VPN devices.

The customer gateway needs to support route-based IPSec VPNs where the VPN connection is treated as a connection that a routing protocol and normal user traffic can traverse over. Currently, AWS recommends using BGP to exchange routes.

On the VPC side, we can follow a similar routing table where we can route a particular subnet toward the virtual private gateway (VPG) target:

Figure 25: VPC VPN connection (source: https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_VPN.html)

Besides an IPSec VPN, we can also use a dedicated circuit to connect, which is termed Direct Connect.

Direct Connect

The IPSec VPN connection we looked at is an easy way to provide connectivity for on-premise equipment to AWS cloud resources. However, it suffers the same faults that IPSec over the internet always does: it is unreliable, and we have very little control over the reliability of it. There is very little performance monitoring and no service-level agreement (SLA) until the connection reaches a part of the internet that we can control.

For all of these reasons, any production-level, mission-critical traffic is more likely to traverse through the second option Amazon provides, that is, AWS Direct Connect. AWS Direct Connect allows customers to connect their data center and colocation to their AWS VPC with a dedicated virtual circuit.

The somewhat difficult part of this operation is usually bringing our network to where we can connect with AWS physically, typically in a carrier hotel.

You can find a list of the AWS Direct Connect locations here: https://aws.amazon.com/directconnect/details/. The Direct Connect link is just a fiber patch connection that you can order from the particular carrier hotel to patch the network to a network port and configure the dot1q trunk's connectivity.

There are also increasingly more connectivity options for Direct Connect via a third-party carrier with MPLS circuits and aggregated links. One of the most affordable options that I found and use is Equinix Cloud Exchange Fabric (https://www.equinix.com/services/interconnection-connectivity/cloud-exchange/). By using Equinix Cloud Exchange Fabric, we can leverage the same circuit and connect to different cloud providers at a fraction of the cost of dedicated circuits:

Figure 26: Equinix Cloud Exchange (source: https://www.equinix.com/services/interconnection-connectivity/cloud-exchange/)

In the upcoming section, we will take a look at some of the network scaling services AWS offers.

Network scaling services

In this section, we will take a look at some of the network services AWS offers. Many of these services do not have direct network implications, such as DNS and content distribution networks. They are relevant in our discussion due to their close relationship with the network and application's performance.

Elastic Load Balancing

Elastic Load Balancing (ELB) allows incoming traffic from the internet to be automatically distributed across multiple EC2 instances. Just like load balancers in the physical world, this allows us to have better redundancy and fault tolerance while reducing the per-server load. ELB comes in two flavors: application and network Load Balancing.

The Application Load Balancer handles web traffic via HTTP and HTTPS; the Network Load Balancer operates on a TCP level. If your application runs on HTTP or HTTPS, it is generally a good idea to go with the application load balancer. Otherwise, using the network load balancer is a good bet.

A detailed comparison of the application and network load balancer can be found at: https://aws.amazon.com/elasticloadbalancing/details/:

Figure 27: ELB comparison (source: https://aws.amazon.com/elasticloadbalancing/details/)

ELB offers a way to load balance traffic once it enters the resource in our Region. The AWS Route 53 DNS service allows geographic Load Balancing between Regions, sometimes referred to as Global Server Load Balancing.

Route 53 DNS service

We all know what domain name services are – Route 53 is AWS's DNS service. Route 53 is a full-service domain registrar where you can purchase and manage domains directly from AWS. Regarding network services, DNS allows a way to load balance between geographic regions using service domain names in a round-robin fashion between Regions.

We need the following items before we can use DNS for Load Balancing:

  • A load balancer in each of the intended load balance Regions
  • A registered domain name. We do not need Route 53 to be the domain registrar
  • Route 53 is the DNS service for the domain

We can then use the Route 53 latency-based routing policy with a health-check in an active-active environment between the two Elastic Load Balancers. In the next section, we will turn our attention to the content delivery network built by AWS, called CloudFront.

CloudFront CDN services

CloudFront is Amazon's content delivery network (CDN), which reduces the latency of content delivery by physically serving the content closer to the customer. The content can be static web page content, videos, applications, APIs, or most recently, Lambda functions. CloudFront edge locations include the existing AWS Regions but are also in many other locations around the globe. The high-level operation of CloudFront is as follows:

  • Users access your website for one or more objects
  • DNS routes the request to the Amazon CloudFront edge location closest to the user's request
  • The CloudFront edge location will either service the content via the cache or request the object from the origin

AWS CloudFront and CDN services, in general, are typically handled by application developers or DevOps engineers. However, it is always good to be aware of their operations.

Other AWS network services

There are lots of other AWS network services that we do not have the space to cover here. Some of the more ones are listed in this section:

  • AWS Transit VPC (https://aws.amazon.com/blogs/aws/aws-solution-transit-vpc/): This is a way to connect multiple VPCs to a common VPC that serves as a transit center. This is a relatively new service, but it can minimize the number of connections that you need to set up and manage. This can also serve as a tool when you need to share resources between separate AWS accounts.
  • Amazon GuardDuty (https://aws.amazon.com/guardduty/): This is a managed threat detection service that continuously monitors for malicious or unauthorized behavior to help protect our AWS workloads. It monitors API calls or potentially unauthorized deployments.
  • AWS WAF (https://aws.amazon.com/waf/): This is a web application firewall that helps protect web applications from common exploits. We can define customized web security rules to allow or block web traffic.
  • AWS Shield (https://aws.amazon.com/shield/): This is a managed Distributed Denial of Service (DDoS) protection service that safeguards applications running on AWS. The protection service is free for all customers at the basic level; the advanced version of AWS Shield is a fee-based service.

There are lots of new and exciting AWS networking services constantly being announced, such as the ones we have looked at in this section. Not all of them are foundational services such as VPC or NAT gateways; however, they all serve useful purposes in their respective fields.

Summary

In this chapter, we looked at AWS cloud networking services. We went over the AWS network definitions of Region, Availability Zone, edge locations, and Transit Center. By understanding the overall AWS network, this gives us a good idea of some of the limitations and constraints of the other AWS network services. Throughout this chapter, we used the AWS CLI, the Python Boto3 library, as well as CloudFormation to automate some of the tasks.

We covered AWS Virtual Private Cloud in depth, with the configuration of the route table and route targets. The example on security groups and network ACLs took care of the security for our VPC. We also looked at EIPs and NAT gateways in relation to allowing external access.

There are two ways to connect AWS VPC to on-premise networks: Direct Connect and IPSec VPN. We briefly looked at each and the advantages of using them. Toward the end of this chapter, we looked at network scaling services offered by AWS, including Elastic Load Balancing, Route 53 DNS, and CloudFront.

In the next chapter, we will take a look at the networking services offered by another public cloud provider, Microsoft Azure.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset