Czego się dowiesz
W tym artykule stworzę topologię sieci, która odwzorowuje tą dostarczaną domyślnie przez AWS dla każdego nowego konta (Default VPC). Podczas tworzenia opiszę działanie poszczególnych elementów i funkcjonalność, którą dostarczają.
Całość opiszę za pomocą CloudFormation by usprawnić wdrożenie i późniejsze utrzymanie. Opis szablonu podzielę na sekcje, które opiszę, tak by łatwo dowiedzieć się co w nich zadeklarowałem.
Na samym końcu pochylę się nad tematem kosztu wykonanej przeze mnie sieci.
Po co mi to wszystko?
Virtual Private Cloud czyli VPC, to wirtualne sieci. Używając ich zyskuję pełną kontrolę nad ruchem sieciowym. Dzięki temu jestem w stanie ukryć moje wrażliwe zasoby(np. baza danych, maszyna wirtualna, etc.) w prywatnych subnetach, z którymi nie ma połączenia z internetem. Z kolei w przypadku w którym moi klienci komunikują się ze mną poprzez publiczny internet zasoby które muszę im udostępnić, ulokuję w publicznych subnetach. Jeżeli natomiast komunikacja z klientem odbywa się za pomocą np. VPN’a (może jest to system on-prem) to ruch mogę przekierować do konkretnego subnetu!
Jak widzisz opcji na wykorzystanie VPC i jego składników jest bardzo, bardzo dużo.
VPC – wymagania
Zacznę od ogólnego opisu funkcjonalnego. W mojej sieci chcę:
- korzystać z usług o wysokiej dostępności, w tym celu stworzę subnety w różnych strefach dostępności,
- by we wszystkich subnetach mojego VPC był dostęp do Internetu oraz by zasoby w nich umieszczone mogły być z niego dostępne. W skrócie, by wszystkie subnety były publiczne.
Końcowa topologia mojej sieci jest widoczna na diagramie poniżej. Widać na nim trzy subnety, które mają możliwość komunikowania się z Internetem, ich tablicę routingu oraz NACL – namiastkę sieciowego firewalla.

Anatomia sieci w AWS
VPC
VPC jest fundamentem na którym opiera się cała infrastruktura sieciowa którą tworzy się w AWS. Jako wirtualna sieć pozwala na lokowanie zasobów w dowolnej availability zone, jeśli tylko utworzymy w niej subnet. To z kolei pozwala na tworzenie rozwiązań które maja wysoką dostępność(High Availability).
Podczas tworzenia VPC określa się blok CIDR, w którym będą znajdować się wszystkie zasoby przypisane do naszej sieci.
Subnet
Określa logiczny podział sieci. Adresy dostępne wewnątrz subnetu określa się za pomocą bloku CIDR. Określa on również rozmiar naszej przestrzeni adresowej, czyli to jak wiele zasobów może znaleźć się w opisywanym subnecie.
Na poziomie subnetu określa się tablice routingu(route table) oraz listy kontroli dostępu (NACL).
Route table
Tablica trasowania – jest to mapa mówiąca o tym gdzie każdy z pakietów wychodzących z naszego subnetu powinien zostać przekierowany.
Adres docelowy | Kolejny cel |
---|---|
10.4.0.0/16 | local |
192.168.0.0/16 | virtual-private-gateway |
0.0.0.0/0 | internet-gateway |
Załóżmy, że do naszego subnetu przypinamy powyższą tablicę routingu. W takim przypadku kolejny cel pakietu wychodzącego określamy patrząc na adres docelowy. Jeżeli znajduje się wewnątrz bloku:
- 10.4.0.0/16 to przekieruj pakiet wewnątrz VPC
- 192.168.0.0/16 to jest to pakiet przeznaczony do sieci naszego klienta i przekieruj go do połączenia VPN
- Adres nie pasuje do żadnej poprzedniej reguły przekieruj do internet gateway’a
Podczas routingu przeglądana jest cała tablica, z której jest wybierany najlepiej dopasowany wpis, na podstawie docelowego adresu. Najlepiej dopasowaną będzie reguła dla konkretnego adresu (maska /32).
Internet gateway
Jest to komponent który pozwala na komunikację między zasobami w VPC a Internetem. Komunikacja jest możliwa tylko jeśli zasób posiada publiczny adres IP.
Internet Gateway jest skalowalny i ma wysoką dostępność. Dzięki temu nie muszę martwić się czy da radę obsłużyć ruch między moją siecią a Internetem. Jeżeli subnet ma trasę prowadzącą bezpośrednio do Internet Gateway’a nazywa się go subnetem publicznym.
W sytuacji w której zasoby nie mogą mieć lub zwyczajnie nie chcę przypisać im publicznych adresów IP muszę wykorzystać NAT Gateway. Subnet, który nie ma trasy do Internet Gateway’a nazywa się subnetem prywatnym.
NAT Gateway
Podobnie jak Internet Gateway pozwala na komunikację między zasobami wewnątrz subnetu a Internetem. Zasadniczą różnicą jest to, że dokonuje translacji adresów przez co nie wymaga aby zasoby, które z niego korzystają miały przypisany publiczny adres IP. Brak tego wymogu oznacza również, że zasoby które korzystają z NAT Gateway jako bramy na świat nie są osiągalne z publicznego Internetu.
Network ACL
To nic innego jak listy dostępu do subneta – firewall. W domyślnej konfiguracji przepuszcza cały ruch wejściowy i wyjściowy.
NACL działa na podstawie zdefiniowanych reguł. Wpisy rozpatrywane są w odpowiedniej kolejności – od najniższej do najwyższej.
Jako decydująca brana jest pierwsza z reguł która pasuje do rozpatrywanego adresu IP.
Każdy NACL posiada regułę, oznaczoną za pomocą znaku *
. Reguła ta rozpatrywana jest jako ostatnia i odrzuca ruch, który nie został dopasowany do poprzednich.
Wykonanie
W celu ułatwienia wielokrotnego tworzenia naszego VPC zostanie opisane za pomocą CloudFormation. Całość podzielę na cztery kroki.
VPC
AWSTemplateFormatVersion: "2010-09-09"
Description: Basic Network Structure
Resources:
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: '10.0.0.0/16'
EnableDnsHostnames: true
Dodaję tutaj jedynie VPC. Ustalam blok adresów na 10.0.0.0-10.0.255.255. Moim celem jest odwzorowanie domyślnie tworzonego VPC więc ustawiam EnableDnsHostnames
na true
by każdemu zasobowi z publicznym adresem IP przydzielać jednocześnie publicznie rozwiązywalny adres w DNS. Dla przykładu jeśli nasza EC2 dostanie adres 176.34.138.87
to równocześnie zostanie jej przydzielona domena ec2-176-34-138-87.eu-west-1.compute.amazonaws.com
Internet Gateway
AWSTemplateFormatVersion: "2010-09-09"
Description: Basic Network Structure
Resources:
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: '10.0.0.0/16'
EnableDnsHostnames: true
InternetGateway:
Type: AWS::EC2::InternetGateway
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref Vpc
Następnie w liniach 9-10 tworzę Internet Gateway a później(11-15) przypisuję do wcześniej utworzonego VPC.
Tablica routingu
AWSTemplateFormatVersion: "2010-09-09"
Description: Basic Network Structure
Resources:
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: '10.0.0.0/16'
EnableDnsHostnames: true
InternetGateway:
Type: AWS::EC2::InternetGateway
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref Vpc
RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref Vpc
InternetRoute:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
RouteTableId: !Ref RouteTable
GatewayId: !Ref InternetGateway
Kolejnym krokiem jest stworzenie RouteTable(17-20) oraz jednej trasy dla każdego pakietu(0.0.0.0/0) wskazującej na wcześniej utworzony Internet Gateway.
Każda tablica routingu ma domyślny wpis dla ruchu lokalnego. W tym przypadku jest to 10.0.0.0/16.
Stworzona tablica w rezultacie wygląda w ten sposób:

