Wrap a deployment in maintenance
Suppress deployment noise with one bounded maintenance window and end it safely from CI/CD.
This tutorial creates one maintenance window for a deployment. The window ends automatically at its deadline, and the workflow can end it earlier with a short-lived deployment token.
Before you start
Create a workspace API token that can manage maintenance windows. Store it in the CI system's secret store as HOWLOPS_TOKEN. Do not print either the API token or the deployment token in build logs.
Decide whether the deployment affects every monitor or a known list of monitor IDs. An empty monitor_ids array means all monitors in the workspace.
Create the window
Call the authenticated endpoint before the deployment:
response="$(curl --fail-with-body --silent --show-error \
--request POST \
--header "Authorization: Bearer $HOWLOPS_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"name": "Production deploy",
"duration_minutes": 30,
"monitor_ids": []
}' \
https://api.howlops.com/api/v1/maintenance/deploy)"
deploy_token="$(printf '%s' "$response" | jq -r '.token')"
The response also contains maintenance_id, started_at, and ends_at. The requested duration defaults to 10 minutes when omitted or non-positive and is capped at 480 minutes.
Treat deploy_token as a credential. HowlOps stores only its SHA-256 hash. The token expires one hour after the scheduled end.
Run the deployment
Run the normal deployment only after the create request succeeds. If the request fails, decide explicitly whether to stop the deployment or continue without maintenance. Do not silently assume alert suppression is active.
End maintenance in a cleanup step
Call the unauthenticated end endpoint with the deployment token, including when the deployment fails:
curl --fail-with-body --silent --show-error \
--request POST \
"https://api.howlops.com/api/v1/maintenance/deploy/$deploy_token/end"
The token in the URL is the credential for this one window, so the end request does not use the workspace API token. A successful response includes ended_at.
Put the end request in your CI system's cleanup or finally step. If cleanup never runs, the original deadline still bounds the window.
GitHub Actions pattern
- name: Start HowlOps maintenance
id: howlops
env:
HOWLOPS_TOKEN: ${{ secrets.HOWLOPS_TOKEN }}
run: |
response="$(curl --fail-with-body --silent --show-error \
-X POST \
-H "Authorization: Bearer $HOWLOPS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Production deploy","duration_minutes":30,"monitor_ids":[]}' \
https://api.howlops.com/api/v1/maintenance/deploy)"
printf 'deploy_token=%s\n' "$(printf '%s' "$response" | jq -r '.token')" >> "$GITHUB_OUTPUT"
- name: Deploy
run: ./deploy.sh
- name: End HowlOps maintenance
if: ${{ always() && steps.howlops.outputs.deploy_token != '' }}
env:
DEPLOY_TOKEN: ${{ steps.howlops.outputs.deploy_token }}
run: |
curl --fail-with-body --silent --show-error \
-X POST \
"https://api.howlops.com/api/v1/maintenance/deploy/$DEPLOY_TOKEN/end"
After the workflow, open Maintenance and confirm the window has ended. If a monitored target is still failing, its next scheduled check can open an alert.
Was this page helpful?