terraform - 创建灵活的 terraform 模块以自定义可选参数时
问题描述
我想将几个资源放在一个 terrafrom 模块中。其中一个资源aws_ecs_service
有一些可选参数,我可能需要也可能不需要,我想在调用模块时传递值。
例如考虑ordered_placement_strategy
论点。一个服务可以有一个或多个ordered_placement_strategy。有些服务可能有也可能没有placement_constraints
。如何为 aws_ecs_service 编写灵活的通用模块。
resource "aws_ecs_service" "mongo" {
name = "mongodb"
cluster = aws_ecs_cluster.foo.id
task_definition = aws_ecs_task_definition.mongo.arn
desired_count = 3
iam_role = aws_iam_role.foo.arn
depends_on = [aws_iam_role_policy.foo]
ordered_placement_strategy {
type = "binpack"
field = "cpu"
}
load_balancer {
target_group_arn = aws_lb_target_group.foo.arn
container_name = "mongo"
container_port = 8080
}
placement_constraints {
type = "memberOf"
expression = "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]"
}
}
解决方案
看起来像是locals + dynamic blocks的可靠用例。
如果您已经了解模块中应支持的任务放置策略,这将有所帮助。您可以向最终用户公开输入变量,并使用它来相应地创建服务。
例如:假设我们要支持两种服务:
- 简单的
- 复杂的
我会首先定义一个带有这样验证的输入变量,以避免未知数:
variable "ecs_service_type" {
type = string
description = "What kind of service is this?"
validation {
condition = can(regex("^(simple|complex)$", var.ecs_service_type))
error_message = "The service type must be in (simple|complex)."
}
}
您可以使用以下本地值定义支持的任务放置策略和约束:
locals {
ordered_placement_strategy = {
simple = [
{
"field" : "instanceId",
"type" : "spread"
}
]
complex = [
{
type = "spread"
field = "attribute:ecs.availability-zone"
},
{
type = "spread"
field = "instanceId"
}
]
}
placement_constraints = {
simple = []
complex = [
{
type = "distinctInstance"
}
]
}
}
最后,使用动态块相应地创建服务:
resource "aws_ecs_service" "service" {
...
...
dynamic "ordered_placement_strategy" {
for_each = local.ordered_placement_strategy[var.ecs_service_type]
content {
type = ordered_placement_strategy.value.type
field = ordered_placement_strategy.value.field
}
}
dynamic "placement_constraints" {
for_each = local.placement_constraints[var.ecs_service_type]
content {
type = placement_constraints.value.type
}
}
}
PS:这段特定的代码没有经过测试,但我使用了类似的方法。如果您需要任何帮助,请告诉我。
推荐阅读
- angular - 是否可以跨多个子组件使用 cdk-drag-and-drop 指令?
- java - 参数的 Java 通配符
- javascript - 在 XPath 路径中指定可选元素?
- django - 我如何运行 django 项目?
- ios - SwiftUI:如何在没有 AppDelegate 的情况下强制景观
- regex - 尝试使用反向引用查找并替换为 sed,输出不是所需的结果
- python-3.x - 如何通过批处理文件执行 Python 代码并传递参数 - 使用 argparse
- javascript - 如何使用 React 和 React-Router 测试私有路由
- node.js - Parcel.js HMR & Socket.IO 冲突(新用户连接)
- python - 如何使用 Selenium 设置虚假的设备内存或 CPU 并发