Разбиение монолита Terraform на несколько сред

Представьте, что некоторое время назад вы начали небольшой проект в terraform. А теперь у ваших приложений сотни клиентов, инфраструктура имеет несколько окружений, но все тот же монолит terraform отвечает за всю вашу облачную инфраструктуру. Звучит знакомо? Тогда продолжайте читать, и вы узнаете, как разбить монолит terraform на несколько окружений без рекреации ресурсов.


Аудитория

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

Теория

Давайте быстро вспомним, что мы знаем о состоянии terraform. Terraform хранит информацию о своих ресурсах в файле состояния. У Terraform есть несколько вариантов хранения файла состояния, самый популярный из которых, вероятно, находится в облачном хранилище объектов. Поэтому в качестве примера мы будем использовать S3.

Если мы хотим управлять окружениями отдельно, нам нужно иметь состояние для каждого окружения. Чтобы мы могли применять конфигурацию независимо друг от друга. Создание еще одного состояния не представляет собой большой проблемы. Сложная задача — перенести информацию об облачных ресурсах из одного состояния в другое. И сделать это без простоя или без необходимости воссоздавать ресурсы.

В начале у нас есть один каталог с кодом terraform для обеих сред. Наша цель — разделить код, а затем переместить записи о ресурсах из одного состояния в другое.

Теперь давайте договоримся о структуре файловой системы. Для целевого состояния мы будем использовать две отдельные директории. Эта схема очень хорошо объяснена здесь

Если вы хотите узнать больше о лучших практиках Terraform, я бы настоятельно рекомендовал взглянуть на руководство по лучшим практикам Terraform от Антона Бабенко.

Миграция в деталях

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

Далее вам нужно будет немного поработать с инструментом terraform. Вот что необходимо сделать

  1. Создайте новое состояние для нового окружения
  2. Извлеките файл состояния из удаленного бэкенда в свой локальный каталог
  3. Переместить соответствующие ресурсы из одного состояния в другое
  4. Наконец, переместите обновленное состояние для удаленного бэкенда.

Короткий пример

Если вы опытный пользователь terraform, то этот короткий пример для вас

cd dev

# now set up remote backend for this new env

terraform init
terraform state pull > new.tfstate

# now open your favourite text editor
# and move resource definitions from prod tf files to dev tf files

cd ../prod
terraform state list > resource_list.txt

# now open resource_list.txt
# and leave there only the resource that you want to move

for i in $(cat resource_list.txt); do
  terraform state mv -state-out=../dev/new.tfstate ${i} ${i}
done

cd ../dev
terraform state pull > new.tfstate
Вход в полноэкранный режим Выход из полноэкранного режима

Подробный пример

Существующая инфраструктура

Мы рассмотрим простой пример с двумя сетями VPC.

# prod/main.tf

resource "aws_vpc" "prod" {
  cidr_block = "10.0.0.0/24"
}

resource "aws_vpc" "dev" {
  cidr_block = "10.1.1.0/24"
}
Вход в полноэкранный режим Выход из полноэкранного режима

Конфигурация удаленного бэкенда выглядит следующим образом

# prod/provider.tf
terraform {
  required_version = "~> 1.0.0"

  backend "s3" {
    region = "eu-central-1"
    bucket = "myterraformstatemonolith"
    key    = "prod"
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Инициализация нового окружения

$ mkdir dev
$ cd dev
Вход в полноэкранный режим Выход из полноэкранного режима

Настройка удаленного бэкенда. Обратите внимание, что ключ изменился, вы также можете установить новый bucket, если хотите. Но сейчас для наших нужд достаточно отдельного файла состояния.

# dev/provider.tf
terraform {
  required_version = "~> 1.0.0"

  backend "s3" {
    region = "eu-central-1"
    bucket = "myterraformstatemonolith"
    key    = "dev"
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь запустите terraform init, это создаст файл в ведре S3.

$ terraform init

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.

<output omitted>
Войти в полноэкранный режим Выход из полноэкранного режима

Перемещение определений ресурсов

Теперь вам нужно переместить содержимое файлов terraform, относящихся к новому окружению. В моем случае мой новый dev/main.tf будет выглядеть следующим образом

resource "aws_vpc" "dev" {
cidr_block = "10.1.1.0/24"
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Переместить ресурсы из файла состояния в новый файл.

Это немного сложнее, чем предыдущие шаги. Сначала давайте вытащим новое удаленное состояние

$ cd dev
$ terraform state pull > new.tfstate
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем вернемся в каталог prod и переместим ресурсы

$ cd prod
$ terraform state list
aws_vpc.dev
aws_vpc.prod

$ terraform state mv -state-out=../dev/new.tfstate aws_vpc.dev aws_vpc.dev
Move "aws_vpc.dev" to "aws_vpc.dev"
Successfully moved 1 object(s).
Войти в полноэкранный режим Выйти из полноэкранного режима

Переместите обновленный файл состояния обратно в ведро S3

$ terraform state push new.tfstate
Войти в полноэкранный режим Выйти из полноэкранного режима

Вот и все, теперь убедитесь, что все обновлено

$ terraform plan
aws_vpc.dev: Refreshing state... [id=vpc-070562866e6399b45a]

No changes. Your infrastructure matches the configuration.
Войдите в полноэкранный режим Выйти из полноэкранного режима

Оцените статью
devanswers.ru
Добавить комментарий