Лучшие практики Terraform - избегайте дублирования - PullRequest
0 голосов
/ 30 октября 2018

Я подумываю о переходе некоторых наших инфраструктурных кодов на Terraform, так как мы столкнулись с проблемой AWS CloudFormation.

Позвольте мне привести пример того, чего я пытаюсь достичь. У меня есть кластер ECS, который может выполнять более 10 различных определений задач. Каждое определение задачи содержит практически одинаковые конфигурации, поэтому во избежание дублирования кода я создаю модуль многократного использования.

Из того, что я понял, есть 3 основных способа структурирования ваших каталогов terraform.

1

project
├── modules
|      ├─ ecs
|            ├── main.tf
|            ├── variables.tf
|            ├── task
|                 ├── main.tf
|                 ├── variables.tf
|
|
└── env
|       ├─── dev.tfvars
|       ├─── prod.tfvars
|       ├─── stage.tfvars
|       ├─── 10+   
|
|
|── main.tf 
|── variable.tf

С этой структурой мне нужно было бы получить переменные из папки env и передать ее с -var-files="env/dev.tfvars", а затем в моем main.tf мне пришлось бы передать переменную в modules / ecs / task / main.tf что кажется длинным путем, и много шагов, чтобы получить переменную в ecs / task / main.tf

2

project
├── modules
|       ├─ ecs
|            ├── main.tf
|            ├── variables.tf
|            ├── task
|                ├── main.tf
|                ├── variables.tf
|
|
└── stage
|    ├─── main.tf    
|    ├─── variable.tf
|    ├─── stage.tfvars 
|
└── dev
|    ├─── main.tf    
|    ├─── variable.tf
|    ├─── dev.tfvars
|
└── 10+
|   ├─── main.tf    
|   ├─── variable.tf
|   ├─── X.tfvars

Если вы хотите применить переменные окружения к modules/ecs/task/main.tf, вам придется начинать с main.tf, например, на этапе, который вызывает modules/ecs/main.tf. и оттуда примените его через /modules/ecs/main.tf, который затем применяет его к /modules/ecs/task/main.tf.

Проблема с этим подходом также заключается в том, что всякий раз, когда я добавляю новый модуль, мне нужно было бы добавить его ко всем различным средам main.tf

3.

project
├── modules
|         ├── ecs
|       ├── main.tf
|       ├── variables.tf
|       ├── task
|            ├── main.tf
|                    ├── variables.tf
|
|
|
|
|──  main.tf 
|── variable.tf

Используя рабочие пространства terraform, я могу использовать локальные файлы в файле modules / ecs / task / variables.tf, чтобы определить, какую среду я создаю. Как это:

modules/ecs/task.variables.tf

locals {

env="${terraform.workspace}"

masterAccountIDS = {

"default"="12121212"

"dev"="84848484"

}



masterAccountID="${lookup(local.masterAccountIDS, local.env)}"

}

Но для этого потребуется каждый раз, когда я добавляю новую среду, я просматриваю все мои файлы variables.tf и добавляю новую запись, которая называется, например, "stage".

Я не могу найти способ, который позволил бы мне не копировать код вставки или вставлять новые элементы при добавлении новых сред или хранить все это в одном месте, поэтому мне, возможно, придется редактировать только один файл.

1 Ответ

0 голосов
/ 31 октября 2018

Использование рабочих мест - лучший выбор на данный момент. Я использую что-то вроде ниже, чтобы управлять всеми переменными в одном месте -

defaults.tf -

/* DEFAULT VARIABLES */

locals {
  tags = {
      Project = "${var.project}"
      Contact = "vivek@vivekyadav.me"
      Requester = "Vivek"
      Creator = "Vivek"
      ManagedBy = "TF"
      Environ = "${local.workspace["environ"]}"
   }
}

locals {
  meta = {
      name_prefix = "hpy-${local.workspace["environ"]}-${local.workspace["project_name"]}"
      account_id = "${local.workspace["account_id"]}"
      region_name = "${local.workspace["region_name"]}"
   }
}

/* CUSTOM VARIABLES - ENVIRONMENT SPECIFIC */

################  DEFAULT LOCALS - DEFINE ENV VARIABLES FOR APP  #################
locals {
  env = {
    default = {
      project_name = "${var.project}"
      region_name = "${var.region}"
      environ = "dev"
      account_id = "356******001"
    }
    default_list = {
    }

################  DEV LOCALS - DEFINE ENV VARIABLES FOR APP  #################

    dev = {
      environ = "dev"
    }
    dev_list = {
    }

################  UAT LOCALS - DEFINE ENV VARIABLES FOR APP  #################

    uat = {
      environ = "uat"
    }
    uat_list = {
    }

################  PREP LOCALS - DEFINE ENV VARIABLES FOR APP  #################

    prep = {
      environ = "prep"
    }
    prep_list = {
    }

################  PRD LOCALS - DEFINE ENV VARIABLES FOR APP  #################

    prod = {
      environ = "prod"
      account_id = "3621****8334"
    }
    prod_list = {
    }

  }

################  EXPORTING ENV/WORKSPACE VARIABLES FOR APP  #################

  workspace = "${merge(local.env["default"], local.env[terraform.workspace])}"
  workspace_lists= "${merge(local.env["default_list"], local.env[format("%v_list",terraform.workspace)])}"
}

Теперь вы можете вызывать вышеуказанные переменные в своем основном определении -

main.tf -

module "s3" {
  source = "s3"
  tags = "${local.tags}"
  meta = "${local.meta}"
  workspace = "${local.workspace}"
  workspace_list = "${local.workspace_list}"
}

Теперь вы можете вызывать определенные переменные внутри модулей, как показано ниже -

"${var.workspace["environ"]}"

PS - Это обходной путь, но работает очень хорошо, как если бы сейчас. Terraform должен предоставить что-то из коробки для управления этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...