我想在云形成模板中创建安全组的入站规则。我想从许多不同的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"]
之类的操作以避免多次写同一个块吗?
答案 0 :(得分:7)
不幸的是,CloudFormation Intrinsic Functions没有可用的迭代,并且正如您所指出的那样,AWS::EC2::SecurityGroupIngress
资源本身只接受String
个CidrIp
{1}}属性。
作为替代方案,我建议选择一种中间格式,使用预处理器编译为CloudFormation模板JSON,如果/需要更强的表现力。您可以使用像troposphere这样的功能齐全的库,但它也很容易编写您自己的基本预处理层,以满足您的用例和编程语言/库首选项。
我目前的选择是YAML与嵌入式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
}
]
}
答案 1 :(得分:6)
不要害怕,因为文档声明它只接受String而不是List,因此需要多个块。
与在Web控制台中创建入口规则的方式相同,每个CIDR都有一条新规则。
答案 2 :(得分:0)
根据wjordan的方法,您可以通过类似的方式在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'
此外,您可以验证生成的YAML文件,如下所示:
aws cloudformation validate-template --template-body "file://__PATH_TO_FILE__.yml"
答案 3 :(得分:0)
我很好奇为什么没有关于Cloudformation Custom资源的答案。
您仍然可以使用lambda函数创建自己的自定义安全组,该函数根据您的cloudformation状态(创建,更新,删除)创建/删除安全组。
我编写了一个简单的自定义资源here,请在方便时随意修改自定义资源参数。
然后,您可以在创建堆栈时输入逗号分隔的cidr块。
您可以使用以下方法在实例(或其他资源)上引用此安全组:
!GetAtt CustomSG.SecGroupId