为每个使用 terraform 版本从 0.12 升级到 0.13

using for each with terraform version upgrade from 0.12 to 0.13

我正在将 Terraform 的版本从 0.12 升级到 0.13。到目前为止,我能够通过更改提供者和我的模块来创建必要的部分。

service.tf

的现状
module "services" {
  source   = "../../modules/aws-ecs-servicev2"
  for_each = var.applications

  container_name               = each.value.container_name
  container_cpu                = each.value.container_cpu
  container_image              = each.value.container_image
  container_memory_total       = each.value.container_memory_total
  container_memory_reservation = each.value.container_memory_reservation
  deployment_max_percent       = each.value.deployment_max_percent
  deployment_min_healthy       = each.value.deployment_min_healthy
  container_host_port          = each.value.container_host_port
  container_port               = each.value.container_port
  command                      = each.value.command
  replica_count                = each.value.replica_count
  stage                        = each.value.stage
  alb_enabled                  = each.value.alb_enabled
  alb_subnets                  = module.vpc.public_subnets
  alb_https_enabled            = each.value.alb_https_enabled
  alb_ssl_arn                  = each.value.alb_ssl_arn
  health_check_path            = each.value.health_check_path
  internal_lb                  = each.value.health_check_path
  vault_key                    = each.value.vault_key
  vault_backend                = each.value.vault_backend
  cpu_based_autoscaling        = each.value.cpu_based_autoscaling
  target_cpu_value             = each.value.target_cpu_value
  max_capacity                 = each.value.max_capacity
  min_capacity                 = each.value.min_capacity
  scale_out_adjustment         = each.value.scale_out_adjustment
  scale_out_cooldown           = each.value.scale_out_cooldown
  scale_in_adjustment          = each.value.scale_in_adjustment
  scale_in_cooldown            = each.value.scale_in_cooldown
  disable_scale_in             = each.value.disable_scale_in
  ecs_arn                      = module.ecs.arn
  namespace                    = var.namespace
  sd_namespace_id              = aws_service_discovery_private_dns_namespace.default.id
  vpc_id                       = module.vpc.vpc_id
  health_check_response        = "200"
  alb_sgs                      = [aws_security_group.ecs_sg.id]
}

application.tf

variable "applications" {
  description = "Map for the services to be deployed"
  type        = any
  default = {
    service-a = {
      container_cpu                = 512
      container_image              = service-a-image:latest
      container_memory_total       = 2048
      container_memory_reservation = 1024
      container_name               = "service-a"
      command                      = null
      deployment_max_percent       = 200
      deployment_min_healthy       = 50
      container_host_port          = [0]
      container_port               = [80]
      replica_count                = 1
      stage                        = "dev"
      health_check_path            = null
      internal_lb                  = false
      vault_key                    = null
      vault_backend                = null
      alb_enabled                  = false
      alb_ssl_arn                  = null
      alb_https_enabled            = false
      cpu_based_autoscaling        = false
      target_cpu_value             = null
      max_capacity                 = null
      min_capacity                 = null
      scale_out_adjustment         = null
      scale_out_cooldown           = null
      scale_in_adjustment          = null
      scale_in_cooldown            = null
      disable_scale_in             = false
    }
  }
}

我想达到什么目的?

是否有可能以某种方式将默认值传递给一些变量,例如 health_check_path= null,这样我就不必担心在不需要这些值的服务中不包含这个。还有一些服务确实需要这样的值,然后我将从相同的变量中提供这些值。例子

    service-b = {
      container_name               = "service-b-container"
      container_cpu                = 1024
      container_image              = "service-b-image:latest"
      container_memory_total       = 1024
      container_memory_reservation = 1024
      deployment_max_percent       = 200
      deployment_min_healthy       = 50
      container_host_port          = [0]
      container_port               = [80]
      command                      = null
      replica_count                = 1
      stage                        = "dev"
      alb_enabled                  = true
      alb_https_enabled            = true
      alb_ssl_arn                  = "ssl-arn"
      health_check_response        = 200
      health_check_path            = "/status"
      internal_lb                  = false
      vault_key                    = "servia-b"
      vault_backend                = "service"
      cpu_based_autoscaling        = true
      target_cpu_value             = 40
      max_capacity                 = 8
      min_capacity                 = 1
      scale_out_adjustment         = 2
      scale_out_cooldown           = 60
      scale_in_adjustment          = 1
      scale_in_cooldown            = 300
      disable_scale_in             = false
    },

