Instructions on how to set up infrastructure behind a secure virtual private cloud on Amazon web services.
- Protects all of your infrastructure behind a secure network, so it's an added layer of security.
- Forces all access to your instances to go through a limited number of manageable points.
- Allows you to interact quickly and more freely on a private network while staying secure.
SPECIAL NOTE: There are a couple of notes in this document were I'm unclear on how it actually came together. Please read over the notes first to make sure you know what you're geting yourself into. Maybe You can help me clear these parts up.
I'm going to start with an outline based on my most recent notes. Once I've documented the overall process, I'll take some time and go back and flesh it out with more detail. A lot of this comes directly from the AWS docs.
So, one thing to keep in mind here is there are countless ways to set these things up. This may not be the perfect way for every system, but it's a solid config that I use a lot. I'm documenting it because it works for me in most cases and the AWS docs take so long to study and analyze. I just wanted a quick way to share this process and get feedback from the community.
Service | Usage |
---|---|
Virtual Private Cloud | Secures all of the system's infrastructure. |
Security Group | Controls access to all the instances on the vpc. |
Network ACL (Access Control List) | |
Private Subnets | Allows the instances to communicate behind the vpc. |
Public Subnets | Opens up access for your NAT Gateway and your IGW |
Route Tables | To manage your subnets and gateways. |
Elastic IP | A Static IP to point your DNS records at while you swap your instances in and out. |
NAT (Network Access Translation) Gateway | So that your |
IGW (Internet Gateway) | |
Elastic Network Interfaces (ENI) |
This will set up everything we need to secure application instances behind a VPC with a single bastion instance that is publicly accessible for outside access.
A VPC is an isolated portion of the AWS cloud populated by AWS objects, such as Amazon EC2 instances. You must specify an IPv4 address range for your VPC. Specify the IPv4 address range as a Classless Inter-Domain Routing (CIDR) block; for example, 10.0.0.0/16. You cannot specify an IPv4 CIDR block larger than /16. You can optionally associate an Amazon-provided IPv6 CIDR block with the VPC.
- Go to the VPC console and select "Your VPCs".
- Click the "Create VPC" button.
- Use a /16 subnet.
- Select default tenancy.
A Network ACL is an optional layer of security that acts as a firewall for controlling traffic in and out of a subnet.
- From the VPC console, select "Network ACLs"
- Click the "Create network ACL" button.
- Name it.
- Add it to the new VPC.
- Once it's created, go back and add rules to allow inbound and outbound traffic
Specify your subnet's IP address block in CIDR format; for example, 10.0.0.0/24. IPv4 block sizes must be between a /16 netmask and /28 netmask, and can be the same size as your VPC. An IPv6 CIDR block must be a /64 CIDR block. You're going to need at least four subnets to make this work. Two public and two private. They are all going to be
- Make each name tag descriptive, so they will be easy to work with later. For example,
public_1
andpublic_2
. Thenprivate_1
andprivate_2
. - Select the new VPC.
- Alternate the availability zones so that both public subnets are not in the same zone and both of the private ones are in different zones as well. I like to use
us-east-1
. Just use whatever makes sense for your system, - Set the IPv4 CIDR block to
10.0.x.0/24
- Click create. You'll have to do all this for each one until you have created all four.
Now that you have all the subnets you need, you can associate them with the ACL you created.
- From the VPC console, select Network ACLs.
- Click on your new ACL to highlight it.
- In the "Actions" dropdown, select "Edit subnet associations".
- Add all four subnets and save it.
A Route Table specifies how packets are forwarded between the subnets within your VPC, the internet, and your VPN connection.
- Go to the "Route Tables" tab. You should already have a route table for the VPC. Name this something descriptive that follows the same convention as the rest of the infrastructure so you know what goes with what if you or the client builds more systems on this AWS account.
- Create a new route table. Click the "Create route table" button. Name it for the private subnet, so you can easily select it when working with private subnets.
- Select the VPC from the dropdown.
- Click "Create".
- Now repeat the 2 and 3 for the public route table, naming it for the public subnet so you can tell them apart easily.
- Click on the public route table to select it.
- In the "Actions" dropdown, click "Edit subnet associations".
- Click on the two public subnets to associate them. They should be easy to spot if you named them descriptively.
- Save your associations.
- Repeat 1--4 for your private route table.
- Set the private route table as the main route table. Click it to highlight it. In the "Actions" dropdown, click "Set Main Route Table".
An Elastic IP address is a static IPv4 address designed for dynamic cloud computing. An Elastic IP address is associated with your AWS account. With an Elastic IP address, you can mask the failure of an instance or software by rapidly remapping the address to another instance in your account.
- From the Elastic IPs tab, click "Allocate new address".
- Just let Amazon pull one from their pool, unless you have one you insist on using.
- Click "Allocate".
You can use a network address translation (NAT) gateway to enable instances in a private subnet to connect to the internet or other AWS services, but prevent the internet from initiating a connection with those instances.
- From the NAT Gateway tab, click "Create NAT Gateway".
- Select one of your new public subnets.
- Select your new elastic ip.
- Click "Create a NAT Gateway"
- From the "Route Tables" tab, click on the private subnet to highlight it. (Do you see now why we named them descriptively).
- Click the "Routes" tab below.
- Click "Edit Routes".
- Click "Add route".
- Set the Destination to
0.0.0.0/0
- Set the Target to the new NAT Gateway.
- Save it.
NOTE: For some reason that last step failed the first time I tried it. I'll update this the next time I follow this process. I'm not sure what fixed it.
An internet gateway is a virtual router that connects a VPC to the internet. To create a new internet gateway specify the name for the gateway below.
- From the Internet Gateways tab, click "Create Internet Gateway"
- Give it a name. Remember, name everything descriptively with a unique convention.
- Save it.
- Attach it to the VPC. Click on the new IGW to highlight it in the list.
- In the actions droplist, click "Attach to VPC".
- Select your new VPC.
- Give it a route in the public route table the same way you added the NAT Gateway to the private route table.
- Finally, you're going to bounce over to the EC2 Console and create a security group if you haven't already.
- From the "Security Groups" tab, click "Create Security Group".
- Name it. (I'm going to go ahead and keep repeating this. Be descriptive. You're not a robot yet.)
- Add a description while you're at it.
- Select the new VPC.
- You can open up all traffic in the rules for now, but make sure you come back and adjust it to only allow the ports you are using and the ips of the people that will be working on it. For example, you'll want to add ports 80 and 443 for HTTP and HTTPS. You'll also want 22 for SSH and 3306 for database. There could be more for other services you might use and these could be different depending on how you set up your particular system. The point is, only allow what you need an only while you need it.
An Elastic Network Interface (ENI) (referred to as a network interface in this documentation) is a logical networking component in a VPC that represents a virtual network card.
- Also from the EC2 Console
- From the "Network Interfaces" tab, click "Create Network Interface"
- Add a description.
- Add one of your public subnets.
- Select your new security group from the list.
- Click "Create".
- Click on your new ENI in the list to highlight it.
- From the "Actions" dropdown, click associate address.
NOTE: That last step is documented as failing. Looking back, it appears that this step may be automated. It looks like AWS generated on for me that ended up being attached to the elastic IP for me. Again, I'll watch more closely next time I follow these docs so I can improve this part.
You now have a secure VPC with all of the infrastructure you need to make your instances public on the web, while also protecting them from access but allowing your team to tunnel into any of them through a single bastion.
Next, I'll be adding a docs about Load Balancing, AutoScaling and CodeDeploy with BitBucket Pipelines.