Skip to content

Project team

Use case: a team manages its own project's settings — protected branches, feature flags, approvals, and the GraphQL-served incident management and security-policy surfaces — with a project-scoped token. GitLab RBAC enforces the token's reach, so the scoping is safety, not just tidiness: this token cannot touch instance settings or other groups. All surfaces here are served by the default api preset (REST + GraphQL).

ansible-playbook -i localhost, examples/project-team.yml

Source: examples/project-team.yml

---
# Persona: project team.
# Scope: their own project's settings, applied with a project-scoped token.
# GitLab RBAC enforces the boundary — this token cannot touch instance or
# other groups' settings, so scoping is safety, not just tidiness.
#
#   ansible-playbook -i localhost, examples/project-team.yml
#
# All surfaces here are served by the default `api` preset (rest + graphql).
- name: Converge project settings
  hosts: localhost
  gather_facts: false
  connection: local
  vars:
    gitlab_settings_target:
      url: https://gitlab.example.com
      auth:
        type: project_access_token
        token: "{{ vault_project_token }}"
        bound_to:
          resource: project
          identifier: platform/service
  tasks:
    - name: Apply project settings
      ansible.builtin.include_role:
        name: primetheus.gitlab_settings
        tasks_from: apply
      vars:
        gitlab_settings_resource: projects
        gitlab_settings_projects:
          - path: platform/service
            project:
              visibility: private
              merge_method: ff
            protected_branches:
              - name: main
                allowed_to_push:
                  - access_level: maintainer
            members:
              - username: alice
                access_level: maintainer
              - username: bob
                access_level: developer
            # Project feature flags (declared-state-wins — GitOps owns rollout):
            feature_flags:
              - name: beta_ui
                active: true
                description: Redesigned UI
            feature_flag_user_lists:
              - name: beta_testers
                user_xids: "1001,1002,1003"
            # GraphQL-only incident management. Each escalation rule targets
            # exactly one username or a known existing schedule iid.
            oncall_schedules:
              - name: primary
                timezone: Etc/UTC
                rotations:
                  - name: weekly
                    starts_at: {date: "2026-01-05", time: "09:00"}
                    rotation_length: {length: 1, unit: WEEKS}
                    participants:
                      - username: oncall-engineer
            escalation_policies:
              - name: primary-escalation
                rules:
                  - username: oncall-engineer
                    status: ACKNOWLEDGED
                    elapsed_time_seconds: 300
            # GraphQL-only security policies. The project must already be linked
            # to a Security Policy Project; the role owns the whole document
            # (full-replace) — declare every policy you want to keep.
            security_policies:
              scan_execution_policy:
                - name: nightly-sast
                  enabled: true
                  rules:
                    - type: schedule
                      cadence: "0 2 * * *"
                  actions:
                    - scan: sast
              approval_policy:
                - name: require-security-approval
                  enabled: true