创建灵活的地形模块以自定义可选参数时
When creating flexible terraform module to customize optional parameters
我想将一些资源放入 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:这段特定的代码没有经过测试,但我使用了类似的方法。如果您需要任何帮助,请告诉我。
我想将一些资源放入 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:这段特定的代码没有经过测试,但我使用了类似的方法。如果您需要任何帮助,请告诉我。