gitlab_user_runner import does not populate group_id causing force replacement

gitlab_user_runner import does not populate group_id field

Bug Report

When importing a gitlab_user_runner resource that was created via the GitLab UI (or API), the group_id attribute is not populated in the Terraform state during import. This causes Terraform to show a perpetual diff with + group_id = <id> # forces replacement, leading to an unnecessary destroy+recreate cycle on the next apply.

The runner is correctly associated with the group (confirmed via GitLab API), but the import function does not read and set the group_id attribute from the API response's groups array.

Expected behavior: After importing a group runner, the group_id should be automatically populated in the state based on the runner's group association returned by the GitLab API.

Actual behavior: The group_id remains unset after import, causing Terraform to plan a force replacement to add it.

Relevant Terraform Configuration

terraform {
  required_providers {
    gitlab = {
      source  = "gitlabhq/gitlab"
      version = ">= 18.0"
    }
  }

  required_version = "~> 1"
}

resource "gitlab_user_runner" "this" {
  runner_type = "group_type"
  group_id    = <group_id>
  description = "Whatever"
}

Relevant Terraform Command

# Import the runner
terraform import gitlab_user_runner.this <group_id>

# Then run plan
terraform plan

In the statefile, the imported resource will have the group_id as null:

{
  "module": "module.gitlab",
  "mode": "managed",
  "type": "gitlab_user_runner",
  "name": "this",
  "provider": "provider[\"registry.terraform.io/gitlabhq/gitlab\"]",
  "instances": [
    {
      "schema_version": 0,
      "attributes": {
        "access_level": "not_protected",
        "description": "Whatever",
        "group_id": null,
        "id": "<id>",
        "locked": false,
        "maintenance_note": "",
        "maximum_timeout": 0,
        "paused": false,
        "project_id": null,
        "runner_type": "group_type",
        "tag_list": [],
        "token": null,
        "untagged": true
      },
      "sensitive_attributes": [
        [
          {
            "type": "get_attr",
            "value": "token"
          }
        ]
      ],
      "identity_schema_version": 0
    }
  ]
}

Relevant Log Output

Terraform Plan Output (showing the force replacement)

  # gitlab_user_runner.this must be replaced
  # (imported from "<group_id>")
  # Warning: this will destroy the imported resource
-/+ resource "gitlab_user_runner" "this" {
      ~ access_level     = "not_protected" -> (known after apply)
        description      = "Whatever"
      + group_id         = <group_id> # forces replacement
      ~ id               = "<id>" -> (known after apply)
      ~ locked           = false -> (known after apply)
      + maintenance_note = (known after apply)
      ~ maximum_timeout  = 0 -> (known after apply)
      ~ paused           = false -> (known after apply)
        runner_type      = "group_type"
      ~ tag_list         = [] -> (known after apply)
      + token            = (sensitive value)
      ~ untagged         = true -> (known after apply)
    }

Note the + group_id = <group_id> # forces replacement line - the + indicates this attribute is being added (not changed), meaning it was not populated during import.

Additional Details

  • GitLab Terraform Provider Version: >= 18.0 (tested with 18.x)
  • GitLab Instance Version: GitLab.com (SaaS)
  • Terraform Version: ~> 1.0
  • License Tier: Free and Premium (using GitLab.com)
Edited by 🤖 GitLab Bot 🤖