PagerDuty SDK Integration

Set up PagerDuty for use in the Sym SDK

With Sym and PagerDuty, you can take advantage of your existing Incident Response workflows to speed up break-glass escalations in a secure way, and tie access requests to incidents for better auditable visibility.

Common uses of the PagerDuty Integration include checking if a User is on call for conditional logic, and routing requests to individuals on call for a certain schedule.

Connect Sym with your AWS Secrets Manager

Follow the Manage Secrets with AWS Secrets Manager tutorial to connect your AWS Secrets Manager with the Sym Runtime.

Create a PagerDuty API Key

In order to grant Sym access to PagerDuty, you'll need to create a new API Key.

Follow the PagerDuty documentation to create a token with write permissions: Generate a General Access REST API Key

Share your PagerDuty API Key with Sym

Follow the Share Secrets with the Sym Runtime tutorial to share your credentials. We recommend using the plain style secret.

# Note: This example snippet shows only the PagerDuty specific resources.

# An AWS Secrets Manager Secret to hold your PagerDuty API Key. Set the value with:
# aws secretsmanager put-secret-value --secret-id "main/pagerduty-api-key" --secret-string "YOUR-PAGERDUTY-API-KEY"
resource "aws_secretsmanager_secret" "pagerduty_api_key" {
  name        = "sym/main/pagerduty-api-key"
  description = "API Key for Sym to call PagerDuty APIs"

  # This SymEnv tag is required and MUST match the SymEnv tag in the 
  # aws_iam_policy.secrets_manager_access in your `secrets.tf` file
  tags = {
    SymEnv = local.environment_name
  }
}

resource "sym_secret" "pagerduty_api_key" {
  # `sym_secrets` is defined in "Manage Secrets with AWS Secrets Manager"
  source_id = sym_secrets.this.id

  path = aws_secretsmanager_secret.pagerduty_api_key.name
}

Add a PagerDuty integration

Define a sym_integration resource with type = pagerduty. This integration will specify the PagerDuty API Key, and will ensure that your PagerDuty API key is available to the Sym Runtime when invoking the pagerduty module in your impl.py

  • external_id: Your PagerDuty subdomain
  • api_token_secret: A required setting which must be set to the ID of a sym_secret referencing your PagerDuty API Key
resource "sym_integration" "pagerduty" {
  type = "pagerduty"
  name = "pagerduty-main"

  # Your PagerDuty subdomain
  external_id = "YOUR-ORG.pagerduty.com"

  settings = {
    # This secret was defined in the previous step
    api_token_secret = sym_secret.pagerduty_api_key.id
  }
}

Add Your PagerDuty Integration to your Environment

Finally, add the PagerDuty integration to your sym_environment as pagerduty_id. This will ensure that the PagerDuty SDK methods can authenticate their API calls with the correct API token.

resource "sym_environment" "this" {
  name            = var.environment_name
  runtime_id      = sym_runtime.this.id
  error_logger_id = sym_error_logger.slack.id

  integrations = {
    slack_id = sym_integration.slack.id

    # This `pagerduty_id` is required to be able to use the `pagerduty` SDK methods
    # It tells the Sym Runtime to use the API Token defined in `sym_integration.pagerduty` resource
    pagerduty_id = sym_integration.pagerduty.id
  }
}

Using PagerDuty in your Flows

Now you can use information about on-calls, schedules, and active incidents in your Flow implementations.

For more information on the supported methods in the pagerduty module, please visit the Sym SDK PagerDuty Docs.

Full Example: Auto-approve on-call user

You can find the complete code (Terraform configuration and impl.py) for this example in our PagerDuty On-Call Example.

Example implementations

Auto-approve if on-call for a specific schedule

from sym.sdk.annotations import hook
from sym.sdk.integrations import pagerduty
from sym.sdk.templates import ApprovalTemplate


@hook
def on_request(event):
    if pagerduty.is_on_call(event.user, schedule_id="P0ABCDE"):
        # If the user is currently on-call for this schedule, then auto-approve their requests
        return ApprovalTemplate.approve()

Allow self-approvals when a User is on call for any schedule

from sym.sdk.annotations import reducer
from sym.sdk.request_permission import PermissionLevel, RequestPermission
from sym.sdk.integrations import pagerduty


@reducer
def get_permissions(event):
    return RequestPermission(
        webapp_view=PermissionLevel.MEMBER,
        approve_deny=PermissionLevel.MEMBER,
        # Allow self-approval if the user is on-call for any schedule.
        allow_self_approval=pagerduty.is_on_call(event.user),
    )

Fetch an on-call schedule of managers to route an approval

from sym.sdk.annotations import reducer
from sym.sdk.integrations import pagerduty, slack
from sym.sdk.notifications import Notification


@reducer
def get_request_notifications(event):
    # Notify the on-call managers that there is a pending request
    on_call_mgrs = pagerduty.users_on_call(escalation_policy_name="mgr_on_call")
    return [Notification(destinations=[slack.group(on_call_mgrs)])]

Auto-approve if there is an active incident

from sym.sdk.annotations import hook
from sym.sdk.integrations import pagerduty, PagerDutyStatus
from sym.sdk.templates import ApprovalTemplate


@hook
def on_request(event):
    """If there are ANY active incidents, auto-approve the requester"""
    if pagerduty.get_incidents(statuses=[PagerDutyStatus.TRIGGERED, PagerDutyStatus.ACKNOWLEDGED]):
        return ApprovalTemplate.approve()