Manages a single Dynatrace email problem-notification configuration (
dynatrace_email_notification) β recipients, subject/body templates, and the alerting profile it attaches to β for providerdynatrace-oss/dynatrace ~> 1.98.
- Manages exactly one
dynatrace_email_notificationresource β a Settings 2.0-backed problem notification channel (schemaIdbuiltin:problem.notifications). - Configures the primary (
to), carbon-copy (cc), and blind-carbon-copy (bcc) recipient sets, each aset(string)of email addresses. - Configures the subject and body templates using Dynatrace's problem-notification placeholder syntax
(
{ProblemTitle},{ProblemDetailsText},{State}, etc.). - Attaches to an existing alerting profile by ID via the
profileinput β this module never creates or manages the alerting profile itself. - Ships secure by default:
activedefaults tofalse, so a newly-applied integration cannot send email until a caller explicitly reviews and enables it.
π‘ Why it matters: email is frequently the fallback notification channel every Dynatrace environment configures first, and often the one every team assumes "just works" once wired to a distribution list. A typed
set(string)recipient model and a secure-by-defaultactiveflag turn two common failure modes β a typo'd recipient string silently accepted atplantime, and a freshly applied channel paging people before its content has been reviewed β into either a type error the planner catches or a deliberate opt-in the caller has to type.
If these Terraform modules have been helpful to you or your organization, I'd appreciate your support in any of the following ways:
- β Star this repository to help others discover this Terraform module.
- π€ Connect with me on LinkedIn: linkedin.com/in/microsoftexpert
- β Buy me a coffee: buymeacoffee.com/microsoftexpert
Whether it's a star, a professional connection, or a coffee, every gesture helps keep these modules actively maintained and continually improving. Thank you for being part of the community!
flowchart LR
AP["terraform-dynatrace-alerting-profile"]:::sibling
EN["terraform-dynatrace-email-notification"]:::thismodule
RES["dynatrace_email_notification"]:::keystone
AP -- "id β profile" --> EN
EN -- "provisions" --> RES
classDef thismodule fill:#1496FF,color:#FFFFFF,stroke:#0A2540,stroke-width:1px;
classDef keystone fill:#0A2540,color:#FFFFFF,stroke:#0A2540,stroke-width:1px;
classDef sibling fill:#E5E7EB,color:#0A2540,stroke:#9CA3AF,stroke-width:1px;
This module consumes an alerting profile's id output (from terraform-dynatrace-alerting-profile) and
provisions the email notification channel that fires against it. It has no children of its own and no
other sibling module consumes its outputs by id β it sits at the end of the notification-channel
family's dependency chain, not in the middle of it. (Diagram validated via the Mermaid Chart MCP β
valid: true.)
flowchart LR
subgraph Inputs["Inputs (variables.tf)"]
name["name"]
profile["profile"]
subject["subject"]
body["body"]
to["to"]
cc["cc"]
bcc["bcc"]
ncp["notify_closed_problems"]
active["active"]
end
RES["dynatrace_email_notification.this"]:::keystone
name --> RES
profile --> RES
subject --> RES
body --> RES
to --> RES
cc --> RES
bcc --> RES
ncp --> RES
active --> RES
RES -- "id" --> OUT_ID["output: id"]
RES -- "name" --> OUT_NAME["output: name"]
classDef keystone fill:#0A2540,color:#FFFFFF,stroke:#0A2540,stroke-width:1px;
(Diagram validated via the Mermaid Chart MCP β valid: true.)
Resource inventory:
dynatrace_email_notification.thisβ the sole resource. Nofor_each-driven children, no nesteddynamicblocks β the live schema for this resource has noblock_typesat all, somain.tfis a direct, flat 1:1 attribute pass-through.
| Component | Requirement |
|---|---|
| Terraform | >= 1.12.0 |
| Provider | dynatrace-oss/dynatrace ~> 1.98 (confirmed against the live schema at provider v1.100.0) |
| Provider block | None β no provider "dynatrace" {} in this module; the caller configures auth and dt_env_url outside it |
Schema notes that bite:
- This is the only channel in the notification family with no provider-flagged sensitive fields.
Confirmed against the live schema:
dynatrace_email_notificationhas no secret/token/webhook-URL attribute of any kind β recipients are plain email-address strings. Contrast with sibling channels such as Slack (webhook URL), PagerDuty/OpsGenie (integration key), or ServiceNow (credentials), each of which carries at least one field this house standard requires treating as sensitive. activehas no provider-documented default β this module defaults the variable tofalseso a newly-applied integration does not fire before review. This is a module-level secure default, not a provider default; the provider itself simply leaves the behavior undocumented when the argument is entirely absent.tois required and typedset(string)(the provider's ownTypeSetof strings) β not a list, and not a comma-joined string. Order is not significant and duplicate addresses within the same field are collapsed by Terraform before the resource is ever created or updated.ccandbccare optional, also typedset(string), and default to[]in this module β omitting them produces no CC/BCC recipients, matching the provider's own "absent means none" behavior.subjectandbodyare both confirmed required strings on the live schema β an earlier scaffolding assumption thatbodymight be optional does not hold; there is no fallback template.notify_closed_problemsis optional with no provider-documented default; this module leaves it atnull, which omits the argument from the rendered resource block entirely rather than guessingtrueorfalse. Verify the resulting server-side behavior in a non-production environment if deterministic open/close notification behavior matters, and set it explicitly rather than relying on the omission.- The resource also exposes a computed
legacy_idattribute (its Config API V1 cross-reference id). This module does not surface it as an output β it is provider interop metadata, not a caller-facing value.
This module manages dynatrace_email_notification, a Settings 2.0-backed resource. It accepts either
OAuth client credentials or a legacy API token.
- API token (confirmed via the live provider documentation, v1.100.0): the provider's own resource
page states explicitly β "This resource requires the API token scopes Read settings
(
settings.read) and Write settings (settings.write)." Grant a legacy API token exactly these two scopes. - OAuth (recommended): grant the OAuth client's IAM policy the equivalent Settings 2.0 scope pair,
settings:objects:readandsettings:objects:write, consistent with this domain's other Settings-2.0-backed resources (e.g.dynatrace_alerting, which documents the identicalsettings.read/settings.writeAPI-token scope pair at the same provider version). The provider's resource-level page fordynatrace_email_notificationdocuments only the API-token scope names explicitly β the OAuth scope-pair mapping follows this module suite's general Settings 2.0 auth convention rather than an explicit per-resource OAuth scope list in the provider's own docs. Verify against your environment's IAM policy model before a production apply. - This module does not touch IAM or Automation resources, so no
account-idm-*orautomation:*scopes are required.
- An OAuth client (or legacy API token) provisioned with the scopes/permissions above, bound via an IAM policy (OAuth) or token permissions (API token).
- The target alerting profile must already exist (or be created in the same plan via an implicit
reference to a
terraform-dynatrace-alerting-profileinstance'sidoutput) β this module only references it by id and does not create or manage it. - Settings 2.0 schema availability (
builtin:problem.notifications) for the target environment tier.
terraform-dynatrace-email-notification/
βββ providers.tf # required_version, required_providers pin β no provider {} block
βββ variables.tf # name, profile, subject, body, to, cc, bcc, notify_closed_problems, active
βββ main.tf # dynatrace_email_notification.this β thin, total, single-resource renderer
βββ outputs.tf # id, name
βββ README.md # this file
βββ SCOPE.md # lightweight cross-module contract
βββ examples/
βββ quickstart/
βββ main.tf
module "email_notification" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Platform Team - Critical Problems"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71" # existing dynatrace_alerting profile ID
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["oncall-platform@example.com"]
}The caller configures the dynatrace provider (OAuth client credentials, platform token, or legacy API
token, plus dt_env_url) once, outside this module. This module declares no provider {} block and no
auth-related variables.
Consumes
| Input | Type | Source module |
|---|---|---|
profile |
string, required |
terraform-dynatrace-alerting-profile (its id output) |
Emits
| Output | Description | Consumed by |
|---|---|---|
id |
The Dynatrace settings-object ID of this email notification configuration | Reference only β no sibling module in this catalog consumes this by id |
name |
The display name of this email notification configuration, as configured via var.name |
Documentation/reference only |
1 Β· Minimal inert integration (secure-by-default)
module "email_notification_inert" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Platform Team - Critical Problems"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71" # existing dynatrace_alerting profile ID
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["oncall-platform@example.com"]
}π
activeis omitted here, so it defaults tofalseβ the configuration is created but sends nothing until it is explicitly reviewed and turned on (Example 2).
2 Β· Activating a reviewed integration
module "email_notification_active" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Platform Team - Critical Problems"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71"
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["oncall-platform@example.com"]
active = true
}
β οΈ Setactive = trueonly after subject, body, and recipients have been reviewed β a newly enabled email integration begins firing on the next matching problem.
3 Β· Multi-recipient (to/cc/bcc) integration
module "email_notification_multi_recipient" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Platform Team - Critical Problems (Escalation)"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71"
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["oncall-platform@example.com", "sre-team@example.com"]
cc = ["escalation-manager@example.com"]
bcc = ["compliance-archive@example.com"]
active = true
}βΉοΈ
to,cc, andbccare each modeled asset(string)(the provider's ownTypeSettype) β order is not significant, and an address is only deduplicated within the field it's listed in, not across fields. An address present in bothtoandccreceives two separate copies from Dynatrace.
4 Β· Distribution lists, not personal inboxes
module "email_notification_distribution_list" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Data Platform - Critical Problems"
profile = "0987654321fedcba0987654321fedcba"
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["data-platform-oncall@example.com"]
active = true
}π‘ Point
to/cc/bccat organizational alerting distribution lists or shared mailboxes, not individual employees' personal inboxes β this keeps the channel functional through on-call rotations and staffing changes without a Terraform change.
5 Β· Notify on both open and close
module "email_notification_notify_on_close" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Platform Team - Problem Lifecycle"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71"
subject = "[{State}] {ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["oncall-platform@example.com"]
notify_closed_problems = true
active = true
}βΉοΈ The
{State}placeholder in the subject line resolves toOPENorRESOLVED, distinguishing the two emails a recipient now receives per problem lifecycle.
6 Β· Explicitly suppress close notifications
module "email_notification_open_only" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Platform Team - Open Problems Only"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71"
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["oncall-platform@example.com"]
notify_closed_problems = false
active = true
}βΉοΈ Leaving
notify_closed_problemsunset (the module'snulldefault) defers to whatever the Dynatrace API applies server-side when the argument is absent β that behavior is not documented by the provider. Set it explicitly, as above, whenever deterministic open/close notification behavior matters.
7 Β· Compliance BCC archive
module "email_notification_compliance_archive" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Core Banking Platform - Critical Problems"
profile = "3fa1c9d2b7e04a6f8c5d1e2a9b7c4f60"
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["core-banking-oncall@example.com"]
bcc = ["compliance-archive@example.com"]
active = true
}π Confirm with Compliance/Risk whether routing an unmonitored BCC archive mailbox of this kind falls under existing records-retention policy before enabling it for a regulated workload β this is a human decision this module does not make for you.
8 Β· Placeholder-rich subject line for triage
module "email_notification_triage_subject" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Platform Team - Triage"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71"
subject = "{ProblemSeverity}/{ProblemImpact}: {ImpactedEntity} β {ProblemTitle} ({ProblemID})"
body = "{ProblemDetailsText}"
to = ["oncall-platform@example.com"]
active = true
}π‘ Type
{in the Dynatrace UI when drafting subject/body templates for placeholder autocomplete; this module passes the string through unmodified, so a typo'd placeholder name is rendered literally rather than substituted.
9 Β· Structured JSON body for downstream ingestion
module "email_notification_json_body" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Automation Pipeline - Problem Feed"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71"
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsJSONv2}"
to = ["problem-feed-parser@example.com"]
active = true
}βΉοΈ
{ProblemDetailsJSONv2}renders the full Problems V2 API structure as the email body β useful when a downstream mail-processing rule or ingestion mailbox parses the body as structured data rather than displaying it to a human.
10 Β· Markdown body for chat-forwarded triage
module "email_notification_markdown_body" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Platform Team - Markdown Digest"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71"
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsMarkdown}"
to = ["oncall-platform@example.com"]
active = true
}βΉοΈ
{ProblemDetailsMarkdown}is convenient when the receiving mailbox or a mail-to-chat bridge renders Markdown; use{ProblemDetailsHTML}instead for HTML-rendering mail clients, or{ProblemDetailsText}for the plainest-common-denominator case (see Example 1).
11 Β· Escalation CC chain
module "email_notification_escalation_cc" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Payments Platform - Critical Problems"
profile = "7c2e9f14a8b3d05e6f1a2c3b4d5e6f70"
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["payments-oncall@example.com"]
cc = ["payments-eng-manager@example.com", "payments-duty-manager@example.com"]
active = true
}βΉοΈ
ccrecipients receive every notification alongsideto; useccfor stakeholders who need visibility without being the primary responder, and reservetofor the team actually expected to act.
12 Β· Per-environment routing (prod vs. non-prod)
locals {
environments = {
prod = {
name = "Email - Platform Team - Production Critical Problems"
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71"
to = ["oncall-platform@example.com"]
active = true
}
nonprod = {
name = "Email - Platform Team - Non-Production Problems"
profile = "b4a6c8d0e2f4a6c8d0e2f4a6c8d0e2f4"
to = ["platform-team@example.com"]
active = false # reviewed on a slower cadence; left inert until confirmed
}
}
}
module "email_notification_by_environment" {
for_each = local.environments
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = each.value.name
profile = each.value.profile
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = each.value.to
active = each.value.active
}π‘ The module itself is a standalone primitive with no internal
for_eachβ breadth at scale is achieved byfor_each-ing the module block itself in the calling root module, keyed by a caller-chosen map key (nevercount), consistent with the house standard.
13 Β· Fleet of team channels via for_each
locals {
team_channels = {
platform = {
profile = "e5d24d1e-de08-4738-89bd-1a1dc9377b71"
to = ["oncall-platform@example.com"]
}
data = {
profile = "0987654321fedcba0987654321fedcba"
to = ["oncall-data@example.com"]
}
payments = {
profile = "7c2e9f14a8b3d05e6f1a2c3b4d5e6f70"
to = ["payments-oncall@example.com"]
}
}
}
module "team_email_notifications" {
for_each = local.team_channels
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - ${title(each.key)} Team - Critical Problems"
profile = each.value.profile
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = each.value.to
active = true
}π‘ Each team's channel is independently addressable by its map key (
module.team_email_notifications["payments"]) β adding or removing a team never renumbers the others.
14 Β· Minimal required-only call
module "email_notification_required_only" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Sandbox - Test Notification"
profile = "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d"
subject = "{ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["sandbox-test@example.com"]
}βΉοΈ Every argument here is required by the live provider schema except
active,cc,bcc, andnotify_closed_problems, all four of which fall back to their module defaults (false,[],[], andnullrespectively).
15 Β· ποΈ End-to-end composition
Wires a terraform-dynatrace-alerting-profile instance's id output into this module's profile input β
the shape every caller should use in practice, rather than hardcoding a profile ID.
module "critical_availability_profile" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-alerting-profile.git?ref=v1.0.0"
name = "Critical Availability - Platform"
rules = {
availability-all-entities = {
severity_level = "AVAILABILITY"
include_mode = "INCLUDE_ALL"
delay_in_minutes = 5
tags = ["Team:platform", "Environment:production"]
}
}
}
module "platform_email_notification" {
source = "git::https://github.com/microsoftexpert/terraform-dynatrace-email-notification.git?ref=v1.0.0"
name = "Email - Platform Team - Critical Availability"
profile = module.critical_availability_profile.id
subject = "{ProblemSeverity} problem {ProblemID}: {ProblemTitle}"
body = "{ProblemDetailsText}"
to = ["oncall-platform@example.com"]
cc = ["escalation-manager@example.com"]
active = true
}π‘ Referencing
module.critical_availability_profile.iddirectly (instead of a literal string) gives Terraform an implicit reference, so the alerting profile is always created or updated before the email notification that depends on it β nodepends_onrequired.
| Variable | Type | Required | Default |
|---|---|---|---|
name |
string |
Yes | β |
profile |
string |
Yes | β |
subject |
string |
Yes | β |
body |
string |
Yes | β |
to |
set(string) |
Yes | β |
cc |
set(string) |
No | [] |
bcc |
set(string) |
No | [] |
notify_closed_problems |
bool |
No | null (argument omitted; defers to server-side behavior) |
active |
bool |
No | false (secure-by-default) |
Full variable schemas (as declared in variables.tf)
name(string, required) β the name of the notification configuration. No documented provider default.profile(string, required) β the ID of the associated Dynatrace alerting profile. Pass theidoutput of aterraform-dynatrace-alerting-profileinstance; this module does not create or manage the profile itself.subject(string, required) β the subject line of the email notifications. Supports Dynatrace notification placeholders ({ProblemTitle},{ProblemID},{ProblemSeverity},{ProblemImpact},{ImpactedEntity},{State},{ProblemURL}, among others).body(string, required) β the template body of the email notifications. Supports a broader placeholder set thansubject, including{ProblemDetailsHTML},{ProblemDetailsJSONv2},{ProblemDetailsMarkdown},{ProblemDetailsText},{Tags}/{Tags[key]}, and more.to(set(string), required) β primary recipient email addresses. Raw provider schema type["set", "string"](TypeSet); order is not significant and duplicates are collapsed. Point these at organizational alerting distribution lists rather than individual personal inboxes.cc(set(string), optional, default[]) β additional (CC) recipient email addresses. SameTypeSetsemantics asto.bcc(set(string), optional, default[]) β blind-carbon-copy recipient email addresses. SameTypeSetsemantics asto.notify_closed_problems(bool, optional, defaultnull) β whether an email is also sent when a problem closes (true) or only when a problem opens (false). The provider documents no default for this field; leaving itnullomits the argument entirely rather than guessing a value. Verify the resulting server-side behavior in a non-production environment before relying on it.active(bool, optional, defaultfalse) β whether this configuration is enabled. Defaults tofalseper this module suite's secure-by-default standard for notification integrations, so a newly-applied integration does not fire before the caller reviews recipients, subject, body, and alerting profile scope.
| Output | Description | Sensitive |
|---|---|---|
id |
The Dynatrace settings-object ID of this email notification configuration | No |
name |
The display name of this email notification configuration, as configured via var.name |
No |
- Flat, single-resource renderer. The live schema for
dynatrace_email_notificationhas no nestedblock_types, somain.tfis a direct attribute-to-argument pass-through with nodynamicblocks and notry(x, null)wrapping needed beyond what the variable defaults already provide. to/cc/bccare sets, not lists. They mirror the provider's ownTypeSettype. Order carries no meaning in either direction, and Terraform deduplicates entries within each field before they reach the API β do not build automation that depends on recipient ordering being preserved.profileis a plain cross-module string reference. This module does notdepends_onthe alerting profile; wiringmodule.<alerting_profile>.iddirectly intoprofile(see Example 15) gives Terraform an implicit reference so the profile is always created or updated first.activefalse is a module-level default, not a provider default. The provider leaves this field's behavior undocumented when entirely absent from the resource block; this module makes the choice explicit by renderingactive = falseunless the caller opts in.notify_closed_problemsleftnullis deliberate, not an oversight. Per house guidance for undocumented provider defaults, the module does not invent a plausible-sounding default β it omits the argument and defers to the Dynatrace API's own server-side behavior when unset.- No credential-bearing fields exist on this resource at all β unlike sibling notification-channel
modules (Slack, webhook, PagerDuty, OpsGenie, ServiceNow, etc.), there is no
sensitive = truevariable in this module because there is no secret-shaped attribute in the underlying provider schema to protect. - No owned children, no
for_eachinside this module. Breadth at scale (multiple teams, environments, or channels) is achieved by the calling root modulefor_each-ing this module block itself, keyed by a caller-chosen map key β see Examples 12 and 13.
| Concern | Safe default | Opt-out (caller must set explicitly) |
|---|---|---|
| Newly-applied notification integration | active = false β the integration is created inert and cannot send email until reviewed |
Explicit active = true |
| Ambiguous open/close notification behavior | notify_closed_problems = null β no invented default; the module does not guess the provider's undocumented server-side behavior |
Explicit true or false |
| CC/BCC recipient breadth | cc/bcc default to [] β no additional recipients beyond to unless explicitly listed |
Populate cc/bcc explicitly |
| Primary recipients | No default β to is required; a caller cannot apply this module without explicitly naming recipients |
N/A β required by the provider schema, not a module-level opt-out |
| Credential-bearing fields | Not applicable β this resource has no sensitive fields; it is the one channel in this family without one | N/A |
terraform init -backend=false
terraform validate
terraform fmt -checkPin the module source to an explicit tag β ?ref=v1.0.0 β never a branch. This library is plan-only: a
human applies from CI after reviewing the plan.
terraform validate and terraform fmt -check prove the module's HCL is syntactically well-formed,
that every required variable is supplied, that to/cc/bcc type-check as set(string) (rejecting a
comma-joined string or a list literal with mismatched element types), and that the resource graph
resolves. They do not prove that a given profile ID exists in the target environment, that the
configured OAuth client or API token actually carries the settings.read/settings.write scopes, that
Dynatrace accepts the literal email address strings supplied, or that subject/body placeholder syntax
resolves the way the caller expects β those are only exercised by a real terraform plan/apply against
a live Dynatrace environment, which this authoring process does not perform.
$ terraform output
id = "vu9U3hXa3q0AAAAA"
name = "Email - Platform Team - Critical Availability"
| Symptom | Cause | Fix |
|---|---|---|
apply fails with an authentication/authorization error |
The configured API token lacks settings.read/settings.write, or the OAuth client's IAM policy lacks settings:objects:read/settings:objects:write β or the wrong auth mechanism is configured at the provider level entirely |
Confirm the accepted mechanisms and scopes in Β§ Required OAuth Scopes / API Token Permissions above, and confirm the provider configuration itself (OAuth vs. platform token vs. API token) |
apply succeeds but no email is ever sent |
active was left at its secure default of false |
Set active = true once recipients, subject, body, and alerting profile scope have been reviewed |
plan fails because profile doesn't resolve |
The referenced alerting profile ID doesn't exist yet, or the wrong module's output was wired in | Confirm the terraform-dynatrace-alerting-profile instance applies first, or reference its id output directly (Example 15) so Terraform orders the two implicitly |
A cc/bcc address you added doesn't seem to show up, or order looks different than you typed it |
to/cc/bcc are TypeSets, not ordered lists; duplicates within a field are collapsed and element order isn't preserved |
Expect a deduplicated, unordered set; don't build downstream automation that depends on recipient order |
| Recipients get two copies of the same email | The same address was listed in both to and cc (or cc and bcc) |
Deduplication only happens within a single field, not across to/cc/bcc β remove the address from all but one field |
| Open/close notification behavior seems inconsistent across environments | notify_closed_problems was left at its null default, deferring to an undocumented server-side behavior |
Set notify_closed_problems explicitly to true or false for deterministic behavior |
| Subject or body renders a placeholder literally instead of substituting a value | A placeholder name was typed incorrectly (e.g. {ProblemTile} instead of {ProblemTitle}) |
This module passes the string through unmodified β type { in the Dynatrace UI to get placeholder autocomplete, then copy the exact template into subject/body |
- Dynatrace provider resource reference:
dynatrace_email_notification(dynatrace-oss/dynatrace, schemaIdbuiltin:problem.notifications) - Sibling module:
terraform-dynatrace-alerting-profile(owns theprofilethis module references) - Sibling notification-channel modules in this domain:
terraform-dynatrace-slack-notification,terraform-dynatrace-webhook-notification,terraform-dynatrace-pagerduty-notification,terraform-dynatrace-ops-genie-notification,terraform-dynatrace-servicenow-notification,terraform-dynatrace-jira-notification,terraform-dynatrace-trello-notification,terraform-dynatrace-victorops-notification,terraform-dynatrace-xmatters-notification,terraform-dynatrace-ansible-tower-notification - This module's
SCOPE.md
π "Infrastructure as Code should be standardized, consistent, and secure."