Различные среды для Terraform (Hashicorp)
Я использую Terraform для сборки своего стека AWS и наслаждаюсь им. Если он должен использоваться в коммерческих настройках, конфигурация должна быть повторно использована для разных сред (например, QA, STAGING, PROD).
Как я смогу добиться этого? Должен ли я создать оболочку script, которая вызывает вызовы terraform cli при передаче в разных файлах состояния для каждой среды, как показано ниже? Мне интересно, есть ли более естественное решение, предоставленное Terraform.
terraform apply -state=qa.tfstate
Ответы
Ответ 1
Я предлагаю вам взглянуть на репозиторий best-practices hashicorp, который имеет неплохую настройку для работы с разными средами (аналогично тому, что предложил Джеймс Вулфенден),
Мы используем аналогичную настройку, и она работает очень хорошо. Тем не менее, это передовой опыт репо предполагает, что вы используете Atlas, которого нет. Мы создали довольно сложный Rakefile, который в основном (перейдя на репозиторий лучших практик) получает все подпапки /terraform/providers/aws и предоставляет их как разные сборки с использованием пространств имен. Таким образом, наш вывод rake -T
отображает следующие задачи:
us_east_1_prod:init
us_east_1_prod:plan
us_east_1_prod:apply
us_east_1_staging:init
us_east_1_staging:plan
us_east_1_staging:apply
Это разделение предотвращает изменения, которые могут быть исключительными для того, чтобы dev случайно повлиял (или, что еще хуже, уничтожил) что-то в prod, так как это другой файл состояния. Он также позволяет тестировать изменения в dev/staging, прежде чем применять его к prod.
Кроме того, я недавно наткнулся на эту небольшую запись, которая в основном показывает, что может произойти, если вы будете держать все вместе:
https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/
Ответ 2
Решение Paul с модулями - правильная идея. Тем не менее, я настоятельно рекомендую не определять все ваши среды (например, QA, этап, производство) в том же файле Terraform. Если вы это сделаете, то всякий раз, когда вы делаете изменения в постановке, вы рискуете также случайным нарушением производства, что частично поражает точку, в которой эти среды изолированы в первую очередь! См. Terraform, VPC и почему вы хотите использовать файл tfstate для env для яркого обсуждения того, что может пойти не так.
Я всегда рекомендую хранить код Terraform для каждой среды в отдельной папке. Фактически, вы можете даже захотеть сохранить код Terraform для каждого "компонента" (например, базы данных, VPC, одного приложения) в отдельных папках. Опять же, причина заключается в изоляции: при внесении изменений в одно приложение (которое вы можете делать 10 раз в день), вы не хотите подвергать весь ваш VPC риску (который вы, вероятно, никогда не измените).
Поэтому мой типичный макет файла выглядит примерно так:
stage
└ vpc
└ main.tf
└ vars.tf
└ outputs.tf
└ app
└ db
prod
└ vpc
└ app
└ db
global
└ s3
└ iam
Весь код Terraform для промежуточной среды входит в папку stage
, весь код для среды prod входит в папку prod
и весь код, который живет за пределами среды (например, пользователи IAM, S3 ведра) переходит в папку global
.
Для получения дополнительной информации ознакомьтесь с Как управлять состоянием Terraform. Для более глубокого изучения лучших практик Terraform, посмотрите книгу Terraform: Up and Running.
Ответ 3
По мере расширения вашего использования terraform вам необходимо разделить состояние (между разработчиками, процессы сборки и различные проекты), поддерживать несколько сред и регионов.
Для этого вам нужно использовать удаленное состояние.
Перед тем, как выполнить свою терраформию, вам нужно настроить свое состояние.
(Im using powershell)
$environment="devtestexample"
$region ="eu-west-1"
$remote_state_bucket = "${environment}-terraform-state"
$bucket_key = "yoursharedobject.$region.tfstate"
aws s3 ls "s3://$remote_state_bucket"|out-null
if ($lastexitcode)
{
aws s3 mb "s3://$remote_state_bucket"
}
terraform remote config -backend S3 -backend-config="bucket=$remote_state_bucket" -backend-config="key=$bucket_key" -backend-config="region=$region"
#(see here: https://www.terraform.io/docs/commands/remote-config.html)
terraform apply -var='environment=$environment' -var='region=$region'
Ваше состояние теперь сохраняется в S3, по регионам, по среде, и вы можете получить доступ к этому состоянию в других проектах tf.
Ответ 4
Не нужно создавать обертку script. Что мы делаем, так это разделить наш env на модуль, а затем получить файл верхнего уровня, где мы просто импортируем этот модуль для каждой среды. Пока у вас есть настройка модуля, чтобы принимать достаточно переменных, как правило, env_name и несколько других, вы хороши. В качестве примера
# project/main.tf
module "dev" {
source "./env"
env = "dev"
aws_ssh_keyname = "dev_ssh"
}
module "stage" {
source "./env"
env = "stage"
aws_ssh_keyname = "stage_ssh"
}
# Then in project/env/main.tf
# All the resources would be defined in here
# along with variables for env and aws_ssh_keyname, etc.
Ответ 5
Обратите внимание, что начиная с версии 0.10.0 Terraform поддерживает концепцию Workspaces (среды в 0.9.x).
Рабочее пространство - это именованный контейнер для состояния Terraform. При использовании нескольких рабочих пространств единый каталог конфигурации Terraform может использоваться для управления несколькими различными наборами ресурсов инфраструктуры.
Подробнее см. здесь: https://www.terraform.io/docs/state/workspaces.html