Skip to content

Terraform import fails to populate connector_id field for stack components, causing state inconsistency #11

@htahir1

Description

@htahir1

When importing existing ZenML stack components into Terraform state using terraform import, the connector_id field is not properly populated, remaining null despite the component having an associated service connector. This causes state inconsistency and makes the Terraform provider unusable for managing existing infrastructure.

Steps to Reproduce:

Have an existing orchestrator component (vertex flavor) that uses a service connector (GCP type)

Run terraform import command:

terraform import zenml_stack_component.vertex_ai_orchestrator 60cdb09f-0973-4d20-9ee8-1d2f4a5baaf8

Check the imported state

Expected Behavior: Both connector_id and connector_resource_id should be properly populated in the Terraform state after import.

Actual Behavior:

connector_id: null

connector_resource_id: "sib-data-science-team" (correctly populated)

Impact:

Terraform will attempt to destroy and recreate the component to fix the null connector_id

Destroy operation fails because the component is actively used within a stack

This makes the Terraform provider unusable for managing existing ZenML infrastructure

Additional Context: Code analysis shows that connector_resource_id is mapped in the provider code (https://github.com/zenml-io/terraform-provider-zenml/blob/main/internal/provider/resource_stack_component.go#L184) but connector_id mapping appears to be missing.

Environment:

Terraform provider: zenml

Component type: Stack component (vertex AI orchestrator)

Connector type: GCP service connector

Original slack thread: https://zenmlteam.slack.com/archives/C07VANH2JQ1/p1750111989599959

Proposed solution

Looking at the code, the user's claim is absolutely correct. There's a clear bug in the resourceStackComponentRead function.

The Problem

In resourceStackComponentRead (lines ~140-170), the code properly reads and sets connector_resource_id:

if component.Metadata.ConnectorResourceID != nil {
    d.Set("connector_resource_id", *component.Metadata.ConnectorResourceID)
}

However, there's no corresponding code to read and set the connector_id from the API response. This means during import (which calls the Read function), the connector_id field remains null in the Terraform state even though the actual component has a connector.

Permanent Fix

Add the missing connector_id reading in the resourceStackComponentRead function. Here's the fix:

func resourceStackComponentRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
    client, ok := m.(*Client)
    if !ok {
        return diag.FromErr(fmt.Errorf("invalid client type: expected *Client"))
    }

    component, err := client.GetComponent(ctx, d.Id())
    if err != nil {
        return diag.FromErr(fmt.Errorf("error getting component: %w", err))
    }

    if component == nil {
        d.SetId("")
        return nil
    }

    d.Set("name", component.Name)

    if component.Body != nil {
        d.Set("type", component.Body.Type)
        d.Set("flavor", component.Body.Flavor)
    }

    if component.Metadata != nil {
        d.Set("configuration", component.Metadata.Configuration)

        // FIX: Add this missing connector_id reading
        if component.Metadata.ConnectorID != nil {
            d.Set("connector_id", *component.Metadata.ConnectorID)
        }

        if component.Metadata.ConnectorResourceID != nil {
            d.Set("connector_resource_id", *component.Metadata.ConnectorResourceID)
        }
        if component.Metadata.Labels != nil {
            d.Set("labels", component.Metadata.Labels)
        }
    }

    return nil
}

Note: You'll need to verify that component.Metadata.ConnectorID is the correct field path in your API response structure. If the connector ID is stored elsewhere in the response (e.g., component.ConnectorID or component.Body.ConnectorID), adjust the path accordingly.

This fix will ensure that both connector_id and connector_resource_id are properly populated during import operations.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingplannedPlanned for the short term

Type

No type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions