View a markdown version of this page

正在连接 ServiceNow - AWS DevOps 代理人

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

正在连接 ServiceNow

本教程指导您如何将 ServiceNow 实例连接到 AWS DevOps Agent,使其能够在创建票证时自动启动事件响应调查,并将其关键发现发布到原始票证中。它还包含有关如何配置您的 ServiceNow 实例以仅向代理空间发送特定票证以及如何协调跨多个 DevOps DevOps 代理空间的票证路由的示例。

初始设置

第一步是在 AWS DevOps 可用于访问您的 ServiceNow ServiceNow 实例的 OAuth 应用程序客户端中创建。

创建 ServiceNow OAuth 应用程序客户端

  1. 启用您的实例的客户端凭证系统属性

    1. sys_properties.list在过滤器搜索框中搜索,然后按回车键(它不会显示该选项,但按回车有效)

    2. 选择 “新建”

    3. 将名称添加为glide.oauth.inbound.client.credential.grant_type.enabled,将值添加为 true,类型为 true | false

系统属性表单显示已启用 OAuth 入站客户端凭据授予类型。
  1. 从筛选器搜索框导航到系统 OAuth > 应用程序注册表

  2. 选择 “新增” > “全新入站集成体验” > “新集成” > “OAuth-客户凭证授予”

  3. 选择一个名称并将 OAuth 应用程序用户设置为 “问题管理员”,选择 “保存”

OAuth 客户凭证的新记录表单,其中包含名称、客户端 ID 和密钥字段。

将您的 ServiceNow OAuth 客户端连接到 AWS DevOps 代理人

  1. 你可以在两个地方启动这个过程。首先,导航到 “能力提供者” 页面并在 “通信” ServiceNow 下找到,然后选择 “注册”。或者,您可以选择您可能创建的任何 DevOps 代理空间,导航到功能 → 通信 → 添加 →, ServiceNow 然后选择注册。

  2. 接下来,授权 DevOps 代理使用您刚刚创建的 OAuth 应用程序客户端访问您的 ServiceNow 实例。

每个注册都连接到一个 ServiceNow 实例。要连接其他实例,请对每个实例重复此过程。

ServiceNow 包含客户名称、客户端 ID 和实例 URL 字段的注册表单。
  • 按照后续步骤操作,并保存有关 webhook 的结果信息

重要

您将不会再看到此信息

显示连接状态和 Webhook URL 的 Webhook 配置面板。

配置您的 ServiceNow 业务规则

建立连接后,您需要在中配置业务规则, ServiceNow 以便将票证发送到 DevOps 代理空间。

  1. 导航到 “活动订阅” → “管理” → “业务规则”,然后选择 “新建”。

  2. 将 “表” 字段设置为 “事件 [事件]”,选中 “高级” 复选框,并将规则设置为在插入、更新和删除之后运行。

事件表中 CloudSmith 集成的业务规则表单。
  1. 导航到 “高级” 选项卡并添加以下 webhook 脚本,在指示的地方插入您的 webhook 密钥和 URL,然后选择提交。

(function executeRule(current, previous /*null when async*/ ) { var WEBHOOK_CONFIG = { webhookSecret: GlideStringUtil.base64Encode('<<< INSERT WEBHOOK SECRET HERE >>>'), webhookUrl: '<<< INSERT WEBHOOK URL HERE >>>' }; function generateHMACSignature(payloadString, secret) { try { var mac = new GlideCertificateEncryption(); var signature = mac.generateMac(secret, "HmacSHA256", payloadString); return signature; } catch (e) { gs.error('HMAC generation failed: ' + e); return null; } } function callWebhook(payload, config) { try { var timestamp = new Date().toISOString(); var payloadString = JSON.stringify(payload); var payloadWithTimestamp =`${timestamp}:${payloadString}`; var signature = generateHMACSignature(payloadWithTimestamp, config.webhookSecret); if (!signature) { gs.error('Failed to generate signature'); return false; } gs.info('Generated signature: ' + signature); var request = new sn_ws.RESTMessageV2(); request.setEndpoint(config.webhookUrl); request.setHttpMethod('POST'); request.setRequestHeader('Content-Type', 'application/json'); request.setRequestHeader('x-amzn-event-signature', signature); request.setRequestHeader('x-amzn-event-timestamp', timestamp); request.setRequestBody(payloadString); var response = request.execute(); var httpStatus = response.getStatusCode(); var responseBody = response.getBody(); if (httpStatus >= 200 && httpStatus < 300) { gs.info('Webhook sent successfully. Status: ' + httpStatus); return true; } else { gs.error('Webhook failed. Status: ' + httpStatus + ', Response: ' + responseBody); return false; } } catch (ex) { gs.error('Error sending webhook: ' + ex.getMessage()); return false; } } function createReference(field) { if (!field || field.nil()) { return null; } return { link: field.getLink(true), value: field.toString() }; } function getStringValue(field) { if (!field || field.nil()) { return null; } return field.toString(); } function getIntValue(field) { if (!field || field.nil()) { return null; } var val = parseInt(field.toString()); return isNaN(val) ? null : val; } var eventType = (current.operation() == 'insert') ? "create" : "update"; var incidentEvent = { eventType: eventType.toString(), sysId: current.sys_id.toString(), priority: getStringValue(current.priority), impact: getStringValue(current.impact), active: getStringValue(current.active), urgency: getStringValue(current.urgency), description: getStringValue(current.description), shortDescription: getStringValue(current.short_description), parent: getStringValue(current.parent), incidentState: getStringValue(current.incident_state), severity: getStringValue(current.severity), problem: createReference(current.problem), additionalContext: {} }; incidentEvent.additionalContext = { number: current.number.toString(), opened_at: getStringValue(current.opened_at), opened_by: current.opened_by.nil() ? null : current.opened_by.getDisplayValue(), assigned_to: current.assigned_to.nil() ? null : current.assigned_to.getDisplayValue(), category: getStringValue(current.category), subcategory: getStringValue(current.subcategory), knowledge: getStringValue(current.knowledge), made_sla: getStringValue(current.made_sla), major_incident: getStringValue(current.major_incident) }; for (var key in incidentEvent.additionalContext) { if (incidentEvent.additionalContext[key] === null) { delete incidentEvent.additionalContext[key]; } } gs.info(JSON.stringify(incidentEvent, null, 2)); // Pretty print for logging only if (WEBHOOK_CONFIG.webhookUrl && WEBHOOK_CONFIG.webhookSecret) { callWebhook(incidentEvent, WEBHOOK_CONFIG); } else { gs.info('Webhook not configured.'); } })(current, previous);

如果您从 “能力提供者” 页面注册了 ServiceNow 连接,请导航到要调查 ServiceNow 事件单的 DevOps 代理空间。选择能力,然后选择通信,然后选择您在能力提供者页面上注册的 ServiceNow 实例。单个 DevOps 代理空间可以使用多个 ServiceNow 注册。要添加另一个实例,请重复此步骤。现在,一切都应该设置完毕,所有将呼叫者设置为 “问题管理员”(模仿您授予 AWS DevOps OAuth客户端的权限)的事件都将在配置 DevOps 的代理空间中触发事件响应调查。您可以通过在中创建新事件 ServiceNow 并将事件的 “来电者” 字段设置为 “问题管理员” 来对此进行测试。

ServiceNow 事件表显示了问题管理员来电者的号码 INC0010001。

ServiceNow 门票更新

在所有触发的事件响应调查中,您的 DevOps 代理将在原始通知单中提供其主要调查结果、根本原因分析和缓解计划的最新信息。特工调查结果将发布到事件评论中,我们目前仅发布类型为finding、causeinvestigation_summarymitigation_summary、和的特工记录和调查状态更新(例如AWS DevOps Agent started/finished its investigation)。

票务路由和编排示例

场景:筛选哪些事件被发送到 DevOps 代理空间

这是一个简单的场景,但需要进行一些配置 ServiceNow 才能在中创建 ServiceNow 用于跟踪事件源的字段。出于本示例的目的,使用 SNOW 表单生成器创建新的来源 (u_source) 字段。这将允许跟踪事件来源,并使用它来将请求从特定来源路由到 DevOps 代理空间。路由是通过创建 “立即服务” 业务规则并在 “何时运行” 选项卡中设置 “何时” 触发器和 “筛选条件” 来完成的。在此示例中,过滤条件设置如下:

在触发器和 Source 过滤器之前,“何时运行” 选项卡包含 Dynatrace。

场景:跨多个 DevOps 代理空间路由事件

此示例说明如何在紧急程度为1、类别为或服务为时在 DevOps 代理空间 B 中触发调查AWS,并在服务为、来源为时在 DevOps 代理空间 A 中触发调查Dynatrace。Software AWS

这个场景可以通过两种方式来实现。可以更新 webhook 脚本本身以包含此业务逻辑。在本场景中,我们将展示如何使用 ServiceNow 业务规则来实现这一目标,以提高透明度并简化调试。路由是通过创建两个 “立即服务” 业务规则来完成的。

  • 在 DevOps 代理空间 A 中 ServiceNow 创建业务规则,并使用条件生成器创建条件,仅根据我们指定的条件发送事件。

业务规则配置表单,其中包含紧急情况和类别的筛选条件。
  • 接下来,在中 ServiceNow 为 AgentSpace B 创建另一个业务规则,只有当服务为 Dynatrace AWS 且来源为 Dynatrace 时,业务规则才会触发。

用于向代理空间 B 发送事件的业务规则配置表单

现在,当您创建符合指定条件的新事件时,它将触发对 DevOps 代理空间 A 或 DevOps 代理空间 B 的调查,从而为您提供对事件路由的精细控制。