Ваша инфраструктура, вероятно, содержит ресурсы, которые были созданы вне процесса «инфраструктура как код» (IaC). К счастью, если вы используете OpenTofu, вы можете легко импортировать эти ресурсы, используя либо CLI, либо блок import внутри вашей конфигурации.
В этой статье мы рассмотрим, что такое импорт в OpenTofu и когда его использовать, как импортировать ресурс с помощью CLI и блока import, лучшие практики импорта в OpenTofu, а также как управлять импортом в масштабе с помощью Spacelift.
- Импорт в OpenTofu переводит существующую инфраструктуру под управление OpenTofu, записывая её в файл состояния (state file) без изменения самого ресурса.
- Вы можете импортировать ресурсы двумя способами: CLI-команда tofu import обрабатывает по одному ресурсу за раз и записывает данные напрямую в состояние без предварительного просмотра. Блок import проверяется с помощью tofu plan и выполняется через tofu apply.
- CLI-команда tofu import обрабатывает по одному ресурсу за раз и записывает данные напрямую в состояние без предварительного просмотра.
- Блок import проверяется с помощью tofu plan и выполняется через tofu apply.
- Используйте блок import. Это рекомендуемый метод, который поддерживает for_each (начиная с OpenTofu 1.7+) и аргумент identity (начиная с OpenTofu 1.12+), а также оставляет запись в коде.
- Команда tofu plan -generate-config-out может написать конфигурацию ресурса за вас, но она является экспериментальной и не работает с for_each.
- Находите ID импорта для каждого ресурса в разделе «Import» на странице соответствующего ресурса в реестре OpenTofu.
Что такое импорт в OpenTofu и когда его использовать?
С помощью импорта в OpenTofu вы привязываете ресурс инфраструктуры в вашем провайдере к ресурсу OpenTofu. Если импорт прошел успешно, ваш файл состояния будет содержать запись об атрибутах этого объекта, и вы сможете управлять его жизненным циклом через OpenTofu, как и любым другим ресурсом, созданным непосредственно через него.
Вам потребуется использовать импорт OpenTofu всякий раз, когда инфраструктура существует вне вашей конфигурации OpenTofu. Вот наиболее распространенные сценарии использования:
- Вы создали инфраструктуру вручную или с помощью пользовательских скриптов.
- Вы хотите мигрировать с других инструментов, таких как CloudFormation, Pulumi, Crossplane или Azure Bicep.
- Восстановление состояния, которое произошло из-за случайного удаления или повреждения.
- Разделение состояния, когда у вас есть большой стек и вам нужно переместить объекты в меньшие конфигурации.
- Экстренные изменения, выполненные вручную.
OpenTofu предоставляет два механизма для реализации импорта ресурсов:
Использование CLI-команды tofu import
Использование CLI-команды tofu import было первоначальным подходом, унаследованным от Terraform. Если вы используете эту команду с адресом ресурса OpenTofu и ID из вашего облачного провайдера, она немедленно запишет данные в ваш файл состояния. Однако у вас не будет этапа планирования, предварительного просмотра или утверждения.
Использование блока import
Блок import — это импорт на основе конфигурации, который вы прописываете в своих файлах OpenTofu. Он оценивается во время выполнения tofu plan, показывая вам точно, что произойдет, а сам импорт выполняется во время tofu apply.
Блок import доступен начиная с OpenTofu 1.6. Он получил поддержку for_each в OpenTofu 1.7 и аргумент identity в OpenTofu 1.12.
Примечание: Аргумент identity полезен для ресурсов, идентификатор которых представляет собой составной ключ.
Перед выполнением импорта в OpenTofu вам нужно убедиться, что вы используете версию OpenTofu, которая поддерживает необходимые вам возможности импорта.
Вам нужно будет настроить провайдера, удаленный бэкенд (если вы работаете в производственной среде) и обеспечить доступ на чтение к ресурсам. Вы также должны убедиться, что тип ресурса поддерживает импорт (эта информация есть в документации).
Как найти правильный ID импорта для вашего ресурса
Некоторые ресурсы импортируются просто по их ID, например, инстанс EC2. Другие, такие как группа безопасности, будут иметь составной ключ (в этом случае вам понадобятся ID группы безопасности, тип правила, протокол, порты и источник, соединенные подчеркиваниями).
В любом случае, вам всегда следует проверять раздел «Import» ресурса в нижней части соответствующей страницы в документации провайдера в реестре OpenTofu. Для своих ресурсов вы также можете использовать CLI облачного провайдера, чтобы найти их фактические ID и другие параметры, не заходя в консоль.
Если вы хотите увидеть, как использовать terraform import (tofu import работает почти так же, с заменой бинарного файла и некоторыми дополнительными параметрами), вы можете посмотреть это видео:
Метод 1: Импорт ресурса с помощью CLI-команды tofu import
Давайте теперь рассмотрим, как использовать подход CLI для импорта ресурса в OpenTofu.
Базовый синтаксис
Чтобы узнать, какие параметры вы можете использовать, вы можете запустить:
ADDR — это любой допустимый адрес ресурса, что означает, что вы можете использовать импорт OpenTofu для ресурсов в корневом модуле, внутри модуля или даже для конкретных экземпляров ресурсов, если вы используете count или for_each. Как упоминалось ранее, ID — это просто специфичный для провайдера ID импорта.
Пошаговый пример
Теперь давайте рассмотрим пример. В этом случае я создам S3-бакет с помощью CLI:
После успешного создания бакета давайте создадим конфигурацию OpenTofu, которая импортирует этот ресурс:
Теперь я инициализирую конфигурацию с помощью tofu init. Как указано в документации, вам нужно использовать имя бакета в качестве ID.
Давайте теперь импортируем ресурс:
Чтобы проверить импорт, мы можем использовать tofu state list. Например:
В то же время мы можем запустить tofu plan, чтобы увидеть, нужно ли нам вносить какие-либо изменения в нашу конфигурацию:
Флаги импорта CLI, которые стоит знать
При запуске tofu import --help вы получите список всех поддерживаемых флагов, которые можно использовать с командой импорта. Имейте в виду, что все эти флаги являются необязательными.
Наиболее важные из них:
- -config=path: Это путь к каталогу, содержащему конфигурацию OpenTofu, которая настраивает провайдера (по умолчанию используется рабочий каталог).
- -var 'name=value' и -var-file=file.tfvars: Это помогает вам задать входные переменные.
- -no-color: Полезно в логах CI.
- -input=false: Предотвращает интерактивные запросы OpenTofu.
Импорт в модули, count и экземпляры ресурсов for_each через CLI
Любой адрес ресурса является допустимым, поэтому давайте рассмотрим, как импортировать ресурсы в модули, count и for_each.
Предположим, у вас есть модуль под названием networking, и в нем есть aws_vpc под названием main.
Команда будет выглядеть примерно так:
Теперь предположим, что у вас есть ресурс aws_vpc под названием main с установленным параметром count. Команда импорта будет выглядеть так:
Аналогично, предположим, что у вас есть тот же ресурс aws_vpc, но на этот раз с установленным параметром for_each. Команда импорта будет выглядеть так:
В некоторых операционных системах вам может потребоваться экранировать двойные кавычки в имени ресурса с помощью обратной косой черты, как мы сделали здесь:
Ограничения импорта через CLI
Использование импорта через CLI имеет реальные недостатки, поэтому рекомендуется использовать блок import.
Вот некоторые из ключевых ограничений:
- У вас есть один объект на вызов, поэтому, если вам нужно импортировать 50 ресурсов, вам придется запускать команду 50 раз.
- Предварительного просмотра нет, поэтому эта команда фактически напрямую изменяет состояние. Если вы укажете неверный адрес, вам придется удалить этот ресурс из состояния, а затем добавить правильный.
- Генерация конфигурации отсутствует, поэтому вам придется писать каждый блок ресурса вручную (вы могли бы потенциально использовать tofu state show для обратной разработки).
- В коде нет записи, поэтому через полгода вы не будете знать, был ли ресурс импортирован или создан.
- Это плохо сочетается с CI/CD конвейерами, поскольку импорт ресурса в ваш код OpenTofu требует изменения конвейера для добавления шага импорта. Затем вам нужно будет удалить его после однократного выполнения.
Блок import — это рекомендуемый способ импорта ресурса, и на то есть веские причины. Блок import решает все вышеперечисленные проблемы, и поскольку каждый блок является кодом в вашей конфигурации, он проходит проверку, планирование и его легко увидеть в истории.
Он отлично работает с любым типом адреса ресурса, поэтому вы по-прежнему можете использовать модули, count и for_each.
Базовый синтаксис
Блок import может находиться в любом файле HCL в вашей конфигурации, но лучшей практикой является наличие выделенного файла imports.tf или размещение блока рядом с ресурсом, в который вы будете выполнять импорт.
Аргумент to
Аргумент to — это ресурс, в который вы будете выполнять импорт. Таким образом, для нашего примера с бакетом это будет адрес ресурса бакета, то есть в нашем случае: aws_s3_bucket.my_bucket.
Блок import активен только тогда, когда OpenTofu еще не отслеживает объект по адресу в to. Поэтому после завершения импорта вы можете сохранить блок для истории или удалить его, если хотите.
Аргумент id против более нового аргумента identity
Аргумент id и аргумент identity помогают отслеживать, какой объект вы хотите импортировать в OpenTofu. Первый — это устаревший подход: одна строка в формате, который ожидает провайдер, в то время как второй (добавленный в OpenTofu 1.12) определяет ресурс с использованием объекта, атрибуты которого взяты из схемы идентификации типа ресурса (в документации).
Например, импорт того же бакета S3 выглядел бы так:
Аргумент provider
Если вы используете несколько провайдеров в своей конфигурации OpenTofu с псевдонимами, вы можете легко использовать мета-аргумент provider, чтобы указать, какой провайдер следует использовать при импорте ресурса.
Давайте рассмотрим простой пример:
Это укажет блоку import, что он должен использовать конфигурацию от провайдера import для проверки этого бакета и импорта его с использованием этих учетных данных.
Пошаговый пример
Для пошагового примера мы можем повторно использовать один из примеров кода выше. Давайте сначала выберем самый простой:
Во-первых, вам нужно убедиться, что вы удалили предыдущую конфигурацию, и самый простой способ сделать это — фактически удалить каталог .terraform, файл .terraform.lock.hcl, файл terraform.tfstate, а также файл terraform.tfstate.backup.
Конечно, если вы начинаете с нуля, вам не нужно ничего из этого делать. В любом случае, сначала вам нужно будет запустить tofu init, а затем вы сможете запустить tofu plan, чтобы увидеть, как произойдет импорт:
Как видите, план говорит, что есть один ресурс для импорта, и он показывает вам параметры этого ресурса. Если вы запустите tofu apply, ресурс будет импортирован:
Теперь импорт завершен, и если вы запустите tofu apply еще раз, не удаляя блок import, это не окажет никакого влияния:
Импорт нескольких ресурсов с помощью for_each в блоке import
Давайте изучим, как импортировать несколько ресурсов с помощью for_each. Для этого я создам второй бакет с помощью AWS CLI:
Теперь давайте посмотрим, как будет выглядеть конфигурация:
Я объявил переменную, содержащую bucket_names, ресурс с for_each на основе этой переменной, и в блоке import я добавил мета-аргумент for_each на основе той же переменной.
Когда я ссылаюсь на адрес ресурса в аргументе to, я также использую в нем each.value, чтобы сообщить OpenTofu, что мне нужен экземпляр этого ресурса.
Далее вам нужно будет пройти рабочий процесс tofu init/plan/apply, и ресурсы будут импортированы:
Почему блоки import являются рекомендуемым подходом?
Блоки import являются рекомендуемым подходом, потому что они устраняют все ограничения команды CLI tofu import. С блоком import:
- У вас есть история ресурса (вы знаете, был ли он импортирован или создан OpenTofu).
- Вы можете импортировать несколько ресурсов с помощью одного блока, если используете аргумент for_each.
- У вас есть предварительный просмотр того, что произойдет, потому что вы используете tofu plan перед внесением каких-либо изменений, что делает процесс удобным для CI.
- Вы также можете генерировать конфигурацию автоматически, без необходимости писать код ресурса (мы рассмотрим это в следующем разделе).
Давайте теперь посмотрим, как автоматически генерировать конфигурацию, используя параметр -generate-config-out.
Примечание: это не работает для ресурсов, которые используют for_each или count, и эта функция все еще является экспериментальной.
Вот как выглядит конфигурация:
Сначала вам нужно будет снова запустить tofu init, а затем вы запустите:
Для бакетов S3 вы можете увидеть что-то вроде этого:
Удалите bucket_prefix из сгенерированного файла и снова запустите tofu plan:
Вот некоторые из наиболее распространенных ошибок импорта, с которыми вы столкнетесь:
- Конфигурация для цели импорта не существует: это происходит потому, что вы написали блок import без соответствующего блока ресурса и не использовали -generate-config-out.
- Невозможно импортировать несуществующий удаленный объект: это происходит потому, что ID ресурса, который вы хотите использовать, не существует (или вы просто допустили опечатку). Чтобы убедиться, что вы указали правильный ID, который ожидает OpenTofu, всегда используйте документацию ресурса и ищите раздел импорта.
- Ресурс уже управляется OpenTofu: если у вас уже есть что-то в состоянии по тому же адресу ресурса, импорт не сработает. Вам следует использовать команды tofu state list/show и выяснить, что происходит, а затем выбрать другой адрес.
- Ресурс не поддерживает импорт: некоторые ресурсы не имеют логики импорта, реализованной в провайдере, поэтому всегда проверяйте документацию перед началом импорта ресурса.
Самая важная лучшая практика для импорта ресурсов в OpenTofu — это использование блоков import. Многие ограничения команды CLI import решаются простым использованием блока import вместо нее.
Вы всегда должны использовать удаленное состояние для своих конфигураций OpenTofu, независимо от размера вашей команды. Ниже приведены некоторые другие лучшие практики:
- Включите версионирование состояния перед запуском tofu import, так как вам может потребоваться откат к предыдущей версии состояния.
- Старайтесь импортировать свои ресурсы небольшими партиями, используя свой рабочий процесс CI (можно просмотреть до 20 ресурсов в запросе на слияние, но не сотни).
- Вы всегда должны относиться к сгенерированной конфигурации как к черновику. Удалите атрибуты null и значения по умолчанию перед фиксацией этого кода и помните, что это все еще экспериментальная функция в OpenTofu 1.12.
- Используйте атрибут identity там, где он поддерживается. Вы получите более высокую гранулярность, чем при использовании id.
- Проверяйте импорт так же, как вы проверяете любые другие изменения.
Импорт сотен ресурсов в нескольких учетных записях с участием нескольких команд может стать обременительным. Управление общим процессом CI/CD для классических операций OpenTofu в масштабе чревато ошибками, а добавление импорта может легко превратить это в кошмар.
Вам нужна платформа для оркестрации инфраструктуры, которая обеспечивает контрольный журнал, учетные данные, которые не хранятся на чьем-то компьютере, этап проверки с утверждениями перед изменением состояния и политики, гарантирующие, что импортированные ресурсы соответствуют границам вашей организации.
Spacelift — это платформа для оркестрации инфраструктуры, которая поддерживает OpenTofu, Terraform, Terragrunt, Pulumi, CloudFormation, Ansible и Kubernetes.
Что касается именно импорта в OpenTofu, вы получаете облачные интеграции, которые выдают краткосрочные учетные данные для каждого запуска, контрольный журнал, который помогает понять, что произошло, и политику как код на основе OPA, чтобы вы могли определить, сколько утверждений вам нужно для запусков, какие типы ресурсов могут быть созданы и какие параметры они могут иметь, куда отправлять уведомления и многое другое.
Поскольку блок import будет проходить через ваш обычный процесс GitOps, вы можете использовать все возможности Spacelift, что делает импорт ресурсов в масштабе управляемым.
Если вы хотите узнать больше о том, как Spacelift может помочь вам с импортом ресурсов, запишитесь на демонстрацию с одним из наших инженеров.
Импорт ресурсов в OpenTofu — это стандартный процесс при работе с инфраструктурой. Ресурсы иногда создаются вне вашего обычного процесса IaC, поэтому вам нужно что-то, что поможет вам добавить этот ресурс в ваше состояние. Импорт ресурса не изменит его, пока вы не примените конфигурацию, которая его изменит.
Вам всегда следует использовать блок import вместо команды CLI, потому что он позволяет обрабатывать операцию импорта так же, как операцию создания/изменения/удаления.
Часто задаваемые вопросы
- В чем разница между tofu import и блоком import? Команда tofu import импортирует один ресурс за запуск и записывает его непосредственно в состояние без плана или предварительного просмотра. Блок import находится в вашей конфигурации, поэтому импортируемые ресурсы отображаются в tofu plan, запускаются во время tofu apply, поддерживают for_each и могут генерировать конфигурацию.
В чем разница между tofu import и блоком import?
Команда tofu import импортирует один ресурс за запуск и записывает его непосредственно в состояние без плана или предварительного просмотра. Блок import находится в вашей конфигурации, поэтому импортируемые ресурсы отображаются в tofu plan, запускаются во время tofu apply, поддерживают for_each и могут генерировать конфигурацию.
- В чем разница между tofu import и terraform import? Оба привязывают существующий объект инфраструктуры к адресу ресурса в состоянии. OpenTofu унаследовал эту команду от Terraform, поэтому tofu import работает почти так же, с заменой бинарного файла и несколькими дополнительными параметрами.
В чем разница между tofu import и terraform import?
Оба привязывают существующий объект инфраструктуры к адресу ресурса в состоянии. OpenTofu унаследовал эту команду от Terraform, поэтому tofu import работает почти так же, с заменой бинарного файла и несколькими дополнительными параметрами.
- Может ли OpenTofu автоматически генерировать конфигурацию при импорте? Да. Запуск tofu plan -generate-config-out=<file> с блоками import записывает HCL для ресурсов, которых еще нет в вашей конфигурации, но эта функция является экспериментальной, не работает с for_each или count, а ее вывод следует рассматривать как черновик.
Может ли OpenTofu автоматически генерировать конфигурацию при импорте?
Да. Запуск tofu plan -generate-config-out=<file> с блоками import записывает HCL для ресурсов, которых еще нет в вашей конфигурации, но эта функция является экспериментальной, не работает с for_each или count, а ее вывод следует рассматривать как черновик.
- Поддерживает ли OpenTofu импорт всех ресурсов? Нет. Поддержка импорта зависит от того, реализовал ли провайдер ее для этого типа ресурса, поэтому перед началом проверьте раздел «Import» на странице ресурса в OpenTofu Registry.
Поддерживает ли OpenTofu импорт всех ресурсов?
Нет. Поддержка импорта зависит от того, реализовал ли провайдер ее для этого типа ресурса, поэтому перед началом проверьте раздел «Import» на странице ресурса в OpenTofu Registry.
![Как импортировать существующие ресурсы в OpenTofu [Руководство]](/_next/image?url=%2Fapi%2Fuploads%2Farticles%2F959228ac34584bfc1a7416d4541e12d8.webp&w=1920&q=75)











