gitlab_group_service_account_access_token cannot be imported
Bug Report
When importing a gitlab_group_service_account_access_token manually created, the terraform configuration wants to delete/re-create it.
Relevant Terraform Configuration
resource "gitlab_group" "mygroup" {
name = "mygroup"
path = "mygroup"
visibility_level = "private"
}
resource "gitlab_group_service_account" "renovate_bot" {
group = gitlab_group.mygroup.id
name = "renovate-bot-001"
username = "renovate-bot-001"
}
resource "gitlab_group_service_account_access_token" "renovate_bot" {
expires_at = "2026-11-12"
group = gitlab_group.mygroup.id
name = "renovate-bot-001"
user_id = gitlab_group_service_account.renovate_bot.service_account_id
scopes = ["api", "write_repository"]
}
Relevant Terraform Command
terraform import gitlab_group_service_account_access_token.renovate_bot xxx:yyy:zzz
terraform plan
# gitlab_group_service_account_access_token.renovate_bot must be replaced
-/+ resource "gitlab_group_service_account_access_token" "renovate_bot" {
+ active = (known after apply)
+ created_at = (known after apply)
+ expires_at = "2026-11-12" # forces replacement
+ group = "xxx" # forces replacement
~ id = "xxx:yyy:zzz" -> (known after apply)
+ name = "renovate-bot-001" # forces replacement
+ revoked = (known after apply)
+ scopes = [ # forces replacement
+ "api",
+ "write_repository",
]
+ token = (sensitive value)
+ user_id = yyy # forces replacement
}
Plan: 1 to add, 0 to change, 1 to destroy.
Relevant Log Output
{"@caller":"github.com/hashicorp/terraform-plugin-sdk/v2@v2.37.0/helper/logging/logging_http_transport.go:160","@level":"debug","@message":"Sending HTTP Request","@module":"gitlab.GitLab","@timestamp":"2025-11-13T09:10:38.128304+01:00","Accept":"application/json","Accept-Encoding":"gzip","Authorization":"Bearer ...","Host":"gitlab.com","User-Agent":"Terraform/1.13.5 (+https://www.terraform.io) Terraform-Plugin-Framework terraform-provider-gitlab/18.4.1","new_logger_warning":"This log was generated by a subsystem logger that wasn't created before being used. Use tflog.NewSubsystem to create this logger before it is used.","tf_http_op_type":"request","tf_http_req_body":"","tf_http_req_method":"GET","tf_http_req_uri":"/api/v4/personal_access_tokens/zzz","tf_http_req_version":"HTTP/1.1","tf_http_trans_id":"817a146d-6ef7-754c-9aa1-86dfafab5450","timestamp":"2025-11-13T09:10:38.128+0100"}
{"@caller":"github.com/hashicorp/terraform-plugin-sdk/v2@v2.37.0/helper/logging/logging_http_transport.go:160","@level":"debug","@message":"Received HTTP Response","@module":"gitlab.GitLab","@timestamp":"2025-11-13T09:10:38.743299+01:00","Cache-Control":"no-cache","Cf-Cache-Status":"MISS","Cf-Ray":"99dccb32380ce1ac-MRS","Content-Length":"30","Content-Security-Policy":"default-src 'none'","Content-Type":"application/json","Date":"Thu, 13 Nov 2025 08:10:38 GMT","Gitlab-Lb":"haproxy-main-16-lb-gprd","Gitlab-Sv":"api-gke-us-east1-b","Nel":"{\"max_age\": 0}","Ratelimit-Limit":"8000","Ratelimit-Name":"throttle_authenticated_api","Ratelimit-Observed":"19","Ratelimit-Remaining":"7981","Ratelimit-Reset":"1763021460","Referrer-Policy":"strict-origin-when-cross-origin","Server":"cloudflare","Set-Cookie":["..."],"Strict-Transport-Security":"max-age=31536000","Vary":"Origin, Accept-Encoding","X-Content-Type-Options":"nosniff","X-Frame-Options":"SAMEORIGIN","X-Gitlab-Meta":"{\"correlation_id\":\"99dccb32518ce1ac-ATL\",\"version\":\"1\"}","X-Request-Id":"99dccb32518ce1ac-ATL","X-Runtime":"0.416037","new_logger_warning":"This log was generated by a subsystem logger that wasn't created before being used. Use tflog.NewSubsystem to create this logger before it is used.","tf_http_op_type":"response","tf_http_res_body":"{\"message\":\"401 Unauthorized\"}","tf_http_res_status_code":401,"tf_http_res_status_reason":"401 Unauthorized","tf_http_res_version":"HTTP/2.0","tf_http_trans_id":"817a146d-6ef7-754c-9aa1-86dfafab5450","timestamp":"2025-11-13T09:10:38.742+0100"}
{"@caller":"gitlab.com/gitlab-org/terraform-provider-gitlab/internal/provider/resource_gitlab_group_service_account_access_token.go:537","@level":"warn","@message":"AccessToken read returned a 401, ignoring because service account access tokens can't be read without an admin (top-level group owner on gitlab.com) token currently. This will make the tfplan rely on state data instead of the current API values.","@module":"gitlab","@timestamp":"2025-11-13T09:10:38.743529+01:00","tf_mux_provider":"*proto6server.Server","tf_provider_addr":"registry.terraform.io/gitlabhq/gitlab","tf_req_id":"1c6b0487-f65d-3d14-afc4-abf79757df33","tf_resource_type":"gitlab_group_service_account_access_token","tf_rpc":"ReadResource","timestamp":"2025-11-13T09:10:38.743+0100","token_id":"zzz","user_id":"yyy"}
Additional Details
It seems like the terraform is using the wrong API. It looks like it uses /api/v4/personal_access_tokens/:user_id, while it should use /groups/:id/service_accounts/:user_id/personal_access_tokens. The used API will always return 401 when not used with the service account in question.
The relevant APIs are implemented under ListServiceAccountPersonalAccessTokensOptions, CreateServiceAccountPersonalAccessTokenOptions and RevokeServiceAccountPersonalAccessToken
One API may be missing to implement this properly: GET a single token by ID.
Implementation Guide
- Read the
CONTRIBUTING.mdguide to set up your local development environment and clone the community fork of this project. - Amend the
Readfunction inresource_gitlab_group_service_account_access_token.goto user.client.Groups.ListServiceAccountPersonalAccessTokensand find the entry with the correctID.
Edited by 🤖 GitLab Bot 🤖