Skip to content

Repository files navigation

terraform-pagerduty-rhythmic-azuremanaged

Provisions the PagerDuty side of Rhythmic's Azure managed-monitoring stack: four notification services (account, compliance, cost and security), an umbrella business service, the Datadog service integrations that Datadog monitors alert into, and the native Jira Cloud issue mapping for each service. It is the Azure sibling of rhythmictech/rhythmic-awsmanaged/pagerduty and exposes the same output contract, so client repositories consume it as a drop-in replacement.

What it creates

  • One PagerDuty business service (<org> - <cloud> Managed Services (<customer>)) that hangs off the customer's existing business service.
  • Four notification services: account, compliance and cost run at constant low urgency; security runs on a support-hours urgency schedule (high 07:00-20:00 America/New_York on weekdays, low otherwise).
  • A service dependency wiring each notification service under the business service, and the business service under the customer business service.
  • A Datadog service integration on each notification service (the datadog_integrations output feeds datadog_integration_pagerduty_service_object on the Datadog side).
  • A Jira Cloud account mapping rule on each service, including the priority map (P1-P5), status mapping and any custom fields.
  • Optional Slack connections per concern (created only when the matching channel id is supplied).
  • Optional event orchestration suppression rules per concern (default, custom and timebound), used to mute known-benign signals.

Prerequisites

These objects must already exist; the module data-sources them by name and does not create them:

  • The four escalation policies, by exact name: Account Notifications Policy, Compliance Notifications Policy, Cost Notifications Policy and Security Notifications Policy. They are shared with the AWS-managed customers.
  • The customer business service, named exactly var.customer_name.
  • The Customer Success Team in PagerDuty.
  • A Jira Cloud account mapping in PagerDuty for each profile's subdomain.
  • An Azure Key Vault populated with the Jira integration profile secrets described below. The vault and its secrets are an onboarding-runbook step.

Key Vault secret naming contract

The module reads eleven secrets per Jira integration profile. Key Vault secret names allow only letters, numbers and dashes, so the parameter names are dash-delimited and each secret is named jira-<profile>-<param> (the default profile is NOC, so jira-NOC-project, jira-NOC-issue-type, and so on).

Secret suffix Meaning Value shape
account-mapping-name Jira Cloud account mapping subdomain plain string
project Jira project id:key (for example 10001:OPS)
project-name Jira project display name plain string
issue-type Jira issue type id:name (for example 10001:Task)
issue-status-open status applied when an incident triggers id:name
issue-status-acknowledged status applied when acknowledged id:name
issue-status-resolved status applied when resolved id:name
sync-notes-user PagerDuty user email used to sync notes plain string
create-issue-on-incident-trigger auto-create a Jira issue on trigger true or false
custom-jira-fields dynamic Jira-value custom fields JSON array
custom-fixed-fields constant custom fields JSON array

The five id:... secrets are colon-joined and split inside the module. The two JSON-array secrets each hold a list of objects with target_issue_field, target_issue_field_name and value keys (use [] when there are none).

Populate a secret with, for example:

az keyvault secret set \
  --vault-name my-vault \
  --name "jira-NOC-issue-type" \
  --value "10001:Task"

az keyvault secret set \
  --vault-name my-vault \
  --name "jira-NOC-custom-jira-fields" \
  --value '[]'

Suppression defaults

Default suppression rules ship enabled and are spread across the concerns whose services receive the matching events. Override any concern's <concern>_default_suppression_rules to [] to disable it.

Rule label Concern Condition
Service Health planned maintenance account event.custom_details.body matches part 'Planned Maintenance' or event.custom_details.body matches part 'incidentType: Maintenance'
Advisor informational recommendation account event.custom_details.body matches part 'Microsoft.Advisor/recommendations'
Defender informational alert security event.custom_details.body matches part 'severity: Informational' or event.custom_details.body matches part 'Severity: Informational'

The condition strings match against the forwarded event body. The exact field and text depend on the Datadog monitor message templates and the forwarded event shape, so review them against sample event payloads before relying on them, and adjust or clear the defaults as needed.

Output contract

The datadog_integrations output is a map keyed by concern (account, compliance, cost, security), each entry carrying the service name and integration key. It matches the AWS sibling exactly and is designed to drive the Datadog side of the wiring:

resource "datadog_integration_pagerduty_service_object" "this" {
  for_each = module.azure_managed_services.datadog_integrations

  service_name = each.value.name
  service_key  = each.value.key
}

Per-concern *_service_id, *_service_name, *_datadog_integration_key and *_datadog_mention outputs, plus a pagerduty_services list, are also exposed.

Usage

module "azure_managed_services" {
  source = "git::https://github.com/rhythmictech/terraform-pagerduty-rhythmic-azuremanaged.git?ref=v0.1.0"

  org_name             = "ExampleOrg"
  customer_name        = "ExampleCustomer"
  jira_organization_id = "00000000-0000-0000-0000-000000000000"
  key_vault_id         = azurerm_key_vault.jira.id
}

The azurerm provider must be configured by the calling configuration (the module reads Key Vault secrets through it). See examples/basic for a complete invocation.

Differences from the AWS sibling

Compared with rhythmictech/rhythmic-awsmanaged/pagerduty:

  • org_name replaces awsorg_name, and cloud_name defaults to Azure.
  • Jira integration profile secrets are read from an Azure Key Vault instead of AWS SSM parameters, using the naming contract above.
  • The default suppression rules are Azure-specific and spread by concern (account gets the Service Health and Advisor rules; security gets the Defender rule) rather than shipping only on the account service.
  • An explicit azurerm provider is required for the Key Vault reads.

Requirements

Name Version
terraform >= 1.9
azurerm ~> 4.0
pagerduty ~> 3.17

Providers

Name Version
azurerm 4.81.0
pagerduty 3.34.0

Modules

No modules.

Resources

Name Type
pagerduty_business_service.azure resource
pagerduty_event_orchestration_service.account_rules resource
pagerduty_event_orchestration_service.compliance_rules resource
pagerduty_event_orchestration_service.cost_rules resource
pagerduty_event_orchestration_service.security_rules resource
pagerduty_jira_cloud_account_mapping_rule.account resource
pagerduty_jira_cloud_account_mapping_rule.compliance resource
pagerduty_jira_cloud_account_mapping_rule.cost resource
pagerduty_jira_cloud_account_mapping_rule.security resource
pagerduty_service.account resource
pagerduty_service.compliance resource
pagerduty_service.cost resource
pagerduty_service.security resource
pagerduty_service_dependency.account resource
pagerduty_service_dependency.azure resource
pagerduty_service_dependency.compliance resource
pagerduty_service_dependency.cost resource
pagerduty_service_dependency.security resource
pagerduty_service_integration.account resource
pagerduty_service_integration.compliance resource
pagerduty_service_integration.cost resource
pagerduty_service_integration.security resource
pagerduty_slack_connection.account resource
pagerduty_slack_connection.compliance resource
pagerduty_slack_connection.cost resource
pagerduty_slack_connection.security resource
azurerm_key_vault_secret.jira_account data source
azurerm_key_vault_secret.jira_compliance data source
azurerm_key_vault_secret.jira_cost data source
azurerm_key_vault_secret.jira_security data source
pagerduty_business_service.customer data source
pagerduty_escalation_policy.account data source
pagerduty_escalation_policy.compliance data source
pagerduty_escalation_policy.cost data source
pagerduty_escalation_policy.security data source
pagerduty_jira_cloud_account_mapping.account data source
pagerduty_jira_cloud_account_mapping.compliance data source
pagerduty_jira_cloud_account_mapping.cost data source
pagerduty_jira_cloud_account_mapping.security data source
pagerduty_priority.p1 data source
pagerduty_priority.p2 data source
pagerduty_priority.p3 data source
pagerduty_priority.p4 data source
pagerduty_priority.p5 data source
pagerduty_team.customer_success data source
pagerduty_user.account_user data source
pagerduty_user.compliance_user data source
pagerduty_user.cost_user data source
pagerduty_user.security_user data source
pagerduty_vendor.datadog data source

Inputs

