使用 AWS::Include 和嵌套堆栈编写可重用的 CloudFormation 片段
Writing reusable CloudFormation snippets with AWS::Include and Nested Stacks
我在 CloudFormation
中使用 nested stacks 几个月了,它们非常有用。所以我想我应该花点时间让每个嵌套堆栈都可以重用给组织中的其他团队。
我看到了 AWS::Include in several places like here and here 的用例,这对我来说很有意义。
我想到的一种方法是每个资源一个 snippet,比如可以包含的 AWS::EC2::Subnet
或 AWS::EC2::InternetGateway
零次或多次 进入vpc.json
模板,模板本身可用作较大应用程序中的嵌套堆栈。
代码段不带任何参数,但可以引用父模板中存在的参数。
乍一看,这对我来说似乎还不够。考虑这个例子:
"PublicSubnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {"Ref": "VPC"},
"AvailabilityZone": {
"Fn::Select" : [ "0", { "Fn::GetAZs" : {"Ref": "AWS::Region"} }]
},
"CidrBlock": {
"Fn::FindInMap": ["AZSubnetMap", {
"Fn::Select" : [ "0", { "Fn::GetAZs" : {"Ref": "AWS::Region"} }]},
"PublicSubnet"]},
"MapPublicIpOnLaunch": "true",
"Tags": [..]
}
}
例如,如何避免在子网片段中对 AZ 进行 "0"
硬编码?
遗憾的是,AWS 不提供根据要求动态更新模板的方法。
我已经使用 Mustache Templates using Java Library Handle Bars 解决了类似的问题。使用此库,您可以根据要求动态生成模板。
希望这对您有所帮助。
您将必须使用位于以下位置的两个 AWS::Include 文件:
- s3://yourname/PublicSubnetA.yaml
- s3://yourname/PublicSubnetB.yaml
并从您的主模板调用它们:
Fn::Transform:
Name: AWS::Include
Parameters:
Location : "s3://yourname/PublicSubnetA.yaml"
Fn::Transform:
Name: AWS::Include
Parameters:
Location : "s3://yourname/PublicSubnetB.yaml"
我正在尝试找到向 AWS::include 发送附加参数或覆盖参数的方法,如您所见
参数:
位置:
为什么 ti 不了解更多参数而不仅仅是位置,我很高兴有这样的东西:
Fn::Transform:
Name: AWS::Include
Parameters:
MySubnetIndex: 0
Location : "s3://yourname/PublicSubnetB.yaml"
我试过这种方式发送附加参数:
Fn::Transform:
Name: AWS::Include
Parameters:
Location : "s3://my.test/create-ec2.yaml"
EC2Size :
Type: String
Default: "t2.micro"
并得到有趣的错误:
转换包含下的参数 EC2Size 的值必须解析为字符串、数字、布尔值或任何这些的列表
貌似明白这是什么附加参数了,可能需要配置的有点不同吧。我还没有找到解决这个错误的方法。
我在 CloudFormation
中使用 nested stacks 几个月了,它们非常有用。所以我想我应该花点时间让每个嵌套堆栈都可以重用给组织中的其他团队。
我看到了 AWS::Include in several places like here and here 的用例,这对我来说很有意义。
我想到的一种方法是每个资源一个 snippet,比如可以包含的 AWS::EC2::Subnet
或 AWS::EC2::InternetGateway
零次或多次 进入vpc.json
模板,模板本身可用作较大应用程序中的嵌套堆栈。
代码段不带任何参数,但可以引用父模板中存在的参数。
乍一看,这对我来说似乎还不够。考虑这个例子:
"PublicSubnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": {"Ref": "VPC"},
"AvailabilityZone": {
"Fn::Select" : [ "0", { "Fn::GetAZs" : {"Ref": "AWS::Region"} }]
},
"CidrBlock": {
"Fn::FindInMap": ["AZSubnetMap", {
"Fn::Select" : [ "0", { "Fn::GetAZs" : {"Ref": "AWS::Region"} }]},
"PublicSubnet"]},
"MapPublicIpOnLaunch": "true",
"Tags": [..]
}
}
例如,如何避免在子网片段中对 AZ 进行 "0"
硬编码?
遗憾的是,AWS 不提供根据要求动态更新模板的方法。
我已经使用 Mustache Templates using Java Library Handle Bars 解决了类似的问题。使用此库,您可以根据要求动态生成模板。
希望这对您有所帮助。
您将必须使用位于以下位置的两个 AWS::Include 文件:
- s3://yourname/PublicSubnetA.yaml
- s3://yourname/PublicSubnetB.yaml
并从您的主模板调用它们:
Fn::Transform:
Name: AWS::Include
Parameters:
Location : "s3://yourname/PublicSubnetA.yaml"
Fn::Transform:
Name: AWS::Include
Parameters:
Location : "s3://yourname/PublicSubnetB.yaml"
我正在尝试找到向 AWS::include 发送附加参数或覆盖参数的方法,如您所见 参数: 位置:
为什么 ti 不了解更多参数而不仅仅是位置,我很高兴有这样的东西:
Fn::Transform:
Name: AWS::Include
Parameters:
MySubnetIndex: 0
Location : "s3://yourname/PublicSubnetB.yaml"
我试过这种方式发送附加参数:
Fn::Transform:
Name: AWS::Include
Parameters:
Location : "s3://my.test/create-ec2.yaml"
EC2Size :
Type: String
Default: "t2.micro"
并得到有趣的错误:
转换包含下的参数 EC2Size 的值必须解析为字符串、数字、布尔值或任何这些的列表
貌似明白这是什么附加参数了,可能需要配置的有点不同吧。我还没有找到解决这个错误的方法。