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

时间:2013-07-25 13:48:41

标签: amazon-web-services amazon-cloudformation cidr amazon-vpc

我们正在调整我们的应用程序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是面向字符串的),或者更好地解决这个难题。

2 个答案:

答案 0 :(得分:6)

我遇到了类似的情况。我想控制模板中的所有内容,而不使用某些脚本生成模板。我的输入范围也受限于您的情况。我最终搞了一个可怕的黑客。我很惭愧在这里发布,但如果它有助于一个人,那可能是值得的。

有一个映射表,可以为您做数学计算并为所有可能的输入定义

"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" ] }

答案 1 :(得分:2)

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

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