[{"data":1,"prerenderedAt":1684},["ShallowReactive",2],{"content-query-LL2V9UohzU":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"head":11,"author":13,"tags":14,"categories":20,"date":21,"image":22,"faq":23,"excerpt":33,"body":74,"_type":1677,"_id":1678,"_source":1679,"_file":1680,"_stem":1681,"_extension":1682,"sitemap":1683},"/blog/awx-job-template-webhook","blog",false,"","Trigger an AWX Job Template from a Webhook","Trigger an AWX job template from GitHub, Bitbucket or any webhook. Filter events, map extra_vars, add bearer auth and reach a private AWX server.","post",{"title":12},"AWX Webhook: Trigger a Job Template from Any Service","Karolis Rusenas",[15,16,17,18,19],"awx","ansible","webhooks","automation","cicd",[18],"2026-09-06 10:45:00","/images/blog/heroes/route.jpg",[24,27,30],{"q":25,"a":26},"How do I launch an AWX job template with a webhook?","Send the webhook through a transform that makes a POST request to /api/v2/job_templates/{id}/launch/, adds Authorization: Bearer {token}, and builds the allowed extra_vars JSON body.",{"q":28,"a":29},"Can a webhook reach AWX behind a firewall?","Yes. Run the Webhook Relay agent inside the AWX network and forward a stable public input to the private AWX URL. The connection is outbound, so AWX needs no public IP or inbound firewall rule.",{"q":31,"a":32},"Why are AWX extra_vars ignored or rejected?","The job template must allow variables at launch, usually through Prompt on launch or an enabled survey. Check the template launch metadata before relying on webhook-supplied values.",{"type":34,"children":35},"root",[36,44],{"type":37,"tag":38,"props":39,"children":40},"element","p",{},[41],{"type":42,"value":43},"text","AWX can launch a job template through its REST API. That makes any webhook a possible automation trigger: a Bitbucket push, a monitoring alert, an approved form submission, or an internal deployment event.",{"type":37,"tag":38,"props":45,"children":46},{},[47,49,56,58,64,66,72],{"type":42,"value":48},"The safe pattern is to receive the source webhook, allowlist the event and branch, map only approved values into ",{"type":37,"tag":50,"props":51,"children":53},"code",{"className":52},[],[54],{"type":42,"value":55},"extra_vars",{"type":42,"value":57},", add an AWX API token, and then ",{"type":37,"tag":50,"props":59,"children":61},{"className":60},[],[62],{"type":42,"value":63},"POST",{"type":42,"value":65}," to ",{"type":37,"tag":50,"props":67,"children":69},{"className":68},[],[70],{"type":42,"value":71},"/api/v2/job_templates/{id}/launch/",{"type":42,"value":73},". If AWX is private, the Webhook Relay agent delivers the request from inside its network.",{"type":34,"children":75,"toc":1659},[76,80,102,109,114,119,149,173,179,269,274,280,285,305,335,340,345,351,356,454,459,465,485,490,525,530,536,557,1400,1413,1426,1432,1437,1470,1482,1488,1493,1537,1550,1556,1563,1576,1582,1595,1606,1611,1617,1622,1628,1641,1653],{"type":37,"tag":38,"props":77,"children":78},{},[79],{"type":42,"value":43},{"type":37,"tag":38,"props":81,"children":82},{},[83,84,89,90,95,96,101],{"type":42,"value":48},{"type":37,"tag":50,"props":85,"children":87},{"className":86},[],[88],{"type":42,"value":55},{"type":42,"value":57},{"type":37,"tag":50,"props":91,"children":93},{"className":92},[],[94],{"type":42,"value":63},{"type":42,"value":65},{"type":37,"tag":50,"props":97,"children":99},{"className":98},[],[100],{"type":42,"value":71},{"type":42,"value":73},{"type":37,"tag":103,"props":104,"children":106},"h2",{"id":105},"when-to-use-this-pattern",[107],{"type":42,"value":108},"When to use this pattern",{"type":37,"tag":38,"props":110,"children":111},{},[112],{"type":42,"value":113},"Automation Controller and AWX include native webhook support for selected source-control integrations such as GitHub and GitLab. Use that built-in path when it matches your provider and workflow.",{"type":37,"tag":38,"props":115,"children":116},{},[117],{"type":42,"value":118},"Use the job-template launch API when:",{"type":37,"tag":120,"props":121,"children":122},"ul",{},[123,129,134,139,144],{"type":37,"tag":124,"props":125,"children":126},"li",{},[127],{"type":42,"value":128},"The sender is Bitbucket or another generic webhook provider.",{"type":37,"tag":124,"props":130,"children":131},{},[132],{"type":42,"value":133},"An incident or monitoring event should run remediation.",{"type":37,"tag":124,"props":135,"children":136},{},[137],{"type":42,"value":138},"You need to map a provider payload into a small set of AWX variables.",{"type":37,"tag":124,"props":140,"children":141},{},[142],{"type":42,"value":143},"AWX has no public URL.",{"type":37,"tag":124,"props":145,"children":146},{},[147],{"type":42,"value":148},"One event should trigger AWX and other destinations.",{"type":37,"tag":38,"props":150,"children":151},{},[152,154,163,165,171],{"type":42,"value":153},"AWX's current ",{"type":37,"tag":155,"props":156,"children":160},"a",{"href":157,"rel":158},"https://docs.ansible.com/projects/awx/en/latest/open_api/explorer.html",[159],"nofollow",[161],{"type":42,"value":162},"API explorer",{"type":42,"value":164}," documents ",{"type":37,"tag":50,"props":166,"children":168},{"className":167},[],[169],{"type":42,"value":170},"POST /api/v2/job_templates/{id}/launch/",{"type":42,"value":172},".",{"type":37,"tag":103,"props":174,"children":176},{"id":175},"architecture",[177],{"type":42,"value":178},"Architecture",{"type":37,"tag":180,"props":181,"children":184},"pre",{"className":182,"code":183,"language":42,"meta":7,"style":7},"language-text shiki shiki-themes github-dark","source webhook\n      |\n      v\nWebhook Relay input\n filter + map + authenticate\n      |\n      | outbound relay agent\n      v\nprivate AWX /api/v2/job_templates/42/launch/\n",[185],{"type":37,"tag":50,"props":186,"children":187},{"__ignoreMap":7},[188,199,208,217,226,235,243,252,260],{"type":37,"tag":189,"props":190,"children":193},"span",{"class":191,"line":192},"line",1,[194],{"type":37,"tag":189,"props":195,"children":196},{},[197],{"type":42,"value":198},"source webhook\n",{"type":37,"tag":189,"props":200,"children":202},{"class":191,"line":201},2,[203],{"type":37,"tag":189,"props":204,"children":205},{},[206],{"type":42,"value":207},"      |\n",{"type":37,"tag":189,"props":209,"children":211},{"class":191,"line":210},3,[212],{"type":37,"tag":189,"props":213,"children":214},{},[215],{"type":42,"value":216},"      v\n",{"type":37,"tag":189,"props":218,"children":220},{"class":191,"line":219},4,[221],{"type":37,"tag":189,"props":222,"children":223},{},[224],{"type":42,"value":225},"Webhook Relay input\n",{"type":37,"tag":189,"props":227,"children":229},{"class":191,"line":228},5,[230],{"type":37,"tag":189,"props":231,"children":232},{},[233],{"type":42,"value":234}," filter + map + authenticate\n",{"type":37,"tag":189,"props":236,"children":238},{"class":191,"line":237},6,[239],{"type":37,"tag":189,"props":240,"children":241},{},[242],{"type":42,"value":207},{"type":37,"tag":189,"props":244,"children":246},{"class":191,"line":245},7,[247],{"type":37,"tag":189,"props":248,"children":249},{},[250],{"type":42,"value":251},"      | outbound relay agent\n",{"type":37,"tag":189,"props":253,"children":255},{"class":191,"line":254},8,[256],{"type":37,"tag":189,"props":257,"children":258},{},[259],{"type":42,"value":216},{"type":37,"tag":189,"props":261,"children":263},{"class":191,"line":262},9,[264],{"type":37,"tag":189,"props":265,"children":266},{},[267],{"type":42,"value":268},"private AWX /api/v2/job_templates/42/launch/\n",{"type":37,"tag":38,"props":270,"children":271},{},[272],{"type":42,"value":273},"The source never receives the AWX URL or token. It only knows the stable public input URL.",{"type":37,"tag":103,"props":275,"children":277},{"id":276},"_1-prepare-the-awx-job-template",[278],{"type":42,"value":279},"1. Prepare the AWX job template",{"type":37,"tag":38,"props":281,"children":282},{},[283],{"type":42,"value":284},"Create or select a job template and note its numeric ID from the URL or API. Run it manually once before adding a webhook.",{"type":37,"tag":38,"props":286,"children":287},{},[288,290,295,297,303],{"type":42,"value":289},"If the webhook will provide ",{"type":37,"tag":50,"props":291,"children":293},{"className":292},[],[294],{"type":42,"value":55},{"type":42,"value":296},", configure the template to accept them through ",{"type":37,"tag":298,"props":299,"children":300},"strong",{},[301],{"type":42,"value":302},"Prompt on launch",{"type":42,"value":304}," or an enabled survey. Define a narrow interface such as:",{"type":37,"tag":120,"props":306,"children":307},{},[308,317,326],{"type":37,"tag":124,"props":309,"children":310},{},[311],{"type":37,"tag":50,"props":312,"children":314},{"className":313},[],[315],{"type":42,"value":316},"revision",{"type":37,"tag":124,"props":318,"children":319},{},[320],{"type":37,"tag":50,"props":321,"children":323},{"className":322},[],[324],{"type":42,"value":325},"environment",{"type":37,"tag":124,"props":327,"children":328},{},[329],{"type":37,"tag":50,"props":330,"children":332},{"className":331},[],[333],{"type":42,"value":334},"service",{"type":37,"tag":38,"props":336,"children":337},{},[338],{"type":42,"value":339},"Do not expose arbitrary playbook variables merely because they are present in the source event.",{"type":37,"tag":38,"props":341,"children":342},{},[343],{"type":42,"value":344},"Create an AWX OAuth2 or personal access token for a service account with only the permissions required to execute this template. Store the token securely.",{"type":37,"tag":103,"props":346,"children":348},{"id":347},"_2-test-the-awx-launch-endpoint-directly",[349],{"type":42,"value":350},"2. Test the AWX launch endpoint directly",{"type":37,"tag":38,"props":352,"children":353},{},[354],{"type":42,"value":355},"From a machine that can reach AWX:",{"type":37,"tag":180,"props":357,"children":361},{"className":358,"code":359,"language":360,"meta":7,"style":7},"language-bash shiki shiki-themes github-dark","curl -i -X POST \\\n  https://awx.example.internal/api/v2/job_templates/42/launch/ \\\n  -H 'Authorization: Bearer YOUR_AWX_TOKEN' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"extra_vars\":{\"revision\":\"abc123\",\"environment\":\"staging\"}}'\n","bash",[362],{"type":37,"tag":50,"props":363,"children":364},{"__ignoreMap":7},[365,396,408,425,441],{"type":37,"tag":189,"props":366,"children":367},{"class":191,"line":192},[368,374,380,385,391],{"type":37,"tag":189,"props":369,"children":371},{"style":370},"--shiki-default:#B392F0",[372],{"type":42,"value":373},"curl",{"type":37,"tag":189,"props":375,"children":377},{"style":376},"--shiki-default:#79B8FF",[378],{"type":42,"value":379}," -i",{"type":37,"tag":189,"props":381,"children":382},{"style":376},[383],{"type":42,"value":384}," -X",{"type":37,"tag":189,"props":386,"children":388},{"style":387},"--shiki-default:#9ECBFF",[389],{"type":42,"value":390}," POST",{"type":37,"tag":189,"props":392,"children":393},{"style":376},[394],{"type":42,"value":395}," \\\n",{"type":37,"tag":189,"props":397,"children":398},{"class":191,"line":201},[399,404],{"type":37,"tag":189,"props":400,"children":401},{"style":387},[402],{"type":42,"value":403},"  https://awx.example.internal/api/v2/job_templates/42/launch/",{"type":37,"tag":189,"props":405,"children":406},{"style":376},[407],{"type":42,"value":395},{"type":37,"tag":189,"props":409,"children":410},{"class":191,"line":210},[411,416,421],{"type":37,"tag":189,"props":412,"children":413},{"style":376},[414],{"type":42,"value":415},"  -H",{"type":37,"tag":189,"props":417,"children":418},{"style":387},[419],{"type":42,"value":420}," 'Authorization: Bearer YOUR_AWX_TOKEN'",{"type":37,"tag":189,"props":422,"children":423},{"style":376},[424],{"type":42,"value":395},{"type":37,"tag":189,"props":426,"children":427},{"class":191,"line":219},[428,432,437],{"type":37,"tag":189,"props":429,"children":430},{"style":376},[431],{"type":42,"value":415},{"type":37,"tag":189,"props":433,"children":434},{"style":387},[435],{"type":42,"value":436}," 'Content-Type: application/json'",{"type":37,"tag":189,"props":438,"children":439},{"style":376},[440],{"type":42,"value":395},{"type":37,"tag":189,"props":442,"children":443},{"class":191,"line":228},[444,449],{"type":37,"tag":189,"props":445,"children":446},{"style":376},[447],{"type":42,"value":448},"  -d",{"type":37,"tag":189,"props":450,"children":451},{"style":387},[452],{"type":42,"value":453}," '{\"extra_vars\":{\"revision\":\"abc123\",\"environment\":\"staging\"}}'\n",{"type":37,"tag":38,"props":455,"children":456},{},[457],{"type":42,"value":458},"Confirm AWX creates a job before introducing webhook routing. A direct test separates AWX permissions and template configuration from delivery problems.",{"type":37,"tag":103,"props":460,"children":462},{"id":461},"_3-create-the-webhook-relay-route",[463],{"type":42,"value":464},"3. Create the Webhook Relay route",{"type":37,"tag":38,"props":466,"children":467},{},[468,470,476,478,484],{"type":42,"value":469},"Create a bucket with a public input. If AWX is public, add ",{"type":37,"tag":50,"props":471,"children":473},{"className":472},[],[474],{"type":42,"value":475},"https://awx.example.com",{"type":42,"value":477}," as a ",{"type":37,"tag":155,"props":479,"children":481},{"href":480},"/docs/webhooks/public/public-destination",[482],{"type":42,"value":483},"public output",{"type":42,"value":172},{"type":37,"tag":38,"props":486,"children":487},{},[488],{"type":42,"value":489},"If AWX is private, set the output to its internal base URL and run:",{"type":37,"tag":180,"props":491,"children":493},{"className":358,"code":492,"language":360,"meta":7,"style":7},"relay forward --bucket awx https://awx.example.internal\n",[494],{"type":37,"tag":50,"props":495,"children":496},{"__ignoreMap":7},[497],{"type":37,"tag":189,"props":498,"children":499},{"class":191,"line":192},[500,505,510,515,520],{"type":37,"tag":189,"props":501,"children":502},{"style":370},[503],{"type":42,"value":504},"relay",{"type":37,"tag":189,"props":506,"children":507},{"style":387},[508],{"type":42,"value":509}," forward",{"type":37,"tag":189,"props":511,"children":512},{"style":376},[513],{"type":42,"value":514}," --bucket",{"type":37,"tag":189,"props":516,"children":517},{"style":387},[518],{"type":42,"value":519}," awx",{"type":37,"tag":189,"props":521,"children":522},{"style":387},[523],{"type":42,"value":524}," https://awx.example.internal\n",{"type":37,"tag":38,"props":526,"children":527},{},[528],{"type":42,"value":529},"The agent can run beside AWX, on a bastion, or in the same Kubernetes network, as long as it can resolve the hostname and validate its TLS certificate.",{"type":37,"tag":103,"props":531,"children":533},{"id":532},"_4-filter-and-transform-the-webhook",[534],{"type":42,"value":535},"4. Filter and transform the webhook",{"type":37,"tag":38,"props":537,"children":538},{},[539,541,547,549,555],{"type":42,"value":540},"This synthetic example accepts a deployment request for ",{"type":37,"tag":50,"props":542,"children":544},{"className":543},[],[545],{"type":42,"value":546},"main",{"type":42,"value":548}," or a version tag, then launches job template ",{"type":37,"tag":50,"props":550,"children":552},{"className":551},[],[553],{"type":42,"value":554},"42",{"type":42,"value":556},":",{"type":37,"tag":180,"props":558,"children":562},{"className":559,"code":560,"language":561,"meta":7,"style":7},"language-javascript shiki shiki-themes github-dark","const event = JSON.parse(r.body)\nconst ref = String(event.ref || \"\")\nconst allowedRef = ref === \"refs/heads/main\" || /^refs\\/tags\\/v\\d+\\.\\d+\\.\\d+$/.test(ref)\n\nif (event.type !== \"deployment.requested\" || !allowedRef) {\n  r.stopForwarding()\n  return\n}\n\nconst environment = ref.startsWith(\"refs/tags/\") ? \"production\" : \"staging\"\nconst revision = String(event.revision || \"\")\n\nif (!/^[a-f0-9]{7,40}$/i.test(revision)) {\n  r.stopForwarding()\n  return\n}\n\nconst payload = {\n  extra_vars: {\n    revision,\n    environment,\n    service: \"example-api\",\n    source_event_id: String(event.id || \"\")\n  }\n}\n\nr.setMethod(\"POST\")\nr.setPath(\"/api/v2/job_templates/42/launch/\")\nr.setRawQuery(\"\")\nr.setHeader(\"Authorization\", \"Bearer \" + cfg.get(\"AWX_API_TOKEN\"))\nr.setHeader(\"Content-Type\", \"application/json\")\nr.setBody(JSON.stringify(payload))\n","javascript",[563],{"type":37,"tag":50,"props":564,"children":565},{"__ignoreMap":7},[566,605,646,773,782,819,837,845,853,860,922,960,968,1026,1042,1050,1058,1066,1088,1097,1106,1115,1134,1165,1174,1182,1190,1217,1243,1269,1330,1364],{"type":37,"tag":189,"props":567,"children":568},{"class":191,"line":192},[569,575,580,585,590,595,600],{"type":37,"tag":189,"props":570,"children":572},{"style":571},"--shiki-default:#F97583",[573],{"type":42,"value":574},"const",{"type":37,"tag":189,"props":576,"children":577},{"style":376},[578],{"type":42,"value":579}," event",{"type":37,"tag":189,"props":581,"children":582},{"style":571},[583],{"type":42,"value":584}," =",{"type":37,"tag":189,"props":586,"children":587},{"style":376},[588],{"type":42,"value":589}," JSON",{"type":37,"tag":189,"props":591,"children":593},{"style":592},"--shiki-default:#E1E4E8",[594],{"type":42,"value":172},{"type":37,"tag":189,"props":596,"children":597},{"style":370},[598],{"type":42,"value":599},"parse",{"type":37,"tag":189,"props":601,"children":602},{"style":592},[603],{"type":42,"value":604},"(r.body)\n",{"type":37,"tag":189,"props":606,"children":607},{"class":191,"line":201},[608,612,617,621,626,631,636,641],{"type":37,"tag":189,"props":609,"children":610},{"style":571},[611],{"type":42,"value":574},{"type":37,"tag":189,"props":613,"children":614},{"style":376},[615],{"type":42,"value":616}," ref",{"type":37,"tag":189,"props":618,"children":619},{"style":571},[620],{"type":42,"value":584},{"type":37,"tag":189,"props":622,"children":623},{"style":370},[624],{"type":42,"value":625}," String",{"type":37,"tag":189,"props":627,"children":628},{"style":592},[629],{"type":42,"value":630},"(event.ref ",{"type":37,"tag":189,"props":632,"children":633},{"style":571},[634],{"type":42,"value":635},"||",{"type":37,"tag":189,"props":637,"children":638},{"style":387},[639],{"type":42,"value":640}," \"\"",{"type":37,"tag":189,"props":642,"children":643},{"style":592},[644],{"type":42,"value":645},")\n",{"type":37,"tag":189,"props":647,"children":648},{"class":191,"line":210},[649,653,658,662,667,672,677,682,687,692,698,704,709,713,718,723,728,733,737,741,745,749,754,759,763,768],{"type":37,"tag":189,"props":650,"children":651},{"style":571},[652],{"type":42,"value":574},{"type":37,"tag":189,"props":654,"children":655},{"style":376},[656],{"type":42,"value":657}," allowedRef",{"type":37,"tag":189,"props":659,"children":660},{"style":571},[661],{"type":42,"value":584},{"type":37,"tag":189,"props":663,"children":664},{"style":592},[665],{"type":42,"value":666}," ref ",{"type":37,"tag":189,"props":668,"children":669},{"style":571},[670],{"type":42,"value":671},"===",{"type":37,"tag":189,"props":673,"children":674},{"style":387},[675],{"type":42,"value":676}," \"refs/heads/main\"",{"type":37,"tag":189,"props":678,"children":679},{"style":571},[680],{"type":42,"value":681}," ||",{"type":37,"tag":189,"props":683,"children":684},{"style":387},[685],{"type":42,"value":686}," /",{"type":37,"tag":189,"props":688,"children":689},{"style":571},[690],{"type":42,"value":691},"^",{"type":37,"tag":189,"props":693,"children":695},{"style":694},"--shiki-default:#DBEDFF",[696],{"type":42,"value":697},"refs",{"type":37,"tag":189,"props":699,"children":701},{"style":700},"--shiki-default:#85E89D;--shiki-default-font-weight:bold",[702],{"type":42,"value":703},"\\/",{"type":37,"tag":189,"props":705,"children":706},{"style":694},[707],{"type":42,"value":708},"tags",{"type":37,"tag":189,"props":710,"children":711},{"style":700},[712],{"type":42,"value":703},{"type":37,"tag":189,"props":714,"children":715},{"style":694},[716],{"type":42,"value":717},"v",{"type":37,"tag":189,"props":719,"children":720},{"style":376},[721],{"type":42,"value":722},"\\d",{"type":37,"tag":189,"props":724,"children":725},{"style":571},[726],{"type":42,"value":727},"+",{"type":37,"tag":189,"props":729,"children":730},{"style":700},[731],{"type":42,"value":732},"\\.",{"type":37,"tag":189,"props":734,"children":735},{"style":376},[736],{"type":42,"value":722},{"type":37,"tag":189,"props":738,"children":739},{"style":571},[740],{"type":42,"value":727},{"type":37,"tag":189,"props":742,"children":743},{"style":700},[744],{"type":42,"value":732},{"type":37,"tag":189,"props":746,"children":747},{"style":376},[748],{"type":42,"value":722},{"type":37,"tag":189,"props":750,"children":751},{"style":571},[752],{"type":42,"value":753},"+$",{"type":37,"tag":189,"props":755,"children":756},{"style":387},[757],{"type":42,"value":758},"/",{"type":37,"tag":189,"props":760,"children":761},{"style":592},[762],{"type":42,"value":172},{"type":37,"tag":189,"props":764,"children":765},{"style":370},[766],{"type":42,"value":767},"test",{"type":37,"tag":189,"props":769,"children":770},{"style":592},[771],{"type":42,"value":772},"(ref)\n",{"type":37,"tag":189,"props":774,"children":775},{"class":191,"line":219},[776],{"type":37,"tag":189,"props":777,"children":779},{"emptyLinePlaceholder":778},true,[780],{"type":42,"value":781},"\n",{"type":37,"tag":189,"props":783,"children":784},{"class":191,"line":228},[785,790,795,800,805,809,814],{"type":37,"tag":189,"props":786,"children":787},{"style":571},[788],{"type":42,"value":789},"if",{"type":37,"tag":189,"props":791,"children":792},{"style":592},[793],{"type":42,"value":794}," (event.type ",{"type":37,"tag":189,"props":796,"children":797},{"style":571},[798],{"type":42,"value":799},"!==",{"type":37,"tag":189,"props":801,"children":802},{"style":387},[803],{"type":42,"value":804}," \"deployment.requested\"",{"type":37,"tag":189,"props":806,"children":807},{"style":571},[808],{"type":42,"value":681},{"type":37,"tag":189,"props":810,"children":811},{"style":571},[812],{"type":42,"value":813}," !",{"type":37,"tag":189,"props":815,"children":816},{"style":592},[817],{"type":42,"value":818},"allowedRef) {\n",{"type":37,"tag":189,"props":820,"children":821},{"class":191,"line":237},[822,827,832],{"type":37,"tag":189,"props":823,"children":824},{"style":592},[825],{"type":42,"value":826},"  r.",{"type":37,"tag":189,"props":828,"children":829},{"style":370},[830],{"type":42,"value":831},"stopForwarding",{"type":37,"tag":189,"props":833,"children":834},{"style":592},[835],{"type":42,"value":836},"()\n",{"type":37,"tag":189,"props":838,"children":839},{"class":191,"line":245},[840],{"type":37,"tag":189,"props":841,"children":842},{"style":571},[843],{"type":42,"value":844},"  return\n",{"type":37,"tag":189,"props":846,"children":847},{"class":191,"line":254},[848],{"type":37,"tag":189,"props":849,"children":850},{"style":592},[851],{"type":42,"value":852},"}\n",{"type":37,"tag":189,"props":854,"children":855},{"class":191,"line":262},[856],{"type":37,"tag":189,"props":857,"children":858},{"emptyLinePlaceholder":778},[859],{"type":42,"value":781},{"type":37,"tag":189,"props":861,"children":863},{"class":191,"line":862},10,[864,868,873,877,882,887,892,897,902,907,912,917],{"type":37,"tag":189,"props":865,"children":866},{"style":571},[867],{"type":42,"value":574},{"type":37,"tag":189,"props":869,"children":870},{"style":376},[871],{"type":42,"value":872}," environment",{"type":37,"tag":189,"props":874,"children":875},{"style":571},[876],{"type":42,"value":584},{"type":37,"tag":189,"props":878,"children":879},{"style":592},[880],{"type":42,"value":881}," ref.",{"type":37,"tag":189,"props":883,"children":884},{"style":370},[885],{"type":42,"value":886},"startsWith",{"type":37,"tag":189,"props":888,"children":889},{"style":592},[890],{"type":42,"value":891},"(",{"type":37,"tag":189,"props":893,"children":894},{"style":387},[895],{"type":42,"value":896},"\"refs/tags/\"",{"type":37,"tag":189,"props":898,"children":899},{"style":592},[900],{"type":42,"value":901},") ",{"type":37,"tag":189,"props":903,"children":904},{"style":571},[905],{"type":42,"value":906},"?",{"type":37,"tag":189,"props":908,"children":909},{"style":387},[910],{"type":42,"value":911}," \"production\"",{"type":37,"tag":189,"props":913,"children":914},{"style":571},[915],{"type":42,"value":916}," :",{"type":37,"tag":189,"props":918,"children":919},{"style":387},[920],{"type":42,"value":921}," \"staging\"\n",{"type":37,"tag":189,"props":923,"children":925},{"class":191,"line":924},11,[926,930,935,939,943,948,952,956],{"type":37,"tag":189,"props":927,"children":928},{"style":571},[929],{"type":42,"value":574},{"type":37,"tag":189,"props":931,"children":932},{"style":376},[933],{"type":42,"value":934}," revision",{"type":37,"tag":189,"props":936,"children":937},{"style":571},[938],{"type":42,"value":584},{"type":37,"tag":189,"props":940,"children":941},{"style":370},[942],{"type":42,"value":625},{"type":37,"tag":189,"props":944,"children":945},{"style":592},[946],{"type":42,"value":947},"(event.revision ",{"type":37,"tag":189,"props":949,"children":950},{"style":571},[951],{"type":42,"value":635},{"type":37,"tag":189,"props":953,"children":954},{"style":387},[955],{"type":42,"value":640},{"type":37,"tag":189,"props":957,"children":958},{"style":592},[959],{"type":42,"value":645},{"type":37,"tag":189,"props":961,"children":963},{"class":191,"line":962},12,[964],{"type":37,"tag":189,"props":965,"children":966},{"emptyLinePlaceholder":778},[967],{"type":42,"value":781},{"type":37,"tag":189,"props":969,"children":971},{"class":191,"line":970},13,[972,976,981,986,990,994,999,1004,1008,1013,1017,1021],{"type":37,"tag":189,"props":973,"children":974},{"style":571},[975],{"type":42,"value":789},{"type":37,"tag":189,"props":977,"children":978},{"style":592},[979],{"type":42,"value":980}," (",{"type":37,"tag":189,"props":982,"children":983},{"style":571},[984],{"type":42,"value":985},"!",{"type":37,"tag":189,"props":987,"children":988},{"style":387},[989],{"type":42,"value":758},{"type":37,"tag":189,"props":991,"children":992},{"style":571},[993],{"type":42,"value":691},{"type":37,"tag":189,"props":995,"children":996},{"style":376},[997],{"type":42,"value":998},"[a-f0-9]",{"type":37,"tag":189,"props":1000,"children":1001},{"style":571},[1002],{"type":42,"value":1003},"{7,40}$",{"type":37,"tag":189,"props":1005,"children":1006},{"style":387},[1007],{"type":42,"value":758},{"type":37,"tag":189,"props":1009,"children":1010},{"style":571},[1011],{"type":42,"value":1012},"i",{"type":37,"tag":189,"props":1014,"children":1015},{"style":592},[1016],{"type":42,"value":172},{"type":37,"tag":189,"props":1018,"children":1019},{"style":370},[1020],{"type":42,"value":767},{"type":37,"tag":189,"props":1022,"children":1023},{"style":592},[1024],{"type":42,"value":1025},"(revision)) {\n",{"type":37,"tag":189,"props":1027,"children":1029},{"class":191,"line":1028},14,[1030,1034,1038],{"type":37,"tag":189,"props":1031,"children":1032},{"style":592},[1033],{"type":42,"value":826},{"type":37,"tag":189,"props":1035,"children":1036},{"style":370},[1037],{"type":42,"value":831},{"type":37,"tag":189,"props":1039,"children":1040},{"style":592},[1041],{"type":42,"value":836},{"type":37,"tag":189,"props":1043,"children":1045},{"class":191,"line":1044},15,[1046],{"type":37,"tag":189,"props":1047,"children":1048},{"style":571},[1049],{"type":42,"value":844},{"type":37,"tag":189,"props":1051,"children":1053},{"class":191,"line":1052},16,[1054],{"type":37,"tag":189,"props":1055,"children":1056},{"style":592},[1057],{"type":42,"value":852},{"type":37,"tag":189,"props":1059,"children":1061},{"class":191,"line":1060},17,[1062],{"type":37,"tag":189,"props":1063,"children":1064},{"emptyLinePlaceholder":778},[1065],{"type":42,"value":781},{"type":37,"tag":189,"props":1067,"children":1069},{"class":191,"line":1068},18,[1070,1074,1079,1083],{"type":37,"tag":189,"props":1071,"children":1072},{"style":571},[1073],{"type":42,"value":574},{"type":37,"tag":189,"props":1075,"children":1076},{"style":376},[1077],{"type":42,"value":1078}," payload",{"type":37,"tag":189,"props":1080,"children":1081},{"style":571},[1082],{"type":42,"value":584},{"type":37,"tag":189,"props":1084,"children":1085},{"style":592},[1086],{"type":42,"value":1087}," {\n",{"type":37,"tag":189,"props":1089,"children":1091},{"class":191,"line":1090},19,[1092],{"type":37,"tag":189,"props":1093,"children":1094},{"style":592},[1095],{"type":42,"value":1096},"  extra_vars: {\n",{"type":37,"tag":189,"props":1098,"children":1100},{"class":191,"line":1099},20,[1101],{"type":37,"tag":189,"props":1102,"children":1103},{"style":592},[1104],{"type":42,"value":1105},"    revision,\n",{"type":37,"tag":189,"props":1107,"children":1109},{"class":191,"line":1108},21,[1110],{"type":37,"tag":189,"props":1111,"children":1112},{"style":592},[1113],{"type":42,"value":1114},"    environment,\n",{"type":37,"tag":189,"props":1116,"children":1118},{"class":191,"line":1117},22,[1119,1124,1129],{"type":37,"tag":189,"props":1120,"children":1121},{"style":592},[1122],{"type":42,"value":1123},"    service: ",{"type":37,"tag":189,"props":1125,"children":1126},{"style":387},[1127],{"type":42,"value":1128},"\"example-api\"",{"type":37,"tag":189,"props":1130,"children":1131},{"style":592},[1132],{"type":42,"value":1133},",\n",{"type":37,"tag":189,"props":1135,"children":1137},{"class":191,"line":1136},23,[1138,1143,1148,1153,1157,1161],{"type":37,"tag":189,"props":1139,"children":1140},{"style":592},[1141],{"type":42,"value":1142},"    source_event_id: ",{"type":37,"tag":189,"props":1144,"children":1145},{"style":370},[1146],{"type":42,"value":1147},"String",{"type":37,"tag":189,"props":1149,"children":1150},{"style":592},[1151],{"type":42,"value":1152},"(event.id ",{"type":37,"tag":189,"props":1154,"children":1155},{"style":571},[1156],{"type":42,"value":635},{"type":37,"tag":189,"props":1158,"children":1159},{"style":387},[1160],{"type":42,"value":640},{"type":37,"tag":189,"props":1162,"children":1163},{"style":592},[1164],{"type":42,"value":645},{"type":37,"tag":189,"props":1166,"children":1168},{"class":191,"line":1167},24,[1169],{"type":37,"tag":189,"props":1170,"children":1171},{"style":592},[1172],{"type":42,"value":1173},"  }\n",{"type":37,"tag":189,"props":1175,"children":1177},{"class":191,"line":1176},25,[1178],{"type":37,"tag":189,"props":1179,"children":1180},{"style":592},[1181],{"type":42,"value":852},{"type":37,"tag":189,"props":1183,"children":1185},{"class":191,"line":1184},26,[1186],{"type":37,"tag":189,"props":1187,"children":1188},{"emptyLinePlaceholder":778},[1189],{"type":42,"value":781},{"type":37,"tag":189,"props":1191,"children":1193},{"class":191,"line":1192},27,[1194,1199,1204,1208,1213],{"type":37,"tag":189,"props":1195,"children":1196},{"style":592},[1197],{"type":42,"value":1198},"r.",{"type":37,"tag":189,"props":1200,"children":1201},{"style":370},[1202],{"type":42,"value":1203},"setMethod",{"type":37,"tag":189,"props":1205,"children":1206},{"style":592},[1207],{"type":42,"value":891},{"type":37,"tag":189,"props":1209,"children":1210},{"style":387},[1211],{"type":42,"value":1212},"\"POST\"",{"type":37,"tag":189,"props":1214,"children":1215},{"style":592},[1216],{"type":42,"value":645},{"type":37,"tag":189,"props":1218,"children":1220},{"class":191,"line":1219},28,[1221,1225,1230,1234,1239],{"type":37,"tag":189,"props":1222,"children":1223},{"style":592},[1224],{"type":42,"value":1198},{"type":37,"tag":189,"props":1226,"children":1227},{"style":370},[1228],{"type":42,"value":1229},"setPath",{"type":37,"tag":189,"props":1231,"children":1232},{"style":592},[1233],{"type":42,"value":891},{"type":37,"tag":189,"props":1235,"children":1236},{"style":387},[1237],{"type":42,"value":1238},"\"/api/v2/job_templates/42/launch/\"",{"type":37,"tag":189,"props":1240,"children":1241},{"style":592},[1242],{"type":42,"value":645},{"type":37,"tag":189,"props":1244,"children":1246},{"class":191,"line":1245},29,[1247,1251,1256,1260,1265],{"type":37,"tag":189,"props":1248,"children":1249},{"style":592},[1250],{"type":42,"value":1198},{"type":37,"tag":189,"props":1252,"children":1253},{"style":370},[1254],{"type":42,"value":1255},"setRawQuery",{"type":37,"tag":189,"props":1257,"children":1258},{"style":592},[1259],{"type":42,"value":891},{"type":37,"tag":189,"props":1261,"children":1262},{"style":387},[1263],{"type":42,"value":1264},"\"\"",{"type":37,"tag":189,"props":1266,"children":1267},{"style":592},[1268],{"type":42,"value":645},{"type":37,"tag":189,"props":1270,"children":1272},{"class":191,"line":1271},30,[1273,1277,1282,1286,1291,1296,1301,1306,1311,1316,1320,1325],{"type":37,"tag":189,"props":1274,"children":1275},{"style":592},[1276],{"type":42,"value":1198},{"type":37,"tag":189,"props":1278,"children":1279},{"style":370},[1280],{"type":42,"value":1281},"setHeader",{"type":37,"tag":189,"props":1283,"children":1284},{"style":592},[1285],{"type":42,"value":891},{"type":37,"tag":189,"props":1287,"children":1288},{"style":387},[1289],{"type":42,"value":1290},"\"Authorization\"",{"type":37,"tag":189,"props":1292,"children":1293},{"style":592},[1294],{"type":42,"value":1295},", ",{"type":37,"tag":189,"props":1297,"children":1298},{"style":387},[1299],{"type":42,"value":1300},"\"Bearer \"",{"type":37,"tag":189,"props":1302,"children":1303},{"style":571},[1304],{"type":42,"value":1305}," +",{"type":37,"tag":189,"props":1307,"children":1308},{"style":592},[1309],{"type":42,"value":1310}," cfg.",{"type":37,"tag":189,"props":1312,"children":1313},{"style":370},[1314],{"type":42,"value":1315},"get",{"type":37,"tag":189,"props":1317,"children":1318},{"style":592},[1319],{"type":42,"value":891},{"type":37,"tag":189,"props":1321,"children":1322},{"style":387},[1323],{"type":42,"value":1324},"\"AWX_API_TOKEN\"",{"type":37,"tag":189,"props":1326,"children":1327},{"style":592},[1328],{"type":42,"value":1329},"))\n",{"type":37,"tag":189,"props":1331,"children":1333},{"class":191,"line":1332},31,[1334,1338,1342,1346,1351,1355,1360],{"type":37,"tag":189,"props":1335,"children":1336},{"style":592},[1337],{"type":42,"value":1198},{"type":37,"tag":189,"props":1339,"children":1340},{"style":370},[1341],{"type":42,"value":1281},{"type":37,"tag":189,"props":1343,"children":1344},{"style":592},[1345],{"type":42,"value":891},{"type":37,"tag":189,"props":1347,"children":1348},{"style":387},[1349],{"type":42,"value":1350},"\"Content-Type\"",{"type":37,"tag":189,"props":1352,"children":1353},{"style":592},[1354],{"type":42,"value":1295},{"type":37,"tag":189,"props":1356,"children":1357},{"style":387},[1358],{"type":42,"value":1359},"\"application/json\"",{"type":37,"tag":189,"props":1361,"children":1362},{"style":592},[1363],{"type":42,"value":645},{"type":37,"tag":189,"props":1365,"children":1367},{"class":191,"line":1366},32,[1368,1372,1377,1381,1386,1390,1395],{"type":37,"tag":189,"props":1369,"children":1370},{"style":592},[1371],{"type":42,"value":1198},{"type":37,"tag":189,"props":1373,"children":1374},{"style":370},[1375],{"type":42,"value":1376},"setBody",{"type":37,"tag":189,"props":1378,"children":1379},{"style":592},[1380],{"type":42,"value":891},{"type":37,"tag":189,"props":1382,"children":1383},{"style":376},[1384],{"type":42,"value":1385},"JSON",{"type":37,"tag":189,"props":1387,"children":1388},{"style":592},[1389],{"type":42,"value":172},{"type":37,"tag":189,"props":1391,"children":1392},{"style":370},[1393],{"type":42,"value":1394},"stringify",{"type":37,"tag":189,"props":1396,"children":1397},{"style":592},[1398],{"type":42,"value":1399},"(payload))\n",{"type":37,"tag":38,"props":1401,"children":1402},{},[1403,1405,1411],{"type":42,"value":1404},"Add ",{"type":37,"tag":50,"props":1406,"children":1408},{"className":1407},[],[1409],{"type":42,"value":1410},"AWX_API_TOKEN",{"type":42,"value":1412}," under the function's configuration values. Attach the function to the AWX output so other outputs can still receive the original event.",{"type":37,"tag":38,"props":1414,"children":1415},{},[1416,1418,1424],{"type":42,"value":1417},"Adapt the event names and fields to your provider. For GitHub or Bitbucket, filter using the provider event header and its documented push payload. The ",{"type":37,"tag":155,"props":1419,"children":1421},{"href":1420},"/blog/webhook-rule-based-filters",[1422],{"type":42,"value":1423},"webhook filtering guide",{"type":42,"value":1425}," has branch and tag examples.",{"type":37,"tag":103,"props":1427,"children":1429},{"id":1428},"_5-verify-the-source-before-launching-automation",[1430],{"type":42,"value":1431},"5. Verify the source before launching automation",{"type":37,"tag":38,"props":1433,"children":1434},{},[1435],{"type":42,"value":1436},"Filtering a field is not authentication. Before an untrusted public request can run an AWX job:",{"type":37,"tag":120,"props":1438,"children":1439},{},[1440,1445,1450,1455,1460,1465],{"type":37,"tag":124,"props":1441,"children":1442},{},[1443],{"type":42,"value":1444},"Configure and verify the provider's webhook signature or secret.",{"type":37,"tag":124,"props":1446,"children":1447},{},[1448],{"type":42,"value":1449},"Allowlist event types and refs.",{"type":37,"tag":124,"props":1451,"children":1452},{},[1453],{"type":42,"value":1454},"Map approved fields into a new object rather than forwarding the whole body.",{"type":37,"tag":124,"props":1456,"children":1457},{},[1458],{"type":42,"value":1459},"Validate revisions, inventory choices and environment names.",{"type":37,"tag":124,"props":1461,"children":1462},{},[1463],{"type":42,"value":1464},"Give the AWX service account the smallest usable role.",{"type":37,"tag":124,"props":1466,"children":1467},{},[1468],{"type":42,"value":1469},"Avoid accepting credentials, command fragments or playbook paths from the webhook.",{"type":37,"tag":38,"props":1471,"children":1472},{},[1473,1475,1481],{"type":42,"value":1474},"For GitHub and Bitbucket HMAC examples, see ",{"type":37,"tag":155,"props":1476,"children":1478},{"href":1477},"/blog/verify-webhook-signature",[1479],{"type":42,"value":1480},"how to verify a webhook signature",{"type":42,"value":172},{"type":37,"tag":103,"props":1483,"children":1485},{"id":1484},"_6-test-and-observe-the-launch",[1486],{"type":42,"value":1487},"6. Test and observe the launch",{"type":37,"tag":38,"props":1489,"children":1490},{},[1491],{"type":42,"value":1492},"Send a test event and inspect both sides:",{"type":37,"tag":1494,"props":1495,"children":1496},"ol",{},[1497,1509,1520,1532],{"type":37,"tag":124,"props":1498,"children":1499},{},[1500,1502,1507],{"type":42,"value":1501},"Webhook Relay should show the transformed ",{"type":37,"tag":50,"props":1503,"children":1505},{"className":1504},[],[1506],{"type":42,"value":63},{"type":42,"value":1508},", AWX path and response status.",{"type":37,"tag":124,"props":1510,"children":1511},{},[1512,1514,1519],{"type":42,"value":1513},"AWX should create a job linked to template ",{"type":37,"tag":50,"props":1515,"children":1517},{"className":1516},[],[1518],{"type":42,"value":554},{"type":42,"value":172},{"type":37,"tag":124,"props":1521,"children":1522},{},[1523,1525,1530],{"type":42,"value":1524},"The job's ",{"type":37,"tag":298,"props":1526,"children":1527},{},[1528],{"type":42,"value":1529},"Extra Variables",{"type":42,"value":1531}," should contain only the mapped allowlist.",{"type":37,"tag":124,"props":1533,"children":1534},{},[1535],{"type":42,"value":1536},"A feature-branch or malformed event should be marked rejected and should not create a job.",{"type":37,"tag":38,"props":1538,"children":1539},{},[1540,1542,1548],{"type":42,"value":1541},"Keep ",{"type":37,"tag":50,"props":1543,"children":1545},{"className":1544},[],[1546],{"type":42,"value":1547},"source_event_id",{"type":42,"value":1549}," when the provider supplies a stable ID. AWX may create another job if a webhook is retried after an ambiguous response, so use the ID in your playbook or an external lock when duplicate execution would be dangerous.",{"type":37,"tag":103,"props":1551,"children":1553},{"id":1552},"troubleshooting",[1554],{"type":42,"value":1555},"Troubleshooting",{"type":37,"tag":1557,"props":1558,"children":1560},"h3",{"id":1559},"awx-returns-401-or-403",[1561],{"type":42,"value":1562},"AWX returns 401 or 403",{"type":37,"tag":38,"props":1564,"children":1565},{},[1566,1568,1574],{"type":42,"value":1567},"Check the token, its owner, template execute permission and the exact ",{"type":37,"tag":50,"props":1569,"children":1571},{"className":1570},[],[1572],{"type":42,"value":1573},"Authorization: Bearer ...",{"type":42,"value":1575}," header. Confirm the configuration value exists on the function actually attached to the output.",{"type":37,"tag":1557,"props":1577,"children":1579},{"id":1578},"awx-returns-404",[1580],{"type":42,"value":1581},"AWX returns 404",{"type":37,"tag":38,"props":1583,"children":1584},{},[1585,1587,1593],{"type":42,"value":1586},"Verify the template ID and keep the trailing slash in ",{"type":37,"tag":50,"props":1588,"children":1590},{"className":1589},[],[1591],{"type":42,"value":1592},"/launch/",{"type":42,"value":1594},". Inspect the final transformed path in the delivery log.",{"type":37,"tag":1557,"props":1596,"children":1598},{"id":1597},"awx-rejects-extra_vars",[1599,1601],{"type":42,"value":1600},"AWX rejects ",{"type":37,"tag":50,"props":1602,"children":1604},{"className":1603},[],[1605],{"type":42,"value":55},{"type":37,"tag":38,"props":1607,"children":1608},{},[1609],{"type":42,"value":1610},"Open the template launch configuration and allow only the required variables through Prompt on launch or a survey. Test the same body directly with curl to see AWX's full validation response.",{"type":37,"tag":1557,"props":1612,"children":1614},{"id":1613},"the-relay-agent-cannot-reach-awx",[1615],{"type":42,"value":1616},"The relay agent cannot reach AWX",{"type":37,"tag":38,"props":1618,"children":1619},{},[1620],{"type":42,"value":1621},"Test DNS and HTTPS from the agent host or container. Internal certificate trust, proxy configuration and split DNS are common causes. The source webhook reaching Webhook Relay only proves the public half of the route works.",{"type":37,"tag":1557,"props":1623,"children":1625},{"id":1624},"the-same-webhook-launches-two-jobs",[1626],{"type":42,"value":1627},"The same webhook launches two jobs",{"type":37,"tag":38,"props":1629,"children":1630},{},[1631,1633,1639],{"type":42,"value":1632},"Assume webhooks can be retried. Deduplicate by the provider event ID, or make the launched playbook idempotent and safe to repeat. The ",{"type":37,"tag":155,"props":1634,"children":1636},{"href":1635},"/blog/webhook-retries-and-idempotency",[1637],{"type":42,"value":1638},"retries and idempotency guide",{"type":42,"value":1640}," covers the delivery model.",{"type":37,"tag":38,"props":1642,"children":1643},{},[1644,1646,1652],{"type":42,"value":1645},"For more integrations that change method, path, headers and body, use the ",{"type":37,"tag":155,"props":1647,"children":1649},{"href":1648},"/blog/auto-transform-webhook",[1650],{"type":42,"value":1651},"webhook transformation cookbook",{"type":42,"value":172},{"type":37,"tag":1654,"props":1655,"children":1656},"style",{},[1657],{"type":42,"value":1658},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":210,"depth":210,"links":1660},[1661,1662,1663,1664,1665,1666,1667,1668,1669],{"id":105,"depth":201,"text":108},{"id":175,"depth":201,"text":178},{"id":276,"depth":201,"text":279},{"id":347,"depth":201,"text":350},{"id":461,"depth":201,"text":464},{"id":532,"depth":201,"text":535},{"id":1428,"depth":201,"text":1431},{"id":1484,"depth":201,"text":1487},{"id":1552,"depth":201,"text":1555,"children":1670},[1671,1672,1673,1675,1676],{"id":1559,"depth":210,"text":1562},{"id":1578,"depth":210,"text":1581},{"id":1597,"depth":210,"text":1674},"AWX rejects extra_vars",{"id":1613,"depth":210,"text":1616},{"id":1624,"depth":210,"text":1627},"markdown","content:blog:awx-job-template-webhook.md","content","blog/awx-job-template-webhook.md","blog/awx-job-template-webhook","md",{"loc":4},1788727846973]