Terraform 0.12 使用模板创建入口规则
Posted
技术标签:
【中文标题】Terraform 0.12 使用模板创建入口规则【英文标题】:Terraform 0.12 Creating ingress rules with template 【发布时间】:2020-06-03 12:39:06 【问题描述】:我想知道是否可以使用这样的东西。我有功能代码工作,但由于 kubernetes 中的 pod 会快速增长,我想转换为模板。这是为每个 wordpress 站点 pod 创建每个 nginx 入口规则的示例。
现在,每个 pod 都有其 wordpress 入口条目:
resource "kubernetes_ingress" "ingress_nginx_siteA"
metadata
name = "ingress-nginx-siteA"
namespace = "default"
annotations = "kubernetes.io/ingress.class" = "nginx", "nginx.ingress.kubernetes.io/configuration-snippet" = "modsecurity_rules '\n SecRuleEngine On\n SecRequestBodyAccess On\n SecAuditEngine RelevantOnly\n SecAuditLogParts ABCIJDEFHZ\n SecAuditLog /var/log/modsec_audit.log\n SecRuleRemoveById 932140\n';\n", "nginx.ingress.kubernetes.io/ssl-passthrough" = "true"
spec
tls
hosts = ["siteA.test.com"]
secret_name = "wildcard-test-com"
rule
host = "siteA.test.com"
http
path
path = "/"
backend
service_name = "siteA"
service_port = "80"
现在我想拆分成包含整个站点变量的 variables.tf、模板文件 rules.tpl 和 main.tf > 编排这些东西。
变量.tf:
variable "wordpress_site"
type = map(object(
name = string
url = string
certificate = string
))
default =
siteA =
name = siteA
url = siteA.test.com
certificate = wildcard-test-com
siteB =
name = siteB
url = siteB.test.com
certificate = wildcard-test-com
rules.tpl:
% for name in wordpress_site.name ~
resource "kubernetes_ingress" "ingress_nginx_$name"
metadata
name = "ingress-nginx-$name"
namespace = "default"
annotations = "kubernetes.io/ingress.class" = "nginx", "nginx.ingress.kubernetes.io/configuration-snippet" = "modsecurity_rules '\n SecRuleEngine On\n SecRequestBodyAccess On\n SecAuditEngine RelevantOnly\n SecAuditLogParts ABCIJDEFHZ\n SecAuditLog /var/log/modsec_audit.log\n SecRuleRemoveById 932140\n';\n", "nginx.ingress.kubernetes.io/ssl-passthrough" = "true"
spec
tls
hosts = ["$wordpress_site.url"]
secret_name = "$wordpress_site.certificate"
rule
host = "$wordpress_site.url"
http
path
path = "/"
backend
service_name = "$name"
service_port = "80"
% endfor ~
现在,在 main.tf 中,混合所有内容的最佳方法是什么?我看到在 TF 0.12 中添加了新功能,例如 templatefile 功能,但根本不知道我是否可以像这样使用它:
main.tf:
templatefile($path.module/rules.tpl, $module.var.wordpress_site)
感谢大家的支持!
【问题讨论】:
【参考方案1】:templatefile
函数用于从模板生成字符串,而不是用于生成 Terraform 配置。尽管可以渲染给定模板以生成包含 Terraform 配置的字符串,但 Terraform 只会将结果视为普通字符串,而不是要评估的更多配置。
相反,我们需要得到所需结果的是resource for_each
,它允许基于映射值从单个资源创建多个实例。
resource "kubernetes_ingress" "nginx"
for_each = var.wordpress_site
metadata
name = "ingress-nginx-$each.value.name"
namespace = "default"
annotations =
"kubernetes.io/ingress.class" = "nginx"
"nginx.ingress.kubernetes.io/configuration-snippet" = <<-EOT
modsecurity_rules '
SecRuleEngine On
SecRequestBodyAccess On
SecAuditEngine RelevantOnly
SecAuditLogParts ABCIJDEFHZ
SecAuditLog /var/log/modsec_audit.log
SecRuleRemoveById 932140
';
EOT
"nginx.ingress.kubernetes.io/ssl-passthrough" = "true"
spec
tls
hosts = [each.value.url]
secret_name = each.value.certificate
rule
host = each.value.url
http
path
path = "/"
backend
service_name = each.value.name
service_port = "80"
当资源设置了for_each
时,Terraform 将评估给定参数以获取地图,然后将为该地图中的每个元素创建一个资源实例,每个元素由其对应的地图键标识。在这种情况下,假设默认值为var.wordpress_site
,您将获得两个具有以下地址的实例:
kubernetes_ingress.nginx["siteA"]
kubernetes_ingress.nginx["siteB"]
在resource
块内,以each.value
开头的引用指的是地图中的值,在本例中是描述每个站点的对象。
【讨论】:
非常感谢@martin-atkins!我将调整代码并对其进行测试。我会带着结果回来的。以上是关于Terraform 0.12 使用模板创建入口规则的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Terraform 附加或删除安全组的入口/出口规则?
Terraform 0.12:桶的输出列表,用作另一个模块的输入并迭代