Как обработать странный поток API с неявным шагом создания в пользовательском поставщике terraform - PullRequest
1 голос
/ 04 октября 2019

Большинство провайдеров terraform требуют предопределенного потока: Create / Read / Update / Delete / Exists

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

Существует два вида ресурсов: Host и Scope. Хост может иметь много областей. Области обновляются с помощью конфигураций.

Как правило, это хорошо вписывается в поток terraform, у него возможен полный поток CRUDE - за исключением одного экземпляра.

Когда создается новый хост, он автоматическик нему прилагается область по умолчанию. Он всегда есть, его нельзя удалить и т. Д.

Я не могу понять, как заставить моего провайдера изящно с этим справиться, так как я бы хотел, чтобы tf относился к нему как к любому другому ресурсу, но это не такиметь явное CREATE / DELETE, только READ / UPDATE / EXISTS - но любая другая область, присоединенная к хосту, будет иметь CREATE / DELETE.

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

Первоначально я собирался попытаться разделить области и конфигурации на отдельные ресурсы, чтобы один мог быть полностью заполнен хостом (хост, предоставляющий идентификатор области для конфигурации, а затем другиеконфигурации могут получить свои идентификаторы области из ресурса области)

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

Перефразированный пример выполнения, о котором я подумал, о реализации

resource "host" "test_integrations" {
    name = "test.integrations.domain.com"
    account_hash = "${local.integrationAccountHash}"
    services = [40]

}

resource "configuration" "test_integrations_root_configuration" {
    name = "root"
    parent_host = "${host.test_integrations.id}"
    account_hash = "${local.integrationAccountHash}"
    scope_id = "${host.test_integrations.root_scope_id}"
    hostnames = ["test.integrations.domain.com"]
}

resource "scope" "test_integrations_other" {
    account_hash = "${local.integrationAccountHash}"
    host_hash = "${host.test_integrations.id}"
    path = "/non/root/path"
    name = "Some Other URI Path"
}

resource "configuration" "test_integrations_other_configuration" {
    name = "other"
    parent_host = "${host.test_integrations.id}"
    account_hash = "${local.integrationAccountHash}"
    scope_id = "${host.test_integrations_other.id}"
}

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

Но я не могу понять, как жизненный цикл TF позволил быдля ресурса, который будет ОБНОВЛЯТЬ / ЧИТАТЬ / СУЩЕСТВУЕТ, если, скажем, был задан флаг (и как это будет обрабатывать состояние)

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

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

Документация для провайдеров подразумевает, что вы можете использовать ресурс в качестве объекта схемы вресурс, но не объясняет, как и почему. Если это работает так, как я себе это представляю, это может сработать для создания ресурса, который, возможно, используется только для внедрения в хост, но я не знаю, так ли это работает и как это сделать.

1 Ответ

0 голосов
/ 09 октября 2019

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

Используя Поставщик AWS по умолчанию VPC в качестве ссылки, я могу "клонировать" ресурс в одинс пользовательским жизненным циклом создания / удаления

Свободный пример:

func defaultResourceConfiguration() *schema.Resource {
    drc := resourceConfiguration()
    drc.Create = resourceDefaultConfigurationCreate
    drc.Delete = resourceDefaultConfigurationDelete

    return drc
}

func resourceDefaultConfigurationCreate(d *schema.ResourceData, m interface{}) error {
    // double check it exists and update the resource instead
    return resourceConfigurationUpdate(d, m)
}

func resourceDefaultConfigurationDelete(d *schema.ResourceData, m interface{}) error {
    log.Printf("[WARN] Cannot destroy Default Scope Configuration. Terraform will remove this resource from the state file, however resources may remain.")
    return nil
}

Это должно позволить мне предоставить идентичный ресурс, предназначенный для взаимодействия с уже существующим ресурсом, созданным его родительским хостом.

...