Skip to content

Requesting services from Git (consumer)

The consumer half of the load-balancer scenario, again straight from the level-6 demo: your team consumes services (load balancers, DNS records, firewall rules...) by declaring them as YAML in your own Git repository. A merge request validates the declaration, merging submits it, and NetOrca works out the rest declaratively - you never file a ticket and you can watch your request move through the service owner's pipeline in real time.

The GitOps loop

  1. Declare. Copy the service's example from the NetOrca Service Catalogue into your repo:

    # app01.yml in your team's infrastructure repo
    application1:
      services:
        LOAD_BALANCER:
          - name: load_balancer1
            partition: prod
            type: http
            virtual_server:
              ip: 10.1.10.152
              port: 80
            members:
              - ip: 10.1.20.21
                port: 30880
    
  2. Merge request. The repo's CI validates the declaration against the service's JSON Schema before merge - schema errors come back as pipeline failures with the exact field named, so bad requests never reach the service owner.

  3. Merge. CI submits the merged state to NetOrca. Because submission is declarative, NetOrca diffs it against your previous state and raises change instances only for what changed: CREATE for new entries, MODIFY for edits, DELETE for entries you removed. An unchanged file produces no changes at all - resubmitting is always safe.
  4. Track. Each change instance moves PENDING → APPROVED → COMPLETED (or REJECTED/ERROR with the service owner's reason in its log). COMPLETED means it is live, and the service item's deployed item shows what actually serves it.

Submitting from Ansible

Step 3's submission call ships later in the v2 series as netorca_submission (server-side validation as check mode, submit for real otherwise). Until then, consumer repos use NetOrca's standard CI template for the submit step - see the level-6 consumer repo for a complete working example. Everything below works today.

Tracking your requests from Ansible

Everything the modules do in this scenario runs with context: consumer (or NETORCA_CONTEXT=consumer for the whole pipeline) - the same modules the service owner uses, scoped to what your team consumes.

The pattern consumer pipelines want most: block until everything from this merge is done, then fail loudly with the service owner's reasons if anything was rejected. The commit_id filter ties change instances back to the exact merge that caused them:

- name: Wait for my merge to be fulfilled
  hosts: localhost
  gather_facts: false
  vars:
    commit: "{{ lookup('env', 'CI_COMMIT_SHORT_SHA') }}"
  tasks:
    - name: Wait until no change from this commit is still open
      netautomate.netorca.netorca_change_instance_info:
        context: consumer
        commit_id: "{{ commit }}"
        state: [PENDING, APPROVED]
      register: open_changes
      until: open_changes.count == 0
      retries: 60
      delay: 30

    - name: Did anything get rejected or fail?
      netautomate.netorca.netorca_change_instance_info:
        context: consumer
        commit_id: "{{ commit }}"
        state: [REJECTED, ERROR]
      register: bad

    - name: Surface the service owner's reasons
      ansible.builtin.fail:
        msg: >-
          {{ bad.count }} change(s) not fulfilled:
          {{ bad.change_instances | map(attribute='log') | list }}
      when: bad.count > 0

    - name: All deployed
      ansible.builtin.debug:
        msg: "everything from commit {{ commit }} is COMPLETED"

Day-to-day estate questions are one task each:

- name: Everything my team consumes
  netautomate.netorca.netorca_service_item_info:
    context: consumer
  register: mine

- name: My requests still in flight anywhere
  netautomate.netorca.netorca_change_instance_info:
    context: consumer
    state: [PENDING, APPROVED]
  register: open_requests

- name: The full history of one of my changes (who approved it, when)
  netautomate.netorca.netorca_change_instance_info:
    context: consumer
    id: 987
    include_history: true
  register: audit

A runnable version ships as examples/scenarios/consumer_gitops/query_my_items.yml.

Why teams do it this way

Straight from the level-6 demo's rationale: the merge request gives you review before submission, the repository is the single source of truth for your team's infrastructure, every change is version-controlled and auditable, and deletion/modification are first-class - remove the YAML, merge, and the decommission flows through the same pipeline as everything else.