gitlab_group_security_policy_attachment does not refresh state nor show a diff after manual removal of policy link

Bug Report

We use the gitlab_group_security_policy_attachment to link Security Policy Projects to Groups. We expect Terraform to reinstate the policy link when manually removed. When we remove a Security Policy Project manually Terraform does not see the change in state on GitLab and thinks the resource is in-place.

Relevant Terraform Configuration

resource "gitlab_group_security_policy_attachment" "security_policy_link" {
  group          = 11111111
  policy_project = 22222222
}

Relevant Terraform Command

When running Terraform like this:

wouter@LAPTOP ~/bug-test (main) $ tf init -upgrade
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/http versions matching ">= 3.5.0"...
- Finding hashicorp/local versions matching ">= 2.5.1"...
- Finding gitlabhq/gitlab versions matching ">= 18.0.0"...
- Using previously-installed hashicorp/local v2.6.2
- Using previously-installed gitlabhq/gitlab v18.8.2
- Using previously-installed hashicorp/http v3.5.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
wouter@LAPTOP ~/bug-test (main) $ tf plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # gitlab_group_security_policy_attachment.security_policy_link will be created
  + resource "gitlab_group_security_policy_attachment" "security_policy_link" {
      + group                     = "11111111"
      + group_graphql_id          = (known after apply)
      + id                        = (known after apply)
      + policy_project            = "22222222"
      + policy_project_graphql_id = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
wouter@LAPTOP ~/bug-test (main) $ tf apply -auto-approve  

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # gitlab_group_security_policy_attachment.security_policy_link will be created
  + resource "gitlab_group_security_policy_attachment" "security_policy_link" {
      + group                     = "11111111"
      + group_graphql_id          = (known after apply)
      + id                        = (known after apply)
      + policy_project            = "22222222"
      + policy_project_graphql_id = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.
gitlab_group_security_policy_attachment.security_policy_link: Creating...
gitlab_group_security_policy_attachment.security_policy_link: Creation complete after 3s [id=11111111:22222222]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

This applies the Security Policy Project and is visible in the UI. Then when I delete the link manually (on Group > Secure > Policies > Edit Policy Project > Using Trashcan icon to remove the link) and re-run Terraform:

wouter@LAPTOP ~/bug-test (main) $ tf plan
gitlab_group_security_policy_attachment.security_policy_link: Refreshing state... [id=11111111:22222222]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

TF does not see the state change.

Relevant Log Output

These are the debug logs of the `terraform` command output:

When using GraphQL API and getting the securityPolicyProject for the group the output is:

{
    "data": {
        "group": {
            "id": "gid://gitlab/Group/11111111",
            "fullPath": "COMPANY/bug-test",
            "name": "ITFP Delivery Pipelines",
            "securityPolicyProject": null
        }
    }
}

Additional Details

  • GitLab Terraform Provider Version: `18.8.2`
  • GitLab Instance Version: `18.9.0-pre`
  • Terraform Version: `1.14.4`
  • License Tier: Ultimate

Implementation Guide

  • Follow the CONTRIBUTING.md guide for setting up your local development environment.
  • Clone the community fork of this project.
  • In internal/provider/resource_gitlab_group_security_policy_attachment.go, in the Read function, if response.Data.Group.SecurityPolicyProject is null/empty string, add a block similar to the block when response.Data.Group is null above so the resource is removed from state.
  • In internal/provider/resource_gitlab_group_security_policy_attachment_test.go, add a test to verify the resource is recreated if deleted through the API between steps.
Edited by 🤖 GitLab Bot 🤖