diff --git a/extra/alerts/alert_file.sh.sample b/extra/alerts/alert_file.sh.sample
index 7844c77e60..f6c2211513 100644
--- a/extra/alerts/alert_file.sh.sample
+++ b/extra/alerts/alert_file.sh.sample
@@ -1,109 +1,122 @@
 #!/bin/sh
 #
 # Copyright 2015-2021 the Pacemaker project contributors
 #
 # The version control history for this file may have further details.
 #
 # This source code is licensed under the GNU General Public License version 2
 # or later (GPLv2+) WITHOUT ANY WARRANTY.
 #
 ##############################################################################
 # Sample configuration (cib fragment in xml notation)
 # ================================
 # <configuration>
 #   <alerts>
 #     <alert id="alert_sample" path="/path/to/alert_file.sh">
 #       <instance_attributes id="config_for_alert_file">
 #         <nvpair id="debug_option_1" name="debug_exec_order" value="false"/>
 #       </instance_attributes>
 #       <meta_attributes id="config_for_timestamp">
 #         <nvpair id="ts_fmt" name="timestamp-format" value="%H:%M:%S.%06N"/>
 #       </meta_attributes>
 #       <recipient id="logfile_destination" value="/path/to/logfile"/>
 #     </alert>
 #   </alerts>
 # </configuration>
 
+# Explicitly list all environment variables used, to make static analysis happy
+: ${CRM_alert_version:=""}
+: ${CRM_alert_recipient:=""}
+: ${CRM_alert_node_sequence:=""}
+: ${CRM_alert_timestamp:=""}
+: ${CRM_alert_kind:=""}
+: ${CRM_alert_node:=""}
+: ${CRM_alert_desc:=""}
+: ${CRM_alert_task:=""}
+: ${CRM_alert_rsc:=""}
+: ${CRM_alert_attribute_name:=""}
+: ${CRM_alert_attribute_value:=""}
+
 # No one will probably ever see this echo, unless they run the script manually.
 # An alternative would be to log to the system log, or similar. (We can't send
 # this to the configured recipient, because that variable won't be defined in
 # this case either.)
 if [ -z $CRM_alert_version ]; then
     echo "$0 must be run by Pacemaker version 1.1.15 or later"
     exit 0
 fi
 
 # Alert agents must always handle the case where no recipients are defined,
 # even if it's a no-op (a recipient might be added to the configuration later).
 if [ -z "${CRM_alert_recipient}" ]; then
     echo "$0 requires a recipient configured with a full filename path"
     exit 0
 fi
 
 debug_exec_order_default="false"
 
 # Pacemaker passes instance attributes to alert agents as environment variables.
 # It is completely up to the agent what instance attributes to support.
 # Here, we define an instance attribute "debug_exec_order".
 : ${debug_exec_order=${debug_exec_order_default}}
 
 if [ "${debug_exec_order}" = "true" ]; then
     tstamp=`printf "%04d. " "$CRM_alert_node_sequence"`
     if [ ! -z "$CRM_alert_timestamp" ]; then
         tstamp="${tstamp} $CRM_alert_timestamp (`date "+%H:%M:%S.%06N"`): "
     fi
 else
     if [ ! -z "$CRM_alert_timestamp" ]; then
         tstamp="$CRM_alert_timestamp: "
     fi
 fi
 
 case $CRM_alert_kind in
     node)
         echo "${tstamp}Node '${CRM_alert_node}' is now '${CRM_alert_desc}'" >> "${CRM_alert_recipient}"
         ;;
     fencing)
         # Other keys:
         #
         # CRM_alert_node
         # CRM_alert_task
         # CRM_alert_rc
         #
         echo "${tstamp}Fencing ${CRM_alert_desc}" >> "${CRM_alert_recipient}"
         ;;
     resource)
         # Other keys:
         #
         # CRM_alert_target_rc
         # CRM_alert_status
         # CRM_alert_rc
         #
         if [ ${CRM_alert_interval} = "0" ]; then
             CRM_alert_interval=""
         else
             CRM_alert_interval=" (${CRM_alert_interval})"
         fi
 
         if [ ${CRM_alert_target_rc} = "0" ]; then
             CRM_alert_target_rc=""
         else
             CRM_alert_target_rc=" (target: ${CRM_alert_target_rc})"
         fi
 
         case ${CRM_alert_desc} in
             Cancelled) ;;
             *)
                 echo "${tstamp}Resource operation '${CRM_alert_task}${CRM_alert_interval}' for '${CRM_alert_rsc}' on '${CRM_alert_node}': ${CRM_alert_desc}${CRM_alert_target_rc}" >> "${CRM_alert_recipient}"
                 ;;
         esac
         ;;
     attribute)
         #
         echo "${tstamp}Attribute '${CRM_alert_attribute_name}' on node '${CRM_alert_node}' was updated to '${CRM_alert_attribute_value}'" >> "${CRM_alert_recipient}"
         ;;
 
     *)
         echo "${tstamp}Unhandled $CRM_alert_kind alert" >> "${CRM_alert_recipient}"
         env | grep CRM_alert >> "${CRM_alert_recipient}"
         ;;
 esac
diff --git a/extra/alerts/alert_smtp.sh.sample b/extra/alerts/alert_smtp.sh.sample
index 5da83ade4a..62bfc41517 100644
--- a/extra/alerts/alert_smtp.sh.sample
+++ b/extra/alerts/alert_smtp.sh.sample
@@ -1,106 +1,118 @@
 #!/bin/sh
 #
-# Copyright 2016-2017 the Pacemaker project contributors
+# Copyright 2016-2021 the Pacemaker project contributors
 #
 # The version control history for this file may have further details.
 #
 # This source code is licensed under the GNU General Public License version 2
 # or later (GPLv2+) WITHOUT ANY WARRANTY.
 #
 ##############################################################################
 #
 # Sample configuration (cib fragment in xml notation)
 # ================================
 # <configuration>
 #   <alerts>
 #     <alert id="smtp_alert" path="/path/to/alert_smtp">
 #       <instance_attributes id="config_for_alert_smtp">
 #         <nvpair id="cluster_name" name="cluster_name" value=""/>
 #         <nvpair id="email_client" name="email_client" value=""/>
 #         <nvpair id="email_sender" name="email_sender" value=""/>
 #       </instance_attributes>
 #       <recipient id="smtp_destination" value="admin@example.com"/>
 #     </alert>
 #   </alerts>
 # </configuration>
 
+# Explicitly list all environment variables used, to make static analysis happy
+: ${CRM_alert_version:=""}
+: ${CRM_alert_recipient:=""}
+: ${CRM_alert_timestamp:=""}
+: ${CRM_alert_kind:=""}
+: ${CRM_alert_node:=""}
+: ${CRM_alert_desc:=""}
+: ${CRM_alert_task:=""}
+: ${CRM_alert_rsc:=""}
+: ${CRM_alert_attribute_name:=""}
+: ${CRM_alert_attribute_value:=""}
+
 email_client_default="sendmail"
 email_sender_default="hacluster"
 email_recipient_default="root"
 
 : ${email_client=${email_client_default}}
 : ${email_sender=${email_sender_default}}
 email_recipient="${CRM_alert_recipient-${email_recipient_default}}"
 
 node_name=`uname -n`
 cluster_name=`crm_attribute --query -n cluster-name -q`
 email_body=`env | grep CRM_alert_`
 
 if [ ! -z "${email_sender##*@*}" ]; then
     email_sender="${email_sender}@${node_name}"
 fi
 
 if [ ! -z "${email_recipient##*@*}" ]; then
     email_recipient="${email_recipient}@${node_name}"
 fi
 
 if [ -z ${CRM_alert_version} ]; then
     email_subject="Pacemaker version 1.1.15 or later is required for alerts"
 else
     case ${CRM_alert_kind} in
         node)
             email_subject="${CRM_alert_timestamp} ${cluster_name}: Node '${CRM_alert_node}' is now '${CRM_alert_desc}'"
             ;;
         fencing)
             email_subject="${CRM_alert_timestamp} ${cluster_name}: Fencing ${CRM_alert_desc}"
             ;;
         resource)
             if [ ${CRM_alert_interval} = "0" ]; then
                 CRM_alert_interval=""
             else
                 CRM_alert_interval=" (${CRM_alert_interval})"
             fi
 
             if [ ${CRM_alert_target_rc} = "0" ]; then
                 CRM_alert_target_rc=""
             else
                 CRM_alert_target_rc=" (target: ${CRM_alert_target_rc})"
             fi
 
             case ${CRM_alert_desc} in
                 Cancelled) ;;
                 *)
                     email_subject="${CRM_alert_timestamp} ${cluster_name}: Resource operation '${CRM_alert_task}${CRM_alert_interval}' for '${CRM_alert_rsc}' on '${CRM_alert_node}': ${CRM_alert_desc}${CRM_alert_target_rc}"
                     ;;
             esac
             ;;
         attribute)
             #
             email_subject="${CRM_alert_timestamp} ${cluster_name}: The '${CRM_alert_attribute_name}' attribute of the '${CRM_alert_node}' node was updated in '${CRM_alert_attribute_value}'"
             ;;
         *)
             email_subject="${CRM_alert_timestamp} ${cluster_name}: Unhandled $CRM_alert_kind alert"
             ;;
 
     esac
 fi
 
 if [ ! -z "${email_subject}" ]; then
     case $email_client in
         # This sample script supports only sendmail for sending the email.
 	# Support for additional senders can easily be added by adding
 	# new cases here.
         sendmail)
             sendmail -t -r "${email_sender}" <<__EOF__
 From: ${email_sender}
 To: ${email_recipient}
 Return-Path: ${email_sender}
 Subject: ${email_subject}
 
 ${email_body}
 __EOF__
             ;;
         *)
             ;;
     esac
 fi
diff --git a/extra/alerts/alert_snmp.sh.sample b/extra/alerts/alert_snmp.sh.sample
index 8354f82308..841f30f0c7 100644
--- a/extra/alerts/alert_snmp.sh.sample
+++ b/extra/alerts/alert_snmp.sh.sample
@@ -1,183 +1,186 @@
 #!/bin/sh
 #
 # Copyright 2013 Florian CROUZAT <gentoo@floriancrouzat.net>
 # Later changes copyright 2013-2021 the Pacemaker project contributors
 #
 # The version control history for this file may have further details.
 #
 # This source code is licensed under the GNU General Public License version 2
 # or later (GPLv2+) WITHOUT ANY WARRANTY.
 #
 # Description:  Manages a SNMP trap, provided by NTT OSSC as a
 #               script under Pacemaker control
 #
 ##############################################################################
 # This sample script assumes that only users who already have
 # hacluster-equivalent access to the cluster nodes can edit the CIB. Otherwise,
 # a malicious user could run commands as hacluster by inserting shell code into
 # the trap_options or timestamp-format parameters.
 #
 # Sample configuration (cib fragment in xml notation)
 # ================================
 # <configuration>
 #   <alerts>
 #     <alert id="snmp_alert" path="/path/to/alert_snmp.sh">
 #       <instance_attributes id="config_for_alert_snmp">
 #         <nvpair id="trap_node_states" name="trap_node_states" value="all"/>
 #       </instance_attributes>
 #       <meta_attributes id="config_for_timestamp">
 #         <nvpair id="ts_fmt" name="timestamp-format" value="%Y-%m-%d,%H:%M:%S.%01N"/>
 #       </meta_attributes>
 #       <recipient id="snmp_destination" value="192.168.1.2"/>
 #     </alert>
 #   </alerts>
 # </configuration>
 # ================================
 #
 # This uses the official Pacemaker MIB.
 # 1.3.6.1.4.1.32723 has been assigned to the project by IANA:
 # http://www.iana.org/assignments/enterprise-numbers
 
-if [ -z "$CRM_alert_version" ]; then
-    echo "$0 must be run by Pacemaker version 1.1.15 or later"
-    exit 0
-fi
-
-if [ -z "$CRM_alert_recipient" ]; then
-    echo "$0 requires a recipient configured with the SNMP server IP address"
-    exit 0
-fi
-
 # Defaults for user-configurable values
 trap_binary_default="/usr/bin/snmptrap"
 trap_version_default="2c"
 trap_options_default=""
 trap_community_default="public"
 trap_node_states_default="all"
 trap_fencing_tasks_default="all"
 trap_resource_tasks_default="all"
 trap_monitor_success_default="false"
 trap_add_hires_timestamp_oid_default="true"
 trap_snmp_persistent_dir_default="/var/lib/pacemaker/snmp"
 trap_ignore_int32_default=2147483647  # maximum Integer32 value
 trap_ignore_string_default="n/a"      # doesn't conflict with valid XML IDs
 
 # Ensure all user-provided variables have values.
 : ${trap_binary=${trap_binary_default}}
 : ${trap_version=${trap_version_default}}
 : ${trap_options=${trap_options_default}}
 : ${trap_community=${trap_community_default}}
 : ${trap_node_states=${trap_node_states_default}}
 : ${trap_fencing_tasks=${trap_fencing_tasks_default}}
 : ${trap_resource_tasks=${trap_resource_tasks_default}}
 : ${trap_monitor_success=${trap_monitor_success_default}}
 : ${trap_add_hires_timestamp_oid=${trap_add_hires_timestamp_oid_default}}
 : ${trap_snmp_persistent_dir=${trap_snmp_persistent_dir_default}}
 : ${trap_ignore_int32=${trap_ignore_int32_default}}
 : ${trap_ignore_string=${trap_ignore_string_default}}
 
 # Ensure all cluster-provided variables have values, regardless of alert type.
 : ${CRM_alert_node=${trap_ignore_string}}
 : ${CRM_alert_rsc=${trap_ignore_string}}
 : ${CRM_alert_task=${trap_ignore_string}}
 : ${CRM_alert_desc=${trap_ignore_string}}
 : ${CRM_alert_status=${trap_ignore_int32}}
 : ${CRM_alert_rc=${trap_ignore_int32}}
 : ${CRM_alert_target_rc=${trap_ignore_int32}}
 : ${CRM_alert_attribute_name=${trap_ignore_string}}
 : ${CRM_alert_attribute_value=${trap_ignore_string}}
+: ${CRM_alert_version:=""}
+: ${CRM_alert_recipient:=""}
+: ${CRM_alert_kind:=""}
+
+if [ -z "$CRM_alert_version" ]; then
+    echo "$0 must be run by Pacemaker version 1.1.15 or later"
+    exit 0
+fi
+
+if [ -z "$CRM_alert_recipient" ]; then
+    echo "$0 requires a recipient configured with the SNMP server IP address"
+    exit 0
+fi
 
 # Echo a high-resolution equivalent of the Pacemaker-provided time values
 # using NetSNMP's DateAndTime specification ("%Y-%m-%d,%H:%M:%S.%01N").
 get_system_date() {
     : ${CRM_alert_timestamp_epoch=$(date +%s)}
     : ${CRM_alert_timestamp_usec=0}
 
     YMDHMS=$(date --date="@${CRM_alert_timestamp_epoch}" +"%Y-%m-%d,%H:%M:%S")
     USEC=$(echo ${CRM_alert_timestamp_usec} | cut -b 1)
     echo "${YMDHMS}.${USEC}"
 }
 
 is_in_list() {
     item_list=`echo "$1" | tr ',' ' '`
 
     if [ "${item_list}" = "all" ]; then
         return 0
     else
         for act in $item_list
         do
             act=`echo "$act" | tr A-Z a-z`
             [ "$act" != "$2" ] && continue
             return 0
         done
     fi
     return 1
 }
 
 send_pacemaker_trap() {
     PREFIX="PACEMAKER-MIB::pacemakerNotification"
 
     OUTPUT=$("${trap_binary}" -v "${trap_version}" ${trap_options} \
         -c "${trap_community}" "${CRM_alert_recipient}" "" \
         "${PREFIX}Trap" \
         "${PREFIX}Node"             s "${CRM_alert_node}" \
         "${PREFIX}Resource"         s "${CRM_alert_rsc}" \
         "${PREFIX}Operation"        s "${CRM_alert_task}" \
         "${PREFIX}Description"      s "${CRM_alert_desc}" \
         "${PREFIX}Status"           i "${CRM_alert_status}" \
         "${PREFIX}ReturnCode"       i "${CRM_alert_rc}" \
         "${PREFIX}TargetReturnCode" i "${CRM_alert_target_rc}" \
         "${PREFIX}AttributeName"    s "${CRM_alert_attribute_name}" \
         "${PREFIX}AttributeValue"   s "${CRM_alert_attribute_value}" \
         ${hires_timestamp} 2>&1)
 
     if [ $? -ne 0 ]; then
         echo "${trap_binary} returned error : rc=$? $OUTPUT"
     fi
 }
 
 if [ "${trap_add_hires_timestamp_oid}" = "true" ]; then
     hires_timestamp="HOST-RESOURCES-MIB::hrSystemDate s $(get_system_date)"
 fi
 
 if [ -z ${SNMP_PERSISTENT_DIR} ]; then
     export SNMP_PERSISTENT_DIR="${trap_snmp_persistent_dir}"
     # mkdir for snmp trap tools.
     if [ ! -d ${SNMP_PERSISTENT_DIR} ]; then
         mkdir -p ${SNMP_PERSISTENT_DIR}
     fi
 fi
 
 case "$CRM_alert_kind" in
     node)
         if is_in_list "${trap_node_states}" "${CRM_alert_desc}"; then
             send_pacemaker_trap
         fi
         ;;
 
     fencing)
         if is_in_list "${trap_fencing_tasks}" "${CRM_alert_task}"; then
             send_pacemaker_trap
         fi
         ;;
 
     resource)
         if is_in_list "${trap_resource_tasks}" "${CRM_alert_task}" && \
            [ "${CRM_alert_desc}" != "Cancelled" ] ; then
 
             if [ "${trap_monitor_success}" = "false" ] && \
                [ "${CRM_alert_rc}" = "${CRM_alert_target_rc}" ] && \
                [ "${CRM_alert_task}" = "monitor" ]; then
                 exit 0
             fi
             send_pacemaker_trap
         fi
         ;;
 
     attribute)
         send_pacemaker_trap
         ;;
 
     *)
         ;;
 esac