AWS CloudFormation Hands-on 03: Khởi tạo Virtual Private Cloud
Overview
Trong phần này, mình sẽ chia sẻ các bước để tạo AWS Virtual Private Cloud với CloudFormation Template file.
Trước đó, hãy làm rõ một số khái niệm trước:
- Virtual Private Cloud: một network ảo riêng biệt cho phép bạn dễ dàng khởi tạo và quản trị tài nguyên AWS trên đó. Mỗi VPC sẽ có tập IP address riêng.
- Subnet: là một tập IP adresss con của VPC. Subnet có hai loại: private subnet và public subnet
- Internet Gateway: cổng kết nối public subnet với Internet
- NAT Gateway: cổng kết nối private subnet với Internet, thường được đặt ở public subnet
- Route table: bảng gồm các bản ghi dạng
<destination> <target>
quy định cách thức điều hướng các request trong hệ thống. Ví dụ bản ghi10.169.0.0/8 igw-id
sẽ điều hướng tất cả các request có đích là IP thuộc tập 10.169.0.0/8 tới Internet Gateway có id igw-id. - Router: thành phần trực tiếp thực hiện việc điều hướng request, dựa vào route table.
Chúng ta sẽ khởi tạo VPC với thiết kế gồm các thành phần như sau:
Cụ thể, VPC sẽ gồm:
- 4 subnet: 2 subnet (1 private, 1 public) tại Available Zone A, 2 subnet (1 private, 1 public) tại Available Zone B
- 1 InternetGateway
- 2 NAT Gateway
- 3 Route table: 1 public route table và 2 private route table
Hands-on
Bước 1: Khởi tạo template file
Khởi tạo file template.yml với bản mô tả đơn giản
## =================== DESCRIPTION =================== #
Description: >-
AWS CloudFormation sample template.
Create a custom VPC with a pair of public and private subnets spread across two AZs
Bổ sung các tham số
## =================== PARAMETERS =================== #
Parameters:
paramVpcCIDR:
Description: Enter the IP range (CIDR notation) for VPC
Type: String
Default: 10.192.0.0/16
paramPublicSubnet1CIDR:
Description: Enter the IP range (CIDR notation) for the public subnet in AZ A
Type: String
Default: 10.192.10.0/24
paramPublicSubnet2CIDR:
Description: Enter the IP range (CIDR notation) for the public subnet in AZ B
Type: String
Default: 10.192.11.0/24
paramPrivateSubnet1CIDR:
Description: Enter the IP range (CIDR notation) for the private subnet in AZ A
Type: String
Default: 10.192.20.0/24
paramPrivateSubnet2CIDR:
Description: Enter the IP range (CIDR notation) for the private subnet in AZ B
Type: String
Default: 10.192.21.0/24
paramUniqueName:
Description: Give a unique name for "CloudFormationLab" tag value
Type: String
Default: CodeFormation Practise
Các tham số này tương ứng với dải IP (dạng CIDR notation) cho VPC và 4 subnet. Ngoài ra, thêm một tham số paramUniqueName để đánh tag cho các resources.
Tiếp theo, ta khởi tạo các resources.
Bổ sung resource VPC
Resources:
# Create a VPC
myVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref paramVpcCIDR
EnableDnsSupport: true # let instances in the VPC get DNS hostnames
EnableDnsHostnames: true # allow DNS resolution
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
Internet Gateway
myInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
NAT Gateway
myVPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref myVPC
InternetGatewayId: !Ref myInternetGateway
Public Route Table với bản ghi route 0.0.0.0/0 myInternetGateway
nhằm điều hướng tất cả request tới Internet Gateway đã thêm phía trên.
# Create a public route table for the VPC (will be public once it is associated with the Internet Gateway)
myPublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref myVPC
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
# Associate the public route table with the Internet Gateway
myPublicRoute:
Type: AWS::EC2::Route
DependsOn: myVPCGatewayAttachment
Properties:
RouteTableId: !Ref myPublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref myInternetGateway
Khởi tạo 2 public subnet
# Create a public subnet in AZ 1 (will be public once it is associated with public route table)
myPublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref myVPC
AvailabilityZone: !Select [ 0, !GetAZs '' ] # AZ 1
CidrBlock: !Ref paramPublicSubnet1CIDR
MapPublicIpOnLaunch: true # allow instances launched in this subnet receive a public IPv4 address
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
# Create a public subnet in AZ 2 (will be public once it is associated with public route table)
myPublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref myVPC
AvailabilityZone: !Select [ 1, !GetAZs '' ] # AZ 2
CidrBlock: !Ref paramPublicSubnet2CIDR
MapPublicIpOnLaunch: true # allow instances launched in this subnet receive a public IPv4 address
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
Liên kết hai public subnet vừa tạo với public route table
# Associate the public route table with the public subnet in AZ 1
myPublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref myPublicRouteTable
SubnetId: !Ref myPublicSubnet1
# Associate the public route table with the public subnet in AZ 2
myPublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref myPublicRouteTable
SubnetId: !Ref myPublicSubnet2
Khởi tạo 2 NAT Gateway, mỗi NAT Gateway sẽ cần được gán Elastic IP nằm trong public subnet
# Specify an Elastic IP (EIP) address for a NAT Gateway in AZ 1
myEIPforNatGateway1:
Type: AWS::EC2::EIP
DependsOn: myVPCGatewayAttachment
Properties:
Domain: vpc # if the region supports EC2-Classic, the default is "standard", otherwise - "vpc"
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
# Specify an Elastic IP (EIP) address for a NAT Gateway in AZ 2
myEIPforNatGateway2:
Type: AWS::EC2::EIP
DependsOn: myVPCGatewayAttachment
Properties:
Domain: vpc # if the region supports EC2-Classic, the default is "standard", otherwise - "vpc"
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
# Create a NAT Gateway in the public subnet for AZ 1
myNatGateway1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt myEIPforNatGateway1.AllocationId
SubnetId: !Ref myPublicSubnet1
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
# Create a NAT Gateway in the public subnet for AZ 2
myNatGateway2:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt myEIPforNatGateway2.AllocationId
SubnetId: !Ref myPublicSubnet2
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
Tạo 2 route table nhằm điều hướng tất cả request tới 2 NAT Gateway tương ứng
# Create a private route table for AZ 1
myPrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref myVPC
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
# Create a private route table for AZ 2
myPrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref myVPC
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
# Associate the private route table with the Nat Gateway in AZ 1
myPrivateRouteForAz1:
Type: AWS::EC2::Route
DependsOn: myVPCGatewayAttachment
Properties:
RouteTableId: !Ref myPrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref myNatGateway1
# Associate the private route table with the Nat Gateway in AZ 2
myPrivateRouteForAz2:
Type: AWS::EC2::Route
DependsOn: myVPCGatewayAttachment
Properties:
RouteTableId: !Ref myPrivateRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref myNatGateway2
Bước cuối cùng, bổ sung 2 private subnet và liên kết chúng với 2 route table
# Create a private subnet in AZ 1
myPrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref myVPC
AvailabilityZone: !Select [ 0, !GetAZs '' ] # AZ 1
CidrBlock: !Ref paramPrivateSubnet1CIDR
MapPublicIpOnLaunch: false # private subnet doesn't need public IP
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
# Create a private subnet in AZ 2
myPrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref myVPC
AvailabilityZone: !Select [ 1, !GetAZs '' ] # AZ 2
CidrBlock: !Ref paramPrivateSubnet2CIDR
MapPublicIpOnLaunch: false # private subnet doesn't need public IP
Tags:
- Key: MasteringCF
Value: !Ref paramUniqueName
# Associate the private route table with the private subnet in AZ 1
myPrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref myPrivateRouteTable1
SubnetId: !Ref myPrivateSubnet1
# Associate the private route table with the private subnet in AZ 2
myPrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref myPrivateRouteTable2
SubnetId: !Ref myPrivateSubnet2
Vậy là hoàn tất, bạn có thể tham khảo file template hoàn chỉnh tại đây.
Chi tiết về cú pháp sử dụng trong Template file, bạn có thể tham khảo tại "Sơ lược về CloudFormation".
Bước 2: Khởi tạo stack từ template file
Chạy lệnh sau để khởi tạo stack trên AWS
aws cloudformation create-stack \
--stack-name custom-vpc \
--template-body file://template.yml
Truy cập website AWS, mục CloudFormation để kiểm tra trạng thái của stack vừa tạo.
Tham khảo các phần Resources được tạo:
Kiểm tra mục Parameter của stack trong tab "Parameters"
Bước 3: Cập nhật stack
Trong phần này, ta sẽ tạo changeset để cập nhật dải IP của một subnet
Sử dụng lệnh sau để tạo changeset
aws cloudformation create-change-set --change-set-name update-private-subnet-id\
--stack-name custom-vpc \
--use-previous-template \
--parameters ParameterKey=paramPrivateSubnet2CIDR,ParameterValue="10.192.41.0/24"
Mục tiêu ở đây là cập nhật giá trị của tham số paramPrivateSubnet2CIDR - dải IP của private subnet 2 với giá trị: 10.192.41.0/24
Truy cập website AWS, click chọn changeset vừa tạo để view các resources sẽ cập nhật nếu execute changeset:
Ở đây, nếu ta apply changeset sẽ có hai đối tượng được cập nhật là: myPrivateSubnet2 và myPrivateSubnet2RouteTableAssociation (đối tượng liên kết subnet với route table)
Để apply changeset, chạy lệnh
aws cloudformation execute-change-set \
--change-set-name update-private-subnet-id \
--stack-name custom-vpc
Theo dõi stack được cập nhật trên website. Parameter sau khi được cập nhật:
Vậy là xong, bạn đã thực hiện hầu hết các thao tác cơ bản khi làm việc với AWS CloudFormation.
Bước 4: Delete stack
Last but not least, đừng quên xóa stack để tránh bị tính phí ngoài ý muốn.
aws cloudformation delete-stack --stack-name custom-vpc
Kết luận
Trong bài viết này, mình đã chia sẻ chi tiết các bước để triển khai Virtual Private Cloud sử dụng CloudFormation template. Hi vọng bài viết này có ích cho bạn. Trân trọng!
Link tham khảo
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-guide.html
All rights reserved