+86 135 410 16684Mon. - Fri. 10:00-22:00

建立 VPC 并基于参数动态创建子网的 CloudFormation 模板

建立 VPC 并基于参数动态创建子网的 CloudFormation 模板

建立 VPC 并基于参数动态创建子网的 CloudFormation 模板

创建 Subnet

在大型企业云迁移项目组,经常会遇到企业将线下数据中心的子网迁移到 AWS 云上。线下的子网划分一般会根据子网的使用功能不同进行划分,例如防火墙子网、负载均衡器子网、配合部署高可用架构的心跳线子网、应用系统子网等。不同企业的子网划分规则、子网的掩码大小和路由规则均不相同,并且在迁移后的系统上线后,企业还会经常划分新的网段以部署新的应用系统,这就需要有一个通用的模板来协助网络管理人员简化工作流程,提高工作效率。在我所经历过的一个项目中,生产 VPC 的子网划分有47个之多,且子网掩码有/24, /25, /26. 27/, /28等不同,在添加新的子网时,需要仔细计算新的子网 CIDR 以及为新建子网配置路由表。

动态创建子网的方案概述

因为 CloudFormation 不支持程序逻辑,只支持静态资源的创建,所以在本方案中采用 AWS Lambda 来基于输入参数动态创建不同类型的子网。我们定义了3种不同类型的子网:公共子网 (Public Subnet), 外部子网 (External Subnet),内部子网 (Internal Subnet) Subnet。
公共子网的路由表有如下路由信息:

Destination Target
0.0.0.0/0 igw-xxxxx (Internet Gateway)

部署在公共子网中的服务器可以直接与 Internet 进行通信(缺省分配 Internet IP 地址,并且有指向 Internet Gateway 的缺省路由)。
外部子网的路由表有如下路由信息:

Destination Target
0.0.0.0/0 nat-xxxxx (NAT gateway)
pl-xxxxxx (com.amazonaws.cn-north-1.s3) vpce-xxxxxxx
pl-xxxx (com.amazonaws.cn-north-1.dynamodb) vpce-xxxx

部署在外部子网的服务器可以通过 NAT Gateway 与 Internet 进行通信,并且可以不通过互联网访问 S3 和 dynamodb。
内部子网的路由表有如下路由信息:

Destination Target
pl-xxxxxx (com.amazonaws.cn-north-1.s3) vpce-xxxxxxx
pl-xxxx (com.amazonaws.cn-north-1.dynamodb) vpce-xxxx

部署在内部子网的服务器不能访问 Internet,但是能直接访问 S3 和 dynamodb。
本方案使用2个 CloudFomation 模板, 第一个模板(CreateBaseVpc.json)创建共享资源,例如 VPC、Internet Gateway、公共子网 (Public Subnet) 路由表、在各个可用区内创建公共子网、NAT Gateway、 VPC Endpoint (S3 endpoint和DynamoDB endpoint)和创建外部子网路由表。在这个模板中还创建了3个 Lambda 功能函数:

    • SharedInfra – 对应 python 程序 create_shared_infra.zip

功能:根据输入的参数,在程序运行的AWS Region的每个AZ内创建公共子网,将在 CreateBaseVpc.json 模板中建立的公共子网路由表关联到每个公共子网。 在每个公共子网内创建 NAT Gateway 和VPC endpoint,创建内部子网路由表,创建外部子网路由表。删除已经创建完成的资源,包括:子网、路由表、vpc endpoint、NAT Gateway、Elastic IP。

    • CreateExternalRoute – 对应 python 程序 create_external_route.zip

功能:创建外部子网路由表中的路由。因为 NAT Gateway 的创建速度比较慢,创建路由时一定要等待 NAT Gateway 的状态变成 available 后才可以成功。如果将此功能与 SharedInfra 放在一起,在执行的时候容易发生 Lambda 运行超时错误。删除已经创建的路由信息。

    • SubnetAutomation – 对应 python 程序 subnet_creation.zip

功能:根据输入的参数,计算网路的子网掩码,创建公共子网、外部子网和内部子网,并将在公共子网路由表、内部子网路由表和外部子网路由表关联到相应的子网上。删除已经创建完成子网。在 CreateBaseVpc.json 模板运行时,通过创建用户定义资源 ExternalRouteCreation和SharedInfraCreation 分别触发 Lambda 功能 CreateExternalRoute 和 SharedInfra,从而完成共享资源的创建。并提供了 SubnetAutomation 的功能函数 ARN,供运行第二个模板时调用。

第二个模板 (SubnetAuto.json) 创建动态资源,例如根据输入参数的不同计算子网掩码、创建子网并分配路由表。

本方案中创建子网时的输入参数并不需要 CIDR,只需要指定子网要提供的可用 IP 地址的个数即可,程序在计算可用 IP 地址时已经排除了 AWS 子网子网中保留的5个 IP 地址。例如:如果要创建有50个 IP 的子网,则子网掩码是/26,共计有64-5=59个可用IP地址;如果要创建有16个 IP 的子网,则子网掩码是/27,共计有32-5=27个可用 IP 地址。

创建子网的参数输入规则如下:

  1. 每个子网包含4个部分,之间使用“:”分隔 – 功能: IP 地址数量:可用区:子网类型
  2. 可用区根据Region的不同可选项为:1a,1b,1c,1d,1e等
  3. 子网类型的可选项为:p(公共子网),e(外部子网)或者 i(内部子网)
  4. 不同子网之间使用“,”分隔。

安装和运行

    1. 在浏览器中输入:https://github.com/shaneliuyx/autosubnet_creation, 下载2个 json 文件和3个 zip 文件。将3个 zip 文件上传到一个 S3 存储桶中。
    2. 打开 AWS 控制台,并选择 CloudFormation,选择存储在本地的 json 文件 json,运行 CloudFormation 模板。
    3. 假设输入缺省的 PublicSubnetCapacity 和 VpcCidr 如下:

