Провайдер Pulumi, созданный с использованием pulumi-terraform-bridge, не обнаруживает изменения в вложенном списковом атрибуте от провайдера terraform-plugin-framework.

Вопрос или проблема

Здравствуйте, коллеги-разработчики,

Я столкнулся с проблемой при создании провайдера Pulumi с использованием pulumi-terraform-bridge. Провайдер не отображает отличия для изменений в конкретном поле, когда я пытаюсь обновить его с помощью pulumi up, хотя базовый провайдер Terraform работает корректно.

Вот контекст:

  1. Я создал провайдер Terraform (github.com/pgEdge/terraform-provider-pgedge) с использованием terraform-plugin-framework.
  2. Затем я создал провайдер Pulumi (github.com/pgEdge/pulumi-pgedge, ветка sync-v007) с использованием pulumi-terraform-bridge.

Проблема связана с полем “nodes” в моем ресурсе базы данных. Вот полная схема для поля “nodes”:

"nodes": schema.ListNestedAttribute{
    Description: "Список узлов в базе данных.",
    Computed:    true,
    Optional:    true,
    NestedObject: schema.NestedAttributeObject{
        Attributes: map[string]schema.Attribute{
            "name": schema.StringAttribute{
                Computed: true,
                Optional: true,
            },
            "connection": schema.SingleNestedAttribute{
                Computed: true,
                PlanModifiers: []planmodifier.Object{
                    objectplanmodifier.UseStateForUnknown(),
                },
                Attributes: map[string]schema.Attribute{
                    "database":            schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "host":                schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "password":            schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "port":                schema.Int64Attribute{Computed: true, PlanModifiers: []planmodifier.Int64{int64planmodifier.UseStateForUnknown()}},
                    "username":            schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "external_ip_address": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "internal_ip_address": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "internal_host":       schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                },
            },
            "location": schema.SingleNestedAttribute{
                Computed: true,
                PlanModifiers: []planmodifier.Object{
                    objectplanmodifier.UseStateForUnknown(),
                },
                Attributes: map[string]schema.Attribute{
                    "code":        schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "country":     schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "latitude":    schema.Float64Attribute{Computed: true, PlanModifiers: []planmodifier.Float64{float64planmodifier.UseStateForUnknown()}},
                    "longitude":   schema.Float64Attribute{Computed: true, PlanModifiers: []planmodifier.Float64{float64planmodifier.UseStateForUnknown()}},
                    "name":        schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "region":      schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "region_code": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "timezone":    schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "postal_code": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "metro_code":  schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "city":        schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                },
            },
            "region": schema.SingleNestedAttribute{
                Computed: true,
                PlanModifiers: []planmodifier.Object{
                    objectplanmodifier.UseStateForUnknown(),
                },
                Attributes: map[string]schema.Attribute{
                    "active":             schema.BoolAttribute{Computed: true, PlanModifiers: []planmodifier.Bool{boolplanmodifier.UseStateForUnknown()}},
                    "availability_zones": schema.ListAttribute{Computed: true, ElementType: types.StringType, PlanModifiers: []planmodifier.List{listplanmodifier.UseStateForUnknown()}},
                    "cloud":              schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "code":               schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "name":               schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                    "parent":             schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}},
                },
            },
            "extensions": schema.SingleNestedAttribute{
                Computed: true,
                PlanModifiers: []planmodifier.Object{
                    conditionalUseStateForUnknownModifier{},
                },
                Attributes: map[string]schema.Attribute{
                    "errors":    schema.MapAttribute{Computed: true, ElementType: types.StringType, PlanModifiers: []planmodifier.Map{mapplanmodifier.UseStateForUnknown()}},
                    "installed": schema.ListAttribute{Computed: true, ElementType: types.StringType, PlanModifiers: []planmodifier.List{listplanmodifier.UseStateForUnknown()}},
                },
            },
        },
    },
},

Ожидаемое поведение заключается в том, что при создании ресурса должны создаваться узлы, а затем удаление или добавление чего-то, например {name: "new_node"} в массив, должно вызвать обновление. Это работает корректно в провайдере Terraform.

Однако провайдер Pulumi вообще не обнаруживает никаких изменений в поле “nodes”, поэтому он не вызывает обновление при pulumi up. Я подтвердил, что узлы сохраняются корректно, но Pulumi не распознает изменения.

