Automating Incident Response: Jira ↔ AWS DevOps Agent Bidirectional Integration
AWS Devops Agent Integration with Jira
The Problem
When an incident ticket is created in Jira, engineers manually investigate — correlating CloudWatch metrics, deployment history, and logs. This takes 2–4 hours per incident. Meanwhile, the Jira ticket sits waiting for someone to add findings.
AWS DevOps Agent can investigate autonomously in under 2 minutes, however the service does not have native integration for Jira. This blog talks about connecting devops agent bidirectionally to Jira using webhooks — so that a Jira issue triggers an investigation AND the findings automatically appear as a Jira comment — requires a few extra pieces.
Architecture
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
┌─────────────────────────────────────────────────────────────────────┐
│ │
│ Jira Issue Created │
│ │ │
│ │ Jira Webhook (native) │
│ ▼ │
│ API Gateway ──► Bridge Lambda │
│ │ │
│ │ HMAC-signed payload │
│ ▼ │
│ AWS DevOps Agent Webhook │
│ │ │
│ ▼ │
│ Investigation Runs (~2 min) │
│ │ │
│ ▼ │
│ EventBridge │
│ "Investigation Completed" │
│ │ │
│ ▼ │
│ Writer Lambda │
│ │ GetBacklogTask → extract Jira key │
│ │ ListJournalRecords → fetch summary │
│ ▼ │
│ Jira REST API → POST /issue/{key}/comment │
│ │ │
│ ▼ │
│ Jira Ticket Updated with Investigation Findings ✅ │
│ │
└─────────────────────────────────────────────────────────────────────┘Why a Bridge Lambda is Required
Jira's native webhook cannot directly trigger AWS DevOps Agent. Here's why:
| Jira sends | DevOps Agent expects | |
|---|---|---|
| Signature header | X-Hub-Signature: sha256=<hex> | x-amzn-event-signature: <base64> |
| Timestamp | Not included | x-amzn-event-timestamp: <ISO8601> |
| Signature input | HMAC(secret, body) | HMAC(secret, timestamp + ":" + body) |
| Payload schema | Jira native format | {eventType, incidentId, priority, title...} |
The Bridge Lambda handles:
- Receiving Jira's native payload
- Transforming it to DevOps Agent's expected schema
- Computing the correct HMAC signature (
timestamp:body→ base64) - Adding
[Jira MDP-X]prefix to the title — this is the key that enables write-back
How Write-back Works (The Clever Part)
The EventBridge event from DevOps Agent only contains a
task_id — no Jira issue key. To post back to the correct ticket, we use the title we set:1
2
3
Bridge Lambda sets title: "[Jira MDP-16-1780950336] Payment service errors"
↑
Jira key embeddedWhen investigation completes, the Writer Lambda:
- Calls
devops-agent:GetBacklogTask(task_id)→ gets the title andreferenceId - Parses
MDP-16fromreferenceId: "MDP-16-1780950336" - Calls
devops-agent:ListBacklogTasks→ finds all other tickets linked to this investigation (e.g.MDP-17,MDP-19) - Calls
devops-agent:ListJournalRecords(executionId)→ gets the full investigation summary - Posts the right comment to each ticket — different message for original vs linked tickets
No DynamoDB, no state management — the Jira key is embedded in the investigation itself, and
ListBacklogTasks provides the fan-out to linked tickets.What Gets Posted to Jira
Original ticket (investigation ran fresh)
1
2
3
4
5
6
7
8
AWS DevOps Agent — Investigation Completed
Status: COMPLETED | Task ID: dd57da79-...
Findings:
[Full RCA summary from DevOps Agent]
View full investigation in the AWS DevOps Agent console.Linked ticket (similar incident seen before)
1
2
3
4
5
6
7
8
9
10
AWS DevOps Agent — Investigation Linked
This incident is similar to a previously investigated issue.
Linked to original investigation from: MDP-16
Task ID: dd57da79-...
Investigation findings from the original incident:
[Summary from the original investigation]
View full investigation in the AWS DevOps Agent console.The linked message tells engineers exactly which ticket the original investigation came from, so they can reference it directly without hunting through the DevOps Agent console.
What Triggers a Comment for Every Outcome
The EventBridge rule catches all investigation lifecycle events — no ticket is ever left without a response:
| Event | Who gets the comment | What the comment says |
|---|---|---|
Investigation Completed | Original ticket only | Full findings + RCA summary |
Investigation Linked | Both original AND newly linked ticket | Original: findings. Linked: "linked to MDP-X" + findings |
Investigation Failed | Original ticket | "Could not complete — investigate manually" |
Investigation Timed Out | Original ticket | "Timed out" |
Investigation Cancelled | Original ticket | "Cancelled" |
Investigation Skipped | Original ticket | "Skipped based on skill criteria" |
Prerequisites
- AWS account with DevOps Agent enabled and an Agent Space configured
- Atlassian Jira Cloud account
- AWS CLI configured (
aws sts get-caller-identityworks) - SAM CLI installed —
pip install aws-sam-cli
Setup — Two Options
📁 All required files available here: Amazon WorkDocs — jira-devops-bridge
Download the completejira-devops-bridgefolder which containstemplate.yaml,bridge_lambda/,writer_lambda/, and the Kiro steering file. Follow either option below.
Option A: Use Kiro (Recommended — automated end-to-end)
Kiro can build and deploy the entire integration for you with zero manual file creation.
Step 1 — Add the steering file
Download the steering file from this repo:
1
.kiro/steering/jira-devops-agent-integration.mdCopy it into your workspace at
.kiro/steering/jira-devops-agent-integration.md.Step 2 — Tell Kiro to install it
Open Kiro and say:
1
Install the Jira DevOps Agent integrationKiro will:
- Ask you for the 6 required credentials (webhook URL, webhook secret, Jira URL, Jira email, Jira API token, Agent Space ID)
- Create all project files (
template.yaml,bridge_lambda/index.py,writer_lambda/index.py) - Run
sam buildandsam deployautomatically - Output the Jira webhook URL to configure
Step 3 — Configure Jira webhook
Kiro will tell you the API Gateway URL. Paste it into Jira:
- Go to
https://<your-org>.atlassian.net/plugins/servlet/webhooks - Click Create a WebHook
- Set URL to the output from Kiro, Events to Issue → created
- Save
Option B: Manual Setup
If you prefer to deploy manually without Kiro.
Step 1 — Get required credentials
| Credential | Where to find it |
|---|---|
| DevOps Agent Webhook URL | Agent Space → Capabilities → Webhook → Generate webhook |
| DevOps Agent Webhook Secret | Shown once when generating the webhook |
| Jira base URL | https://<your-org>.atlassian.net |
| Jira email | Your Atlassian account email |
| Jira API token | https://id.atlassian.com/manage-profile/security/api-tokens |
| Agent Space ID | UUID from DevOps Agent console URL or EventBridge events |
Step 2 — Download the folder and build
Download the complete
jira-devops-bridge folder from Amazon WorkDocs . It contains all files ready to deploy:1
2
3
4
5
6
7
8
jira-devops-bridge/
├── template.yaml ← SAM stack definition
├── bridge_lambda/
│ └── index.py ← Bridge Lambda code
├── writer_lambda/
│ └── index.py ← Writer Lambda code
└── .kiro/steering/
└── jira-devops-agent-integration.md ← Kiro steering fileThen build:
1
2
cd jira-devops-bridge
sam buildStep 3 — Deploy
The SAM stack creates all AWS resources automatically:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sam deploy \
--template-file template.yaml \
--stack-name jira-devops-bridge \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides \
"DevOpsAgentWebhookUrl=<your-webhook-url>" \
"DevOpsAgentWebhookSecret=<your-webhook-secret>" \
"JiraBaseUrl=<https://yourorg.atlassian.net>" \
"JiraEmail=<your-jira-email>" \
"JiraApiToken=<your-jira-api-token>" \
"AgentSpaceId=<your-agent-space-id>" \
--resolve-s3 \
--region us-east-1 \
--no-confirm-changeset--resolve-s3automatically creates an S3 bucket for SAM artifacts — no manual S3 setup needed.
Stack output:
1
JiraWebhookUrl: https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/prod/jiraStep 4 — Configure Jira webhook
- Go to
https://<your-org>.atlassian.net/plugins/servlet/webhooks - Click Create a WebHook
- Fill in:
- Name:
devops-agent-bridge - URL: paste the
JiraWebhookUrlfrom the stack output - Events: check Issue → created
- Name:
- Click Save
Step 5 — Test end-to-end
Create a Jira issue with a unique title and check:
- DevOps Agent console — investigation should start within 30 seconds
- Wait ~2 minutes for investigation to complete
- Jira issue — a comment with investigation findings should appear automatically
What Gets Deployed (Both Options)
| Resource | What it does |
|---|---|
| API Gateway (HTTP API) | Public HTTPS endpoint (/jira) that Jira calls when an issue is created. Routes requests to the Bridge Lambda. |
Bridge Lambda (jira-devops-bridge-v2) | Receives Jira's native payload → transforms it to DevOps Agent schema → computes HMAC signature → triggers investigation |
Writer Lambda (jira-devops-writer-v2) | Triggered by EventBridge → calls DevOps Agent API to get investigation findings → posts comment to Jira |
| EventBridge Rule | Watches default event bus for aws.aidevops events. Triggers Writer Lambda on Completed, Linked, Failed, Timed Out, Cancelled, Skipped |
| Secrets Manager | Stores DevOps Agent webhook secret + Jira API token. Lambdas read at runtime — credentials never in code |
| IAM Roles | Least-privilege roles for each Lambda: Bridge needs Secrets Manager read; Writer needs Secrets Manager + DevOps Agent API read |
Key Implementation Details
Bridge Lambda — HMAC Signing
1
2
3
4
5
6
# DevOps Agent requires: HMAC(secret_as_raw_string, "timestamp:body") → base64
webhook_secret = secrets["webhook_secret"] # use as-is, NOT base64-decoded
sig_input = f"{timestamp}:{payload_str}"
signature = base64.b64encode(
hmac.new(webhook_secret.encode("utf-8"), sig_input.encode("utf-8"), hashlib.sha256).digest()
).decode()Common mistake: base64-decoding the secret before signing. DevOps Agent uses the raw secret string.
Unique incidentId per trigger
1
2
epoch = int(time.time())
incident_id = f"{issue_key}-{epoch}" # e.g. "MDP-16-1780950336"DevOps Agent deduplicates on content similarity. Using a unique
incidentId with epoch ensures each trigger creates a fresh investigation.Writer Lambda — Extracting Jira keys (including linked tickets)
The tricky part: The EventBridge event fires for the primary (original) investigation's
task_id, not the newly linked task. So GetBacklogTask(task_id) returns the original ticket's key — missing all newly linked Jira tickets.The solution: use
ListBacklogTasks to find all tasks where primaryTaskId == task_id, then post to all of them:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def get_all_jira_keys(client, agent_space_id, task_id):
"""Returns Jira keys for the primary task + all linked tasks."""
jira_keys = set()
# 1. Primary task's Jira key
resp = client.get_backlog_task(agentSpaceId=agent_space_id, taskId=task_id)
ref_id = resp["task"]["reference"]["referenceId"] # e.g. "MDP-16-1234567"
m = re.match(r"^([A-Z]+-\d+)", ref_id)
if m:
jira_keys.add(m.group(1)) # "MDP-16"
# 2. All tasks linked to this one (primaryTaskId == task_id)
all_tasks = client.list_backlog_tasks(agentSpaceId=agent_space_id, limit=50)
for t in all_tasks["tasks"]:
if t.get("primaryTaskId") == task_id:
ref_id = t["reference"]["referenceId"] # e.g. "MDP-17-1234567"
m = re.match(r"^([A-Z]+-\d+)", ref_id)
if m:
jira_keys.add(m.group(1)) # "MDP-17"
return jira_keys # {"MDP-16", "MDP-17", "MDP-19", ...}This ensures that when an investigation completes — whether brand new or linked — every associated Jira ticket gets a comment, including the ticket that just triggered it.
Cost Estimate
| Resource | Cost |
|---|---|
| API Gateway | ~$0 (free tier: 1M requests/month) |
| Lambda (bridge + writer) | ~$0 (free tier: 1M invocations/month) |
| EventBridge | ~$0 (free for default bus rules) |
| Secrets Manager | ~$0.40/month per secret |
| Total | < $1/month |
Limitations and Workarounds
DevOps Agent deduplication
DevOps Agent links new investigations to previous ones if content is similar. This is by design. The integration handles this correctly — when a ticket is linked, the Writer Lambda uses
DevOps Agent links new investigations to previous ones if content is similar. This is by design. The integration handles this correctly — when a ticket is linked, the Writer Lambda uses
ListBacklogTasks to find all tickets associated with the primary investigation and posts a "linked" comment to every one of them, including the newly created ticket.Generic webhook only supports HMAC
The DevOps Agent generic webhook requires HMAC authentication. Jira's native webhook format is incompatible (wrong header name, wrong encoding, missing timestamp), requiring the bridge Lambda.
The DevOps Agent generic webhook requires HMAC authentication. Jira's native webhook format is incompatible (wrong header name, wrong encoding, missing timestamp), requiring the bridge Lambda.
EventBridge event has no Jira key
The
The
aws.aidevops EventBridge event only contains task_id. We solve this by:- Embedding the Jira key in the investigation's
referenceIdand title at trigger time - On completion, calling
GetBacklogTask+ListBacklogTasksto recover all associated Jira keys
Next Steps
- Add Slack notification alongside Jira comment
- Filter webhooks by Jira project or priority (JQL filter in Jira webhook config)
- Extend to other ticketing systems using similar pattern or that does not support native integration
Resources
- 📁 Complete jira-devops-bridge folder — Amazon WorkDocs — contains
template.yaml, both Lambda functions, and the Kiro steering file. Download and deploy. - AWS DevOps Agent Webhook Documentation
- AWS DevOps Agent EventBridge Integration
- AWS DevOps Agent Events Reference
- Jira Webhook Documentation
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article