在 CloudFormation 模板中以编程方式生成子网 CIDR 块(或将整数相加)

Posted

技术标签:

【中文标题】在 CloudFormation 模板中以编程方式生成子网 CIDR 块(或将整数相加)【英文标题】:Generating subnet CIDR blocks programmatically in CloudFormation templates (or adding integers together) 【发布时间】:2013-07-25 10:59:14 【问题描述】:

我们正在调整我们的应用程序 CloudFormation 模板以利用 VPC。在此模板中,我们需要以编程方式生成用于我们的 VPC 子网的 CIDR 块,以确保它们不会在 CloudFormation 堆栈之间发生冲突。

我最初的计划是通过将字符串连接在一起来生成 CIDR,例如:

"ProxyLoadBalancerSubnetA" : 
  "Type" : "AWS::EC2::Subnet",
  "Properties" : 
    "VpcId" :  "Ref" : "Vpc" ,
    "AvailabilityZone" : "eu-west-1a",
    "CidrBlock" :  "Fn::Join" : [ ".", [  "Ref" : "VpcCidrPrefix" , "0.0/24" ] ] 
  
,

但是,经过进一步考虑,我们需要使用单个 VPC,而不是为每个堆栈使用一个 VPC。

AWS 将 VPC 限制为最多使用 /16 CIDR 块(我们已要求提高此限制,但显然不可能)。这意味着我们不再可能使用这种串联方法,因为我们的每个堆栈都需要跨越总共超过 255 个地址的子网。

我想即时生成 CIDR 块,而不必将它们定义为 CloudFormation 模板的参数,

我的一个想法是每个堆栈都有一个“基本整数”,并为每个子网的 CIDR 块添加到它。

例如:

    "CidrBlock" :  "Fn::Join" : [ ".", [  "Ref" : "VpcCidrPrefix" ,  "Fn::Sum", [  "Ref" : "VpcCidrStart" , 3 ] , "0/24 ] ] 

其中VpcCidrStart 是一个整数,用于设置脚本中第三个CIDR 八位字节的起始值,3 是子网号。

显然Fn::Sum 内部函数不存在,所以我想知道是否有人有在 VPC 中添加整数的解决方案(这似乎是不可能的,因为 CloudFormation 是面向字符串的),或更好地解决这个难题。

【问题讨论】:

【参考方案1】:

我对这类问题的解决方案是使用合法的编程语言将模板编译成 CloudFormation JSON 文档。我使用的是 php 5.4、Twig 和 Symfony 控制台,但使用的是 YMMV。

基本上,您可以提前使用编程语言进行数学运算,然后在编写 JSON 文档时使用该数据。

【讨论】:

我已经开始开发一个“堆栈管理器”应用程序来处理登台和生产环境需要稍微不同的设置的情况,并在晚上自动“熄灯”非生产环境 -所以我认为这个解决方案对我们来说很有意义。可惜 CloudFormation 本身就缺乏这些功能。 如果您还没有,最好在官方AWS CloudFormation forum 上描述您的用例并提出您的功能请求。我知道开发团队在那里处理支持。 我知道已经有一段时间了,但我确实实现了这一点,最近published it on GitHub。 AWS 最近确实为 CloudFormation 添加了基本逻辑和数学,但它相当繁琐。【参考方案2】:

我也遇到过类似的情况。我想控制模板中的所有内容,而无需使用某些脚本生成模板。我的输入范围也像您的情况一样受到限制。我最后放了一个可怕的骇客。我有点不好意思把它贴在这里,但如果它可以帮助更多的人,它可能是值得的。

有一个映射表,它将为您计算并为所有可能的输入定义它

"Mappings" :  
    "HorribleHackForSubtraction" :  
        "1" : "SubtractOne" : "0",
        "2" : "SubtractOne" : "1",
        "3" : "SubtractOne" : "2",
        "4" : "SubtractOne" : "3",
        "5" : "SubtractOne" : "4",
        "6" : "SubtractOne" : "5",
        "7" : "SubtractOne" : "6",
        "8" : "SubtractOne" : "7",
        "9" : "SubtractOne" : "8",
        "10" : "SubtractOne" : "9",
        "11" : "SubtractOne" : "10",
        "12" : "SubtractOne" : "11",
        "13" : "SubtractOne" : "12",
        "14" : "SubtractOne" : "13",
        "15" : "SubtractOne" : "14",
        "16" : "SubtractOne" : "15",
       
,  

您可以将计算值称为

 "Fn::FindInMap" : [ "HorribleHackForSubtraction",  "Ref" : "MyInputParam", "SubtractOne" ] 

【讨论】:

以上是关于在 CloudFormation 模板中以编程方式生成子网 CIDR 块(或将整数相加)的主要内容,如果未能解决你的问题,请参考以下文章

我们如何在Liferay中以编程方式创建用户和网站模板的角色,权限?

如何根据 IAM 角色 CloudFormation 模板中的参数提供不同的条件

在 iOS 中以编程方式生成视图

如何在android中以编程方式在片段之间导航?

如何在 Vue 3 中以编程方式创建组件实例?

扩大 Cloudformation 模板