AWS CloudFormation 模板:是否可以将许多 CidrIp 添加为列表?
AWS CloudFormation template: Is it possible to add many CidrIp as a list?
我想在云编队模板中创建安全组的入站规则。我想从许多不同的 IP 打开 3306 端口。
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"CidrIp": "0.0.0.0/0",
"FromPort": "3306",
"ToPort": "3306"
}
我知道文档说 String 是 CidrIp
类型,但是是否可以这样做 ["100.10.77.66/32", "100.10.66.66/32" , "101.10.77.66/32"]
以避免多次写入相同的块?
恐怕不会,因为文档指出它只接受字符串而不接受列表,因此需要多个块。
将其视为在 Web 控制台中创建入口规则的方式,每个 CIDR 一个新规则。
不幸的是,CloudFormation 的 Intrinsic Functions, and as you pointed out the AWS::EC2::SecurityGroupIngress
资源本身没有可用的迭代,它的 CidrIp
属性.
只接受一个 String
作为替代方案,我建议选择一种中间格式,使用预处理器编译成 CloudFormation 模板 JSON,if/when 需要更强大的表达能力。您可以使用像 troposphere 这样的全功能库,但编写您自己的基本预处理层代码以适应您的用例和 programming-language/library 偏好也很容易。
我目前的选择是 YAML with embedded Ruby (ERB) 的组合,主要是因为我已经熟悉它们了。这是一个示例 template.yml.erb
文件,它将生成上面的示例 JSON:
SecurityGroupIngress:
<% ["100.10.77.66/32", "100.10.66.66/32" , "101.10.77.66/32"].each do |cidr| -%>
- IpProtocol: tcp
CidrIp: <%=cidr%>
FromPort: 3306
ToPort: 3306
<% end -%>
这是一个最小的预处理器脚本,process_template.rb
:
require 'erb'
require 'yaml'
require 'json'
puts JSON.pretty_generate(YAML.load(ERB.new(ARGF.read, nil, '-').result))
运行 ruby ./process_template.rb template.yml.erb
产生:
{
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"CidrIp": "100.10.77.66/32",
"FromPort": 3306,
"ToPort": 3306
},
{
"IpProtocol": "tcp",
"CidrIp": "100.10.66.66/32",
"FromPort": 3306,
"ToPort": 3306
},
{
"IpProtocol": "tcp",
"CidrIp": "101.10.77.66/32",
"FromPort": 3306,
"ToPort": 3306
}
]
}
基于的方法,这里有一种类似的方法,您可以在与 ERB 模板分离的文件中指定 CidrIp。首先,创建一个 ERB 文件。例如,让我们看看 sgi-trusted-ip-range.erb
:
Type: "AWS::EC2::SecurityGroupIngress"
<%- Dir.glob("trusted-ip-range/cidr-*.csv").map {|f| File.readlines(f)}.flatten.map(&:strip).each do |cidr| -%>
- IpProtocol: tcp
CidrIp: <%=cidr%>
FromPort: 80
ToPort: 80
- IpProtocol: tcp
CidrIp: <%=cidr%>
FromPort: 443
ToPort: 443
<%- end -%>
根据您的要求放置 CIDR 列表文件,并遵循命名约定 trusted-ip-range/cidr-*.csv
,其中内容例如:
100.10.77.66/32
100.10.66.66/32
101.10.77.66/32
然后,一行生成YAML文件:
ruby -r erb -e 'ERB.new(ARGF.read, nil, "-").run' sgi-trusted-ip-range.erb
此外,您可以像下面这样验证生成的 YAML 文件:
aws cloudformation validate-template --template-body "file://__PATH_TO_FILE__.yml"
我很好奇为什么没有提到 Cloudformation 自定义资源的答案。
您仍然可以使用 lambda 函数创建自己的自定义安全组,该函数 creates/deletes 基于您的云形成状态(创建、更新、删除)的安全组。
我写了一个简单的自定义资源here,大家觉得方便可以随意修改自定义资源参数。
然后您可以在创建堆栈时输入逗号分隔的 cidr 块。
您可以使用以下方式在实例(或其他资源)上引用此安全组:
!GetAtt CustomSG.SecGroupId
我不确定为什么没有提到前缀列表。您可以创建包含所有 CIDR 的前缀列表,并在 CF 模板中将前缀列表 ID 作为安全组源。例子
PrefixList:
Type: AWS::EC2::PrefixList
Properties:
PrefixListName: "Name of PL"
AddressFamily: "IPv4"
MaxEntries: 2 # the number of CIDR's you want to add
Entries:
- Cidr: "10.10.0.0/16"
Description: "CIDR1"
- Cidr: "10.100.0.0/16"
Description: "CIDR2"
Tags:
- Key: "Name"
Value: "PL
请完成下面的link。
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html
我想在云编队模板中创建安全组的入站规则。我想从许多不同的 IP 打开 3306 端口。
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"CidrIp": "0.0.0.0/0",
"FromPort": "3306",
"ToPort": "3306"
}
我知道文档说 String 是 CidrIp
类型,但是是否可以这样做 ["100.10.77.66/32", "100.10.66.66/32" , "101.10.77.66/32"]
以避免多次写入相同的块?
恐怕不会,因为文档指出它只接受字符串而不接受列表,因此需要多个块。
将其视为在 Web 控制台中创建入口规则的方式,每个 CIDR 一个新规则。
不幸的是,CloudFormation 的 Intrinsic Functions, and as you pointed out the AWS::EC2::SecurityGroupIngress
资源本身没有可用的迭代,它的 CidrIp
属性.
String
作为替代方案,我建议选择一种中间格式,使用预处理器编译成 CloudFormation 模板 JSON,if/when 需要更强大的表达能力。您可以使用像 troposphere 这样的全功能库,但编写您自己的基本预处理层代码以适应您的用例和 programming-language/library 偏好也很容易。
我目前的选择是 YAML with embedded Ruby (ERB) 的组合,主要是因为我已经熟悉它们了。这是一个示例 template.yml.erb
文件,它将生成上面的示例 JSON:
SecurityGroupIngress:
<% ["100.10.77.66/32", "100.10.66.66/32" , "101.10.77.66/32"].each do |cidr| -%>
- IpProtocol: tcp
CidrIp: <%=cidr%>
FromPort: 3306
ToPort: 3306
<% end -%>
这是一个最小的预处理器脚本,process_template.rb
:
require 'erb'
require 'yaml'
require 'json'
puts JSON.pretty_generate(YAML.load(ERB.new(ARGF.read, nil, '-').result))
运行 ruby ./process_template.rb template.yml.erb
产生:
{
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"CidrIp": "100.10.77.66/32",
"FromPort": 3306,
"ToPort": 3306
},
{
"IpProtocol": "tcp",
"CidrIp": "100.10.66.66/32",
"FromPort": 3306,
"ToPort": 3306
},
{
"IpProtocol": "tcp",
"CidrIp": "101.10.77.66/32",
"FromPort": 3306,
"ToPort": 3306
}
]
}
基于sgi-trusted-ip-range.erb
:
Type: "AWS::EC2::SecurityGroupIngress"
<%- Dir.glob("trusted-ip-range/cidr-*.csv").map {|f| File.readlines(f)}.flatten.map(&:strip).each do |cidr| -%>
- IpProtocol: tcp
CidrIp: <%=cidr%>
FromPort: 80
ToPort: 80
- IpProtocol: tcp
CidrIp: <%=cidr%>
FromPort: 443
ToPort: 443
<%- end -%>
根据您的要求放置 CIDR 列表文件,并遵循命名约定 trusted-ip-range/cidr-*.csv
,其中内容例如:
100.10.77.66/32
100.10.66.66/32
101.10.77.66/32
然后,一行生成YAML文件:
ruby -r erb -e 'ERB.new(ARGF.read, nil, "-").run' sgi-trusted-ip-range.erb
此外,您可以像下面这样验证生成的 YAML 文件:
aws cloudformation validate-template --template-body "file://__PATH_TO_FILE__.yml"
我很好奇为什么没有提到 Cloudformation 自定义资源的答案。
您仍然可以使用 lambda 函数创建自己的自定义安全组,该函数 creates/deletes 基于您的云形成状态(创建、更新、删除)的安全组。
我写了一个简单的自定义资源here,大家觉得方便可以随意修改自定义资源参数。
然后您可以在创建堆栈时输入逗号分隔的 cidr 块。
您可以使用以下方式在实例(或其他资源)上引用此安全组:
!GetAtt CustomSG.SecGroupId
我不确定为什么没有提到前缀列表。您可以创建包含所有 CIDR 的前缀列表,并在 CF 模板中将前缀列表 ID 作为安全组源。例子
PrefixList:
Type: AWS::EC2::PrefixList
Properties:
PrefixListName: "Name of PL"
AddressFamily: "IPv4"
MaxEntries: 2 # the number of CIDR's you want to add
Entries:
- Cidr: "10.10.0.0/16"
Description: "CIDR1"
- Cidr: "10.100.0.0/16"
Description: "CIDR2"
Tags:
- Key: "Name"
Value: "PL
请完成下面的link。
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html