Вот мои вопросы:

  1. Связана ли эта проблема с использованием пользовательских модификаторов плана, особенно conditionalUseStateForUnknownModifier{} в атрибуте “extensions”?
  2. Полностью ли pulumi-terraform-bridge поддерживает пользовательские модификаторы плана из terraform-plugin-framework?
  3. Может ли обширное использование UseStateForUnknown() модификаторов плана привести к тому, что Pulumi игнорирует изменения в этих полях?
  4. Есть ли известные проблемы или ограничения при использовании pulumi-terraform-bridge с провайдерами, созданными с использованием terraform-plugin-framework?
  5. Как я могу дальше отладить это, чтобы понять, почему Pulumi не обнаруживает изменения?

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

Заранее благодарю за вашу помощь!

  1. Я создал провайдер Terraform с использованием terraform-plugin-framework с полем “nodes” как ListNestedAttribute.
  2. Затем я создал провайдер Pulumi, используя pulumi-terraform-bridge, оборачивая этот провайдер Terraform.
  3. В программе Pulumi я создал ресурс с начальным набором узлов.
  4. Затем я попытался обновить ресурс, добавив или удалив узлы из списка.

Что я ожидал:

  1. При создании ресурса я ожидал, что узлы будут созданы в соответствии с заданными параметрами.

  2. При изменении списка “nodes” (например, добавлении {name: “new_node”} или удалении существующего узла) я ожидал, что Pulumi обнаружит это изменение.

  3. При запуске pulumi up я ожидал увидеть отличия, показывающие изменения в списке “nodes”.

  4. Я ожидал, что Pulumi вызовет операцию обновления ресурса, чтобы применить эти изменения.

Ответ или решение

Здравствуйте,

Я понимаю, что вы столкнулись с проблемой при использовании Pulumi и pulumi-terraform-bridge, где изменения в атрибуте "nodes" не детектируются, несмотря на то, что все работает корректно в вашем Terraform-провайдере. Давайте разберемся с вашими вопросами и проблемой в целом.

1. Влияние кастомных модификаторов плана, особенно conditionalUseStateForUnknownModifier{}

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

2. Поддержка кастомных модификаторов плана в pulumi-terraform-bridge

На данный момент pulumi-terraform-bridge в значительной степени совместим с функциональностью terraform-plugin-framework, но могут быть недоработки в отношении кастомных модификаторов. Вам следует проверить документацию по pulumi-terraform-bridge на наличие описания известных ограничений и особенностей работы с кастомными модификаторами.

3. Влияние использования UseStateForUnknown()

Да, интенсивное использование UseStateForUnknown() в ваших планах может привести к тому, что Pulumi не будет отслеживать изменения в этих полях. Этот модификатор сообщает Pulumi о том, что состояние атрибута не обязательно нужно обновлять, если это "неизвестное" состояние. Если это значение выставляется для многих атрибутов, это может создать ситуацию, когда Pulumi просто игнорирует изменения в ресурсах.

4. Известные проблемы и ограничения pulumi-terraform-bridge

Существуют некоторые известные проблемы и ограничения при использовании pulumi-terraform-bridge с провайдерами, созданными с помощью terraform-plugin-framework. Рекомендуется обращаться к сообществу разработчиков Pulumi, а также отслеживать репозиторий pulumi-terraform-bridge на GitHub, чтобы оставаться в курсе новых обновлений и выявленных проблем.

5. Как отладить проблему

Вот некоторые шаги, которые помогут вам в отладке:

  • Логирование: Включите подробное логирование в вашем провайдере. Это может помочь вам увидеть, что происходит на уровне взаимодействия с объектами и как Pulumi воспринимает состояние ресурса.

  • Проверка состояния: Убедитесь, что состояние вашего ресурса правильно сохраняется. Попробуйте вывести текущее состояние поля "nodes" перед и после вашего изменения, чтобы проверить, сохраняет ли провайдер нужные данные.

  • Минимизация использований модификаторов: Попробуйте временно убрать или оставить минимум кастомных модификаторов и посмотреть, повлияет ли это на детектирование изменений.

  • Тестирование в Terraform: Проведите тесты на вашем Terraform-провайдере вне Pulumi, чтобы убедиться, что изменения фиксируются корректно.

  • Обратитесь в сообщество: Если ни один из этих шагов не помог, рассмотрите возможность обращения за помощью в сообщество разработчиков Pulumi через форумы или GitHub Issues.

Надеюсь, эти рекомендации помогут вам разобраться с проблемой. Если у вас есть дополнительные вопросы или вам требуется дальнейшая помощь, пожалуйста, дайте знать.

С уважением.

Оцените материал
Добавить комментарий

Капча загружается...