vpc-cloudformation-template1

    1. 选择 Next,直至 AWS 资源开始创建
    2. 最终运行结果如下:

vpc-cloudformation-template2

创建的 Subnet 如下:

vpc-cloudformation-template3

公共子网路由表:

vpc-cloudformation-template4

    1. 打开 AWS 控制台,并选择 CloudFormation,选择存储在本地的 json 文件 json,运行 CloudFormation 模板。
    2. 输入 SubnetParameters:web1:50:1a:p,web1:50:1b:p,app1:50:1a:e,app1:50:1b:e,db1:50:1a:i,db1:50:1b:i

这将创建6个子网,其中 Web、APP 和 DB 各2个子网,分布在2个 AZ 中:

vpc-cloudformation-template5

    1. 运行结果如下:

vpc-cloudformation-template6

创建的子网:

vpc-cloudformation-template7
vpc-cloudformation-template8
vpc-cloudformation-template9

内部子网路由表:

vpc-cloudformation-template10

外部子网路由表:

vpc-cloudformation-template11

假设现在还要创建一个包含16个有效 IP 的公共子网用于部署网络设备,可以再运行一次SubnetAuto.json,输出参数:net1:16:1a:p,net1:16:1b:p
则可以创建出如下子网:

vpc-cloudformation-template12

与其他 CloudFormation 模板配合使用,进行 Landing Zone 部署

Landing Zone 中文名称翻译成着陆区,是指 AWS 的基本环境,用户在其上部署安全和运维流程。Landing Zone 的内容包含:账户结构、账户安全基线、网络结构和AWS用户访问管理。下面简单的介绍一下 AWS Landing Zone 的最佳实践。

    • 账户结构

AWS 建议账户的划分与企业的组织架构和运维部门的组织架构一致。例如按照如下结构划分账户:

vpc-cloudformation-template13

    • 账户安全基线

AWS 建议在所有账户内打开 CloudTrail 和 AWS Config 功能。所有日志信息要复制到安全账户内的 S3 存储桶中。建立跨账户访问的 Auditor 角色。

vpc-cloudformation-template14

    • 网络结构

AWS 建议删除缺省 VPC,建立客户自己定义的 VPC。建立共享 VPC(包含目录服务、邮件服务器等),应用 VPC 与共享 VP C建立 Peer 关系。通过 VPN 或者 Direct Connect 与线下的数据中心建立网络连接,或者采用 Transit VPC(参考 https://aws.amazon.com/answers/networking/aws-global-transit-network/ ,https://aws.amazon.com/blogs/aws/aws-solution-transit-vpc/ )建立集中的网络控制机制。网络输入输出的安全控制(建立堡垒机,建立 Security Group、网络 ACL 或者第三方的防火墙工具)

    • AWS 用户访问管理

包括建议基于 SAML 的单点登录,建立跨账户角色访问机制等。

上述介绍的建立 VPC 和子网的方法可以看成建立 Landing Zone 的基础,在此之上,我们还可以使用 CloudFormation 建立堡垒机,打开 CloudTrail 和 AWS config,建立不同账户间的日志(log)复制机制,建立 Config Rule 进行合规性检查等等。 AWS 已经开发出多个 QuickStart CloudFormation 脚本协助用户完成上述工作,但是这些脚本在中国区(BJS)运行时需要做一些修改。下表列出了一些可用的资源,其中中国区部署模板是我针对中国区的特点修改过的,可以在BJS正常运行。

原始代码 参考 AWS 中国区部署模板
账户安全基线 配置 AWS config 和 CloudTrail https://github.com/aws-quickstart/quickstart-compliance-pci https://s3.cn-north-1.amazonaws.com.cn/shane/quickstart-security/logging.template
配置 IAM 角色 https://s3.cn-north-1.amazonaws.com.cn/shane/quickstart-security/iam.template
配置 Config rules https://s3.cn-north-1.amazonaws.com.cn/shane/quickstart-security/config-rules.template
将 CloudWatch Log 转储到S3存储桶 https://github.com/alertlogic/cloudwatch-logs-s3-export#setup https://s3.cn-north-1.amazonaws.com.cn/shane/cwl-s3-export-new.template

使用说明:https://s3.cn-north-1.amazonaws.com.cn/shane/User+Guide+-+Copy+VPC+Flow+Logs+to+S3+CloudFormation+Templates.docx

将一个账户下的 S3 存储桶复制到另一个账户的 S3 https://s3.cn-north-1.amazonaws.com.cn/shane/s3-to-s3/1source.jsonhttps://s3.cn-north-1.amazonaws.com.cn/shane/s3-to-s3/2target.jsonhttps://s3.cn-north-1.amazonaws.com.cn/shane/s3-to-s3/3source.json

使用说明:https://s3.cn-north-1.amazonaws.com.cn/shane/s3-to-s3/User+Guide+-+S3+to+S3+Replication+CloudFormation+Templates.docx

网络结构 配置 Linux Bastion https://github.com/aws-quickstart/quickstart-linux-bastion https://s3.cn-north-1.amazonaws.com.cn/shane/linux-bastion.template不支持 CentOS
建立 VPC 和分配 Subnet https://github.com/aws-quickstart/quickstart-aws-vpc https://github.com/shaneliuyx/autosubnet_creation

北京 上海 天津 重庆 河北 山东 辽宁 黑龙江 吉林 甘肃 青海 河南 江苏 湖北 湖南 江西 浙江 广东 云南 福建 海南 山西 四川 陕西 贵州 安徽 广西 内蒙古 西藏 新疆 宁夏 澳门 香港 台湾