我正在尝试使用ECS的terraform模块。问题是,对于某些应用程序,我需要在任务定义中定义一个EFS卷,而在另一些应用程序中,我根本不需要它。我需要一种有条件地添加卷块的方法。我尝试过嵌套动态块,但无法让它们工作。
下面是动态嵌套卷配置块:
dynamic "volume" {
for_each = var.volumes
content {
name = volume.key
host_path = volume.value.host_path
dynamic "efs_volume_configuration" {
for_each = volume.value.efs_volume_configuration
content {
file_system_id = efs_volume_configuration.value.file_system_id
dynamic "authorization_config" {
for_each = efs_volume_configuration.value.authorization_config
content {
access_point_id = authorization_config.value.access_point_id
iam = authorization_config.value.iam
}
}
}
}
}下面是我的变量(我已经更改了这么多次,但仍然不能正确):
variable "volumes" {
description = "(Optional) A set of volume blocks that containers in your task may use"
type = list(object({
host_path = string
name = string
efs_volume_configuration = list(object({
file_system_id = string
authorization_config = list(object({
access_point_id = string
iam = string
}))
}))
}))
default = []
}下面是我在应用程序中声明卷块的值的地方:
volumes = [{
name = "efs-storage-rasa"
host_path = "/model"
efs_volume_configuration = [{
file_system_id = aws_efs_file_system.filessystem.id
authorization_config = [{
access_point_id = aws_efs_access_point.filessystem_access_point.id
iam = "ENABLED"
}]
}]
}]注意事项:THis只是一个测试堆栈,我很快就把它拼凑在一起,看看是否能让它工作起来。我所需要的只是能够有条件地向ECS服务添加EFS卷块。我不想为ECS服务创建两个模块(一个用于需要卷,另一个用于卷不需要时),这是我可以避免的。
谢谢!
发布于 2022-04-06 19:40:33
我们的团队实际上也有同样的问题。下面是我们如何在资源声明中解决这个问题:
resource "aws_ecs_task_definition" "this" {
family = var.family # Naming our first task
requires_compatibilities = ["FARGATE"] # Stating that we are using ECS Fargate
network_mode = "awsvpc" # Using awsvpc as our network mode as this is required for Fargate
memory = var.task_memory # Specifying the hard limit of memory for our task
cpu = var.task_cpu # Specifying the hard limit of CPU for our task
execution_role_arn = var.ecs_task_exec_arn
task_role_arn = var.ecs_task_role_arn
# Created a policy in the templates folder
container_definitions = templatefile("${path.module}/templates/${var.template}.tmpl",
{
"name" = var.container_name
"username" = var.username
"password" = var.password
"region" = var.region
"memory" = var.container_memory
"cpu" = var.container_cpu
"container_path" = var.container_path
"source_volume" = var.source_volume
})
dynamic "volume" {
for_each = var.volume
content {
name = volume.value.source_volume
dynamic "efs_volume_configuration" {
for_each = volume.value.efs_volume_configuration
content {
file_system_id = efs_volume_configuration.value.efs_file_system_id
transit_encryption = efs_volume_configuration.value.transit_encryption
dynamic "authorization_config" {
for_each = efs_volume_configuration.value.authorization_config
content {
access_point_id = authorization_config.value.access_point_id
}
}
}
}
}
}
}下面是我们如何在模块调用中配置它:
volume = [
{
source_volume = "jenkins_home"
efs_volume_configuration = [
{
efs_file_system_id = module.jenkins-efs.efs_file_system_id
transit_encryption = "ENABLED"
authorization_config = [
{
access_point_id = module.jenkins-efs.efs_access_point_id
}
]
}
]
}
]下面是我们如何设置变量:
variable "efs_access_point_id" {
type = string
description = "The ID associated with the EFS access point."
default = null
}
variable "efs_file_system_id" {
type = string
description = "The ID associated with EFS."
default = null
}
variable "transit_encryption" {
type = string
description = "Whether or not to set transit encryption to ENABLE or DISABLED."
default = null
}
variable "transit_encryption_port" {
type = number
description = "Port used for transit encryption. 2049 for EFS."
default = null
}
variable "volume" {
description = "Used for a dynamic volume block for ECS service."
type = any
default = []
}
variable "load_balancer" {
description = "Used for a dynamic load balancer block for ECS service."
type = any
default = []
}对于只需要创建或不创建负载均衡器的一种服务,我们也采取了类似的方法:
resource "aws_ecs_service" "this" {
name = var.name
tags = var.tags
cluster = var.cluster
task_definition = aws_ecs_task_definition.this.arn # Referencing the task our service will spin up
launch_type = "FARGATE"
desired_count = var.desired_count # If number exceeds AZs, launches round robin (13 means 3 in AZ1, 2 in others with 6 subnets/AZs)
# load_balancer {
# target_group_arn = var.target_group_arn
# container_name = var.container_name
# container_port = var.container_port # This port must be exposed by the underlying container and should be used for health checks
# }
dynamic "load_balancer" {
for_each = var.load_balancer
content {
target_group_arn = load_balancer.value.target_group_arn
container_name = load_balancer.value.container_name
container_port = load_balancer.value.container_port
}
}
network_configuration {
subnets = var.subnets
assign_public_ip = var.assign_public_ip # Determines if our containers launch with public IPs
security_groups = ["${aws_security_group.service_security_group.id}"]
}
health_check_grace_period_seconds = var.health_check_grace_period
enable_execute_command = var.enable_execute_command # Enable AWS Exec to be used on Fargate containers as a break glass to retrieve configs
force_new_deployment = var.force_new_deployment # Require the service to create a new task so that break glass is activated
}下面是我们如何在我们的aws_ecs_service资源中调用它:
# Testing using a dynamic configuration block for load balancers
load_balancer = [
{
target_group_arn = module.alb-web.target_group_arns[0]
container_name = "test"
container_port = 443
}
]发布于 2021-07-06 22:38:03
你可以做这样的事。
dynamic "volume" {
for_each = var.volumes == null ? [] : [1]
content {
name = volume.key
host_path = volume.value.host_path
dynamic "efs_volume_configuration" {
for_each = volume.value.efs_volume_configuration
content {
file_system_id = efs_volume_configuration.value.file_system_id
dynamic "authorization_config" {
for_each = efs_volume_configuration.value.authorization_config
content {
access_point_id = authorization_config.value.access_point_id
iam = authorization_config.value.iam
}
}
}
}
}https://stackoverflow.com/questions/68272156
复制相似问题