Wiring AWS DevOps Agent to Jira, ServiceNow, and PagerDuty via EventBridge
Cloud Platform EngineeringAWS DevOps Agent automates investigation and remediation of operational issues — reading CloudWatch alarms, querying logs, correlating signals, proposing or executing remediation steps. The question that operational teams asked immediately: where do the findings go? Most engineering organizations don’t work exclusively in the AWS console. They work in Jira, ServiceNow, PagerDuty, or their own internal systems. The agent’s investigation output needs to route there.
AWS’s EventBridge-based integration pattern answers this. The architecture is clean and extensible: the agent publishes events to EventBridge, a rule filters on the aws.aidevops source, Lambda executes the REST API call to the external system, and DynamoDB maintains the mapping between the agent’s internal task IDs and the external issue keys it creates.
The Architecture
EventBridge Rule Configuration
The agent publishes events with source: "aws.aidevops". An EventBridge rule pattern:
{
"source": ["aws.aidevops"],
"detail-type": ["DevOps Agent Task Created", "DevOps Agent Investigation Complete"]
}
This captures task creation (to create the external ticket) and investigation completion (to update the ticket with findings). Add additional detail-type values to capture status updates during the investigation.
Lambda Integration Handler
The Lambda function receives the EventBridge event and executes the REST API call to the external system. The function structure follows the same pattern for all three targets — only the API endpoint and payload shape differ.
For Jira:
def create_jira_issue(event_detail):
jira_url = f"{JIRA_BASE_URL}/rest/api/3/issue"
payload = {
"fields": {
"project": {"key": JIRA_PROJECT_KEY},
"summary": event_detail["title"],
"description": {
"type": "doc",
"version": 1,
"content": [{"type": "paragraph", "content": [
{"type": "text", "text": event_detail["description"]}
]}]
},
"issuetype": {"name": "Incident"}
}
}
response = requests.post(jira_url, json=payload, auth=(JIRA_EMAIL, JIRA_API_TOKEN))
return response.json()["key"] # e.g. "OPS-1234"
For PagerDuty:
def create_pagerduty_incident(event_detail):
pd_url = "https://api.pagerduty.com/incidents"
payload = {
"incident": {
"type": "incident",
"title": event_detail["title"],
"service": {"id": PAGERDUTY_SERVICE_ID, "type": "service_reference"},
"body": {"type": "incident_body", "details": event_detail["description"]}
}
}
headers = {
"Authorization": f"Token token={PAGERDUTY_API_KEY}",
"From": PAGERDUTY_EMAIL
}
response = requests.post(pd_url, json=payload, headers=headers)
return response.json()["incident"]["id"]
DynamoDB Task ID Mapping
The critical link between the agent’s investigation lifecycle and the external ticket is the task ID mapping. Without it, investigation updates can’t route back to the correct ticket.
Table schema:
- Partition key:
task_id(from theaws.aidevopsevent) - Attributes:
external_issue_key(Jira key, ServiceNow number, PagerDuty incident ID),system(jira/servicenow/pagerduty),created_at,status
On task creation: Lambda creates the external ticket, receives the external ID, and writes the mapping to DynamoDB.
On investigation update events: Lambda queries DynamoDB by task_id, retrieves the external_issue_key, and posts the update to the correct ticket.
def get_external_key(task_id):
response = dynamodb.get_item(
TableName=MAPPING_TABLE,
Key={"task_id": {"S": task_id}}
)
return response["Item"]["external_issue_key"]["S"]
Credentials via Secrets Manager
Lambda environment variables are not appropriate for API credentials. Store credentials in Secrets Manager and retrieve at function initialization:
import boto3, json
def get_secret(secret_name):
client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId=secret_name)
return json.loads(response['SecretString'])
# At cold start (outside handler)
JIRA_CREDS = get_secret("devops-agent/jira-credentials")
JIRA_EMAIL = JIRA_CREDS["email"]
JIRA_API_TOKEN = JIRA_CREDS["api_token"]
Retrieve at initialization (outside the handler) to avoid a Secrets Manager call on every invocation while still refreshing on Lambda cold starts.
IAM Permissions
The Lambda execution role needs:
dynamodb:GetItem,dynamodb:PutItem,dynamodb:UpdateItemon the mapping tablesecretsmanager:GetSecretValueon the credential secrets- Standard Lambda logging permissions
EventBridge needs permission to invoke the Lambda function — add a resource-based policy via aws lambda add-permission or in the EventBridge rule configuration.
Extending to ServiceNow
ServiceNow’s Table API follows the same pattern with a different endpoint structure:
SNOW_URL = f"https://{SNOW_INSTANCE}.service-now.com/api/now/table/incident"
payload = {
"short_description": event_detail["title"],
"description": event_detail["description"],
"urgency": "2", # map from DevOps Agent severity
"impact": "2"
}
response = requests.post(
SNOW_URL,
json=payload,
auth=(SNOW_USERNAME, SNOW_PASSWORD)
)
incident_number = response.json()["result"]["number"] # e.g. "INC0001234"
The So What
This integration pattern closes the gap between AWS DevOps Agent’s investigation capability and the organizational workflows that actually move incidents to resolution. Most operations teams have process discipline built around their ticketing and incident management systems — the agent’s findings need to enter those systems to be actioned by the right people.
The EventBridge architecture is the right choice here because it decouples the agent’s event publication from the integration target. Adding a new external system means adding a Lambda function and a DynamoDB update — the agent itself doesn’t change. The pattern also works for custom internal systems through the same REST API approach.
For platform engineering teams evaluating DevOps Agent adoption: this integration is the bridge between “interesting AWS native capability” and “fits our operational workflow.” Building it from the published pattern is a half-day of work; the architecture complexity is in the DynamoDB mapping design, not the API calls.
Content created with AI assistance and reviewed for accuracy.
Join the conversation
Stack Insiders is our free community for readers who want to go deeper — share resources, ask questions, and connect with others across every vertical we cover.
Join Stack Insiders →