前言:为什么需要自定义VPC?
作为AWS开发者,你是否遇到过这些问题:
- 默认VPC配置太开放,不符合安全规范?
- Lambda需要访问私有数据库,却不知道如何配置网络隔离?
- 多可用区部署时,子网规划混乱导致服务不可用?
自定义VPC是解决这些问题的核心——它能为你的服务提供隔离的网络环境,精准控制流量走向,同时满足Lambda和Aurora的部署要求。今天这份指南,带你从零搭建一套安全、高可用的VPC网络架构。
一、VPC网络架构设计思路
核心需求分析
针对Lambda和Aurora的部署场景,我们需要:
- 公网子网:部署NAT网关,让私有子网内的资源能访问外网(如下载依赖、调用外部API);
- 私有子网:部署Lambda和Aurora,避免直接暴露在公网,提升安全性;
- 安全组隔离:Lambda和Aurora分别配置安全组,仅开放必要端口;
- 多可用区部署:私有子网分布在不同可用区,保障服务高可用。
网络架构图
┌─────────────────────────────────────────────────────────────┐
│ VPC (10.0.0.0/16) │
│ │
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
│ │ 公网子网 │ │ 内网子网区域 │ │
│ │ (10.0.1.0/24) │ │ │ │
│ │ │ │ ┌─────────────────────────────┐ │ │
│ │ ┌───────────┐ │ │ │ 内网子网1 │ │ │
│ │ │ NAT网关 │ │ │ │ (10.0.2.0/24) │ │ │
│ │ └───────────┘ │ │ └─────────────────────────────┘ │ │
│ │ │ │ │ │
│ └─────────────────┘ │ ┌─────────────────────────────┐ │ │
│ │ │ │ 内网子网2 │ │ │
│ │ │ │ (10.0.3.0/24) │ │ │
│ ┌─────────────────┐ │ └─────────────────────────────┘ │ │
│ │ 互联网网关 │ │ │ │
│ └─────────────────┘ │ ┌─────────────────────────────┐ │ │
│ │ │ │ 内网子网3 │ │ │
│ │ │ │ (10.0.4.0/24) │ │ │
│ │ │ └─────────────────────────────┘ │ │
│ │ └─────────────────────────────────┘ │
└───────────┼─────────────────────────────────────────────────┘
│
┌───────────────┐
│ 互联网 │
└───────────────┘
关键组件作用
- VPC:虚拟私有云,整个网络的容器,隔离资源;
- 公网子网:仅部署NAT网关,作为私有子网的外网出口;
- 私有子网:Lambda(业务逻辑)和Aurora(数据库)的部署区域;
- NAT网关:让私有子网内的资源访问外网,但阻止外网主动访问;
- 安全组:Lambda安全组允许出站流量,Aurora安全组仅允许Lambda访问5432端口。
二、前置条件:部署前准备
1. 工具安装
# Windows(使用Chocolatey)
choco install awscli
# macOS/Linux
brew install awscli # macOS
# 或
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install # Linux
2. AWS凭证配置
# 配置Access Key和Secret Key
aws configure
# 输入以下信息:
# AWS Access Key ID [None]: 你的Access Key
# AWS Secret Access Key [None]: 你的Secret Key
# Default region name [None]: us-east-1(或其他区域)
# Default output format [None]: json
# 验证配置是否成功
aws sts get-caller-identity
# 输出用户信息即配置成功
三、部署方式:三种方法任选
方法一:PowerShell脚本一键部署(推荐)
# 基本部署(默认区域)
.\deploy-vpc.ps1 -StackName "my-vpc-stack"
# 指定区域和配置文件
.\deploy-vpc.ps1 -StackName "my-vpc-stack" -Region "us-west-2" -ProfileName "my-aws-profile"
方法二:AWS CLI手动部署
# 部署CloudFormation堆栈
aws cloudformation deploy \
--template-file vpc-template.yaml \
--stack-name my-vpc-stack \
--capabilities CAPABILITY_IAM \
--region us-east-1
# 获取部署输出(记录关键资源ID)
aws cloudformation describe-stacks \
--stack-name my-vpc-stack \
--query "Stacks[0].Outputs" \
--output table
方法三:AWS控制台可视化部署
- 登录AWS控制台,进入CloudFormation服务;
- 点击“创建堆栈”→选择“上传模板文件”→上传
vpc-template.yaml; - 输入堆栈名称(如
my-vpc-stack),确认参数后点击“创建堆栈”; - 等待部署完成(约3-5分钟),在“输出”标签页查看资源ID。
四、核心配置解析:vpc-template.yaml
1. 参数定义(可自定义)
Parameters:
VpcCidr:
Type: String
Default: '10.0.0.0/16' # VPC整体IP段
Description: CIDR block for the VPC
PublicSubnetCidr:
Type: String
Default: '10.0.1.0/24' # 公网子网IP段
Description: CIDR block for the public subnet
PrivateSubnet1Cidr:
Type: String
Default: '10.0.2.0/24' # 私有子网1(可用区1)
Description: CIDR block for private subnet 1
PrivateSubnet2Cidr:
Type: String
Default: '10.0.3.0/24' # 私有子网2(可用区2)
Description: CIDR block for private subnet 2
PrivateSubnet3Cidr:
Type: String
Default: '10.0.4.0/24' # 私有子网3(可用区3)
Description: CIDR block for private subnet 3
2. 核心资源配置
VPC与互联网网关
# VPC创建(启用DNS解析)
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsHostnames: true # 允许实例获取公网DNS
EnableDnsSupport: true # 启用DNS解析
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-VPC'
# 互联网网关(VPC访问外网的入口)
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-IGW'
# 关联互联网网关到VPC
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
公网子网与NAT网关
# 公网子网(部署NAT网关)
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs ''] # 第一个可用区
CidrBlock: !Ref PublicSubnetCidr
MapPublicIpOnLaunch: true # 自动分配公网IP
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-Public-Subnet'
# NAT网关(私有子网的外网出口)
NatGatewayEIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
Domain: vpc
NatGateway:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGatewayEIP.AllocationId
SubnetId: !Ref PublicSubnet
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-NAT-Gateway'
私有子网与路由表
# 私有子网1(可用区1)
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: !Ref PrivateSubnet1Cidr
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-Private-Subnet-1'
# 私有路由表(所有外网流量走NAT网关)
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-Private-Routes'
# 私有子网路由规则(0.0.0.0/0指向NAT网关)
DefaultPrivateRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway
安全组配置(核心安全策略)
# Lambda安全组(允许所有出站流量)
LambdaSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${AWS::StackName}-Lambda-SG'
GroupDescription: Security group for Lambda functions
VpcId: !Ref VPC
SecurityGroupEgress: # 出站规则:允许所有流量
- IpProtocol: -1
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-Lambda-SG'
# Aurora安全组(仅允许Lambda访问5432端口)
AuroraSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${AWS::StackName}-Aurora-SG'
GroupDescription: Security group for Aurora database
VpcId: !Ref VPC
SecurityGroupIngress: # 入站规则:仅Lambda可访问5432
- IpProtocol: tcp
FromPort: 5432
ToPort: 5432
SourceSecurityGroupId: !Ref LambdaSecurityGroup
Description: Allow Lambda to access Aurora
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-Aurora-SG'
3. 输出配置(关键资源ID)
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub '${AWS::StackName}-VPC-ID'
PrivateSubnet1Id:
Description: Private Subnet 1 ID
Value: !Ref PrivateSubnet1
Export:
Name: !Sub '${AWS::StackName}-Private-Subnet-1-ID'
LambdaSecurityGroupId:
Description: Lambda Security Group ID
Value: !Ref LambdaSecurityGroup
Export:
Name: !Sub '${AWS::StackName}-Lambda-SG-ID'
AuroraSecurityGroupId:
Description: Aurora Security Group ID
Value: !Ref AuroraSecurityGroup
Export:
Name: !Sub '${AWS::StackName}-Aurora-SG-ID'
五、验证部署:确保网络配置正确
1. 检查堆栈状态
# 确认堆栈部署成功(状态应为CREATE_COMPLETE)
aws cloudformation describe-stacks --stack-name my-vpc-stack --query "Stacks[0].StackStatus"
2. 验证核心资源
# 检查VPC是否存在
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=my-vpc-stack-VPC"
# 检查子网列表
aws ec2 describe-subnets --filters "Name=tag:Name,Values=my-vpc-stack-*"
# 检查安全组
aws ec2 describe-security-groups --filters "Name=tag:Name,Values=my-vpc-stack-*"
3. 测试网络连通性(可选)
在公网子网启动一台EC2实例,尝试访问私有子网内的资源,验证:
- 私有子网内的Lambda能通过NAT网关访问外网;
- 外网无法直接访问私有子网内的Aurora数据库;
- Lambda能正常连接Aurora数据库(5432端口开放)。
六、故障排除:常见问题速解
1. 权限不足导致部署失败
现象:CloudFormation报错AccessDenied
解决方案:
- 确保AWS用户拥有
EC2FullAccess和CloudFormationFullAccess权限; - 或手动配置细粒度权限(VPC创建、子网管理、安全组配置等)。
2. CIDR地址冲突
现象:报错CIDR block overlaps with existing
解决方案:
- 修改模板中的
VpcCidr或子网CIDR参数,避免与现有VPC的IP段冲突; - 推荐使用
172.16.0.0/16或192.168.0.0/16作为VPC CIDR。
3. NAT网关创建失败
现象:NAT网关状态为failed
解决方案:
- 确保公网子网已关联互联网网关;
- 检查公网子网是否开启
MapPublicIpOnLaunch; - 确认账户在对应区域有足够的弹性IP配额。
4. Lambda无法访问Aurora
现象:Lambda连接数据库超时
解决方案:
- 检查Aurora安全组是否允许Lambda安全组访问5432端口;
- 确认Lambda部署在与Aurora同VPC的私有子网;
- 检查私有子网路由表是否配置正确(指向NAT网关)。
七、最佳实践:VPC配置优化
1. 安全优化
- 最小权限原则:Aurora安全组仅开放必要端口(如5432),且仅允许Lambda访问;
- 禁止公网访问:私有子网不分配公网IP,所有外网访问通过NAT网关;
- 流量审计:启用VPC Flow Logs,监控网络流量异常。
2. 高可用优化
- 多可用区部署:私有子网分布在至少2个可用区,避免单点故障;
- NAT网关冗余:生产环境可在多个可用区部署NAT网关,提升容错性;
- 子网划分合理:按业务模块划分子网(如数据库子网、应用子网)。
3. 成本优化
- 删除闲置资源:测试环境用完后及时删除VPC堆栈,避免资源浪费;
- 使用NAT网关按需付费:避免长期闲置的NAT网关产生费用;
- CIDR规划合理:避免IP段过大导致资源浪费,或过小导致扩展不足。
八、下一步:基于VPC部署服务
VPC部署完成后,可继续:
- 部署Lambda:将Lambda函数配置到私有子网,关联Lambda安全组;
- 部署Aurora:在私有子网创建Aurora集群,关联Aurora安全组;
- 配置API Gateway:将API Gateway与Lambda集成,对外提供服务;
- 监控与告警:启用CloudWatch监控VPC流量和资源状态。
记住:VPC是AWS服务的网络基础,合理的配置能大幅提升服务的安全性和可用性!