我尝试在变量部分中使用局部变量或任何其他此类变量,例如 follwing


variable "cpu" {
  type = number
  default = 1024
  description = "cpu to associate"
}

variable "applications" {
  description = "Map for the services to be deployed"
  type        = any
  default = {
  service-b = {
      container_name               = "service-b-container"
      container_cpu                = var.cpu
      container_image              = "service-b-image:latest"
      container_memory_total       = 1024
      container_memory_reservation = 1024
  },
  service-a = {
      container_name               = "service-a-container"
      container_cpu                = var.cpu
      container_image              = "service-b-image:latest"
      container_memory_total       = 1024
  }
 }
}

但事实证明 terraform 不允许这样做。为了详细说明这一点,让我在这里添加它的日志

Error: Variables not allowed

  on application.tf line 56, in variable "applications":
  56:       container_cpu        = var.cpu

Variables may not be used here.

如果我尝试不包括 services.tf 中存在的变量,则会出现以下错误

Acquiring state lock. This may take a few moments...                                                                                                                                                                                                                                                                                       
Refreshing Terraform state in-memory prior to plan...                                                                                                                                                                                                                                                                                      
The refreshed state will be used to calculate this plan, but will not be                                                                                                                                                                                                                                                                   
persisted to local or remote state storage.                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                           
module.services["service-a"].module.ecs_alb_service_task.data.aws_iam_policy_document.ecs_exec[0]: Refreshing state...                                                                                                                                                                                                            
module.services["service-a"].module.ecs_alb_service_task.data.aws_iam_policy_document.ecs_service_policy[0]: Refreshing state...                                                                                                                                                                                                  
module.services["service-a"].module.ecs_alb_service_task.data.aws_iam_policy_document.ecs_task_exec[0]: Refreshing state...                                                                                                                                                                                                       
module.services["service-a"].module.ecs_alb_service_task.data.aws_iam_policy_document.ecs_task[0]: Refreshing state...                                                                                                                                                                                                            
module.services["service-a"].module.ecs_alb_service_task.data.aws_iam_policy_document.ecs_service[0]: Refreshing state...                                                                                                                                                                                                         
module.vpc.aws_vpc.this[0]: Refreshing state... [id=vpc-0641c1d3435df195a]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
aws_service_discovery_private_dns_namespace.default: Refreshing state... [id=ns-vyggm2ltoxjufhfa]                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                           
Error: Unsupported attribute                                                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                                                                           
  on Service.tf line 22, in module "services":                                                                                                                                                                                                                                                                                             
  22:   alb_enabled                  = each.value.alb_enabled                                                                                                                                                                                                                                                                              
    |----------------                                                                                                                                                                                                                                                                                                                      
    | each.value is object with 12 attributes                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                           
This object does not have an attribute named "alb_enabled".                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                           
Error: Unsupported attribute                                                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                                                                           
  on Service.tf line 25, in module "services":                                                                                                                                                                                                                                                                                             
  25:   alb_https_enabled            = each.value.alb_https_enabled                                                                                                                                                                                                                                                                        
    |----------------                                                                                                                                                                                                                                                                                                                      
    | each.value is object with 12 attributes                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                           
This object does not have an attribute named "alb_https_enabled".                                                                                                                                                                                                                                                                          
                                                                      

有没有办法实现这个,因为有10多个服务需要这样部署,而且有些服务没有变量,有些需要。

选项 1。根据文档,这可能会有所帮助 - 声明一些特殊的对象类型,您可以在其中设置默认值: https://www.terraform.io/docs/configuration/variables.html#declaring-an-input-variable

选项 2 这也可能有帮助(还没有尝试过)- 使用默认值查找 https://www.terraform.io/docs/configuration/functions/lookup.html

选项 2 的简单示例:

子模块:

main.tf

resource "local_file" "simple_file" {
  filename = "file/${var.file_name}"
  content     = "foo!"
}

variables.tf

variable "file_name" {
  description = "file name"
}

根模块: main.tf

module "file" {
  source = "./child_module"
  for_each = var.applications
  file_name = lookup(each.value, "Not_existing_key", "default_value" )
}

default_value 在这种情况下用于子模块

terraform 版本 0.14.3