我一直在测试terraform(v.0.10),以便在AWS中为企业提供EC2实例,安全组,RDS实例等。
我正在使用模块方法,以便可以为我的每个环境“采购”这些方法:
apps:
main.tf
app.tf
vars.tf
sec_groups:
main.tf
sec_group.tf
vars.tf
:
:
对于我的每个环境(非prod,prod),我正在寻找这些模块,并将terraform状态存储在远程s3存储桶中 - 每个环境一个存储桶。
我为每个环境提供必要的变量,如subnet_cidrs,VPC名称等等,并创建环境:VPC有相关的子网,其中包含相关的EC2实例......一切都很好!
当我来添加安全组(我在各种类型的EC2实例和环境中有许多安全组)及其各自的规则时,我遇到了挑战。
虽然我可以在合适的sec_group.tf文件中创建规则库并添加出口/入口规则(每个规则都带有from_port,to_port,protocol,cidr_blocks ..)我想知道是否可以基于a生成信息( json)哈希的数据?
我的想法是,这个全局数据层次结构可用于保存规则,并且可以进行处理以收集每个环境的相关规则,并仅应用与“terraform apply”正在运行的当前环境相关的规则,有2或200条规则。像这样:
non-prod-env:
ssh:
from_port: 22
to_port: 22
protocol: "tcp"
cidr_blocks:
- 10.1.1.1
- 10.2.2.2
:
:
smtp:
from_port: 25
to_port: 25
protocol: "tcp"
cidr_blocks:
- 100.1.1.1
- 100.2.2.2
:
:
prod-env:
ssh:
from_port: 22
to_port: 22
protocol: "tcp"
cidr_blocks:
- 11.1.1.1
- 11.2.2.2
:
:
阅读了各种类型的变量(字符串,列表,地图)后,我不确定我所要求的是否可能,但它将允许所有环境可以从中获取的集中式(全局)数据源。
我有兴趣知道以前是否有人考虑/调查过这种方法,或者是否有一种更简单的方法可能会丢失。
任何想法或意见都将不胜感激。
干杯
答案 0 :(得分:1)
Terraform尚不支持嵌套地图(terraform#2114),但您可以使用External Data Source从全局JSON文件中读取。
这里完全是一个选项,但我已经确定逻辑操作超出了HCL的设计目标,而更复杂的编排应该放入自定义提供程序中。 HCL计划应明确其所做的事情,而不是从外部资源中获取。以下是我处理ACL和安全组规则的方法:
ACL:
变量network_ssh_access
是此VPC允许的cidr块列表
variable network_ssh_access {
type = "list"
default = []
}
resource "aws_network_acl" "main" {
vpc_id = "${aws_vpc.main.id}"
}
resource "aws_network_acl_rule" "network_ssh_access" {
count = "${length(var.network_ssh_access)}"
network_acl_id = "${aws_network_acl.main.id}"
rule_number = "${200 + count.index}"
egress = false
protocol = "tcp"
rule_action = "allow"
cidr_block = "${element(var.network_ssh_access, count.index)}"
from_port = 22
to_port = 22
}
安全组:
变量appname_ssh_access
是应用程序允许的cidr块列表,名为" appname"
variable appname_ssh_access {
type = "list"
default = []
}
resource "aws_security_group" "appname" {
name = "appname"
}
resource "aws_security_group_rule" "allow_all" {
count = "${length(var.appname_ssh_access)}"
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = "${element(var.network_ssh_access, count.index)}"
security_group_id = "${aws_security_group.appname.id}"
}
然后,您将为剩余的端口和协议(邮件,http,https等)复制此模型。