// Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Snapshot test for canary alarm 1`] = ` { "Conditions": { "CanaryBucketCondition": { "Fn::Equals": [ { "Ref": "CreateBucket", }, "Yes", ], }, "CreateBucketCondition": { "Fn::And": [ { "Condition": "CanaryBucketCondition", }, { "Condition": "CreateCanaryCondition", }, ], }, "CreateCanaryCondition": { "Fn::Equals": [ { "Ref": "CreateCanary", }, "Yes", ], }, "IntervalEqualsOne": { "Fn::Equals": [ { "Ref": "Interval", }, 1, ], }, }, "Metadata": { "AWS::CloudFormation::Interface": { "ParameterGroups": [ { "Label": { "default": "Canary Configuration", }, "Parameters": [ "CanaryName", "CreateCanary", "URL", "Interval", "ResponseThreshold", "CreateBucket", "BucketName", ], }, { "Label": { "default": "Application Monitoring", }, "Parameters": [ "AppName", "RepoName", ], }, { "Label": { "default": "Alarm Configuration", }, "Parameters": [ "PercentThreshold", "EvalPeriods", "AlarmPeriods", ], }, ], "ParameterLabels": { "AlarmPeriods": { "default": "Alarm Periods", }, "AppName": { "default": "Application Name", }, "BucketName": { "default": "Artifact Bucket Name", }, "CanaryInterval": { "default": "Canary Interval", }, "CanaryName": { "default": "Canary Name", }, "CreateBucket": { "default": "Create Artifact Bucket?", }, "CreateCanary": { "default": "Create New Canary?", }, "EvalPeriods": { "default": "Evaluation Periods", }, "PercentThreshold": { "default": "% Success Threshold (<)", }, "RepoName": { "default": "Repository Name", }, "ResponseThreshold": { "default": "Response Threshold (ms)", }, "URL": { "default": "URL", }, }, }, }, "Outputs": { "AlarmName": { "Description": "Name of the Canary Alarm", "Value": { "Fn::Join": [ "", [ "SO0143-[", { "Ref": "AppName", }, "]-[", { "Ref": "RepoName", }, "]-MTTR", ], ], }, }, "CanaryName": { "Description": "Name of the Canary", "Value": { "Ref": "CanaryName", }, }, "SolutionVersion": { "Description": "Version for DevOps Monitoring Dashboard on AWS Solution", "Value": "v1.0.0", }, }, "Parameters": { "AlarmPeriods": { "Default": 1, "Description": "Number of collection periods over which the threshold is exceeded before alarming. This value must be less than or equal to Evaluation Periods", "Type": "Number", }, "AppName": { "Description": "Name of the application that canary monitors.", "Type": "String", }, "BucketName": { "Description": "Name of the bucket (new or existing) for logging Canary artifacts. Each Canary will log to this bucket to a different prefix.", "Type": "String", }, "CanaryName": { "AllowedPattern": "^[0-9a-z_-]+$", "Default": "mycanary", "Description": "Name of your Canary (new or existing) so users can easily understand what it is in the console.", "Type": "String", }, "CreateBucket": { "AllowedValues": [ "No", "Yes", ], "Default": "No", "Description": "Canaries store artifacts in an S3 bucket. Should this canary create a new bucket? Enter the bucket name (new or existing) below.", "Type": "String", }, "CreateCanary": { "AllowedValues": [ "No", "Yes", ], "Default": "Yes", "Description": "Should a new canary be created? If yes, a canary with the name specified above will be created. If no, just skip the rest of Canary Configuration and move on to Application Monitoring.", "Type": "String", }, "EvalPeriods": { "Default": 1, "Description": "Number of periods to compare to the threshold.", "Type": "Number", }, "Interval": { "Default": 5, "Description": "Interval, in minutes.", "Type": "Number", }, "PercentThreshold": { "Default": 100, "Description": "Threshold for Success (percentage). Any value less than this value will result in an alarm being triggered.", "Type": "Number", }, "RepoName": { "Description": "Name of CodeCommit repository for the application.", "Type": "String", }, "ResponseThreshold": { "AllowedPattern": "^[0-9]+$", "Default": "15000", "Description": "Number of milliseconds to wait for a url response before considering the canary failed.", "Type": "String", }, "URL": { "Description": "Application or endpoint URL you want to monitor with the canary (for example, https://www.example.com). The canary will check the site every 5 minutes.", "Type": "String", }, }, "Resources": { "AlarmAppAlarm83138885": { "Metadata": { "cfn_nag": { "rules_to_suppress": [ { "id": "W28", "reason": "Static names chosen intentionally to provide fixed name structure required in the solution", }, ], }, }, "Properties": { "AlarmDescription": "Alarm when canary success is less than 100% on the most recent check.", "AlarmName": { "Fn::Join": [ "", [ "SO0143-[", { "Ref": "AppName", }, "]-[", { "Ref": "RepoName", }, "]-MTTR", ], ], }, "ComparisonOperator": "LessThanThreshold", "DatapointsToAlarm": { "Ref": "AlarmPeriods", }, "Dimensions": [ { "Name": "CanaryName", "Value": { "Ref": "CanaryName", }, }, ], "EvaluationPeriods": { "Ref": "EvalPeriods", }, "MetricName": "SuccessPercent", "Namespace": "CloudWatchSynthetics", "Period": 300, "Statistic": "Average", "Threshold": { "Ref": "PercentThreshold", }, }, "Type": "AWS::CloudWatch::Alarm", }, "ArtifactBucket7410C9EF": { "Condition": "CreateBucketCondition", "DeletionPolicy": "Retain", "Metadata": { "cdk_nag": { "rules_to_suppress": [ { "id": "AwsSolutions-S1", "reason": "This bucket is used by canary to store artifacts and no access logging bucket is needed.", }, ], }, "cfn_nag": { "rules_to_suppress": [ { "id": "W35", "reason": "This bucket is used by canary to store artifacts and no access logging bucket is needed.", }, ], }, }, "Properties": { "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { "ServerSideEncryptionByDefault": { "SSEAlgorithm": "AES256", }, }, ], }, "BucketName": { "Ref": "BucketName", }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, "IgnorePublicAcls": true, "RestrictPublicBuckets": true, }, "Tags": [ { "Key": "Name", "Value": "DevOps Monitoring Dashboard on AWS Canary Artifacts", }, ], }, "Type": "AWS::S3::Bucket", "UpdateReplacePolicy": "Retain", }, "ArtifactBucketPolicy4B4B7752": { "Condition": "CreateBucketCondition", "Properties": { "Bucket": { "Ref": "ArtifactBucket7410C9EF", }, "PolicyDocument": { "Statement": [ { "Action": "s3:*", "Condition": { "Bool": { "aws:SecureTransport": "false", }, }, "Effect": "Deny", "Principal": { "AWS": "*", }, "Resource": [ { "Fn::GetAtt": [ "ArtifactBucket7410C9EF", "Arn", ], }, { "Fn::Join": [ "", [ { "Fn::GetAtt": [ "ArtifactBucket7410C9EF", "Arn", ], }, "/*", ], ], }, ], "Sid": "HttpsOnly", }, ], "Version": "2012-10-17", }, }, "Type": "AWS::S3::BucketPolicy", }, "HttpCanaryE06DE534": { "Condition": "CreateCanaryCondition", "Properties": { "ArtifactS3Location": { "Fn::Join": [ "", [ "s3://", { "Ref": "BucketName", }, "/", { "Ref": "AWS::StackName", }, ], ], }, "Code": { "Handler": "index.handler", "Script": { "Fn::Join": [ "", [ "var synthetics = require('Synthetics'); const log = require('SyntheticsLogger'); const pageLoadBlueprint = async function () { const URL = "", { "Ref": "URL", }, ""; let page = await synthetics.getPage(); const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000}); //Wait for page to render. //Increase or decrease wait time based on endpoint being monitored. await page.waitFor(", { "Ref": "ResponseThreshold", }, "); // This will take a screenshot that will be included in test output artifacts await synthetics.takeScreenshot('loaded', 'loaded'); let pageTitle = await page.title(); log.info('Page title: ' + pageTitle); if (response.status() !== 200) { throw "Failed to load page!"; } }; exports.handler = async () => { return await pageLoadBlueprint(); };", ], ], }, }, "ExecutionRoleArn": { "Fn::GetAtt": [ "HttpCanaryServiceRoleF71089F4", "Arn", ], }, "Name": { "Ref": "CanaryName", }, "RuntimeVersion": "syn-nodejs-puppeteer-3.8", "Schedule": { "DurationInSeconds": "0", "Expression": { "Fn::If": [ "IntervalEqualsOne", "rate(1 minute)", { "Fn::Join": [ "", [ "rate(", { "Ref": "Interval", }, " minutes)", ], ], }, ], }, }, "StartCanaryAfterCreation": true, }, "Type": "AWS::Synthetics::Canary", }, "HttpCanaryServiceRoleF71089F4": { "Metadata": { "cdk_nag": { "rules_to_suppress": [ { "id": "AwsSolutions-IAM5", "reason": "Resource * is required by the canary service role.", }, ], }, "cfn_nag": { "rules_to_suppress": [ { "id": "W11", "reason": "Resource * is required by the canary service role.", }, ], }, }, "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com", }, }, ], "Version": "2012-10-17", }, "Policies": [ { "PolicyDocument": { "Statement": [ { "Action": "s3:ListAllMyBuckets", "Effect": "Allow", "Resource": "*", }, { "Action": "s3:GetBucketLocation", "Effect": "Allow", "Resource": { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition", }, ":s3:::", { "Ref": "BucketName", }, ], ], }, }, { "Action": "s3:PutObject", "Effect": "Allow", "Resource": { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition", }, ":s3:::", { "Ref": "BucketName", }, "/", { "Ref": "AWS::StackName", }, "/*", ], ], }, }, { "Action": "cloudwatch:PutMetricData", "Condition": { "StringEquals": { "cloudwatch:namespace": "CloudWatchSynthetics", }, }, "Effect": "Allow", "Resource": "*", }, { "Action": [ "logs:CreateLogStream", "logs:CreateLogGroup", "logs:PutLogEvents", ], "Effect": "Allow", "Resource": { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition", }, ":logs:", { "Ref": "AWS::Region", }, ":", { "Ref": "AWS::AccountId", }, ":log-group:/aws/lambda/cwsyn-*", ], ], }, }, ], "Version": "2012-10-17", }, "PolicyName": "canaryPolicy", }, ], }, "Type": "AWS::IAM::Role", }, }, } `;