How it works
One environment is shown; each environment has its own storage location and Agent, and the pipeline routes by the payload’s target.- A release is deployed to a virtual (Stage) environment in BRMS, directly or through a change request.
- The BRMS webhook queues a run through the Azure DevOps Pipelines API, passing the event as the
GRL_PAYLOADrun variable. The payload carries the project key and the target (for exampleenv:production) in the exact syntaxgorules pullaccepts. - The official steps template resolves the target and downloads the artifact. Resolution and download are two API calls under the hood, but a single
gorules pull- the template handles both. - Your publish step - appended after the template in the same job - uploads the artifact wherever your runtime reads it from.
GRL_PAYLOAD, project and target come from whatever you pass explicitly - queue-time values or schedule configuration. Nothing environment-specific is baked into the pipeline file.
Polling is also supported: a scheduled run passes the previous release id as the current parameter - see Pipeline variables. Without GRL_PAYLOAD, a run must state project and target explicitly (queue-time values or schedule configuration); a missing project fails fast.
Prerequisites
- BRMS webhooks (eligible plan): an organisation admin connects the Azure DevOps integration; a Project Admin (Manage Project) creates the webhook.
- A Stage environment in the project (Settings → Environments): deploying a release to it fires the webhook and defines
env:<key>. - A secret pipeline variable
GORULES_TOKEN(project access token with read access, Settings → Tokens). - A GitHub service connection to reference the template repository, plus credentials for your storage destination; the examples show only the upload step.
1. Create the pipeline
templates/azure-pipelines-pull.yml in the gorules/cli repository is a steps template: it only pulls - downloading the artifact and setting result variables - and your publish step follows it in the same job. The template steps are identical in every variant; only the publish step differs. Pick your destination - each tab is the complete file:
- Amazon S3
- Azure Blob Storage
- Google Cloud Storage
azure-pipelines.yml
case maps the target to a destination; unmapped targets fail the step so nothing is uploaded to an unintended destination.
The artifact is written as <project-key> with no .zip suffix, because the Agent’s storage providers use the object name verbatim as the project key. See naming the output for the other layouts, and Agent configuration for the full provider settings - applications that evaluate through an SDK loader read the same object and need no Agent.
2. Declare the queue-time variable
Unlike GitLab, Azure DevOps only accepts variables at queue time when the pipeline declares them. In the pipeline’s Edit → Variables, add a variable namedGRL_PAYLOAD (any value) with “Let users override this value when running this pipeline” checked.
Organizations with Limit variables that can be set at queue time enabled - the default on newer organizations - reject the BRMS queue request entirely if this variable is not declared. If webhook deliveries fail with a queue error, this is the first thing to check.
3. Connect BRMS
Integrations are connected once per organisation; webhooks are configured per project.- Connect the Azure DevOps integration (organisation admin): open Settings → Integrations & Apps under the organisation group and connect Azure DevOps. The webhook form also deep-links here via Configure Integrations if the connection is missing.
- Create the webhook (Project Admin - the Manage Project permission): in the project, go to Settings → Webhooks → Create webhook, choose type Azure DevOps, then select the repository (
project/repository), the branch, and the pipeline to queue. - Subscribe it to the Release Deployed event - then every run means an environment moved, and the payload always carries an
env:<key>target. - Optionally use the Test Webhook section of the form to send a sample event before relying on it.
IP-restricted organizations. Azure DevOps enforces IP restrictions through Microsoft Entra Conditional Access policies with location conditions, plus the organization policy “Enable IP Conditional Access policy validation”. If your organization uses these, BRMS’s traffic must be permitted by the allowed named locations - otherwise token sign-in or the queue request is rejected even though the same configuration works from your office network. GoRules cloud has no fixed IP addresses - traffic originates from the AWS IP ranges of us-east-1 or eu-central-1 (your region). Fixes: allow those ranges (filter ip-ranges.json by region), switch to scheduled polling, or self-host BRMS with a static egress IP.
4. Test the flow
Deploy a release to the environment in BRMS and watch the run appear under Pipelines. The webhook log in BRMS (Settings → Webhooks → logs) shows the exact payload delivered and lets you replay a delivery, so you can iterate on the pipeline without re-deploying releases. To test without BRMS, run the pipeline manually and set theGRL_PAYLOAD variable at queue time:
Pipeline variables
The template sets these for the steps that follow it in the job:rulesChanged is always 'true' on a BRMS-triggered run - the pipeline never passes current, so the CLI always downloads. It exists for scheduled runs: pass the previous release id as the current parameter and gate your publish step on rulesChanged when the environment has not moved.
Template parameters: url, project, target, out (default $(Build.ArtifactStagingDirectory)/rules), name, unpack, delete, current, and cliVersion.
Committing rules to Git
The same pull can also commit the rules as plain files to your repository. Three optional settings:unpack extracts the archive instead of writing a zip, name: '.' extracts straight into the output directory, and delete removes files that no longer exist in BRMS so the directory mirrors the target exactly. Point the output inside the checkout and commit what changed:
persistCredentials: true keeps the job’s token available for the push. trigger: none already prevents the push from re-queuing the pipeline.