Skip to content

gitlab_project doesn't set builds_access_level during first apply

Bug Report

When using the gitlab_project resource to create a projet, the builds_access_level doesn't have effet during the first terraform apply. However, subsequent runs do change the setting as intended.

This is problematic when generating public repositories that require their CI pipelines and artifacts to be hidden to avoid leaking secrets.

Relevant Terraform Configuration

resource "gitlab_project" "test" {
 name        = "test"
 description = "My awesome codebase"

 visibility_level    = "public"
 builds_access_level = "private"
}
provider "gitlab" {
 token = var.gitlab_token
}
variable "gitlab_token" {
 type = string
}
terraform {
 required_providers {
   gitlab = {
     source = "gitlabhq/gitlab"
   }
 }
}

Relevant Log Output

First run:

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_project.test will be created
 + resource "gitlab_project" "test" {
     + allow_merge_on_skipped_pipeline                  = false
     + analytics_access_level                           = (known after apply)
     + approvals_before_merge                           = 0
     + archived                                         = false
     + auto_cancel_pending_pipelines                    = (known after apply)
     + auto_devops_deploy_strategy                      = (known after apply)
     + auto_devops_enabled                              = (known after apply)
     + autoclose_referenced_issues                      = (known after apply)
     + build_git_strategy                               = (known after apply)
     + build_timeout                                    = (known after apply)
     + builds_access_level                              = "private"
     + ci_default_git_depth                             = (known after apply)
     + ci_forward_deployment_enabled                    = true
     + container_registry_access_level                  = (known after apply)
     + container_registry_enabled                       = true
     + default_branch                                   = (known after apply)
     + description                                      = "My awesome codebase"
     + forking_access_level                             = (known after apply)
     + http_url_to_repo                                 = (known after apply)
     + id                                               = (known after apply)
     + issues_access_level                              = (known after apply)
     + issues_enabled                                   = true
     + lfs_enabled                                      = true
     + merge_method                                     = "merge"
     + merge_pipelines_enabled                          = false
     + merge_requests_access_level                      = (known after apply)
     + merge_requests_enabled                           = true
     + merge_trains_enabled                             = false
     + mirror                                           = false
     + mirror_overwrites_diverged_branches              = false
     + mirror_trigger_builds                            = false
     + name                                             = "test"
     + namespace_id                                     = (known after apply)
     + only_allow_merge_if_all_discussions_are_resolved = false
     + only_allow_merge_if_pipeline_succeeds            = false
     + only_mirror_protected_branches                   = false
     + operations_access_level                          = (known after apply)
     + packages_enabled                                 = true
     + pages_access_level                               = "private"
     + path_with_namespace                              = (known after apply)
     + pipelines_enabled                                = true
     + printing_merge_request_link_enabled              = true
     + repository_access_level                          = (known after apply)
     + repository_storage                               = (known after apply)
     + request_access_enabled                           = true
     + requirements_access_level                        = (known after apply)
     + runners_token                                    = (sensitive value)
     + security_and_compliance_access_level             = (known after apply)
     + shared_runners_enabled                           = (known after apply)
     + snippets_access_level                            = (known after apply)
     + snippets_enabled                                 = true
     + squash_option                                    = "default_off"
     + ssh_url_to_repo                                  = (known after apply)
     + tags                                             = (known after apply)
     + topics                                           = (known after apply)
     + visibility_level                                 = "public"
     + web_url                                          = (known after apply)
     + wiki_access_level                                = (known after apply)
     + wiki_enabled                                     = true

     + container_expiration_policy {
         + cadence           = (known after apply)
         + enabled           = (known after apply)
         + keep_n            = (known after apply)
         + name_regex_delete = (known after apply)
         + name_regex_keep   = (known after apply)
         + next_run_at       = (known after apply)
         + older_than        = (known after apply)
       }

     + push_rules {
         + author_email_regex            = (known after apply)
         + branch_name_regex             = (known after apply)
         + commit_committer_check        = (known after apply)
         + commit_message_negative_regex = (known after apply)
         + commit_message_regex          = (known after apply)
         + deny_delete_tag               = (known after apply)
         + file_name_regex               = (known after apply)
         + max_file_size                 = (known after apply)
         + member_check                  = (known after apply)
         + prevent_secrets               = (known after apply)
         + reject_unsigned_commits       = (known after apply)
       }
   }

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

Do you want to perform these actions?
 Terraform will perform the actions described above.
 Only 'yes' will be accepted to approve.

 Enter a value: yes

gitlab_project.test: Creating...
gitlab_project.test: Creation complete after 3s [id=41262371]

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

Second run:

gitlab_project.test: Refreshing state... [id=41262371]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # gitlab_project.test will be updated in-place
  ~ resource "gitlab_project" "test" {
      ~ builds_access_level                              = "enabled" -> "private"
        id                                               = "41262371"
        name                                             = "test"
        tags                                             = []
        # (59 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

gitlab_project.test: Modifying... [id=41262371]
gitlab_project.test: Modifications complete after 1s [id=41262371]

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

Additional Details

  • GitLab Terraform Provider Version: 3.19.0
  • GitLab Version: gitlab.com
  • Terraform Version: 1.3.4
Edited by oscar