Name Description Type Default Required
account_default_suppression_rules Default event suppression rules (override to an empty list to disable)
list(object({
label = string
condition = string
}))
[
{
"condition": "event.custom_details.body matches part 'Planned Maintenance' or event.custom_details.body matches part 'incidentType: Maintenance'",
"label": "Service Health planned maintenance"
},
{
"condition": "event.custom_details.body matches part 'Microsoft.Advisor/recommendations'",
"label": "Advisor informational recommendation"
}
]
no
account_jira_integration_profile The Jira integration profile string "NOC" no
account_suppression_rules Event suppression rules (uses PagerDuty event orchestration, merged with account_default_suppression_rules)
list(object({
label = string
condition = string
}))
[] no
account_timebound_suppression_rules Timebound event suppression rules (uses PagerDuty event orchestration)
list(object({
label = string
condition = string
start_time = string
end_time = string
}))
[] no
cloud_name Cloud provider name used in PagerDuty service and business-service display names (e.g., Azure, AWS, OCI, GCP) string "Azure" no
compliance_default_suppression_rules Default event suppression rules (override to an empty list to disable)
list(object({
label = string
condition = string
}))
[] no
compliance_jira_integration_profile The Jira integration profile string "NOC" no
compliance_suppression_rules Event suppression rules (uses PagerDuty event orchestration, merged with compliance_default_suppression_rules)
list(object({
label = string
condition = string
}))
[] no
compliance_timebound_suppression_rules Timebound event suppression rules (uses PagerDuty event orchestration)
list(object({
label = string
condition = string
start_time = string
end_time = string
}))
[] no
cost_default_suppression_rules Default event suppression rules (override to an empty list to disable)
list(object({
label = string
condition = string
}))
[] no
cost_jira_integration_profile The Jira integration profile string "NOC" no
cost_suppression_rules Event suppression rules (uses PagerDuty event orchestration, merged with cost_default_suppression_rules)
list(object({
label = string
condition = string
}))
[] no
cost_timebound_suppression_rules Timebound event suppression rules (uses PagerDuty event orchestration)
list(object({
label = string
condition = string
start_time = string # Format "2024-03-00 00:00:00 Etc/UTC"
end_time = string # Format "2024-03-00 00:00:00 Etc/UTC"
}))
[] no
customer_name Customer Name string n/a yes
jira_organization_id Organization ID for Jira integration string n/a yes
key_vault_id Resource ID of the existing Key Vault holding the Jira integration profile secrets (see README for the secret naming contract) string n/a yes
org_name Organization or tenant name used in PagerDuty service and business-service display names (nickname or formal name) string n/a yes
security_default_suppression_rules Default event suppression rules (override to an empty list to disable)
list(object({
label = string
condition = string
}))
[
{
"condition": "event.custom_details.body matches part 'severity: Informational' or event.custom_details.body matches part 'Severity: Informational'",
"label": "Defender informational alert"
}
]
no
security_jira_integration_profile The Jira integration profile string "NOC" no
security_suppression_rules Event suppression rules (uses PagerDuty event orchestration, merged with security_default_suppression_rules)
list(object({
label = string
condition = string
}))
[] no
security_timebound_suppression_rules Timebound event suppression rules (uses PagerDuty event orchestration)
list(object({
label = string
condition = string
start_time = string # Format "2024-03-00 00:00:00 Etc/UTC"
end_time = string # Format "2024-03-00 00:00:00 Etc/UTC"
}))
[] no
slack_compliance_team_channel The Slack channel ID for the compliance team string null no
slack_customer_success_team_channel The Slack channel ID for the customer success team string null no
slack_security_team_channel The Slack channel ID for the security team string null no
slack_workspace_id The Slack workspace ID string null no

Outputs

Name Description
account_datadog_integration_key PagerDuty Datadog Integration for account notifications
account_datadog_mention PagerDuty Service Mention with proper formatting
account_service_id PagerDuty service ID for account notifications
account_service_name PagerDuty service name for account notifications
compliance_datadog_integration_key PagerDuty Datadog Integration for compliance notifications
compliance_datadog_mention PagerDuty Service Mention with proper formatting
compliance_service_id PagerDuty service ID for compliance notifications
compliance_service_name PagerDuty service name for compliance notifications
cost_datadog_integration_key PagerDuty Datadog Integration for cost notifications
cost_datadog_mention PagerDuty Service Mention with proper formatting
cost_service_id PagerDuty service ID for cost notifications
cost_service_name PagerDuty service name for cost notifications
datadog_integrations All PagerDuty Datadog integrations
pagerduty_services All PagerDuty services
security_datadog_integration_key PagerDuty Datadog Integration for security notifications
security_datadog_mention PagerDuty Service Mention with proper formatting
security_service_id PagerDuty service ID for security notifications
security_service_name PagerDuty service name for security notifications

About

Terraform module configuring PagerDuty services, Jira Cloud issue mapping, Slack notifications, and event orchestration for Rhythmic Azure managed services

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages