{
  "Description": "(SO0005-SQ) - quota-monitor-for-aws - Service Quotas Template. Version v6.3.12",
  "AWSTemplateFormatVersion": "2010-09-09",
  "Metadata": {
    "AWS::CloudFormation::Interface": {
      "ParameterGroups": [
        {
          "Label": {
            "default": "Monitoring Account Configuration"
          },
          "Parameters": [
            "EventBusArn",
            "SpokeSnsRegion"
          ]
        },
        {
          "Label": {
            "default": "Service Quotas Configuration"
          },
          "Parameters": [
            "NotificationThreshold",
            "MonitoringFrequency",
            "ReportOKNotifications",
            "SageMakerMonitoring",
            "ConnectMonitoring"
          ]
        }
      ],
      "ParameterLabels": {
        "EventBusArn": {
          "default": "Arn for the EventBridge bus in the monitoring account"
        },
        "SpokeSnsRegion": {
          "default": "Region in which the spoke SNS stack exists in this account"
        },
        "NotificationThreshold": {
          "default": "At what quota utilization do you want notifications?"
        },
        "MonitoringFrequency": {
          "default": "Frequency to monitor quota utilization"
        },
        "ReportOKNotifications": {
          "default": "Report OK Notifications"
        },
        "SageMakerMonitoring": {
          "default": "Enable monitoring for SageMaker quotas"
        },
        "ConnectMonitoring": {
          "default": "Enable monitoring for Connect quotas"
        }
      }
    }
  },
  "Parameters": {
    "EventBusArn": {
      "Type": "String"
    },
    "SpokeSnsRegion": {
      "Type": "String",
      "Default": "",
      "Description": "The region in which the spoke SNS stack exists in this account. Leave blank if the spoke SNS is not needed."
    },
    "NotificationThreshold": {
      "Type": "String",
      "Default": "80",
      "AllowedPattern": "^([1-9]|[1-9][0-9])$",
      "ConstraintDescription": "Threshold must be a whole number between 0 and 100",
      "Description": "Threshold percentage for quota utilization alerts (0-100)"
    },
    "MonitoringFrequency": {
      "Type": "String",
      "Default": "rate(12 hours)",
      "AllowedValues": [
        "rate(6 hours)",
        "rate(12 hours)",
        "rate(1 day)"
      ]
    },
    "ReportOKNotifications": {
      "Type": "String",
      "Default": "No",
      "AllowedValues": [
        "Yes",
        "No"
      ]
    },
    "SageMakerMonitoring": {
      "Type": "String",
      "Default": "Yes",
      "AllowedValues": [
        "Yes",
        "No"
      ]
    },
    "ConnectMonitoring": {
      "Type": "String",
      "Default": "Yes",
      "AllowedValues": [
        "Yes",
        "No"
      ]
    }
  },
  "Mappings": {
    "QuotaMonitorMap": {
      "SSMParameters": {
        "NotificationMutingConfig": "/QuotaMonitor/spoke/NotificationConfiguration"
      }
    }
  },
  "Conditions": {
    "SpokeSnsRegionExists": {
      "Fn::Not": [
        {
          "Fn::Equals": [
            {
              "Ref": "SpokeSnsRegion"
            },
            ""
          ]
        }
      ]
    }
  },
  "Resources": {
    "QMSpokeBus1D13B121": {
      "Type": "AWS::Events::EventBus",
      "Properties": {
        "Name": "QuotaMonitorSpokeBus"
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Spoke-Bus/Resource"
      }
    },
    "QMUtilsLayerquotamonitorsqspokeQMUtilsLayerquotamonitorsqspokeLayerF6FD536E": {
      "Type": "AWS::Lambda::LayerVersion",
      "Properties": {
        "CompatibleRuntimes": [
          "nodejs24.x"
        ],
        "Content": {
          "S3Bucket": {
            "Fn::Sub": "solutions-${AWS::Region}"
          },
          "S3Key": "quota-monitor-for-aws/v6.3.12/assetf6d5c2680d83968bf87c1f718a7cfbbcdc2e873a467dbf89f7c96750a7fd677a.zip"
        },
        "LayerName": "QM-UtilsLayer-quota-monitor-sq-spoke"
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-UtilsLayer-quota-monitor-sq-spoke/QM-UtilsLayer-quota-monitor-sq-spoke-Layer/Resource",
        "aws:asset:path": "asset.f6d5c2680d83968bf87c1f718a7cfbbcdc2e873a467dbf89f7c96750a7fd677a.zip",
        "aws:asset:is-bundled": false,
        "aws:asset:property": "Content"
      }
    },
    "SQServiceTable0182B2D0": {
      "Type": "AWS::DynamoDB::Table",
      "Properties": {
        "AttributeDefinitions": [
          {
            "AttributeName": "ServiceCode",
            "AttributeType": "S"
          }
        ],
        "BillingMode": "PAY_PER_REQUEST",
        "KeySchema": [
          {
            "AttributeName": "ServiceCode",
            "KeyType": "HASH"
          }
        ],
        "PointInTimeRecoverySpecification": {
          "PointInTimeRecoveryEnabled": true
        },
        "SSESpecification": {
          "SSEEnabled": true
        },
        "StreamSpecification": {
          "StreamViewType": "NEW_AND_OLD_IMAGES"
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/SQ-ServiceTable/Resource",
        "guard": {
          "SuppressedRules": [
            "DYNAMODB_TABLE_ENCRYPTED_KMS"
          ]
        }
      }
    },
    "SQQuotaTableD0BC5741": {
      "Type": "AWS::DynamoDB::Table",
      "Properties": {
        "AttributeDefinitions": [
          {
            "AttributeName": "ServiceCode",
            "AttributeType": "S"
          },
          {
            "AttributeName": "QuotaCode",
            "AttributeType": "S"
          }
        ],
        "BillingMode": "PAY_PER_REQUEST",
        "KeySchema": [
          {
            "AttributeName": "ServiceCode",
            "KeyType": "HASH"
          },
          {
            "AttributeName": "QuotaCode",
            "KeyType": "RANGE"
          }
        ],
        "PointInTimeRecoverySpecification": {
          "PointInTimeRecoveryEnabled": true
        },
        "SSESpecification": {
          "SSEEnabled": true
        }
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/SQ-QuotaTable/Resource",
        "guard": {
          "SuppressedRules": [
            "DYNAMODB_TABLE_ENCRYPTED_KMS"
          ]
        }
      }
    },
    "QMListManagerQMListManagerFunctionServiceRole12D19CB7": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "ManagedPolicyArns": [
          {
            "Fn::Join": [
              "",
              [
                "arn:",
                {
                  "Ref": "AWS::Partition"
                },
                ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
              ]
            ]
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManager/QM-ListManager-Function/ServiceRole/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "AWSLambdaBasicExecutionRole added by cdk only gives write permissions for CW logs",
              "id": "AwsSolutions-IAM4"
            },
            {
              "reason": "Actions restricted on kms key ARN. Only actions that do not support resource-level permissions have * in resource",
              "id": "AwsSolutions-IAM5"
            },
            {
              "reason": "GovCloud regions support only up to nodejs 16, risk is tolerable",
              "id": "AwsSolutions-L1"
            },
            {
              "reason": "Actions do not support resource-level permissions",
              "id": "AwsSolutions-IAM5"
            }
          ]
        }
      }
    },
    "QMListManagerQMListManagerFunctionServiceRoleDefaultPolicy314665D0": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": [
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:BatchWriteItem",
                "dynamodb:DeleteItem",
                "dynamodb:Query",
                "dynamodb:Scan"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "SQServiceTable0182B2D0",
                  "Arn"
                ]
              }
            },
            {
              "Action": [
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:BatchWriteItem",
                "dynamodb:DeleteItem",
                "dynamodb:Query",
                "dynamodb:Scan"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "SQQuotaTableD0BC5741",
                  "Arn"
                ]
              }
            },
            {
              "Action": [
                "cloudwatch:GetMetricData",
                "servicequotas:ListServiceQuotas",
                "servicequotas:ListServices",
                "dynamodb:DescribeLimits",
                "autoscaling:DescribeAccountLimits",
                "route53:GetAccountLimit",
                "rds:DescribeAccountAttributes"
              ],
              "Effect": "Allow",
              "Resource": "*"
            },
            {
              "Action": "dynamodb:ListStreams",
              "Effect": "Allow",
              "Resource": "*"
            },
            {
              "Action": [
                "dynamodb:DescribeStream",
                "dynamodb:GetRecords",
                "dynamodb:GetShardIterator"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "SQServiceTable0182B2D0",
                  "StreamArn"
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "QMListManagerQMListManagerFunctionServiceRoleDefaultPolicy314665D0",
        "Roles": [
          {
            "Ref": "QMListManagerQMListManagerFunctionServiceRole12D19CB7"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManager/QM-ListManager-Function/ServiceRole/DefaultPolicy/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "Actions do not support resource-level permissions",
              "id": "AwsSolutions-IAM5"
            }
          ]
        }
      }
    },
    "QMListManagerQMListManagerFunction1F09A88F": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "S3Bucket": {
            "Fn::Sub": "solutions-${AWS::Region}"
          },
          "S3Key": "quota-monitor-for-aws/v6.3.12/asset6030357ea3654ae037f3e322020a56ab1e28a383c2f579572c4ad84b0ef8fd79.zip"
        },
        "Description": "SO0005 quota-monitor-for-aws - QM-ListManager-Function",
        "Environment": {
          "Variables": {
            "SQ_SERVICE_TABLE": {
              "Ref": "SQServiceTable0182B2D0"
            },
            "SQ_QUOTA_TABLE": {
              "Ref": "SQQuotaTableD0BC5741"
            },
            "PARTITION_KEY": "ServiceCode",
            "SORT": "QuotaCode",
            "LOG_LEVEL": "info",
            "CUSTOM_SDK_USER_AGENT": "AwsSolution/SO0005/v6.3.12",
            "VERSION": "v6.3.12",
            "SOLUTION_ID": "SO0005"
          }
        },
        "Handler": "index.handler",
        "Layers": [
          {
            "Ref": "QMUtilsLayerquotamonitorsqspokeQMUtilsLayerquotamonitorsqspokeLayerF6FD536E"
          }
        ],
        "MemorySize": 256,
        "Role": {
          "Fn::GetAtt": [
            "QMListManagerQMListManagerFunctionServiceRole12D19CB7",
            "Arn"
          ]
        },
        "Runtime": "nodejs24.x",
        "Timeout": 900
      },
      "DependsOn": [
        "QMListManagerQMListManagerFunctionServiceRoleDefaultPolicy314665D0",
        "QMListManagerQMListManagerFunctionServiceRole12D19CB7"
      ],
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManager/QM-ListManager-Function/Resource",
        "aws:asset:path": "asset.6030357ea3654ae037f3e322020a56ab1e28a383c2f579572c4ad84b0ef8fd79.zip",
        "aws:asset:is-bundled": false,
        "aws:asset:property": "Code",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "GovCloud regions support only up to nodejs 16, risk is tolerable",
              "id": "AwsSolutions-L1"
            }
          ]
        },
        "guard": {
          "SuppressedRules": [
            "LAMBDA_INSIDE_VPC",
            "LAMBDA_CONCURRENCY_CHECK",
            "LAMBDA_INSIDE_VPC",
            "LAMBDA_CONCURRENCY_CHECK"
          ]
        }
      }
    },
    "QMListManagerQMListManagerFunctionEventInvokeConfigDDD15BD1": {
      "Type": "AWS::Lambda::EventInvokeConfig",
      "Properties": {
        "FunctionName": {
          "Ref": "QMListManagerQMListManagerFunction1F09A88F"
        },
        "MaximumEventAgeInSeconds": 14400,
        "Qualifier": "$LATEST"
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManager/QM-ListManager-Function/EventInvokeConfig/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "GovCloud regions support only up to nodejs 16, risk is tolerable",
              "id": "AwsSolutions-L1"
            }
          ]
        }
      }
    },
    "QMListManagerQMListManagerFunctionDynamoDBEventSourcequotamonitorsqspokeSQServiceTableDFB54B66D184A01F": {
      "Type": "AWS::Lambda::EventSourceMapping",
      "Properties": {
        "BatchSize": 1,
        "EventSourceArn": {
          "Fn::GetAtt": [
            "SQServiceTable0182B2D0",
            "StreamArn"
          ]
        },
        "FunctionName": {
          "Ref": "QMListManagerQMListManagerFunction1F09A88F"
        },
        "StartingPosition": "LATEST"
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManager/QM-ListManager-Function/DynamoDBEventSource:quotamonitorsqspokeSQServiceTableDFB54B66/Resource"
      }
    },
    "QMListManagerQMListManagerProviderframeworkonEventServiceRoleB85FCC1C": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "ManagedPolicyArns": [
          {
            "Fn::Join": [
              "",
              [
                "arn:",
                {
                  "Ref": "AWS::Partition"
                },
                ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
              ]
            ]
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManager/QM-ListManager-Provider/framework-onEvent/ServiceRole/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "AWSLambdaBasicExecutionRole added by cdk only gives write permissions for CW logs",
              "id": "AwsSolutions-IAM4"
            },
            {
              "reason": "IAM policy is appropriated scoped, ARN is provided in policy resource, false warning",
              "id": "AwsSolutions-IAM5"
            },
            {
              "reason": "Lambda function created by Provider L2 construct uses nodejs 14, risk is tolerable",
              "id": "AwsSolutions-L1"
            }
          ]
        }
      }
    },
    "QMListManagerQMListManagerProviderframeworkonEventServiceRoleDefaultPolicy60F3D9D1": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "lambda:InvokeFunction",
              "Effect": "Allow",
              "Resource": [
                {
                  "Fn::GetAtt": [
                    "QMListManagerQMListManagerFunction1F09A88F",
                    "Arn"
                  ]
                },
                {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "QMListManagerQMListManagerFunction1F09A88F",
                          "Arn"
                        ]
                      },
                      ":*"
                    ]
                  ]
                }
              ]
            },
            {
              "Action": "lambda:GetFunction",
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "QMListManagerQMListManagerFunction1F09A88F",
                  "Arn"
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "QMListManagerQMListManagerProviderframeworkonEventServiceRoleDefaultPolicy60F3D9D1",
        "Roles": [
          {
            "Ref": "QMListManagerQMListManagerProviderframeworkonEventServiceRoleB85FCC1C"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManager/QM-ListManager-Provider/framework-onEvent/ServiceRole/DefaultPolicy/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "AWSLambdaBasicExecutionRole added by cdk only gives write permissions for CW logs",
              "id": "AwsSolutions-IAM4"
            },
            {
              "reason": "IAM policy is appropriated scoped, ARN is provided in policy resource, false warning",
              "id": "AwsSolutions-IAM5"
            },
            {
              "reason": "Lambda function created by Provider L2 construct uses nodejs 14, risk is tolerable",
              "id": "AwsSolutions-L1"
            }
          ]
        }
      }
    },
    "QMListManagerQMListManagerProviderframeworkonEvent1F57B2C8": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "S3Bucket": {
            "Fn::Sub": "solutions-${AWS::Region}"
          },
          "S3Key": "quota-monitor-for-aws/v6.3.12/asset07a90cc3efdfc34da22208dcd9d211f06f5b0e01b21e778edc7c3966b1f61d57.zip"
        },
        "Description": "AWS CDK resource provider framework - onEvent (quota-monitor-sq-spoke/QM-ListManager/QM-ListManager-Provider)",
        "Environment": {
          "Variables": {
            "USER_ON_EVENT_FUNCTION_ARN": {
              "Fn::GetAtt": [
                "QMListManagerQMListManagerFunction1F09A88F",
                "Arn"
              ]
            }
          }
        },
        "Handler": "framework.onEvent",
        "LoggingConfig": {
          "ApplicationLogLevel": "FATAL",
          "LogFormat": "JSON"
        },
        "Role": {
          "Fn::GetAtt": [
            "QMListManagerQMListManagerProviderframeworkonEventServiceRoleB85FCC1C",
            "Arn"
          ]
        },
        "Runtime": "nodejs22.x",
        "Timeout": 900
      },
      "DependsOn": [
        "QMListManagerQMListManagerProviderframeworkonEventServiceRoleDefaultPolicy60F3D9D1",
        "QMListManagerQMListManagerProviderframeworkonEventServiceRoleB85FCC1C"
      ],
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManager/QM-ListManager-Provider/framework-onEvent/Resource",
        "aws:asset:path": "asset.07a90cc3efdfc34da22208dcd9d211f06f5b0e01b21e778edc7c3966b1f61d57",
        "aws:asset:is-bundled": false,
        "aws:asset:property": "Code",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "AWSLambdaBasicExecutionRole added by cdk only gives write permissions for CW logs",
              "id": "AwsSolutions-IAM4"
            },
            {
              "reason": "IAM policy is appropriated scoped, ARN is provided in policy resource, false warning",
              "id": "AwsSolutions-IAM5"
            },
            {
              "reason": "Lambda function created by Provider L2 construct uses nodejs 14, risk is tolerable",
              "id": "AwsSolutions-L1"
            }
          ]
        },
        "guard": {
          "SuppressedRules": [
            "LAMBDA_INSIDE_VPC",
            "LAMBDA_CONCURRENCY_CHECK"
          ]
        }
      }
    },
    "QMListManagerSQServiceList2C145D4D": {
      "Type": "Custom::SQServiceList",
      "Properties": {
        "ServiceToken": {
          "Fn::GetAtt": [
            "QMListManagerQMListManagerProviderframeworkonEvent1F57B2C8",
            "Arn"
          ]
        },
        "VERSION": "v6.3.12",
        "SageMakerMonitoring": {
          "Ref": "SageMakerMonitoring"
        },
        "ConnectMonitoring": {
          "Ref": "ConnectMonitoring"
        }
      },
      "DependsOn": [
        "QMUtilizationErr3AEC9915",
        "SQQuotaTableD0BC5741",
        "SQServiceTable0182B2D0"
      ],
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManager/SQServiceList/Default"
      }
    },
    "QMListManagerSchedule2CDA6819": {
      "Type": "AWS::Events::Rule",
      "Properties": {
        "Description": "SO0005 quota-monitor-for-aws - quota-monitor-sq-spoke-EventsRule",
        "ScheduleExpression": "rate(30 days)",
        "State": "ENABLED",
        "Targets": [
          {
            "Arn": {
              "Fn::GetAtt": [
                "QMListManagerQMListManagerFunction1F09A88F",
                "Arn"
              ]
            },
            "Id": "Target0"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManagerSchedule/Resource"
      }
    },
    "QMListManagerScheduleAllowEventRulequotamonitorsqspokeQMListManagerQMListManagerFunction5A8AD0C253E1C515": {
      "Type": "AWS::Lambda::Permission",
      "Properties": {
        "Action": "lambda:InvokeFunction",
        "FunctionName": {
          "Fn::GetAtt": [
            "QMListManagerQMListManagerFunction1F09A88F",
            "Arn"
          ]
        },
        "Principal": "events.amazonaws.com",
        "SourceArn": {
          "Fn::GetAtt": [
            "QMListManagerSchedule2CDA6819",
            "Arn"
          ]
        }
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-ListManagerSchedule/AllowEventRulequotamonitorsqspokeQMListManagerQMListManagerFunction5A8AD0C2"
      }
    },
    "QMCWPollerQMCWPollerEventsRuleE8CD588E": {
      "Type": "AWS::Events::Rule",
      "Properties": {
        "Description": "SO0005 quota-monitor-for-aws - QM-CWPoller-EventsRule",
        "ScheduleExpression": {
          "Ref": "MonitoringFrequency"
        },
        "State": "ENABLED",
        "Targets": [
          {
            "Arn": {
              "Fn::GetAtt": [
                "QMCWPollerQMCWPollerLambda824ABE36",
                "Arn"
              ]
            },
            "Id": "Target0"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-CWPoller/QM-CWPoller-EventsRule/Resource"
      }
    },
    "QMCWPollerQMCWPollerEventsRuleAllowEventRulequotamonitorsqspokeQMCWPollerQMCWPollerLambdaB70526DA3005A260": {
      "Type": "AWS::Lambda::Permission",
      "Properties": {
        "Action": "lambda:InvokeFunction",
        "FunctionName": {
          "Fn::GetAtt": [
            "QMCWPollerQMCWPollerLambda824ABE36",
            "Arn"
          ]
        },
        "Principal": "events.amazonaws.com",
        "SourceArn": {
          "Fn::GetAtt": [
            "QMCWPollerQMCWPollerEventsRuleE8CD588E",
            "Arn"
          ]
        }
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-CWPoller/QM-CWPoller-EventsRule/AllowEventRulequotamonitorsqspokeQMCWPollerQMCWPollerLambdaB70526DA"
      }
    },
    "QMCWPollerQMCWPollerLambdaDeadLetterQueueE535D49E": {
      "Type": "AWS::SQS::Queue",
      "Properties": {
        "KmsMasterKeyId": "alias/aws/sqs"
      },
      "UpdateReplacePolicy": "Delete",
      "DeletionPolicy": "Delete",
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-CWPoller/QM-CWPoller-Lambda-Dead-Letter-Queue/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "Queue itself is dead-letter queue",
              "id": "AwsSolutions-SQS3"
            }
          ]
        }
      }
    },
    "QMCWPollerQMCWPollerLambdaDeadLetterQueuePolicyC81A8B00": {
      "Type": "AWS::SQS::QueuePolicy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "sqs:*",
              "Condition": {
                "Bool": {
                  "aws:SecureTransport": "false"
                }
              },
              "Effect": "Deny",
              "Principal": {
                "AWS": "*"
              },
              "Resource": {
                "Fn::GetAtt": [
                  "QMCWPollerQMCWPollerLambdaDeadLetterQueueE535D49E",
                  "Arn"
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "Queues": [
          {
            "Ref": "QMCWPollerQMCWPollerLambdaDeadLetterQueueE535D49E"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-CWPoller/QM-CWPoller-Lambda-Dead-Letter-Queue/Policy/Resource"
      }
    },
    "QMCWPollerQMCWPollerLambdaServiceRole8985092D": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "ManagedPolicyArns": [
          {
            "Fn::Join": [
              "",
              [
                "arn:",
                {
                  "Ref": "AWS::Partition"
                },
                ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
              ]
            ]
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-CWPoller/QM-CWPoller-Lambda/ServiceRole/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "AWSLambdaBasicExecutionRole added by cdk only gives write permissions for CW logs",
              "id": "AwsSolutions-IAM4"
            },
            {
              "reason": "Actions restricted on kms key ARN. Only actions that do not support resource-level permissions have * in resource",
              "id": "AwsSolutions-IAM5"
            },
            {
              "reason": "GovCloud regions support only up to nodejs 16, risk is tolerable",
              "id": "AwsSolutions-L1"
            }
          ]
        }
      }
    },
    "QMCWPollerQMCWPollerLambdaServiceRoleDefaultPolicy626BCE22": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "sqs:SendMessage",
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "QMCWPollerQMCWPollerLambdaDeadLetterQueueE535D49E",
                  "Arn"
                ]
              }
            },
            {
              "Action": "dynamodb:Query",
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "SQQuotaTableD0BC5741",
                  "Arn"
                ]
              }
            },
            {
              "Action": "dynamodb:Scan",
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "SQServiceTable0182B2D0",
                  "Arn"
                ]
              }
            },
            {
              "Action": "cloudwatch:GetMetricData",
              "Effect": "Allow",
              "Resource": "*"
            },
            {
              "Action": "events:PutEvents",
              "Effect": "Allow",
              "Resource": {
                "Fn::GetAtt": [
                  "QMSpokeBus1D13B121",
                  "Arn"
                ]
              }
            },
            {
              "Action": "servicequotas:ListServices",
              "Effect": "Allow",
              "Resource": "*"
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "QMCWPollerQMCWPollerLambdaServiceRoleDefaultPolicy626BCE22",
        "Roles": [
          {
            "Ref": "QMCWPollerQMCWPollerLambdaServiceRole8985092D"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-CWPoller/QM-CWPoller-Lambda/ServiceRole/DefaultPolicy/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "AWSLambdaBasicExecutionRole added by cdk only gives write permissions for CW logs",
              "id": "AwsSolutions-IAM4"
            },
            {
              "reason": "Actions restricted on kms key ARN. Only actions that do not support resource-level permissions have * in resource",
              "id": "AwsSolutions-IAM5"
            },
            {
              "reason": "GovCloud regions support only up to nodejs 16, risk is tolerable",
              "id": "AwsSolutions-L1"
            }
          ]
        }
      }
    },
    "QMCWPollerQMCWPollerLambda824ABE36": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "S3Bucket": {
            "Fn::Sub": "solutions-${AWS::Region}"
          },
          "S3Key": "quota-monitor-for-aws/v6.3.12/assete4de8f0eeef79ed750bff9eab22b6bd3c68066ff5b912c0577513ba56f326159.zip"
        },
        "DeadLetterConfig": {
          "TargetArn": {
            "Fn::GetAtt": [
              "QMCWPollerQMCWPollerLambdaDeadLetterQueueE535D49E",
              "Arn"
            ]
          }
        },
        "Description": "SO0005 quota-monitor-for-aws - QM-CWPoller-Lambda",
        "Environment": {
          "Variables": {
            "SQ_SERVICE_TABLE": {
              "Ref": "SQServiceTable0182B2D0"
            },
            "SQ_QUOTA_TABLE": {
              "Ref": "SQQuotaTableD0BC5741"
            },
            "SPOKE_EVENT_BUS": {
              "Ref": "QMSpokeBus1D13B121"
            },
            "POLLER_FREQUENCY": {
              "Ref": "MonitoringFrequency"
            },
            "THRESHOLD": {
              "Ref": "NotificationThreshold"
            },
            "REPORT_OK_NOTIFICATIONS": {
              "Ref": "ReportOKNotifications"
            },
            "LOG_LEVEL": "info",
            "CUSTOM_SDK_USER_AGENT": "AwsSolution/SO0005/v6.3.12",
            "VERSION": "v6.3.12",
            "SOLUTION_ID": "SO0005"
          }
        },
        "Handler": "index.handler",
        "Layers": [
          {
            "Ref": "QMUtilsLayerquotamonitorsqspokeQMUtilsLayerquotamonitorsqspokeLayerF6FD536E"
          }
        ],
        "MemorySize": 512,
        "Role": {
          "Fn::GetAtt": [
            "QMCWPollerQMCWPollerLambdaServiceRole8985092D",
            "Arn"
          ]
        },
        "Runtime": "nodejs24.x",
        "Timeout": 900
      },
      "DependsOn": [
        "QMCWPollerQMCWPollerLambdaServiceRoleDefaultPolicy626BCE22",
        "QMCWPollerQMCWPollerLambdaServiceRole8985092D"
      ],
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-CWPoller/QM-CWPoller-Lambda/Resource",
        "aws:asset:path": "asset.e4de8f0eeef79ed750bff9eab22b6bd3c68066ff5b912c0577513ba56f326159.zip",
        "aws:asset:is-bundled": false,
        "aws:asset:property": "Code",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "GovCloud regions support only up to nodejs 16, risk is tolerable",
              "id": "AwsSolutions-L1"
            }
          ]
        },
        "guard": {
          "SuppressedRules": [
            "LAMBDA_INSIDE_VPC",
            "LAMBDA_CONCURRENCY_CHECK"
          ]
        }
      }
    },
    "QMCWPollerQMCWPollerLambdaEventInvokeConfigB943EE46": {
      "Type": "AWS::Lambda::EventInvokeConfig",
      "Properties": {
        "FunctionName": {
          "Ref": "QMCWPollerQMCWPollerLambda824ABE36"
        },
        "MaximumEventAgeInSeconds": 14400,
        "Qualifier": "$LATEST"
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-CWPoller/QM-CWPoller-Lambda/EventInvokeConfig/Resource",
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "reason": "GovCloud regions support only up to nodejs 16, risk is tolerable",
              "id": "AwsSolutions-L1"
            }
          ]
        }
      }
    },
    "QMUtilizationOK588DBAE8": {
      "Type": "AWS::Events::Rule",
      "Properties": {
        "Description": "SO0005 quota-monitor-for-aws - quota-monitor-sq-spoke-EventsRule",
        "EventBusName": {
          "Ref": "QMSpokeBus1D13B121"
        },
        "EventPattern": {
          "account": [
            {
              "Ref": "AWS::AccountId"
            }
          ],
          "detail": {
            "status": [
              "OK"
            ]
          },
          "detail-type": [
            "Service Quotas Utilization Notification"
          ],
          "source": [
            "aws-solutions.quota-monitor"
          ]
        },
        "State": "ENABLED",
        "Targets": [
          {
            "Arn": {
              "Ref": "EventBusArn"
            },
            "Id": "Target0",
            "RoleArn": {
              "Fn::GetAtt": [
                "QMUtilizationOKEventsRoleC12899D6",
                "Arn"
              ]
            }
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Utilization-OK/Resource"
      }
    },
    "QMUtilizationOKEventsRoleC12899D6": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "events.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Utilization-OK/EventsRole/Resource"
      }
    },
    "QMUtilizationOKEventsRoleDefaultPolicyD9D7AF54": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "events:PutEvents",
              "Effect": "Allow",
              "Resource": {
                "Ref": "EventBusArn"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "QMUtilizationOKEventsRoleDefaultPolicyD9D7AF54",
        "Roles": [
          {
            "Ref": "QMUtilizationOKEventsRoleC12899D6"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Utilization-OK/EventsRole/DefaultPolicy/Resource"
      }
    },
    "QMUtilizationWarn1BF84C25": {
      "Type": "AWS::Events::Rule",
      "Properties": {
        "Description": "SO0005 quota-monitor-for-aws - quota-monitor-sq-spoke-EventsRule",
        "EventBusName": {
          "Ref": "QMSpokeBus1D13B121"
        },
        "EventPattern": {
          "account": [
            {
              "Ref": "AWS::AccountId"
            }
          ],
          "detail": {
            "status": [
              "WARN"
            ]
          },
          "detail-type": [
            "Service Quotas Utilization Notification"
          ],
          "source": [
            "aws-solutions.quota-monitor"
          ]
        },
        "State": "ENABLED",
        "Targets": [
          {
            "Arn": {
              "Ref": "EventBusArn"
            },
            "Id": "Target0",
            "RoleArn": {
              "Fn::GetAtt": [
                "QMUtilizationWarnEventsRole4BC4EAB1",
                "Arn"
              ]
            }
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Utilization-Warn/Resource"
      }
    },
    "QMUtilizationWarnEventsRole4BC4EAB1": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "events.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Utilization-Warn/EventsRole/Resource"
      }
    },
    "QMUtilizationWarnEventsRoleDefaultPolicyAE78A2DA": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "events:PutEvents",
              "Effect": "Allow",
              "Resource": {
                "Ref": "EventBusArn"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "QMUtilizationWarnEventsRoleDefaultPolicyAE78A2DA",
        "Roles": [
          {
            "Ref": "QMUtilizationWarnEventsRole4BC4EAB1"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Utilization-Warn/EventsRole/DefaultPolicy/Resource"
      }
    },
    "QMUtilizationErr3AEC9915": {
      "Type": "AWS::Events::Rule",
      "Properties": {
        "Description": "SO0005 quota-monitor-for-aws - quota-monitor-sq-spoke-EventsRule",
        "EventBusName": {
          "Ref": "QMSpokeBus1D13B121"
        },
        "EventPattern": {
          "account": [
            {
              "Ref": "AWS::AccountId"
            }
          ],
          "detail": {
            "status": [
              "ERROR"
            ]
          },
          "detail-type": [
            "Service Quotas Utilization Notification"
          ],
          "source": [
            "aws-solutions.quota-monitor"
          ]
        },
        "State": "ENABLED",
        "Targets": [
          {
            "Arn": {
              "Ref": "EventBusArn"
            },
            "Id": "Target0",
            "RoleArn": {
              "Fn::GetAtt": [
                "QMUtilizationErrEventsRoleAAC90710",
                "Arn"
              ]
            }
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Utilization-Err/Resource"
      }
    },
    "QMUtilizationErrEventsRoleAAC90710": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "events.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Utilization-Err/EventsRole/Resource"
      }
    },
    "QMUtilizationErrEventsRoleDefaultPolicy4BE442C4": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "events:PutEvents",
              "Effect": "Allow",
              "Resource": {
                "Ref": "EventBusArn"
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "QMUtilizationErrEventsRoleDefaultPolicy4BE442C4",
        "Roles": [
          {
            "Ref": "QMUtilizationErrEventsRoleAAC90710"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/QM-Utilization-Err/EventsRole/DefaultPolicy/Resource"
      }
    },
    "SpokeSnsRule5A40CA85": {
      "Type": "AWS::Events::Rule",
      "Properties": {
        "Description": "SO0005 quota-monitor-for-aws - quota-monitor-sq-spoke-SpokeSnsEventsRule",
        "EventBusName": {
          "Ref": "QMSpokeBus1D13B121"
        },
        "EventPattern": {
          "detail": {
            "status": [
              "WARN",
              "ERROR"
            ]
          },
          "detail-type": [
            "Trusted Advisor Check Item Refresh Notification",
            "Service Quotas Utilization Notification"
          ],
          "source": [
            "aws.trustedadvisor",
            "aws-solutions.quota-monitor"
          ]
        },
        "State": "ENABLED",
        "Targets": [
          {
            "Arn": {
              "Fn::Join": [
                "",
                [
                  "arn:",
                  {
                    "Ref": "AWS::Partition"
                  },
                  ":events:",
                  {
                    "Ref": "SpokeSnsRegion"
                  },
                  ":",
                  {
                    "Ref": "AWS::AccountId"
                  },
                  ":event-bus/QuotaMonitorSnsSpokeBus"
                ]
              ]
            },
            "Id": "Target0",
            "RoleArn": {
              "Fn::GetAtt": [
                "SpokeSnsRuleEventsRole851D8C25",
                "Arn"
              ]
            }
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/SpokeSnsRule/Resource"
      },
      "Condition": "SpokeSnsRegionExists"
    },
    "SpokeSnsRuleEventsRole851D8C25": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": "events.amazonaws.com"
              }
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/SpokeSnsRule/EventsRole/Resource"
      },
      "Condition": "SpokeSnsRegionExists"
    },
    "SpokeSnsRuleEventsRoleDefaultPolicyC16FF840": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": "events:PutEvents",
              "Effect": "Allow",
              "Resource": {
                "Fn::Join": [
                  "",
                  [
                    "arn:",
                    {
                      "Ref": "AWS::Partition"
                    },
                    ":events:",
                    {
                      "Ref": "SpokeSnsRegion"
                    },
                    ":",
                    {
                      "Ref": "AWS::AccountId"
                    },
                    ":event-bus/QuotaMonitorSnsSpokeBus"
                  ]
                ]
              }
            }
          ],
          "Version": "2012-10-17"
        },
        "PolicyName": "SpokeSnsRuleEventsRoleDefaultPolicyC16FF840",
        "Roles": [
          {
            "Ref": "SpokeSnsRuleEventsRole851D8C25"
          }
        ]
      },
      "Metadata": {
        "aws:cdk:path": "quota-monitor-sq-spoke/SpokeSnsRule/EventsRole/DefaultPolicy/Resource"
      },
      "Condition": "SpokeSnsRegionExists"
    }
  }
}