Log icon
If icon
AnsibleCLI icon
Update icon

Auto-Remediate a ServiceNow Incident with Ansible

Kestra flow that takes a ServiceNow incident, runs an Ansible playbook for Software category tickets, and closes the incident via the ServiceNow plugin.

Categories
Business

Close the loop between a ServiceNow incident and the actual fix. This Kestra blueprint receives one incident's details as inputs, decides whether the category qualifies for automated remediation, runs an Ansible playbook in a container when it does, and then writes the resolution back to ServiceNow so the ticket is closed with notes, a close code, and a resolution code. It is designed as the per-ticket worker behind a polling or webhook front end such as the servicenow-incident-triage-scan blueprint, but it runs standalone too: execute it manually with any incident's sys_id to remediate and close a single ticket.

How it works

  1. The flow accepts five inputs that identify the incident: ticketNumber, shortDescription, openedAt, sysID, and category.
  2. The logTicket task (io.kestra.plugin.core.log.Log) records every field so the execution itself becomes the audit record.
  3. The triggerAnsibleIfSoftwareCategory task (io.kestra.plugin.core.flow.If) checks inputs.category == 'Software'. Matching tickets run run_remediation_playbook (io.kestra.plugin.ansible.cli.AnsibleCLI), which executes ansible-playbook -i inventory.ini myplaybook.yml inside the cytopia/ansible:latest-tools container. The inventory and playbook are inlined via inputFiles as stubs you replace with real remediation logic. Non-matching tickets hit the out_of_scope branch and are only logged.
  4. The sendNotification task logs completion; in production you would swap it for Slack or email.
  5. The updateServiceNowTicket task (io.kestra.plugin.servicenow.Update) sets state: 7 (Closed) on the incident identified by sysId, adding close_notes, close_code, and resolution_code so the closure passes ServiceNow validation rules.

What you get

  • A self-documenting remediation record: inputs, playbook output, and ticket closure in one execution.
  • Category-based gating so only tickets you trust automation with are touched.
  • Containerized Ansible with the inventory and playbook inlined, nothing to install on workers.
  • Automatic ticket closure with proper resolution metadata, not just a comment.

Who it's for

  • IT operations teams drowning in repetitive Software category incidents.
  • Ansible shops that want playbook runs traceable to the ticket that caused them.
  • MSPs closing customer tickets with proof of the exact commands that ran.

Why orchestrate this with Kestra

Running Ansible from a ServiceNow workflow usually means a MID Server, credentials scattered across the instance, and no unified log. Kestra inverts the model: ServiceNow stays the system of record while Kestra owns execution, secrets, containers, and retries. If the playbook fails, the ticket is not closed and the execution shows exactly which Ansible task broke. Each remediation is an isolated, replayable execution you can rerun after fixing the playbook, and the same flow serves as the reusable worker behind any trigger, polling, webhook, or manual.

Prerequisites

  • A ServiceNow instance with API access to update the incident table.
  • A Kestra worker able to pull and run the cytopia/ansible:latest-tools image.
  • Set the serviceNowInstance variable to your instance name.
  • Optionally the servicenow-incident-triage-scan blueprint as the upstream feeder.

Secrets

  • SERVICENOW_USERNAME: ServiceNow user allowed to update incidents.
  • SERVICENOW_PASSWORD: password for that user, used by the Update task's basic auth.

Quick start

  1. Add the two secrets to your Kestra namespace and set the serviceNowInstance variable.
  2. Replace the stub myplaybook.yml with your real remediation playbook and point inventory.ini at real hosts.
  3. Deploy the flow, then execute it manually with a test incident's sys_id and category set to Software.
  4. Verify the playbook ran in the task logs and the incident shows as Closed in ServiceNow.
  5. Pair it with servicenow-incident-triage-scan for fully automated triage.

How to extend

  • Add more branches with io.kestra.plugin.core.flow.Switch to map categories to different playbooks.
  • Replace the sendNotification log with io.kestra.plugin.notifications.slack.SlackIncomingWebhook.
  • Pause for human approval with io.kestra.plugin.core.flow.Pause before touching production hosts.
  • Set the ticket to Resolved instead of Closed by changing state to 6 and letting the caller confirm.
  • Attach the playbook output to the ticket by adding a work note in the Update task data.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.