首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Terraform ECS任务定义-动态嵌套EFS卷

Terraform ECS任务定义-动态嵌套EFS卷
EN

Stack Overflow用户
提问于 2021-07-06 14:11:42
回答 2查看 720关注 0票数 1

我正在尝试使用ECS的terraform模块。问题是,对于某些应用程序,我需要在任务定义中定义一个EFS卷,而在另一些应用程序中,我根本不需要它。我需要一种有条件地添加卷块的方法。我尝试过嵌套动态块,但无法让它们工作。

下面是动态嵌套卷配置块:

代码语言:javascript
复制
  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
            }
          }
        }
      }
    }

下面是我的变量(我已经更改了这么多次,但仍然不能正确):

代码语言:javascript
复制
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 = []
}

下面是我在应用程序中声明卷块的值的地方:

代码语言:javascript
复制
  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服务创建两个模块(一个用于需要卷,另一个用于卷不需要时),这是我可以避免的。

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-04-06 19:40:33

我们的团队实际上也有同样的问题。下面是我们如何在资源声明中解决这个问题:

代码语言:javascript
复制
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
            }
          }
        }
      }
    }
  }
}

下面是我们如何在模块调用中配置它:

代码语言:javascript
复制
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
            }
          ]
        }
      ]
    }
  ]

下面是我们如何设置变量:

代码语言:javascript
复制
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     = []
}

对于只需要创建或不创建负载均衡器的一种服务,我们也采取了类似的方法:

代码语言:javascript
复制
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资源中调用它:

代码语言:javascript
复制
  # 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
    }
  ]
票数 0
EN

Stack Overflow用户

发布于 2021-07-06 22:38:03

你可以做这样的事。

代码语言:javascript
复制
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
            }
          }
        }
      }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68272156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档