@burna-org/ansible-workflows
v0.0.3
Published
Ansible workflow helpers
Readme
@burna-org/ansible-workflows
Ansible workflow helpers built on top of @burna-org/awx-client.
This library composes:
- Full AWX client API pass-through
- Higher-level helpers for pagination, job polling, cached job reuse, and template auto-provisioning
Install
npm install @burna-org/ansible-workflows @burna-org/awx-clientQuick start (server)
const AWXClient = require('@burna-org/awx-client');
const {createAnsibleWorkflows} = require('@burna-org/ansible-workflows');
const awxClient = new AWXClient({
host: process.env.AWX_HOST,
username: process.env.AWX_USERNAME,
password: process.env.AWX_PASSWORD,
});
const ansible = createAnsibleWorkflows({
awxClient,
config: {
jobResultExpirySeconds: 3600,
pollInitialDelay: 5000,
pollInterval: 2000,
},
});Factory
createAnsibleWorkflows({ awxClient, config })
awxClient(required): an initializedAWXClientinstanceconfig.jobResultExpirySeconds(default3600)config.pollInitialDelay(default5000ms)config.pollInterval(default2000ms)config.runtimeMock(defaultfalse): whentrue, use built-in mock AWX responses and avoid real HTTP calls.
If awxClient is missing, it throws awxClient is required unless config.runtimeMock is enabled.
If required AWX methods are missing, it throws awxClient method "<name>" is required.
Returned API
The returned object includes:
- All AWX methods from
@burna-org/awx-client - Workflow helper methods below
AWX pass-through methods
All of these are directly delegated to awxClient:
getAccessTokenlistInventories,listInventoryHosts,createInventory,manageInventoryHostlistJobs,retrieveJob,retrieveJobStdout,listJobEventslistJobTemplates,createJobTemplate,updateJobTemplate,launchJobTemplate,listJobsForTemplate,manageJobTemplateCredentiallistAdhocCommands,retrieveAdhocCommand,retrieveAdhocCommandStdout,createAdhocCommandlistProjects,createProjectlistCredentials,createCredentiallistOrganizations,createOrganizationupdateHost,listHosts,listHostGroupscreateGroup,updateGroup,listGroups,listGroupHosts,manageGroupHostlistExecutionEnvironmentslistSettingCategories,listSettings,updateSettings
Helper API reference
getGroups({ inventoryName })
Returns all groups for inventory name, handling pagination.
Response:
{ groups: Array, error: '' }getHosts({ inventoryName })
Finds inventory by name, then returns all hosts with pagination.
Response:
{ hosts: Array, error: '' }If inventory is not found:
{ hosts: [], error: 'Failed to found inventory "<name>"' }findJobTemplateId({ jobTemplateName })
Response:
{ jobTemplateId: number | null, error: string }getLastJobResult({ jobTemplateName, limit })
Returns latest non-failed job result if not expired.
Uses configured jobResultExpirySeconds.
Response:
{ job: Object | null, error: string }handleJob({ jobTemplateName, limit, options, useLastJobResult })
Flow:
- Optionally reuse valid previous job
- Else launch new job template run
- Poll until finished
useLastJobResult defaults to true.
Response:
{ job: Object | null, error: string }handleJobEvents({ jobTemplateName, limit, options, urlParams, useLastJobResult })
Runs/reuses job via handleJob, then fetches all events with pagination.
Response:
{ jobEvents: Array, error: string }getJobEventsByJobId({ jobId, urlParams })
Polls job by ID until completion, then returns all events.
Response:
{ jobEvents: Array, error: '' }
// or
{ job: null, error: string }waitForJobToFinish({ jobId })
Polls AWX until job finishes.
Response:
{ job: Object | null, error: string }ensureJobTemplate({ ... })
Ensures template exists and returns template ID. If missing, it creates template and attaches credentials.
Params:
slug(required): logical template key (for exampledeploy_app)templateNamePrefix(optional): prefix for generated nameprojectName(required)inventoryName(required)executionEnvironmentName(required)credentialNames(required): comma-separated string or arrayplaybook(required)extraVars(optional object)options(optional AWX template options)
Notes:
- Template display name is generated from prefix+slug and title-cased
- Uses in-memory cache for template IDs
- Throws on resolution/create failures
clearTemplateCache(slug, templateNamePrefix)
- With
slug, clears one cached entry - With no args, clears all cache
getTemplateCacheStats()
Returns:
{ size: number, keys: string[] }Practical examples
1) Use helper APIs
const {groups, error} = await ansible.getGroups({inventoryName: 'production'});
if (error) throw new Error(error);
const hostsResult = await ansible.getHosts({inventoryName: 'production'});2) Run job with cache fallback
const result = await ansible.handleJob({
jobTemplateName: 'Deploy App',
limit: 'web-01',
options: {
extra_vars: {release: '2026.02'},
},
useLastJobResult: true,
});
if (result.error) {
throw new Error(result.error);
}
console.log('Job ID:', result.job.id);3) Run and collect all events
const events = await ansible.handleJobEvents({
jobTemplateName: 'Deploy App',
urlParams: {
event: 'runner_on_ok',
page_size: 200,
},
});
if (events.error) {
throw new Error(events.error);
}
console.log(events.jobEvents.length);4) Ensure template exists (auto-create)
const templateId = await ansible.ensureJobTemplate({
slug: 'deploy_app',
templateNamePrefix: 'kolla-',
projectName: 'infra-project',
inventoryName: 'prod-inventory',
executionEnvironmentName: 'default-ee',
credentialNames: ['machine-cred', 'vault-cred'],
playbook: 'site.yml',
extraVars: {kolla_action: 'deploy'},
options: {verbosity: 2},
});
console.log('Template ID:', templateId);5) Cache inspection/cleanup
console.log(ansible.getTemplateCacheStats());
ansible.clearTemplateCache('deploy_app', 'kolla-');
ansible.clearTemplateCache();Example server wrapper (Express)
const express = require('express');
const app = express();
app.use(express.json());
app.post('/api/ansible/job', async (req, res) => {
const {jobTemplateName, limit, options} = req.body;
const result = await ansible.handleJob({
jobTemplateName,
limit,
options,
useLastJobResult: true,
});
if (result.error) {
return res.status(400).json(result);
}
return res.json(result);
});
app.get('/api/ansible/job/:id/events', async (req, res) => {
const result = await ansible.getJobEventsByJobId({
jobId: Number(req.params.id),
urlParams: req.query,
});
if (result.error) {
return res.status(400).json(result);
}
return res.json(result);
});Error handling model
- Most helpers return
{..., error: ''}on success and a non-emptyerrorstring on failures ensureJobTemplatethrows when required dependencies/resources cannot be resolved
Development
npm test
npm run typecheck
npm run build:types