Subnety
Teraz pozostaje mi dodać ostatnie brakujące części sieci, subnety. Każdy z nich będzie wyglądał podobnie, tak jak na poniższym listingu.
SubnetA:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: '10.0.1.0/24'
VpcId: !Ref Vpc
AvailabilityZone: eu-west-1a
MapPublicIpOnLaunch: true
Dla każdego z subnetów muszę podać blok CIDR oraz VPC w którym ma się znaleźć.
W moim przypadku chcę lokować subnet w konkretnym availability zone by łatwo je nazywać(SubnetA). Kolejną rzeczą którą muszę zrobić to przypisywać publiczne IP tworzonym zasobom by mogły one korzystać z dostępu do internetu przez Interet Gatway.
Dla każdego subnetu muszę też wskazać z której tablicy routingu korzysta – stworzyć asocjację. Listing poniżej pokazuje jak to zrobić:
SubnetATableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref SubnetA
Finalny CloudFormation ze wszystkimi elementami:
AWSTemplateFormatVersion: "2010-09-09"
Description: Basic Network Structure
Resources:
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: '10.0.0.0/16'
EnableDnsHostnames: true
InternetGateway:
Type: AWS::EC2::InternetGateway
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref Vpc
RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref Vpc
InternetRoute:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
RouteTableId: !Ref RouteTable
GatewayId: !Ref InternetGateway
SubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: eu-west-1a
CidrBlock: '10.0.1.0/24'
MapPublicIpOnLaunch: true
VpcId: !Ref Vpc
SubnetATableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref SubnetA
SubnetB:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: eu-west-1b
CidrBlock: '10.0.2.0/24'
MapPublicIpOnLaunch: true
VpcId: !Ref Vpc
SubnetBTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref SubnetB
SubnetC:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: eu-west-1c
CidrBlock: '10.0.3.0/24'
MapPublicIpOnLaunch: true
VpcId: !Ref Vpc
SubnetCTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref SubnetC
Deploy mojego rozwiązania mogę wykonać na dwa podstawowe sposoby albo za pomocą konsoli webowej albo z użyciem linii poleceń i programu aws cloudformation deploy
.
Ale czegoś tu brakuje?
Jeśli dobrze się przyjrzysz brakuje tutaj jednej z opisanych wcześniej rzeczy – NACL. Jest tak ponieważ jest ona tworzona automatycznie, razem z tworzeniem VPC i domyślnie przypisywana do każdego subnetu. Możesz ją zmienić jawnie tworząc listę a później wiążąc ją z konkretnymi subnetami. W dokładnie taki sam sposób jak przy tworzeniu tablic routingu.
Tak się jednak składa, że domyślne NACL jest takie dokładnie takie jakie mam w założeniu, czyli zezwala na cały ruch do i z sieci.
Koszt
Dobra wiadomość jest taka, że stworzenie powyższego VPC i jego komponentów nie jest obarczone żadnymi dodatkowymi opłatami! Trzeba natomiast uważać na koszta dodatkowego monitorowania, użycia innych elementów, jak NAT Gateway czy połączenia VPN.
Z opisanych przeze mnie zasobów jedynie wykorzystanie NAT Gateway’a wprowadza dodatkowy koszt. W przypadku rejonu eu-west-1( Irlandia) jest to $0.048 za każdą godzinę działania oraz $0.048 za każdy przetworzony GB . Więcej szczegółów na temat dodatkowych kosztów związanych z VPC znajduje się tutaj.