

# Synthetic monitoring (canaries)
<a name="CloudWatch_Synthetics_Canaries"></a>

You can use Amazon CloudWatch Synthetics to create *canaries*, configurable scripts that run on a schedule, to monitor your endpoints and APIs. Canaries follow the same routes and perform the same actions as a customer, which makes it possible for you to continually verify your customer experience even when you don't have any customer traffic on your applications. By using canaries, you can discover issues before your customers do.

Canaries are scripts written in Node.js, Python, or Java. They create Lambda functions in your account that use Node.js, Python, or Java as the runtime. Canaries work over both HTTP and HTTPS protocols. Canaries use Lambda layers that contain the CloudWatch Synthetics library. The library includes CloudWatch Synthetics implementations for NodeJS, Python, and Java.

Canaries in Node.js and Python runtimes offer programmatic access to headless browsers through Playwright, Puppeteer, or Selenium Webdriver. Multiple browsers are supported, including a headless Google Chrome browser, and Mozilla Firefox. For more information about Playwright, see [Playwright](https://playwright.dev/). For more information about Puppeteer, see [Puppeteer](https://developer.chrome.com/docs/puppeteer/). For more information about Selenium, see [Selenium](https://www.selenium.dev/). Canaries on Selenium only support Chrome browser. Canaries in Java are designed for flexibility in monitoring any type of service or application and do not contain browser support or frameworks.

Canaries check the availability and latency of your endpoints and can store load time data and screenshots of the UI. They monitor your REST APIs, URLs, and website content, and they can check for unauthorized changes from phishing, code injection and cross-site scripting.

 CloudWatch Synthetics is integrated with [Application Signals](CloudWatch-Application-Monitoring-Sections.md), which can discover and monitor your application services, clients, Synthetics canaries, and service dependencies. Use Application Signals to see a list or visual map of your services, view health metrics based on your service level objectives (SLOs), and drill down to see correlated X-Ray traces for more detailed troubleshooting. To see your canaries in Application Signals, [turn on X-Ray active tracing](CloudWatch_Synthetics_Canaries_tracing.md). Your canaries are displayed on the [Application Map](ServiceMap.md) connected to your services, and in the [Service detail](ServiceDetail.md) page of the services they call. 

For a video demonstration of canaries, see the following:
+  [Introduction to Amazon CloudWatch Synthetics](https://www.youtube.com/watch?v=MItluIsvfTo) 
+  [Amazon CloudWatch Synthetics Demo](https://www.youtube.com/watch?v=hF3NM9j-u7I) 
+  [Create Canaries Using Amazon CloudWatch Synthetics](https://www.youtube.com/watch?v=DSx65wW7lr0) 
+  [Visual Monitoring with Amazon CloudWatch Synthetics](https://www.youtube.com/watch?v=_PCs-ucZz7E) 



You can run a canary once or on a regular schedule. Canaries can run as often as once per minute. You can use both cron and rate expressions to schedule canaries.

For information about security issues to consider before you create and run canaries, see [Security considerations for Synthetics canaries](servicelens_canaries_security.md). 

By default, canaries create several CloudWatch metrics in the `CloudWatchSynthetics` namespace. These metrics have `CanaryName` as a dimension. Canaries that use the `executeStep()` or `executeHttpStep()` function from the function library also have `StepName` as a dimension. For more information about the canary function library, see [Library functions available for canary scripts](CloudWatch_Synthetics_Canaries_Function_Library.md).

CloudWatch Synthetics integrates well with the X-Ray Trace Map, which uses CloudWatch with AWS X-Ray to provide an end-to-end view of your services to help you more efficiently pinpoint performance bottlenecks and identify impacted users. Canaries that you create with CloudWatch Synthetics appear on the trace map. For more information, see [X-Ray Trace Map](https://docs.aws.amazon.com/xray/latest/devguide/xray-console-servicemap.html). 

CloudWatch Synthetics is currently available in all commercial AWS Regions and the GovCloud Regions.

**Note**  
In Asia Pacific (Osaka), AWS PrivateLink is not supported. In Asia Pacific (Jakarta), AWS PrivateLink and X-Ray are not supported.

**Topics**
+ [

# Required roles and permissions for CloudWatch canaries
](CloudWatch_Synthetics_Canaries_Roles.md)
+ [

# Creating a canary
](CloudWatch_Synthetics_Canaries_Create.md)
+ [

# Groups
](CloudWatch_Synthetics_Groups.md)
+ [

# Test a canary locally
](CloudWatch_Synthetics_Debug_Locally.md)
+ [

# Troubleshooting a failed canary
](CloudWatch_Synthetics_Canaries_Troubleshoot.md)
+ [

# Sample code for canary scripts
](CloudWatch_Synthetics_Canaries_Samples.md)
+ [

# Canaries and X-Ray tracing
](CloudWatch_Synthetics_Canaries_tracing.md)
+ [

# Running a canary on a VPC
](CloudWatch_Synthetics_Canaries_VPC.md)
+ [

# Encrypting canary artifacts
](CloudWatch_Synthetics_artifact_encryption.md)
+ [

# Viewing canary statistics and details
](CloudWatch_Synthetics_Canaries_Details.md)
+ [

# CloudWatch metrics published by canaries
](CloudWatch_Synthetics_Canaries_metrics.md)
+ [

# Edit or delete a canary
](synthetics_canaries_deletion.md)
+ [

# Start, stop, delete, or update runtime for multiple canaries
](synthetics_canaries_multi-action.md)
+ [

# Monitoring canary events with Amazon EventBridge
](monitoring-events-eventbridge.md)
+ [

# Performing safe canary updates
](performing-safe-canary-upgrades.md)

# Required roles and permissions for CloudWatch canaries
<a name="CloudWatch_Synthetics_Canaries_Roles"></a>

Both the users who create and manage canaries, and the canaries themselves, must have certain permissions.

# Required roles and permissions for users who manage CloudWatch canaries
<a name="CloudWatch_Synthetics_Canaries_UserPermissions"></a>

To view canary details and the results of canary runs, you must be signed in as a user with either the `CloudWatchSyntheticsFullAccess` or the ` CloudWatchSyntheticsReadOnlyAccess` policies attached. To read all Synthetics data in the console, you also need the `AmazonS3ReadOnlyAccess` and ` CloudWatchReadOnlyAccess` policies. To view the source code used by canaries, you also need the `AWSLambda_ReadOnlyAccess` policy.

To create canaries, you must be signed in as an user who has the ` CloudWatchSyntheticsFullAccess` policy or a similar set of permissions. To create IAM roles for the canaries, you also need the following inline policy statement:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateRole",
                "iam:CreatePolicy",
                "iam:AttachRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::*:role/service-role/CloudWatchSyntheticsRole*",
                "arn:aws:iam::*:policy/service-role/CloudWatchSyntheticsPolicy*"
            ]
        }
    ]
}
```

------

**Important**  
Granting a user the `iam:CreateRole`, `iam:CreatePolicy`, and ` iam:AttachRolePolicy` permissions gives that user full administrative access to your AWS account. For example, a user with these permissions can create a policy that has full permissions for all resources and can attach that policy to any role. Be very careful about who you grant these permissions to.

For information about attaching policies and granting permissions to users, see [Changing Permissions for an IAM User](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_change-permissions.html#users_change_permissions-add-console) and [To embed an inline policy for a user or role](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html#embed-inline-policy-console).

# Required roles and permissions for canaries
<a name="CloudWatch_Synthetics_Canaries_CanaryPermissions"></a>

Each canary must be associated with an IAM role that has certain permissions attached. When you create a canary using the CloudWatch console, you can choose for CloudWatch Synthetics to create an IAM role for the canary. If you do, the role will have the permissions needed.

If you want to create the IAM role yourself, or create an IAM role that you can use when using the AWS CLI or APIs to create a canary, the role must contain the permissions listed in this section.

All IAM roles for canaries must include the following trust policy statement.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

------

Additionally, the canary's IAM role needs one of the following statements.

 **Basic canary that doesn't use AWS KMS or need Amazon VPC access** 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::path/to/your/s3/bucket/canary/results/folder"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::name/of/the/s3/bucket/that/contains/canary/results"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:CreateLogGroup"
            ],
            "Resource": [
            "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/cwsyn-canary_name-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "xray:PutTraceSegments"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": "*",
            "Action": "cloudwatch:PutMetricData",
            "Condition": {
                "StringEquals": {
                    "cloudwatch:namespace": "CloudWatchSynthetics"
                }
            }
        }
    ]
}
```

------

 **Canary that uses AWS KMS to encrypt canary artifacts but does not need Amazon VPC access** 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::path/to/your/S3/bucket/canary/results/folder"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::name/of/the/S3/bucket/that/contains/canary/results"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:CreateLogGroup"
            ],
            "Resource": [
            "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/cwsyn-canary_name-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "xray:PutTraceSegments"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": "*",
            "Action": "cloudwatch:PutMetricData",
            "Condition": {
                "StringEquals": {
                    "cloudwatch:namespace": "CloudWatchSynthetics"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:GenerateDataKey"
            ],
            "Resource": "arn:aws:kms:us-east-1:111122223333:key/KMS_key_id",
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": [
                        "s3.us-east-1.amazonaws.com"
                    ]
                }
            }
        }
    ]
}
```

------

 **Canary that does not use AWS KMS but does need Amazon VPC access** 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::path/to/your/S3/bucket/canary/results/folder"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::name/of/the/S3/bucket/that/contains/canary/results"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:CreateLogGroup"
            ],
            "Resource": [
            "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/cwsyn-canary_name-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "xray:PutTraceSegments"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": "*",
            "Action": "cloudwatch:PutMetricData",
            "Condition": {
                "StringEquals": {
                    "cloudwatch:namespace": "CloudWatchSynthetics"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DeleteNetworkInterface"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

------

 **Canary that uses AWS KMS to encrypt canary artifacts and also needs Amazon VPC access** 

If you update a non-VPC canary to start using a VPC, you'll need to update the canary's role to include the network interface permissions listed in the following policy.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::path/to/your/S3/bucket/canary/results/folder"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::name/of/the/S3/bucket/that/contains/canary/results"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:CreateLogGroup"
            ],
            "Resource": [
            "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/cwsyn-canary_name-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "xray:PutTraceSegments"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": "*",
            "Action": "cloudwatch:PutMetricData",
            "Condition": {
                "StringEquals": {
                    "cloudwatch:namespace": "CloudWatchSynthetics"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DeleteNetworkInterface"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:GenerateDataKey"
            ],
            "Resource": "arn:aws:kms:us-east-1:111122223333:key/KMS_key_id",
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": [
                        "s3.us-east-1.amazonaws.com"
                    ]
                }
            }
        }
    ]
}
```

------

## AWS managed policies for CloudWatch Synthetics
<a name="CloudWatch_Synthetics_IAMManagedPolicies"></a>

To add permissions to users, groups, and roles, it is easier to use AWS managed policies than to write policies yourself. It takes time and expertise to create IAM customer managed policies that provide your team with only the permissions they need. To get started quickly, you can use our AWS managed policies. These policies cover common use cases and are available in your AWS account. For more information about AWS managed policies, see [AWS managed policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies) AWS managed policies in the IAM User Guide.

AWS services maintain and update AWS managed policies. You can't change the permissions in AWS managed policies. Services occasionally change the permissions in an AWS managed policy. This type of update affects all identities (users, groups, and roles) where the policy is attached.

### CloudWatch Synthetics updates to AWS managed policies
<a name="CloudWatch_Synthetics_IAMManagedPolicies_Updates"></a>

View details about updates to AWS managed policies for CloudWatch Synthetics since this service began tracking these changes. For automatic alerts about changes to this page, subscribe to the RSS feed on the CloudWatch Document history page. 


| Change | Description | Date | 
| --- | --- | --- | 
|  Redundant actions removed from **CloudWatchSyntheticsFullAccess**  |  CloudWatch Synthetics removed the `s3:PutBucketEncryption` and ` lambda:GetLayerVersionByArn` actions from ** CloudWatchSyntheticsFullAccess** policy because those actions were redundant with other permissions in the policy. The removed actions did not provide any permissions, and there’s no net change to the permissions granted by the policy.  | March 12, 2021 | 
|  CloudWatch Synthetics started tracking changes  |  CloudWatch Synthetics started tracking changes for its AWS managed policies.  | March 10, 2021 | 

 **CloudWatchSyntheticsFullAccess** 

Here are the contents of the `CloudWatchSyntheticsFullAccess` policy:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [{
            "Effect": "Allow",
            "Action": [
                "synthetics:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:CreateBucket",
                "s3:PutEncryptionConfiguration"
            ],
            "Resource": [
                "arn:aws:s3:::cw-syn-results-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:ListRoles",
                "s3:ListAllMyBuckets",
                "xray:GetTraceSummaries",
                "xray:BatchGetTraces",
                "apigateway:GET"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::cw-syn-*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::aws-synthetics-library-*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/service-role/CloudWatchSyntheticsRole*"
            ],
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": [
                        "lambda.amazonaws.com",
                        "synthetics.amazonaws.com"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:ListAttachedRolePolicies"
            ],
            "Resource": [
                "arn:aws:iam::*:role/service-role/CloudWatchSyntheticsRole*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:GetMetricData",
                "cloudwatch:GetMetricStatistics"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:PutMetricAlarm",
                "cloudwatch:DeleteAlarms"
            ],
            "Resource": [
                "arn:aws:cloudwatch:*:*:alarm:Synthetics-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:DescribeAlarms"
            ],
            "Resource": [
                "arn:aws:cloudwatch:*:*:alarm:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:GetLogRecord",
                "logs:DescribeLogStreams",
                "logs:StartQuery",
                "logs:GetLogEvents",
                "logs:FilterLogEvents",
                "logs:GetLogGroupFields"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:/aws/lambda/cwsyn-*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": "${aws:PrincipalAccount}"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:AddPermission",
                "lambda:PublishVersion",
                "lambda:UpdateFunctionCode",
                "lambda:UpdateFunctionConfiguration",
                "lambda:GetFunctionConfiguration",
                "lambda:GetFunction",
                "lambda:DeleteFunction",
                "lambda:ListTags",
                "lambda:TagResource",
                "lambda:UntagResource"
            ],
            "Resource": [
                "arn:aws:lambda:*:*:function:cwsyn-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:GetLayerVersion",
                "lambda:PublishLayerVersion",
                "lambda:DeleteLayerVersion"
            ],
            "Resource": [
                "arn:aws:lambda:*:*:layer:cwsyn-*",
                "arn:aws:lambda:*:*:layer:Synthetics:*",
                "arn:aws:lambda:*:*:layer:Synthetics_Selenium:*",
                "arn:aws:lambda:*:*:layer:AWS-CW-Synthetics*:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeVpcs",
                "ec2:DescribeSubnets",
                "ec2:DescribeSecurityGroups"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:ListTopics"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:CreateTopic",
                "sns:Subscribe",
                "sns:ListSubscriptionsByTopic"
            ],
            "Resource": [
                "arn:*:sns:*:*:Synthetics-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:ListAliases"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:DescribeKey"
            ],
            "Resource": "arn:aws:kms:*:*:key/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": "arn:aws:kms:*:*:key/*",
            "Condition": {
                "StringLike": {
                    "kms:ViaService": [
                        "s3.*.amazonaws.com"
                    ]
                }
            }
        }
    ]
}
```

------

 **CloudWatchSyntheticsReadOnlyAccess** 

Here are the contents of the `CloudWatchSyntheticsReadOnlyAccess` policy:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "synthetics:Describe*",
                "synthetics:Get*",
                "synthetics:List*"
            ],
            "Resource": "*"
        }
    ]
}
```

------

# Limiting a user to viewing specific canaries
<a name="CloudWatch_Synthetics_Canaries_Restricted"></a>

You can limit a user's ability to view information about canaries, so that they can only see information about the canaries you specify. To do this, use an IAM policy with a ` Condition` statement similar to the following, and attach this policy to a user or an IAM role.

The following example limits the user to only viewing information about ` name-of-allowed-canary-1` and `name-of-allowed-canary-2`. 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "synthetics:DescribeCanaries",
            "Resource": "*",
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "synthetics:Names": [
                        "name-of-allowed-canary-1",
                        "name-of-allowed-canary-2"
                    ]
                }
            }
        }
    ]
}
```

------

CloudWatch Synthetics supports listing as many as five items in the `synthetics:Names` array.

You can also create a policy that uses a \$1** as a wildcard in canary names that are to be allowed, as in the following example:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "synthetics:DescribeCanaries",
            "Resource": "*",
            "Condition": {
                "ForAnyValue:StringLike": {
                    "synthetics:Names": [
                        "my-team-canary-*"
                    ]
                }
            }
        }
    ]
}
```

------

Any user signed in with one of these policies attached can't use the CloudWatch console to view any canary information. They can view canary information only for the canaries authorized by the policy and only by using the [DescribeCanaries](https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html) API or the [describe-canaries](https://docs.aws.amazon.com/cli/latest/reference/synthetics/describe-canaries.html) AWS CLI command.

# Creating a canary
<a name="CloudWatch_Synthetics_Canaries_Create"></a>

**Important**  
Ensure that you use Synthetics canaries to monitor only endpoints and APIs where you have ownership or permissions. Depending on the canary frequency settings, these endpoints might experience increased traffic.

When you use the CloudWatch console to create a canary, you can use a blueprint provided by CloudWatch to create your canary or you can write your own script. For more information, see [Using canary blueprints](CloudWatch_Synthetics_Canaries_Blueprints.md).

You can also create a canary using CloudFormation if you are using your own script for the canary. For more information, see [ AWS::Synthetics::Canary ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-synthetics-canary.html) in the *AWS CloudFormation User Guide*.

If you are writing your own script, you can use several functions that CloudWatch Synthetics has built into a library. For more information, see [Synthetics runtime versions](CloudWatch_Synthetics_Canaries_Library.md).

**Note**  
When you create a canary, one of the layers created is a Synthetics layer prepended with ` Synthetics`. This layer is owned by the Synthetics service account and contains the runtime code.

**To create a canary**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Application Signals**, **Synthetics Canaries**.

   

1. Choose **Create Canary**.

1. Choose one of the following:
   + To base your canary on a blueprint script, choose **Use a blueprint**, and then choose the type of canary you want to create. For more information about what each type of blueprint does, see [Using canary blueprints](CloudWatch_Synthetics_Canaries_Blueprints.md).
   + To upload your own Node.js script to create a custom canary, choose **Upload a script**.

     You can then drag your script into the **Script** area or choose **Browse files** to navigate to the script in your file system.
   + To import your script from an S3 bucket, choose **Import from S3**. Under **Source location**, enter the complete path to your canary or choose **Browse S3**.

     You must have `s3:GetObject` and `s3:GetObjectVersion` permissions for the S3 bucket that you use. The bucket must be in the same AWS Region where you are creating the canary.

1. Under **Name**, enter a name for your canary. The name is used on many pages, so we recommend that you give it a descriptive name that distinguishes it from other canaries.

1. Under **Application or endpoint URL**, enter the URL that you want the canary to test. This URL must include the protocol (such as https://).

   If you want the canary to test an endpoint on a VPC, you must also enter information about your VPC later in this procedure. 

1. If you are using your own script for the canary, under **Lambda handler**, enter the entry point where you want the canary to start. For information on Lambda handler format, see [Synthetics runtime versions ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html).

1. Under **Script editor**, **Runtime version**, select a synthetics runtime version to execute the canary. For information on synthetics runtime versions, see [Synthetics runtime versions ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html).

   Under **Browser configuration**, you can enable the browser to test the canary. You must select at least one browser.

1. If you are using environment variables in your script, choose **Environment variables** and then specify a value for each environment variable defined in your script. For more information, see [Environment variables](CloudWatch_Synthetics_Canaries_WritingCanary_Nodejs_Pup.md#CloudWatch_Synthetics_Environment_Variables).

1. Under **Schedule**, choose whether to run this canary just once, run it continuously using a rate expression, or schedule it using a cron expression.
   + When you use the CloudWatch console to create a canary that runs continuously, you can choose a rate anywhere between once a minute and once an hour.
   + For more information about writing a cron expression for canary scheduling, see [Scheduling canary runs using cron](CloudWatch_Synthetics_Canaries_cron.md).

1. (Optional) To set a timeout value for the canary, choose **Additional configuration** and then specify the timeout value. Make it no shorter than 15 seconds to allow for Lambda cold starts and the time it takes to boot up the canary instrumentation.

1. Under **Data retention**, specify how long to retain information about both failed and successful canary runs. The range is 1-455 days.

   This setting affects the range of information returned by [GetCanaryRuns](https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_GetCanaryRuns.html) operations, as well as the range of information displayed in the Synthetics console.

   It does not affect the data stored in your Amazon S3 buckets, or logs or metrics that are published by the canary.

   Regardless of the canary's data retention period, the range of information displayed in console has certain limits. In the Synthetics console home view, the relative and absolute time range are limited to seven days. In the Synthetics console view for a specific canary, the relative time range is limited to seven days and the absolute time range is limited to 30 days.

1. Under **Data Storage**, select the Amazon S3 bucket to use to store the data from the canary runs. The bucket name can't contain a period (.). If you leave this blank, a default Amazon S3 bucket is used or created.

1. (Optional) By default, canaries store their artifacts on Amazon S3, and the artifacts are encrypted at rest using an AWS-managed AWS KMS key. You can use a different encryption option by choosing **Additional configuration** in the **Data Storage** section. You can then choose the type of key to use for encryption. For more information, see [Encrypting canary artifacts](CloudWatch_Synthetics_artifact_encryption.md). 

1. Under **Access permissions**, choose whether to create an IAM role to run the canary or use an existing one.

   If you have CloudWatch Synthetics create the role, it automatically includes all the necessary permissions. If you want to create the role yourself, see [Required roles and permissions for canaries](CloudWatch_Synthetics_Canaries_CanaryPermissions.md) for information about the necessary permissions.

   If you use the CloudWatch console to create a role for a canary when you create the canary, you can't re-use the role for other canaries, because these roles are specific to just one canary. If you have manually created a role that works for multiple canaries, you can use that existing role.

   To use an existing role, you must have the `iam:PassRole` permission to pass that role to Synthetics and Lambda. You must also have the `iam:GetRole` permission.

1. (Optional) Under **Alarms**, choose whether you want default CloudWatch alarms to be created for this canary. If you choose to create alarms, they are created with the following name convention:`Synthetics-Alarm-canaryName -index `

   `index` is a number representing each different alarm created for this canary. The first alarm has an index of 1, the second alarm has an index of 2, and so on.

1. (Optional) To have this canary test an endpoint that is on a VPC, choose **VPC settings**, and then do the following:

   1. Select the VPC that hosts the endpoint.

   1. Select one or more subnets on your VPC. You must select a private subnet because a Lambda instance can't be configured to run in a public subnet when an IP address can't be assigned to the Lambda instance during execution. For more information, see [Configuring a Lambda Function to Access Resources in a VPC](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html).

   1. Select one or more security groups on your VPC.

   1. To allow outbound IPv6 traffic for this canary, select **Allow IPv6 Traffic for dual-stack subnets**. This enables the canary to monitor IPv6-only and dual stack enabled endpoints over IPv6.

      You can monitor endpoints external to your VPC by giving the canary internet access and configuring the VPC subnets appropriately. For more information, see [Running a canary on a VPC](CloudWatch_Synthetics_Canaries_VPC.md).

   If the endpoint is on a VPC, you must enable your canary to send information to CloudWatch and Amazon S3. For more information, see [Running a canary on a VPC](CloudWatch_Synthetics_Canaries_VPC.md).

1. (Optional) Under **Tags**, add one or more key-value pairs as tags for this canary. Tags can help you identify and organize your AWS resources and track your AWS costs. For more information, see [Tagging your Amazon CloudWatch resources](CloudWatch-Tagging.md).

   If you want the tags that you apply to the canary to also be applied to the Lambda function that the canary uses, choose **Lambda function** under **Tag Replication**. If you choose this option, CloudWatch Synthetics will keep the tags on the canary and the Lambda function synchronized:
   + Synthetics will apply the same tags that you specify here to both your canary and your Lambda function.
   + If you later update the canary's tags and keep this option selected, Synthetics modifies the tags on your Lambda function to remain in sync with the canary. 

1. (Optional) Under **Active tracing**, choose whether to enable active X-Ray tracing for this canary. Active tracing is only available for Puppeteer and Java runtimes. For more information, see [Canaries and X-Ray tracing](CloudWatch_Synthetics_Canaries_tracing.md).

## Resources that are created for canaries
<a name="CloudWatch_Synthetics_Canaries_Resources_Created"></a>

When you create a canary, the following resources are created:
+ An IAM role with the name `CloudWatchSyntheticsRole-canary-name -uuid` (if you use CloudWatch console to create the canary and specify for a new role to be created for the canary)
+ An IAM policy with the name `CloudWatchSyntheticsPolicy- canary-name-uuid`.
+ An S3 bucket with the name `cw-syn-results-accountID -region`.
+ Alarms with the name `Synthetics-Alarm-MyCanaryName`, if you want alarms to be created for the canary.
+ Lambda functions and layers, if you use a blueprint to create the canary. These resources have the prefix `cwsyn-MyCanaryName`.
+ CloudWatch Logs log groups with the name `/aws/lambda/cwsyn-MyCanaryName -randomId`.

# Using canary blueprints
<a name="CloudWatch_Synthetics_Canaries_Blueprints"></a>

This section provides details about each of the canary blueprints and the tasks each blueprint is best suited for. Blueprints are provided for the following canary types: 

**Topics**
+ [

## Heartbeat monitoring
](#CloudWatch_Synthetics_Canaries_Blueprints_Heartbeat)
+ [

## API canary
](#CloudWatch_Synthetics_Canaries_Blueprints_API)
+ [

## Broken link checker
](#CloudWatch_Synthetics_Canaries_Blueprints_Broken_Links)
+ [

## Visual monitoring blueprint
](#CloudWatch_Synthetics_Canaries_Blueprints_VisualTesting)
+ [

## Canary recorder
](#CloudWatch_Synthetics_Canaries_Blueprints_Recorder)
+ [

## GUI workflow builder
](#CloudWatch_Synthetics_Canaries_Blueprints_GUI_Workflow)
+ [

## Multi checks blueprint
](#CloudWatch_Synthetics_Canaries_Blueprints_Multichecks_Blueprint)
+ [

# Creating multi checks blueprint canary
](CloudWatch_Synthetics_Canaries_MultiCheck_Blueprint.md)

When you use a blueprint to create a canary, as you fill out the fields in the CloudWatch console, the **Script editor** area of the page displays the canary you are creating as a Node.js script. You can also edit your canary in this area to customize it further.

## Heartbeat monitoring
<a name="CloudWatch_Synthetics_Canaries_Blueprints_Heartbeat"></a>

Heartbeat scripts load the specified URL and store a screenshot of the page and an HTTP archive file (HAR file). They also store logs of accessed URLs. 

You can use the HAR files to view detailed performance data about the web pages. You can analyze the list of web requests and catch performance issues such as time to load for an item.

If your canary uses the `syn-nodejs-puppeteer-3.1` or later runtime version, you can use the heartbeat monitoring blueprint to monitor multiple URLs and see the status, duration, associated screenshots, and failure reason for each URL in the step summary of the canary run report.

## API canary
<a name="CloudWatch_Synthetics_Canaries_Blueprints_API"></a>

API canaries can test the basic Read and Write functions of a REST API. REST stands for *representational state transfer* and is a set of rules that developers follow when creating an API. One of these rules states that a link to a specific URL should return a piece of data.

Canaries can work with any APIs and test all types of functionality. Each canary can make multiple API calls.

In canaries that use runtime version `syn-nodejs-2.2` or later, the API canary blueprint supports multi-step canaries that monitor your APIs as HTTP steps. You can test multiple APIs in a single canary. Each step is a separate request that can access a different URL, use different headers, and use different rules for whether headers and response bodies are captured. By not capturing headers and response body, you can prevent sensitive data from being recorded. 

Each request in an API canary consists of the following information:
+ The *endpoint*, which is the URL that you request.
+ The *method*, which is the type of request that is sent to the server. REST APIs support GET (read), POST (write), PUT (update), PATCH (update), and DELETE (delete) operations.
+ The *headers*, which provide information to both the client and the server. They are used for authentication and providing information about the body content. For a list of valid headers, see [HTTP Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
+ The *data* (or *body*), which contains information to be sent to the server. This is used only for POST, PUT, PATCH, or DELETE requests.

**Note**  
API canary blueprints are not supported by Playwright runtimes.

The API canary blueprint supports GET and POST methods. When you use this blueprint, you must specify headers. For example, you can specify **Authorization** as a **Key** and specify the necessary authorization data as the ** Value** for that key.

If you are testing a POST request, you also specify the content to post in the ** Data** field.

 **Integration with API Gateway** 

The API blueprint is integrated with Amazon API Gateway. This enables you to select an API Gateway API and stage from the same AWS account and Region as the canary, or to upload a Swagger template from API Gateway for cross-account and cross-Region API monitoring. You can then choose the rest of the details in the console to create the canary, instead of entering them from scratch. For more information about API Gateway, see [What is Amazon API Gateway?](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html) 

 **Using a private API** 

You can create a canary that uses a private API in Amazon API Gateway. For more information, see [Creating a private API in Amazon API Gateway?](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-apis.html)

## Broken link checker
<a name="CloudWatch_Synthetics_Canaries_Blueprints_Broken_Links"></a>

The broken link checker collects all the links inside the URL that you are testing by using `document.getElementsByTagName('a')`. It tests only up to the number of links that you specify, and the URL itself is counted as the first link. For example, if you want to check all the links on a page that contains five links, you must specify for the canary to follow six links.

Broken link checker canaries created using the `syn-nodejs-2.0-beta` runtime or later support the following additional features:
+ Provides a report that includes the links that were checked, status code, failure reason (if any), and source and destination page screenshots.
+ When viewing canary results, you can filter to see only the broken links and then fix the link based on the reason for failure.
+ This version captures annotated source page screenshots for each link and highlights the anchor where the link was found. Hidden components are not annotated.
+ You can configure this version to capture screenshots of both source and destination pages, just source pages, or just destination pages.
+ This version fixes an issue in the earlier version where the canary script stops after the first broken link even when more links are scraped from the first page.

**Note**  
Broken link checker blueprints are not supported by Playwright runtimes.

To update an existing canary using `syn-1.0` to use the new runtime, you must delete and re-create the canary. Updating an existing canary to the new runtime does not make these features available.

A broken link checker canary detects the following types of link errors:
+ 404 Page Not Found
+ Invalid Host Name
+ Bad URL. For example, the URL is missing a bracket, has extra slashes, or uses the wrong protocol.
+ Invalid HTTP response code.
+ The host server returns empty responses with no content and no response code.
+ The HTTP requests constantly time out during the canary's run.
+ The host consistently drops connections because it is misconfigured or is too busy.

## Visual monitoring blueprint
<a name="CloudWatch_Synthetics_Canaries_Blueprints_VisualTesting"></a>

The visual monitoring blueprint includes code to compare screenshots taken during a canary run with screenshots taken during a baseline canary run. If the discrepancy between the two screenshots is beyond a threshold percentage, the canary fails. Visual monitoring is supported in canaries running **syn-puppeteer-node-3.2** and later. It is not currently supported in canaries running Python and Selenium, or using Playwright runtimes.

The visual monitoring blueprint includes the following line of code in the default blueprint canary script, which enables visual monitoring.

```
syntheticsConfiguration.withVisualCompareWithBaseRun(true);
```

The first time that the canary runs successfully after this line is added to the script, it uses the screenshots taken during that run as the baseline for comparison. After that first canary run, you can use the CloudWatch console to edit the canary to do any of the following:
+ Set the next run of the canary as the new baseline.
+ Draw boundaries on the current baseline screenshot to designate areas of the screenshot to ignore during visual comparisons.
+ Remove a screenshot from being used for visual monitoring.

For more information about using the CloudWatch console to edit a canary, see [Edit or delete a canary](synthetics_canaries_deletion.md).

You can also change the canary run that is used as the baseline by using the ` nextrun` or `lastrun` parameters or specifing a canary run ID in the [UpdateCanary](https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_UpdateCanary.html) API.

When you use the visual monitoring blueprint, you enter the URL where you want the screenshot to be taken, and specify a difference threshold as a percentage. After the baseline run, future runs of the canary that detect a visual difference greater than that threshold trigger a canary failure. After the baseline run, you can also edit the canary to "draw" boundaries on the baseline screenshot that you want to ignore during the visual monitoring.

The visual monitoring feature is powered by the the ImageMagick open source software toolkit. For more information, see [ ImageMagick ](https://imagemagick.org/index.php).

## Canary recorder
<a name="CloudWatch_Synthetics_Canaries_Blueprints_Recorder"></a>

With the canary recorder blueprint, you can use the CloudWatch Synthetics Recorder to record your click and type actions on a website and automatically generate a Node.js script that can be used to create a canary that follows the same steps. The CloudWatch Synthetics Recorder is a Google Chrome extension provided by Amazon. The canary recorder is not supported for canaries that use the Playwright runtime.

**Credits**: The CloudWatch Synthetics Recorder is based on the [ Headless recorder ](https://github.com/checkly/headless-recorder).

For more information, see [Using the CloudWatch Synthetics Recorder for Google Chrome](CloudWatch_Synthetics_Canaries_Recorder.md).

## GUI workflow builder
<a name="CloudWatch_Synthetics_Canaries_Blueprints_GUI_Workflow"></a>

The GUI Workflow Builder blueprint verifies that actions can be taken on your webpage. For example, if you have a webpage with a login form, the canary can populate the user and password fields and submit the form to verify that the webpage is working correctly.

When you use a blueprint to create this type of canary, you specify the actions that you want the canary to take on the webpage. The actions that you can use are the following:
+ **Click**— Selects the element that you specify and simulates a user clicking or choosing the element.

  To specify the element in a Node.js script, use `[id=]` or ` a[class=]`.

  To specify the element in a Python script, use `xpath //*[@id=]` or ` //*[@class=]`.
+ **Verify selector**— Verifies that the specified element exists on the webpage. This test is useful for verifying that a previous action has causes the correct elements to populate the page.

  To specify the element to verify in a Node.js script, use `[id=]` or ` a[class=]`.

  To specify the element to verify in a Python script, use `xpath //*[@id=]` or `//*[class=]`.
+ **Verify text**— Verifies that the specified string is contained within the target element. This test is useful for verifying that a previous action has caused the correct text to be displayed.

  To specify the element in a Node.js script, use a format such as ` div[@id=]//h1` because this action uses the `waitForXPath` function in Puppeteer.

  To specify the element in a Python script, use xpath format such as ` //*[@id=] `or //\$1[@class=] because this action uses the `implicitly_wait` function in Selenium.
+ **Input text**— Writes the specified text in the target element.

  To specify the element to verify in a Node.js script, use `[id=]` or ` a[class=]`.

  To specify the element to verify in a Python script, use `xpath //*[@id=]` or `//*[@class=]`.
+ **Click with navigation**— Waits for the whole page to load after choosing the specified element. This is most useful when you need to reload the page.

  To specify the element in a Node.js script, use `[id=]` or ` a[class=]`.

  To specify the element in a Python script, use `xpath //*[@id=]` or ` //*[@class=]`.

For example, the following blueprint uses Node.js. It clicks the **firstButton** on the specified URL, verifies that the expected selector with the expected text appears, inputs the name `Test_Customer` into the **Name** field, clicks the **Login** button, and then verifies that the login is successful by checking for the **Welcome** text on the next page.

![\[The create canary page in the console, with fields filled in for the GUI Workflow blueprint.\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/images/canary_create_gui_workflow.PNG)


GUI workflow canaries that use the following runtimes also provide a summary of the steps executed for each canary run. You can use the screenshots and error message associated with each step to find the root cause of failure.
+ `syn-nodejs-2.0` or later
+ `syn-python-selenium-1.0` or later

## Multi checks blueprint
<a name="CloudWatch_Synthetics_Canaries_Blueprints_Multichecks_Blueprint"></a>

The Multi check blueprint simplifies canary creation. It reduces costs by using a simple JSON configuration that provides out-of-the-box functionality for performing HTTP, DNS, SSL, and TCP checks. You can configure up to 10 checks. Configure each check as a numerical step that runs sequentially, allowing for clear understanding of the canary flow.

Multi checks blueprints support:
+ Basic HTTP requests, TCP requests, validate DNS records and monitor SSL certificates
+ HTTP authentication methods such as Basic, API Key, OAuth, and Sigv4 integrated with Secrets Manager
+ Assertions for each check

For more information, see [Creating a canary](CloudWatch_Synthetics_Canaries_Create.md).

# Creating multi checks blueprint canary
<a name="CloudWatch_Synthetics_Canaries_MultiCheck_Blueprint"></a>

Amazon CloudWatch Synthetics multi checks blueprint helps you create a Synthetics canary by providing a simple JSON configuration. You can save costs by bundling up to 10 different types of HTTP/DNS/SSL/TCP checks in a step-based sequential manner. Each check includes assertions that provide basic verification against a check result.

Multi checks canaries are designed for simple use cases that require only basic checks without a headless browser. For more complex use cases, review the other canary types that Amazon CloudWatch Synthetics provides.

**Topics**
+ [

## Prerequisites
](#CloudWatch_Synthetics_MultiCheck_Prerequisites)
+ [

## Limitations
](#CloudWatch_Synthetics_MultiCheck_Limitations)
+ [

## Packaging structure, JSON schema, and configuration settings
](#CloudWatch_Synthetics_MultiCheck_Packaging)
+ [

## Creating a multi check canary in AWS Management Console
](#CloudWatch_Synthetics_MultiCheck_Console)
+ [

## Creating a multi check canary using AWS Synthetics APIs
](#CloudWatch_Synthetics_MultiCheck_API)
+ [

## Creating a multi check canary in CloudFormation
](#CloudWatch_Synthetics_MultiCheck_CloudFormation)
+ [

## Authentication configuration
](#CloudWatch_Synthetics_MultiCheck_Authentication)
+ [

## Troubleshooting
](#CloudWatch_Synthetics_MultiCheck_Troubleshooting)

## Prerequisites
<a name="CloudWatch_Synthetics_MultiCheck_Prerequisites"></a>
+ Must be using syn-nodejs-3.0\$1 in order to create a multi check canary
+ When using Authentication and Secrets Manager configuration, you must ensure the canary [ ExecutionRoleArn](https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_CreateCanary.html) allows for the permissions to access these secrets
+ When using Authentication for Sigv4, you must ensure the canary [ ExecutionRoleArn](https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_CreateCanary.html) allows for the permissions to access the related role

## Limitations
<a name="CloudWatch_Synthetics_MultiCheck_Limitations"></a>
+ HTTP Response sizes cannot be greater than 1 MB
+ Maximum of 10 defined variables.
+ When using the JSON RFC, the Checks JSON may have duplicate fields provided however only the last sequential field will be used
+ In the AWS Management Console, a multi check canary will default to showing multi check step metrics to readily identify the availability of each check. When checks are removed, this graph may still show the checks in the availability graph until the metric stops being active for at least 3 hours

## Packaging structure, JSON schema, and configuration settings
<a name="CloudWatch_Synthetics_MultiCheck_Packaging"></a>

The JSON Checks configuration that will be used for the canary must be named ` blueprint-config.json`. The configuration must follow the [ schema](https://github.com/aws-samples/synthetics-canary-local-debugging-sample/tree/main) and follow the instructions under [Writing a JSON configuration for Node.js multi Checks blueprint](CloudWatch_Synthetics_WritingCanary_Multichecks.md).

Compress the `blueprint-config.json` into a ZIP file and provide it in one of the following creation workflows. When there is a `synthetics.json` configuration, then it is also compressed in the same ZIP file. The following is a zip file example called `multi-checks.zip`.

```
multi-checks.zip
├── blueprint-config.json
└── synthetics.json
```

## Creating a multi check canary in AWS Management Console
<a name="CloudWatch_Synthetics_MultiCheck_Console"></a>

1. Open the Amazon CloudWatch synthetics console.

1. Choose **Create Canary**.

1. Under **Use a blueprint**, choose **multi checks** .

   Under **Configure Checks**, you will see two tabs, ** Checks** and **Canary configuration**.

1. Select the runtime version **syn-nodejs-3.0** or later.

1. Follow the procedure under [Writing a JSON configuration for Node.js multi Checks blueprint](CloudWatch_Synthetics_WritingCanary_Multichecks.md) to describe the check you want to perform. Alternatively, the console provides you a default JSON configuration that you can build on.

1. Choose **Create Canary**.

## Creating a multi check canary using AWS Synthetics APIs
<a name="CloudWatch_Synthetics_MultiCheck_API"></a>

Use the `CreateCanary` API and within the `Code` parameter, provide the field/value `BlueprintTypes="multi-checks"` instead of ` Handler`. When both `BlueprintTypes` and `Handler` are specified, a `ValidationException` is displayed. The runtime version provided must be `syn-nodejs-3.0` or later.

```
aws synthetics create-canary \
    --name my-multi-check-canary \
    --code ZipFile="ZIP_BLOB",BlueprintTypes="multi-checks" \
    --runtime-version syn-nodejs-3.0 \
    ...

// Or if you wanted to use S3 to provide your code.

aws synthetics create-canary \
    --name my-multi-check-canary \
    --code S3Bucket="my-code-bucket",S3Key="my-zip-code-key",BlueprintTypes="multi-checks" \
    ...
```

## Creating a multi check canary in CloudFormation
<a name="CloudWatch_Synthetics_MultiCheck_CloudFormation"></a>

In your CloudFormation template for a multi check canary, within the `Code` parameter, provide the field/value `BlueprintTypes="multi-checks"` instead of ` Handler`. When both `BlueprintTypes` and `Handler` are specified, a `ValidationException` is displayed. The runtime version provided must be `syn-nodejs-3.0 or later`. 

An example template:

```
SyntheticsCanary:
    Type: 'AWS::Synthetics::Canary'
    Properties:
      Name: MyCanary
      RuntimeVersion: syn-nodejs-3.0
      Schedule: {Expression: 'rate(5 minutes)', DurationInSeconds: 3600}
      ...
      Code:
        S3Bucket: "my-code-bucket"
        S3Key: "my-zip-code-key"
        BlueprintTypes: ["multi-checks"]
      ...
```

## Authentication configuration
<a name="CloudWatch_Synthetics_MultiCheck_Authentication"></a>

When your canary makes HTTP requests to an authenticated endpoint, you can configure the steps of your blueprint canary to use one of four authentication types: Basic, API Key, OAuth Client Credentials, and SigV4. Rather than setting up request headers yourself, you can specify an authentication type in your blueprint definition, and Synthetics follows the specified authentication type to populate the components of your HTTP request with the authentication information provided.

You specify an authentication type in your blueprint step with the Authentication section. You specify the authentication scheme you want to use, the properties required for your chosen authentication scheme, and Synthetics uses the information provided to construct an authentication header for your HTTP request.

Since storing secrets (such as passwords or API keys) in plain text is a security concern, Synthetics supports integration with AWS Secrets Manager. When you want to authenticate an HTTP request in a Synthetics blueprint canary, you can refer to the secret storing your authentication information and Synthetics handles retrieving the secret and caching it in your canary. This approach provides secrets to Synthetics while keeping your secrets securely stored, without specifying them in plain text in your blueprint configuration.

For more information about AWS Secrets Manager, see [What is AWS Secrets Manager?](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)

### Basic authentication
<a name="CloudWatch_Synthetics_MultiCheck_BasicAuth"></a>

Synthetics implements the Basic HTTP authentication scheme defined in RFC 7617. The process works as follows:
+ A username and password pair is provided from the blueprint configuration.
+ The user-pass is created by concatenating the username, a single colon (":") character, and the password.
+ The user-pass is UTF-8 encoded, then converted into a base64-encoded string.
+ This base64-encoded user-pass is provided in the "Authorization" header with the following format: Authorization: Basic \$1base64-encoded-user-pass\$1

For example, if the user agent wants to send the user-id "Aladdin" and password "open sesame", it uses the following header field: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Example configuration:

```
"Authentication": {
    "type": "BASIC",
    "username": MY_USERNAME, // Required
    "password": MY_PASSWORD // Required
}
```

### API key authentication
<a name="CloudWatch_Synthetics_MultiCheck_APIKeyAuth"></a>

You can provide an API key for authenticating your HTTP requests. When you use API key authentication, your provided API key is put into the "X-API-Key" HTTP header. If you have a custom resource that looks for API key headers in a header besides this one, you can optionally specify a different header name to have Synthetics put the API key into.

Example configuration:

```
"Authentication": {
    "type": "API_KEY",
    "apiKey": S0A1M2P3L4E5, // Required
    "header": X-Specific-Header // Optional, defaults to "X-API-Key"
}
```

### SigV4 authentication
<a name="CloudWatch_Synthetics_MultiCheck_SigV4Auth"></a>

AWS SigV4 (Signature Version 4) is the AWS signing protocol for adding authentication information to AWS API requests. To make a SigV4-authenticated request, you need to specify the region and service you are making requests to, as well as an ARN (AWS Resource Name) identifying an IAM role you want the canary to assume when making this SigV4 request. Synthetics assumes the IAM role provided in the roleArn, and uses it to authenticate your AWS API request.

Example configuration:

```
"Authentication": {
    "type": "SIGV4",
    "region": us-west-2, // Required
    "service": s3, // Required
    "roleArn": arn:AWS:iam:12345678912:role/SampleRole // Required
}
```

#### SigV4 considerations
<a name="CloudWatch_Synthetics_MultiCheck_SigV4Considerations"></a>

For Synthetics to assume the role that you provided in the SigV4 authentication section, the trust policy attached to that role must be configured to allow the canary to assume the provided roleArn. The AWS principal you need to trust is the role that your canary assumed through AWS STS. It takes the format ` aws:sts::{account_running_the_canary}:assumed-role/<canary_name>/<assumed_role_name>` arn:.

For example, if you have a canary running in account 0123456789012, named test-canary, and the role it assumed was named canary-assume-role, then the trust policy needs to include this statement for the canary to assume the roleArn for SigV4 authentication correctly:

```
{
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:AWS:sts::123456789012:assumed-role/test-canary/"
    },
    "Action": "sts:AssumeRole"
}
```

### OAuth client credentials
<a name="CloudWatch_Synthetics_MultiCheck_OAuthAuth"></a>

Synthetics implements the OAuth Client Credentials grant type as defined in RFC 6479 Section 4.4. If you want to make an HTTP request to an endpoint authenticated with a Bearer Token issued by an OAuth token endpoint, Synthetics can request and manage a bearer token on your behalf. When you use the OAuth scheme, Synthetics performs the following steps:
+ Uses the Basic authentication scheme with the clientId and clientSecret to authenticate a request to the tokenUrl, the endpoint that issues bearer tokens
+ If you provide the optional scope, audience, and resource parameters, they are included in the token request
+ Uses the access token returned by the tokenUrl to authenticate your HTTP request
+ Securely stores the refresh token returned from the tokenUrl for future token requests

Example configuration:

```
"Authentication": {
    "type": "OAUTH_CLIENT_CREDENTIALS",
    "tokenUrl": ..., // Required
    "clientId": ..., // Required
    "clientSecret": ..., // Required
    "scope": ..., // Optional
    "audience": ..., // Optional
    "resource": ..., // Optional
}
```

#### OAuth considerations
<a name="CloudWatch_Synthetics_MultiCheck_OAuthConsiderations"></a>

Synthetics refreshes OAuth tokens when a 401 or 407 response is returned.

### AWS Secrets Manager integration
<a name="CloudWatch_Synthetics_MultiCheck_SecretsManager"></a>

To avoid storing secret values (such as passwords or API keys) in plain text, Synthetics provides an integration with AWS Secrets Manager. You can reference an entire secret value in your blueprint configuration with the format ` ${aws_SECRET:<secret_name>}`, or to reference a particular key ` ${aws_SECRET:<secret_name>:<secret_key>}`.

For example, if you have a secret named login/basic-auth-credentials, storing a username and password with the following JSON structure:

```
{
    "username": "Aladdin",
    "password": "open sesame"
}
```

You can reference the username and password in your blueprint configuration as follows, and Synthetics handles retrieving the secret value and using its keys to authenticate your request:

```
"Authentication": {
    "type": "BASIC",
    "username": ${AWS_SECRET:login/basic-auth-credentials:username},
    "password": ${AWS_SECRET:login/basic-auth-credentials:password}
}
```

To allow Synthetics to retrieve the specified secret, the role ARN assumed by the canary needs to have secretsManager:GetSecretValue permissions. If the secret is encrypted using a customer-managed key instead of the AWS managed key AWS/secretsmanager, then you also need kms:Decrypt permissions for that key.

Example permissions:

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:AWS:secretsmanager:us-east-1:123456789012:secret:secretName-AbCdEf"
        },
        {
            "Effect": "Allow",
            "Action": "kms:Decrypt",
            "Resource": "arn:AWS:kms:us-east-1:123456789012:key/key-id"
        }
    ]
}
```

## Troubleshooting
<a name="CloudWatch_Synthetics_MultiCheck_Troubleshooting"></a>

### Common troubleshooting failures
<a name="CloudWatch_Synthetics_MultiCheck_Common_Failures"></a>

The underlying code for multi check blueprint is written in Typescript. See the canary troubleshooting page for common failures: [Troubleshooting a failed canary](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Troubleshoot.html).

### JSON check configuration syntax errors
<a name="CloudWatch_Synthetics_MultiCheck_JSON_Errors"></a>

When there are any syntactic errors related to the canary's JSON check configuration, the AWS Management Console will provide you a failure reason when you attempt to create the canary. If you are creating a canary using an API or CloudFormation, you will see the failure when the canary is executed for the first time. It is recommended to use the safe canary updates workflow for multi check canary. For more information, see [Performing safe canary updates ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/performing-safe-canary-upgrades.html).

### Networking or timeout failures
<a name="CloudWatch_Synthetics_MultiCheck_Network_Failures"></a>

For any intermittent or consistent failures related to timeouts, network connection failures (for example, ENOTFOUND, ECONNRESET) consider turning on ` DEBUG` logs such that the following run will provide more additional details on why the Checks are failing. To do so, provide the Environment Variable CW\$1SYNTHETICS\$1LOG\$1LEVEL: "DEBUG".

If there are still failures that you are unable to debug, consider reaching out to AWS Support or checking if any of the other provided Canary types from CloudWatch Synthetics more closely matches your use-case.

# Using the CloudWatch Synthetics Recorder for Google Chrome
<a name="CloudWatch_Synthetics_Canaries_Recorder"></a>

Amazon provides a CloudWatch Synthetics Recorder to help you create canaries more easily. The recorder is a Google Chrome extension.

The recorder records your click and type actions on a website and automatically generates a Node.js script that can be used to create a canary that follows the same steps.

After you start recording, the CloudWatch Synthetics Recorder detects your actions in the browser and converts them to a script. You can pause and resume the recording as needed. When you stop recording, the recorder produces a Node.js script of your actions, which you can easily copy with the **Copy to Clipboard** button. You can then use this script to create a canary in CloudWatch Synthetics. 

**Credits**: The CloudWatch Synthetics Recorder is based on the [ Headless recorder ](https://github.com/checkly/headless-recorder).

## Installing the CloudWatch Synthetics Recorder extension for Google Chrome
<a name="CloudWatch_Synthetics_Canaries_Recorder-install"></a>

To use the CloudWatch Synthetics Recorder, you can start creating a canary and choose the **Canary Recorder** blueprint. If you do this when you haven't already downloaded the recorder, the CloudWatch Synthetics console provides a link to download it.

Alternatively, you can follow these steps to download and install the recorder directly.

**To install the CloudWatch Synthetics Recorder**

1. Using Google Chrome, go to this website: [ https://chrome.google.com/webstore/detail/cloudwatch-synthetics-rec/bhdnlmmgiplmbcdmkkdfplenecpegfno ](https://chrome.google.com/webstore/detail/cloudwatch-synthetics-rec/bhdnlmmgiplmbcdmkkdfplenecpegfno)

1. Choose **Add to Chrome**, then choose **Add extension** .

## Using the CloudWatch Synthetics Recorder for Google Chrome
<a name="CloudWatch_Synthetics_Canaries_Recorder-using"></a>

To use the CloudWatch Synthetics Recorder to help you create a canary, you can choose **Create canary** in the CloudWatch console, and then choose **Use a blueprint**, **Canary Recorder**. For more information, see [Creating a canary](CloudWatch_Synthetics_Canaries_Create.md). 

Alternatively, you can use the recorder to record steps without immediately using them to create a canary.

**To use the CloudWatch Synthetics Recorder to record your actions on a website**

1. Navigate to the page that you want to monitor.

1. Choose the Chrome extensions icon, and then choose **CloudWatch Synthetics Recorder**.

1. Choose **Start Recording**.

1. Perform the steps that you want to record. To pause recording, choose ** Pause**.

1. When you are finished recording the workflow, choose **Stop recording** .

1. Choose **Copy to clipboard** to copy the generated script to your clipboard. Or, if you want to start over, choose **New recording**.

1. To create a canary with the copied script, you can paste your copied script into the recorder blueprint inline editor, or save it to an Amazon S3 bucket and import it from there.

1. If you're not immediately creating a canary, you can save your recorded script to a file.

## Known limitations of the CloudWatch Synthetics Recorder
<a name="CloudWatch_Synthetics_Canaries_Recorder-limitations"></a>

The CloudWatch Synthetics Recorder for Google Chrome currently has the following limitations.
+ HTML elements that don’t have IDs will use CSS selectors. This can break canaries if the webpage structure changes later. We plan to provide some configuration options (such as using data-id) around this in a future version of the recorder. 
+ The recorder doesn't support actions such as double-click or copy/paste, and doesn't support key combinations such as CMD\$10. 
+ To verify the presence of an element or text on the page, users must add assertions after the script is generated. The recorder doesn't support verifying an element without performing any action on that element. This is similar to the “Verify text” or “Verify element” options in the canary workflow builder. We plan to add some assertions support in a future version of the recorder. 
+ The recorder records all actions in the tab where the recording is initiated. It doesn't record pop-ups (for instance, to allow location tracking) or navigation to different pages from pop-ups. 

# Synthetics runtime versions
<a name="CloudWatch_Synthetics_Canaries_Library"></a>

When you create or update a canary, you choose a Synthetics runtime version for the canary. A Synthetics runtime is a combination of the Synthetics code that calls your script handler, and the Lambda layers of bundled dependencies.

CloudWatch Synthetics currently supports runtimes that use Node.js, Python, or Java languages. The frameworks supported are Puppeteer, Playwright, and Selenium.

We recommend that you always use the most recent runtime version for your canaries, to be able to use the latest features and updates made to the Synthetics library.

**Please note**: whenever you run a canary to use the new version of the Synthetics runtime, all Synthetics library functions that your canary uses are also automatically moved to the same version of NodeJS that the Synthetics runtime supports.

**Topics**
+ [

# Runtime versions using Java
](CloudWatch_Synthetics_Library_Java.md)
+ [

# Runtime versions using Node.js and Playwright
](CloudWatch_Synthetics_Library_nodejs_playwright.md)
+ [

# Runtime versions using Node.js and Puppeteer
](CloudWatch_Synthetics_Library_nodejs_puppeteer.md)
+ [

# Runtime versions using Python and Selenium Webdriver
](CloudWatch_Synthetics_Library_python_selenium.md)
+ [

# Runtime versions using Node.js
](CloudWatch_Synthetics_Library_Nodejs.md)
+ [

# Runtime versions support policy
](CloudWatch_Synthetics_Runtime_Support_Policy.md)
+ [

# Runtime versions update
](CloudWatch_Synthetics_Runtime_Version_Update.md)

# Runtime versions using Java
<a name="CloudWatch_Synthetics_Library_Java"></a>

The following section contains information about the CloudWatch Synthetics runtime versions for Java. This runtime does not have any browser or framework included.

The naming convention for these runtime versions is `syn-language -majorversion.minorversion`. 

## syn-java-1.0
<a name="Synthetics_runtimeversion-syn-java-1.0"></a>

**Major dependencies**:
+ AWS Lambda runtime Java 21

 **Features** 
+ *CloudWatch Logs integration* – You can query and filter for logs through the CloudWatch Synthetics console. Each log message contains unique ` canaryRunId`, making it easy to search for logs for a particular canary run.
+ *Metrics* – You can monitor canary run success percentage and duration through CloudWatch metrics. You can also configure alarms to alert you when canaries detect issues.
+ *Canary artifacts* - Each canary run uploads a detailed report corresponding to the run and the steps in the run which can be accessed through Amazon S3.
+ *Support for traces* - You can emit traces for all the requests made by the canary through X-Ray. Each canary run is associated with one trace Id.

# Runtime versions using Node.js and Playwright
<a name="CloudWatch_Synthetics_Library_nodejs_playwright"></a>

The following sections contain information about the CloudWatch Synthetics runtime versions for Node.js and Playwright. Playwright is an open-source automation library for browser testing. For more information about Playwright, see [ https://playwright.dev/](https://playwright.dev) 

The naming convention for these runtime versions is `syn-language -framework-majorversion. minorversion`. 

## syn-nodejs-playwright-6.0
<a name="Synthetics_runtimeversion-syn-nodejs-playwright-6.0"></a>

**Important**  
Starting Synthetics `syn-nodejs-playwright-5.1` and later, Synthetics runtime uses the new namespace. Please migrate the canary script to use the new namespace. Legacy namespace will be deprecated in a future release.  
@amzn/synthetics-playwright → @aws/synthetics-playwright

**Major dependencies**:
+ AWS Lambda runtime Node.js 22.x
+ Playwright version 1.58.2
+ Playwright/test version 1.58.2
+ Chromium version 145.0.7632.77
+ Firefox version 146.0.1

 **Changes in syn-nodejs-playwright-6.0** 
+ Applied security patches and updated Playwright and browser versions. 

For more information, see the following:
+  [Playwright change log ](https://playwright.dev/docs/release-notes) 
+  [Playwright API reference](https://playwright.dev/docs/api/class-playwright) 

## Previous runtime versions for Node.js and Playwright
<a name="Previousversions-nodejs-playwright"></a>

The following earlier runtime versions for Node.js and Playwright are still supported. 

### syn-nodejs-playwright-5.1
<a name="Synthetics_runtimeversion-syn-nodejs-playwright-5.1"></a>

**Major dependencies**:
+ AWS Lambda runtime Node.js 22.x
+ Playwright version 1.57.0
+ Playwright/test version 1.57.0
+ Chromium version 143.0.7499.169
+ Firefox version 142.0.1

 **Changes in syn-nodejs-playwright-5.1** 
+ Synthetics runtime namespace migration. 
+ Type definition is available in [npm Registry](https://www.npmjs.com/package/@aws/synthetics-playwright). Please ensure the type definition package version matches your canary's runtime version.

For more information, see the following:
+  [Playwright change log ](https://playwright.dev/docs/release-notes) 
+  [Playwright API reference](https://playwright.dev/docs/api/class-playwright) 

### syn-nodejs-playwright-5.0
<a name="Synthetics_runtimeversion-syn-nodejs-playwright-5.0"></a>

**Major dependencies**:
+ AWS Lambda runtime Node.js 22.x
+ Playwright version 1.57.0
+ Playwright/test version 1.57.0
+ Chromium version 143.0.7499.4
+ Firefox version 142.0.1

 **Changes in syn-nodejs-playwright-5.0** 
+ Applied security patches and updated Playwright and browser versions. 

For more information, see the following:
+  [Playwright change log ](https://playwright.dev/docs/release-notes) 
+  [Playwright API reference](https://playwright.dev/docs/api/class-playwright) 

### syn-nodejs-playwright-4.0
<a name="Synthetics_runtimeversion-syn-nodejs-playwright-4.0"></a>

**Major dependencies**:
+ AWS Lambda runtime Node.js 22.x
+ Playwright version 1.55.0
+ Playwright/test version 1.55.0
+ Chromium version 140.0.7339.16
+ Firefox version 141.0

 **Changes in syn-nodejs-playwright-4.0** 
+ Applied security patches and updated Playwright and browser versions. 

For more information, see the following:
+  [Playwright change log ](https://playwright.dev/docs/release-notes) 
+  [Playwright API reference](https://playwright.dev/docs/api/class-playwright) 

### syn-nodejs-playwright-3.0
<a name="Synthetics_runtimeversion-syn-nodejs-playwright-3.0"></a>

**Major dependencies**:
+ AWS Lambda runtime Node.js 20.x
+ Playwright version 1.53.0
+ Playwright/test version 1.53.0
+ Chromium version 138.0.7204.168

 **Changes in syn-nodejs-playwright-3.0** 
+ Multi-browser support – You can now run your nodejs puppeteer canaries in either Firefox or Chrome
+ Support for visual monitoring

For more information, see the following:
+  [Playwright change log ](https://playwright.dev/docs/release-notes) 
+  [Playwright API reference](https://playwright.dev/docs/api/class-playwright) 

### syn-nodejs-playwright-2.0
<a name="Synthetics_runtimeversion-syn-nodejs-playwright-2.0"></a>

**Major dependencies**:
+ AWS Lambda runtime Node.js 20.x
+ Playwright version 1.49.1
+ Playwright/test version 1.49.1
+ Chromium version 131.0.6778.264

 **Changes in syn-nodejs-playwright-2.0** 
+ The mismatch between total duration and sum of timings for a given request in HAR file is fixed.
+ Supports dry runs for the canary which allows for adhoc executions or performing a safe canary update.

For more information, see the following:
+  [Playwright change log ](https://playwright.dev/docs/release-notes) 
+  [Playwright API reference](https://playwright.dev/docs/api/class-playwright) 

### syn-nodejs-playwright-1.0
<a name="Synthetics_runtimeversion-syn-nodejs-playwright-1.0"></a>

**Major dependencies**:
+ AWS Lambda runtime Node.js 20.x
+ Playwright version 1.44.1
+ Playwright/test version 1.44.1
+ Chromium version 126.0.6478.126

**Features**:
+ **PlayWright support** – You can write canary scripts by using the Playwright automation framework. You can bring your existing Playwright scripts to run as canaries, and enhance them with AWS monitoring capabilities. 
+ **CloudWatch Logs integration** – You can query and filter for logs through the CloudWatch Synthetics console. Each log message contains unique `canaryRunId`, making it easy to search for logs for a particular canary run. 
+ **Metrics and canary artifacts** – You can monitor canary run pass rate through CloudWatch metrics, and configure alarms to alert you when canaries detect issues. 
+ **Screenshots and steps association** – You can capture screenshots using native Playwright functionality to visualize the stages of a canary script on each run. Screenshots are automatically associated with canary steps, and are uploaded to Amazon S3 buckets. 
+ **Multiple tabs**– You can create canaries that open multiple browser tabs, and access screenshots from each tab. You can create multi-tab and multi-step user workflows in Synthetics. 

# Runtime versions using Node.js and Puppeteer
<a name="CloudWatch_Synthetics_Library_nodejs_puppeteer"></a>

The first runtime version for Node.js and Puppeteer was named `syn-1.0`. Later runtime versions have the naming convention `syn-language -majorversion.minorversion`. Starting with `syn-nodejs-puppeteer-3.0`, the naming convention is `syn- language-framework-majorversion .minorversion` 

An additional `-beta` suffix shows that the runtime version is currently in a beta preview release.

Runtime versions with the same major version number are backward compatible. 

The Lambda code in a canary is configured to have a maximum memory of 1 GB. Each run of a canary times out after a configured timeout value. If no timeout value is specified for a canary, CloudWatch chooses a timeout value based on the canary's frequency. If you configure a timeout value, make it no shorter than 15 seconds to allow for Lambda cold starts and the time it takes to boot up the canary instrumentation.

## syn-nodejs-puppeteer-15.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-15.0"></a>

`syn-nodejs-puppeteer-15.0` is the most recent Synthetics runtime for Node.js and Puppeteer. 

**Important**  
Starting Synthetics `syn-nodejs-puppeteer-13.1` and later, Synthetics runtime uses the new namespace. Please migrate the canary script to use new namespaces. Legacy namespaces will be deprecated in a future release.  
Synthetics → @aws/synthetics-puppeteer
SyntheticsLink → @aws/synthetics-link
SyntheticsLogger → @aws/synthetics-logger
SyntheticsLogHelper → @aws/synthetics-log-helper
BrokenLinkCheckerReport → @aws/synthetics-broken-link-checker-report

**Important**  
Synthetics runtime `syn-nodejs-puppeteer-11.0` and later versions support only the following step-level configuration overrides:  
 `screenshotOnStepStart` 
 `screenshotOnStepSuccess` 
 `screenshotOnStepFailure` 
 `stepSuccessMetric` 
 `stepDurationMetric` 
 `continueOnStepFailure/continueOnHttpStepFailure` 
 `stepsReport` 

For more information, see the following:
+  [Puppeteer Change log](https://pptr.dev/CHANGELOG#24375-2026-02-19) 
+  [Puppeteer API reference](https://github.com/puppeteer/puppeteer/blob/puppeteer-v24.37.5/docs/api/index.md) 

**Major dependencies**:
+ Lambda runtime Node.js 22.x
+ Puppeteer-core version 24.37.5
+ Chromium version 145.0.7632.77
+ Firefox version 147.0.4

 **Changes in syn-nodejs-puppeteer-15.0** 
+ Applied security patches and updated Puppeteer and browser versions.
+ Fixed bug where continueOnHttpStepFailure was not being honored, causing canary runs to be incorrectly marked as successful despite HTTP step failures occurring.

## Previous runtime versions for Node.js and Puppeteer
<a name="Previousversions-nodejs-puppeteer"></a>

The following earlier runtime versions for Node.js and Puppeteer are still supported. 

### syn-nodejs-puppeteer-14.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-14.0"></a>

For more information, see the following:
+  [Puppeteer Change log](https://pptr.dev/CHANGELOG#24340-2025-12-19) 
+  [Puppeteer API reference](https://github.com/puppeteer/puppeteer/blob/puppeteer-v24.34.0/docs/api/index.md) 

**Major dependencies**:
+ Lambda runtime Node.js 22.x
+ Puppeteer-core version 24.34.0
+ Chromium version 143.0.7499.169
+ Firefox version 146.x

 **Changes in syn-nodejs-puppeteer-14.0** 
+ Applied security patches and updated Puppeteer and browser versions.

### syn-nodejs-puppeteer-13.1
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-13.1"></a>

`syn-nodejs-puppeteer-13.1` is the most recent Synthetics runtime for Node.js and Puppeteer. 

For more information, see the following:
+  [Puppeteer Change log](https://pptr.dev/CHANGELOG#24250-2025-10-15) 
+  [Puppeteer API reference](https://github.com/puppeteer/puppeteer/blob/puppeteer-v24.2.0/docs/api/index.md) 

**Major dependencies**:
+ Lambda runtime Node.js 22.x
+ Puppeteer-core version 24.25.0
+ Chromium version 142.0.7444.175
+ Firefox version 145.x

 **Changes in syn-nodejs-puppeteer-13.1** 
+ Synthetics runtime namespace migration.
+ Type definitions are available in npm Registry. Please ensure the type definition package version matches your canary's runtime version.
  +  [ @aws/synthetics-puppeteer](https://www.npmjs.com/package/@aws/synthetics-puppeteer) 
  +  [ @aws/synthetics-link](https://www.npmjs.com/package/@aws/synthetics-link) 
  +  [ @aws/synthetics-broken-link-checker-report](https://www.npmjs.com/package/@aws/synthetics-broken-link-checker-report) 
  +  [ @aws/synthetics-log-helper](https://www.npmjs.com/package/@aws/synthetics-log-helper) 
  +  [ @aws/synthetics-logger](https://www.npmjs.com/package/@aws/synthetics-logger) 

### syn-nodejs-puppeteer-13.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-13.0"></a>

For more information, see the following:
+  [Puppeteer Change log](https://pptr.dev/CHANGELOG#24250-2025-10-15) 
+  [Puppeteer API reference](https://github.com/puppeteer/puppeteer/blob/puppeteer-v24.2.0/docs/api/index.md) 

**Major dependencies**:
+ Lambda runtime Node.js 22.x
+ Puppeteer-core version 24.25.0
+ Chromium version 142.0.7444.175
+ Firefox version 145.x

 **Changes in syn-nodejs-puppeteer-13.0** 
+ Applied security patches and updated Puppeteer and browser versions.
+ Bug fix – Fixed intermittent runtime extension crash issue caused by concurrent map access

### syn-nodejs-puppeteer-12.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-12.0"></a>

For more information, see the following:
+  [Puppeteer Change log](https://pptr.dev/CHANGELOG#24221-2025-09-23) 
+  [Puppeteer API reference](https://github.com/puppeteer/puppeteer/blob/puppeteer-v24.22.1/docs/api/index.md) 

**Major dependencies**:
+ Lambda runtime Node.js 22.x
+ Puppeteer-core version 24.22.1
+ Chromium version 140.0.7339.185
+ Firefox version 143.0.1

 **Changes in syn-nodejs-puppeteer-12.0** 
+ Applied security patches and updated Puppeteer and browser versions.
+ Bug fix for Restricted header redaction – Fixed an issue where in some situations restricted headers were not being redacted in executeHttpStep(). Behavior is now consistent with Puppeteer 10.0.
+ Bug fix for includeResponseBody configuration – Fixed an issue where HAR file generation can misapply the includeResponseBody configuration setting in certain situations. HAR now ensures response bodies are excluded when setting is configured.
+ Request capture lifecycle fixed – Fixed an issue where in some situations the HTTP request capturer may cause continuous aggregation of requests. Recording now terminates correctly after each step execution.

### syn-nodejs-puppeteer-11.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-11.0"></a>

For more information, see the following:
+  [Puppeteer Change log](https://pptr.dev/CHANGELOG) 
+  [Puppeteer API reference](https://github.com/puppeteer/puppeteer/blob/puppeteer-v24.2.0/docs/api/index.md) 

**Major dependencies**:
+ Lambda runtime Node.js 20.x
+ Puppeteer-core version 24.15.0
+ Chromium version 138.0.7204.168

 **Changes in syn-nodejs-puppeteer-11.0** 
+ Multi-browser support – You can now run Node.js Puppeteer canaries in either Firefox or Chrome
+ Simplified packaging – Package scripts directly under root without using the Node.js/node\$1modules directory structure
+ Screenshot integration – Capture screenshots using native Puppeteer functions to visualize canary script stages. Synthetics automatically associates screenshots with canary steps and uploads them to Amazon S3
+ Enhanced log querying – Query and filter logs through the CloudWatch Insights console. Each log message includes a unique `canaryRunId` for easier searching
+ Configuration file support – Define and update Synthetics settings using a synthetics.json file. This separation of configuration from script logic improves maintenance and reusability
+ Multiple tabs support – Create canaries that open multiple browser tabs and access screenshots from each tab. Build multi-tab and multi-step user workflows in Synthetics
+ Security fixes
+ Visual monitoring bug fixes
+ Added support for structured JSON logging with configurable log levels – Logs are now emitted in JSON format to enable easier parsing and querying in CloudWatch. Log level is configurable (for example, DEBUG, INFO, TRACE) through environment variables allowing users to control verbosity based on their needs
+ Support for ES syntax

### syn-nodejs-puppeteer-10.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-10.0"></a>

For more information, see the following:
+  [Puppeteer Change log](https://pptr.dev/CHANGELOG) 
+  [Puppeteer API reference](https://github.com/puppeteer/puppeteer/blob/puppeteer-v24.2.0/docs/api/index.md) 

**Major dependencies**:
+ Lambda runtime Node.js 20.x
+ Puppeteer-core version 24.2.0
+ Chromium version 131.0.6778.264

 **Changes in syn-nodejs-puppeteer-10.0** 
+ The bug related to closing the browser that took excessively long is fixed.
+ Supports dry runs for the canary which allows for adhoc executions or performing a safe canary update.

### syn-nodejs-puppeteer-9.1
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-9.1"></a>

**Major dependencies**:
+ Lambda runtime Node.js 20.x
+ Puppeteer-core version 22.12.1
+ Chromium version 126.0.6478.126

**Changes in syn-nodejs-puppeteer-9.1** – Bug fixes related to date ranges and pending requests in HAR files are fixed.

### syn-nodejs-puppeteer-9.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-9.0"></a>

**Major dependencies**:
+ Lambda runtime Node.js 20.x
+ Puppeteer-core version 22.12.1
+ Chromium version 126.0.6478.126

**Changes in syn-nodejs-puppeteer-9.0** – The bug fix to enable visual monitoring capabilities is fixed.

### syn-nodejs-puppeteer-8.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-8.0"></a>

**Warning**  
Because of a bug, the `syn-nodejs-puppeteer-8.0` runtime doesn't support visual monitoring in canaries. Upgrade to [syn-nodejs-puppeteer-9.0](#CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-9.0) for the bug fix for visual monitoring.

**Important**  
Lambda Node.js 18 and later runtimes use AWS SDK for JavaScript V3. If you need to migrate a canary from an earlier runtime, follow the [aws-sdk-js-v3 Migration Workshop](https://github.com/aws-samples/aws-sdk-js-v3-workshop) on GitHub. For more information about AWS SDK for JavaScript version 3, see [this blog post](https://aws.amazon.com/blogs/developer/modular-aws-sdk-for-javascript-is-now-generally-available/).

**Major dependencies**:
+ Lambda runtime Node.js 20.x
+ Puppeteer-core version 22.10.0
+ Chromium version 125.0.6422.112

**Updates in syn-nodejs-puppeteer-8.0**:
+  **Support for two-factor authentication** 
+ **Bug fixes** related to some service clients losing data in Node.js SDK V3 responses is fixed.

## Deprecated runtime versions for Node.js and Puppeteer
<a name="CloudWatch_Synthetics_nodejs-puppeteer-Deprecated"></a>

The following runtimes for Node.js and Puppeteer have been deprecated. For information about runtime deprecation dates, see [CloudWatch Synthetics runtime deprecation dates](CloudWatch_Synthetics_Runtime_Support_Policy.md#runtime_deprecation_dates).

### syn-nodejs-puppeteer-7.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-7.0"></a>

**Major dependencies**:
+ Lambda runtime Node.js 18.x
+ Puppeteer-core version 21.9.0
+ Chromium version 121.0.6167.139

**Code size**:

The size of code and dependencies that you can package into this runtime is 80 MB.

**Updates in syn-nodejs-puppeteer-7.0**:
+ **Updated versions of the bundled libraries in Puppeteer and Chromium**— The Puppeteer and Chromium dependencies are updated to new versions.
**Important**  
Moving from Puppeteer 19.7.0 to Puppeteer 21.9.0 introduces breaking changes regarding testing and filters. For more information, see the **BREAKING CHANGES** sections in [puppeteer: v20.0.0](https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-v20.0.0) and [puppeteer-core: v21.0.0](https://github.com/puppeteer/puppeteer/releases/tag/puppeteer-core-v21.0.0).

 **Recommended upgrade to AWS SDK v3** 

The Lambda nodejs18.x runtime doesn't support AWS SDK v2. We strongly recommend that you migrate to AWS SDK v3.

### syn-nodejs-puppeteer-6.2
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-6.2"></a>

**Major dependencies**:
+ Lambda runtime Node.js 18.x
+ Puppeteer-core version 19.7.0
+ Chromium version 111.0.5563.146

**Changes in syn-nodejs-puppeteer-6.2**:
+  **Updated versions of the bundled libraries in Chromium** 
+ **Ephemeral storage monitoring**— This runtime adds ephemeral storage monitoring in customer accounts.
+  **Bug fixes** 

### syn-nodejs-puppeteer-6.1
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-6.1"></a>

**Major dependencies**:
+ Lambda runtime Node.js 18.x
+ Puppeteer-core version 19.7.0
+ Chromium version 111.0.5563.146

**Updates in syn-nodejs-puppeteer-6.1**:
+ **Stability improvements**— Added auto-retry logic for handling intermittent Puppeteer launch errors.
+ **Dependency upgrades**— Upgrades for some third-party dependency packages.
+ **Canaries without Amazon S3 permissions**— Bug fixes, such that canaries that don't have any Amazon S3 permissions can still run. These canaries with no Amazon S3 permissions won't be able to upload screenshots or other artifacts to Amazon S3. For more information about permissions for canaries, see [Required roles and permissions for canaries](CloudWatch_Synthetics_Canaries_CanaryPermissions.md).

**Important**  
IMPORTANT: The included AWS SDK for JavaScript v2 dependency will be removed and updated to use AWS SDK for JavaScript v3 in a future runtime release. When that happens, you can update your canary code references. Alternatively, you can continue referencing and using the included AWS SDK for JavaScript v2 dependency by adding it as a dependency to your source code zip file.

### syn-nodejs-puppeteer-6.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-6.0"></a>

**Major dependencies**:
+ Lambda runtime Node.js 18.x
+ Puppeteer-core version 19.7.0
+ Chromium version 111.0.5563.146

**Updates in syn-nodejs-puppeteer-6.0**:
+ **Dependency upgrade**— The Node.js dependency is upgraded to 18.x.
+ **Intercept mode support**— Puppeteer cooperative intercept mode support was added to the Synthetics canary runtime library.
+ **Tracing behavior change**— Changed default tracing behavior to trace only fetch and xhr requests, and not trace resource requests. You can enable the tracing of resource requests by configuring the `traceResourceRequests` option.
+ **Duration metric refined**— The ` Duration` metric now excludes the operation time the canary uses to upload artifacts, take screenshots, and generate CloudWatch metrics. `Duration` metric values are reported to CloudWatch, and you can also see them in the Synthetics console.
+ **Bug fix**— Clean up core dump generated when Chromium crashes during a canary run.

**Important**  
IMPORTANT: The included AWS SDK for JavaScript v2 dependency will be removed and updated to use AWS SDK for JavaScript v3 in a future runtime release. When that happens, you can update your canary code references. Alternatively, you can continue referencing and using the included AWS SDK for JavaScript v2 dependency by adding it as a dependency to your source code zip file.

### syn-nodejs-puppeteer-5.2
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-5.2"></a>

**Major dependencies**:
+ Lambda runtime Node.js 16.x
+ Puppeteer-core version 19.7.0
+ Chromium version 111.0.5563.146

**Updates in syn-nodejs-puppeteer-5.2**:
+  **Updated versions of the bundled libraries in Chromium** 
+  **Bug fixes** 

### syn-nodejs-puppeteer-5.1
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-5.1"></a>

**Major dependencies**:
+ Lambda runtime Node.js 16.x
+ Puppeteer-core version 19.7.0
+ Chromium version 111.0.5563.146

**Bug fixes in syn-nodejs-puppeteer-5.1**:
+ **Bug fix**— This runtime fixes a bug in ` syn-nodejs-puppeteer-5.0` where the HAR files created by the canaries were missing request headers.

### syn-nodejs-puppeteer-5.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-5.0"></a>

**Major dependencies**:
+ Lambda runtime Node.js 16.x
+ Puppeteer-core version 19.7.0
+ Chromium version 111.0.5563.146

**Updates in syn-nodejs-puppeteer-5.0**:
+ **Dependency upgrade**— The Puppeteer-core version is updated to 19.7.0. The Chromium version is upgraded to 111.0.5563.146.

**Important**  
The new Puppeteer-core version is not completely backward-compatible with previous versions of Puppeteer. Some of the changes in this version can cause existing canaries that use deprecated Puppeteer functions to fail. For more information, see the breaking changes in the change logs for Puppeteer-core versions 19.7.0 through 6.0, in [Puppeteer change logs](https://github.com/puppeteer/puppeteer/releases?q=breaking&expanded=true).

### syn-nodejs-puppeteer-4.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-4.0"></a>

**Major dependencies**:
+ Lambda runtime Node.js 16.x
+ Puppeteer-core version 5.5.0
+ Chromium version 92.0.4512

**Updates in syn-nodejs-puppeteer-4.0**:
+ **Dependency upgrade**— The Node.js dependency is updated to 16.x.

### syn-nodejs-puppeteer-3.9
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.9"></a>

**Important**  
This runtime version was deprecated on January 8, 2024. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 14.x
+ Puppeteer-core version 5.5.0
+ Chromium version 92.0.4512

**Updates in syn-nodejs-puppeteer-3.9**:
+ **Dependency upgrades**— Upgrades some third-party dependency packages.

### syn-nodejs-puppeteer-3.8
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.8"></a>

**Important**  
This runtime version was deprecated on January 8, 2024. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 14.x
+ Puppeteer-core version 5.5.0
+ Chromium version 92.0.4512

**Updates in syn-nodejs-puppeteer-3.8**:
+ **Profile cleanup**— Chromium profiles are now cleaned up after each canary run.

**Bug fixes in syn-nodejs-puppeteer-3.8**:
+ **Bug fixes**— Previously, visual monitoring canaries would sometimes stop working properly after a run with no screenshots. This is now fixed.

### syn-nodejs-puppeteer-3.7
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.7"></a>

**Important**  
This runtime version was deprecated on January 8, 2024. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 14.x
+ Puppeteer-core version 5.5.0
+ Chromium version 92.0.4512

**Updates in syn-nodejs-puppeteer-3.7**:
+ **Logging enhancement**— The canary will upload logs to Amazon S3 even if it times out or crashes.
+ **Lambda layer size reduced**— The size of the Lambda layer used for canaries is reduced by 34%.

**Bug fixes in syn-nodejs-puppeteer-3.7**:
+ **Bug fixes**— Japanese, Simplified Chinese, and Traditional Chinese fonts will render properly.

### syn-nodejs-puppeteer-3.6
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.6"></a>

**Important**  
This runtime version was deprecated on January 8, 2024. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 14.x
+ Puppeteer-core version 5.5.0
+ Chromium version 92.0.4512

**Updates in syn-nodejs-puppeteer-3.6**:
+ **More precise timestamps**— The start time and stop time of canary runs are now precise to the millisecond.

### syn-nodejs-puppeteer-3.5
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.5"></a>

**Important**  
This runtime version was deprecated on January 8, 2024. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 14.x
+ Puppeteer-core version 5.5.0
+ Chromium version 92.0.4512

**Updates in syn-nodejs-puppeteer-3.5**:
+ **Updated dependencies**— The only new features in this runtime are the updated dependencies.

### syn-nodejs-puppeteer-3.4
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.4"></a>

**Important**  
This runtime version was deprecated on November 13, 2022. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 12.x
+ Puppeteer-core version 5.5.0
+ Chromium version 88.0.4298.0

**Updates in syn-nodejs-puppeteer-3.4**:
+ **Custom handler function**— You can now use a custom handler function for your canary scripts. Previous runtimes required the script entry point to include `.handler`. 

  You can also put canary scripts in any folder and pass the folder name as part of the handler. For example, `MyFolder/MyScriptFile.functionname` can be used as an entry point.
+ **Expanded HAR file information**— You can now see bad, pending, and incomplete requests in the HAR files produced by canaries.

### syn-nodejs-puppeteer-3.3
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.3"></a>

**Important**  
This runtime version was deprecated on November 13, 2022. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 12.x
+ Puppeteer-core version 5.5.0
+ Chromium version 88.0.4298.0

**Updates in syn-nodejs-puppeteer-3.3**:
+ **More options for artifact encryption**— For canaries using this runtime or later, instead of using an AWS managed key to encrypt artifacts that the canary stores in Amazon S3, you can choose to use an AWS KMS customer managed key or an Amazon S3-managed key. For more information, see [Encrypting canary artifacts](CloudWatch_Synthetics_artifact_encryption.md). 

### syn-nodejs-puppeteer-3.2
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.2"></a>

**Important**  
This runtime version was deprecated on November 13, 2022. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 12.x
+ Puppeteer-core version 5.5.0
+ Chromium version 88.0.4298.0

**Updates in syn-nodejs-puppeteer-3.2**:
+ **visual monitoring with screenshots**— Canaries using this runtime or later can compare a screenshot taken during a run with a baseline version of the same screenshot. If the screenshots are more different than a specified percentage threshold, the canary fails. For more information, see [Visual monitoring](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_SyntheticsLogger_VisualTesting) or [Visual monitoring blueprint](CloudWatch_Synthetics_Canaries_Blueprints.md#CloudWatch_Synthetics_Canaries_Blueprints_VisualTesting). 
+ **New functions regarding sensitive data** You can prevent sensitive data from appearing in canary logs and reports. For more information, see [SyntheticsLogHelper class](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_SyntheticsLogHelper).
+ **Deprecated function** The ` RequestResponseLogHelper` class is deprecated in favor of other new configuration options. For more information, see [RequestResponseLogHelper class](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_RequestResponseLogHelper).

### syn-nodejs-puppeteer-3.1
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.1"></a>

**Important**  
This runtime version was deprecated on November 13, 2022. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 12.x
+ Puppeteer-core version 5.5.0
+ Chromium version 88.0.4298.0

**Updates in syn-nodejs-puppeteer-3.1**:
+ **Ability to configure CloudWatch metrics**— With this runtime, you can disable the metrics that you do not require. Otherwise, canaries publish various CloudWatch metrics for each canary run.
+ **Screenshot linking**— You can link a screenshot to a canary step after the step has completed. To do this, you take the screenshot by using the **takeScreenshot** method, using the name of the step that you want to associate the screenshot with. For example, you might want to perform a step, add a wait time, and then take the screenshot.
+ **Heartbeat monitor blueprint can monitor multiple URLs**— You can use the heartbeat monitoring blueprint in the CloudWatch console to monitor multiple URLs and see the status, duration, associated screenshots, and failure reason for each URL in the step summary of the canary run report.

### syn-nodejs-puppeteer-3.0
<a name="CloudWatch_Synthetics_runtimeversion-nodejs-puppeteer-3.0"></a>

**Important**  
This runtime version was deprecated on November 13, 2022. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 12.x
+ Puppeteer-core version 5.5.0
+ Chromium version 88.0.4298.0

**Updates in syn-nodejs-puppeteer-3.0**:
+ **Upgraded dependencies**— This version uses Puppeteer version 5.5.0, Node.js 12.x, and Chromium 88.0.4298.0.
+ **Cross-Region bucket access**— You can now specify an S3 bucket in another Region as the bucket where your canary stores its log files, screenshots, and HAR files.
+ **New functions available**— This version adds library functions to retrieve the canary name and the Synthetics runtime version.

  For more information, see [Synthetics class](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_Synthetics_Class_all).

### syn-nodejs-2.2
<a name="CloudWatch_Synthetics_runtimeversion-2.2"></a>

This section contains information about the `syn-nodejs-2.2` runtime version.

**Important**  
This runtime version was deprecated on May 28, 2021. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 10.x
+ Puppeteer-core version 3.3.0
+ Chromium version 83.0.4103.0

**Changes in syn-nodejs-2.2**:
+ **Monitor your canaries as HTTP steps**— You can now test multiple APIs in a single canary. Each API is tested as a separate HTTP step, and CloudWatch Synthetics monitors the status of each step using step metrics and the CloudWatch Synthetics step report. CloudWatch Synthetics creates ` SuccessPercent` and `Duration` metrics for each HTTP step.

  This functionality is implemented by the **executeHttpStep(stepName, requestOptions, callback, stepConfig)** function. For more information, see [executeHttpStep(stepName, requestOptions, [callback], [stepConfig])](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_executeHttpStep).

  The API canary blueprint is updated to use this new feature.
+ **HTTP request reporting**— You can now view detailed HTTP requests reports which capture details such as request/response headers, response body, status code, error and performance timings, TCP connection time, TLS handshake time, first byte time, and content transfer time. All HTTP requests which use the HTTP/HTTPS module under the hood are captured here. Headers and response body are not captured by default but can be enabled by setting configuration options.
+ **Global and step-level configuration**— You can set CloudWatch Synthetics configurations at the global level, which are applied to all steps of canaries. You can also override these configurations at the step level by passing configuration key/value pairs to enable or disable certain options.

  For more information, see [SyntheticsConfiguration class](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_SyntheticsConfiguration).
+ **Continue on step failure configuration**— You can choose to continue canary execution when a step fails. For the ` executeHttpStep` function, this is turned on by default. You can set this option once at global level or set it differently per-step. 

### syn-nodejs-2.1
<a name="CloudWatch_Synthetics_runtimeversion-2.1"></a>

**Important**  
This runtime version was deprecated on May 28, 2021. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 10.x
+ Puppeteer-core version 3.3.0
+ Chromium version 83.0.4103.0

**Updates in syn-nodejs-2.1**:
+ **Configurable screenshot behavior**— Provides the ability to turn off the capturing of screenshots by UI canaries. In canaries that use previous versions of the runtimes, UI canaries always capture screenshots before and after each step. With `syn-nodejs-2.1`, this is configurable. Turning off screenshots can reduce your Amazon S3 storage costs, and can help you comply with HIPAA regulations. For more information, see [SyntheticsConfiguration class](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_SyntheticsConfiguration).
+ **Customize the Google Chrome launch parameters** You can now configure the arguments used when a canary launches a Google Chrome browser window. For more information, see [launch(options)](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_LaunchOptions).

There can be a small increase in canary duration when using syn-nodejs-2.0 or later, compared to earlier versions of the canary runtimes.

### syn-nodejs-2.0
<a name="CloudWatch_Synthetics_runtimeversion-2.0"></a>

**Important**  
This runtime version was deprecated on May 28, 2021. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 10.x
+ Puppeteer-core version 3.3.0
+ Chromium version 83.0.4103.0

**Updates in syn-nodejs-2.0**:
+ **Upgraded dependencies**— This runtime version uses Puppeteer-core version 3.3.0 and Chromium version 83.0.4103.0
+ **Support for X-Ray active tracing.** When a canary has tracing enabled, X-Ray traces are sent for all calls made by the canary that use the browser, the AWS SDK, or HTTP or HTTPS modules. Canaries with tracing enabled appear on the X-Ray Trace Map, even when they don't send requests to other services or applications that have tracing enabled. For more information, see [Canaries and X-Ray tracing](CloudWatch_Synthetics_Canaries_tracing.md).
+ **Synthetics reporting**— For each canary run, CloudWatch Synthetics creates a report named ` SyntheticsReport-PASSED.json` or ` SyntheticsReport-FAILED.json` which records data such as start time, end time, status, and failures. It also records the PASSED/FAILED status of each step of the canary script, and failures and screenshots captured for each step.
+ **Broken link checker report**— The new version of the broken link checker included in this runtime creates a report that includes the links that were checked, status code, failure reason (if any), and source and destination page screenshots.
+ **New CloudWatch metrics**— Synthetics publishes metrics named `2xx`, `4xx`, `5xx`, and `RequestFailed` in the `CloudWatchSynthetics` namespace. These metrics show the number of 200s, 400s, 500s, and request failures in the canary runs. With this runtime version, these metrics are reported only for UI canaries, and are not reported for API canaries. They are also reported for API canaries starting with runtime version ` syn-nodejs-puppeteeer-2.2`.
+ **Sortable HAR files**— You can now sort your HAR files by status code, request size, and duration.
+ **Metrics timestamp**— CloudWatch metrics are now reported based on the Lambda invocation time instead of the canary run end time.

**Bug fixes in syn-nodejs-2.0**:
+ Fixed the issue of canary artifact upload errors not being reported. Such errors are now surfaced as execution errors.
+ Fixed the issue of redirected requests (3xx) being incorrectly logged as errors.
+ Fixed the issue of screenshots being numbered starting from 0. They should now start with 1.
+ Fixed the issue of screenshots being garbled for Chinese and Japanese fonts.

There can be a small increase in canary duration when using syn-nodejs-2.0 or later, compared to earlier versions of the canary runtimes.

### syn-nodejs-2.0-beta
<a name="CloudWatch_Synthetics_runtimeversion-2.0-beta"></a>

**Important**  
This runtime version was deprecated on February 8, 2021. For more information, see [Runtime versions support policy](CloudWatch_Synthetics_Runtime_Support_Policy.md).

**Major dependencies**:
+ Lambda runtime Node.js 10.x
+ Puppeteer-core version 3.3.0
+ Chromium version 83.0.4103.0

**Changes in syn-nodejs-2.0-beta**:
+ **Upgraded dependencies**— This runtime version uses Puppeteer-core version 3.3.0 and Chromium version 83.0.4103.0
+ **Synthetics reporting**— For each canary run, CloudWatch Synthetics creates a report named ` SyntheticsReport-PASSED.json` or ` SyntheticsReport-FAILED.json` which records data such as start time, end time, status, and failures. It also records the PASSED/FAILED status of each step of the canary script, and failures and screenshots captured for each step.
+ **Broken link checker report**— The new version of the broken link checker included in this runtime creates a report that includes the links that were checked, status code, failure reason (if any), and source and destination page screenshots.
+ **New CloudWatch metrics**— Synthetics publishes metrics named `2xx`, `4xx`, `5xx`, and `RequestFailed` in the `CloudWatchSynthetics` namespace. These metrics show the number of 200s, 400s, 500s, and request failures in the canary runs. These metrics are reported only for UI canaries, and are not reported for API canaries.
+ **Sortable HAR files**— You can now sort your HAR files by status code, request size, and duration.
+ **Metrics timestamp**— CloudWatch metrics are now reported based on the Lambda invocation time instead of the canary run end time.

**Bug fixes in syn-nodejs-2.0-beta**:
+ Fixed the issue of canary artifact upload errors not being reported. Such errors are now surfaced as execution errors.
+ Fixed the issue of redirected requests (3xx) being incorrectly logged as errors.
+ Fixed the issue of screenshots being numbered starting from 0. They should now start with 1.
+ Fixed the issue of screenshots being garbled for Chinese and Japanese fonts.

### syn-1.0
<a name="CloudWatch_Synthetics_runtimeversion-1.0"></a>

The first Synthetics runtime version is `syn-1.0`.

**Major dependencies**:
+ Lambda runtime Node.js 10.x
+ Puppeteer-core version 1.14.0
+ The Chromium version that matches Puppeteer-core 1.14.0

# Runtime versions using Python and Selenium Webdriver
<a name="CloudWatch_Synthetics_Library_python_selenium"></a>

The following sections contain information about the CloudWatch Synthetics runtime versions for Python and Selenium Webdriver. Selenium is an open-source browser automation tool. For more information about Selenium, see [ www.selenium.dev/](https://www.selenium.dev)

For features and methods supported by Synthetics runtime on Selenium framework, see [Python and Selenium library classes and functions that apply to UI canaries only ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library_Python.html#CloudWatch_Synthetics_Library_Python_UIcanaries) and [Selenium API reference](https://www.selenium.dev/selenium/docs/api/py/api.html).

The naming convention for these runtime versions is `syn-language -framework-majorversion. minorversion`.

## syn-python-selenium-10.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-10.0"></a>

Version 10.0 is the newest CloudWatch Synthetics runtime for Python and Selenium.

**Major dependencies**:
+ Python 3.11
+ Selenium 4.32.0
+ Chromium version 145.0.7632.77

**Changes in syn-python-selenium-10.0 ** 
+ Applied security patches and updated browser versions.

For more information, see the following:
+  [Selenium Change log](https://www.selenium.dev/blog/2025/selenium-4-32-released) 
+  [Selenium documentation](https://www.selenium.dev/selenium/docs/api/py/api.html) 

## Previous runtime versions for Python and Selenium
<a name="Previousversions-python-selenium"></a>

The following earlier runtime versions for Python and Selenium are still supported. 

### syn-python-selenium-9.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-9.0"></a>

**Major dependencies**:
+ Python 3.11
+ Selenium 4.32.0
+ Chromium version 143.0.7499.169

**Changes in syn-python-selenium-9.0 ** 
+ Applied security patches and updated browser versions.

For more information, see the following:
+  [Selenium Change log](https://www.selenium.dev/blog/2025/selenium-4-32-released) 
+  [Selenium documentation](https://www.selenium.dev/selenium/docs/api/py/api.html) 

### syn-python-selenium-8.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-8.0"></a>

Version 8.0 is the newest CloudWatch Synthetics runtime for Python and Selenium.

**Major dependencies**:
+ Python 3.11
+ Selenium 4.32.0
+ Chromium version 142.0.7444.175

**Changes in syn-python-selenium-8.0 ** 
+ Applied security patches and updated Selenium and browser versions.
+ Modified failed HAR network request log level from ERROR to INFO.

For more information, see the following:
+  [Selenium Change log](https://www.selenium.dev/blog/2025/selenium-4-32-released) 
+  [Selenium documentation](https://www.selenium.dev/selenium/docs/api/py/api.html) 

### syn-python-selenium-7.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-7.0"></a>

**Major dependencies**:
+ Python 3.11
+ Selenium 4.32.0
+ Chromium version 138.0.7204.168

 **Changes in syn-python-selenium-7.0 ** 
+ Applied security patches and updated Selenium and browser versions.

For more information, see the following:
+  [Selenium Change log](https://www.selenium.dev/blog/2025/selenium-4-32-released) 
+  [Selenium documentation](https://www.selenium.dev/selenium/docs/api/py/api.html) 

### syn-python-selenium-6.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-6.0"></a>

**Major dependencies**:
+ Python 3.11
+ Selenium 4.21.0
+ Chromium version 131.0.6778.264

 **Changes in syn-python-selenium-6.0** 
+ Upgrade from Python 3.9 to Python 3.11.

For more information, see the following:
+  [Selenium Change log](https://www.selenium.dev/blog/2024/selenium-4-21-released/) 
+  [Selenium documentation](https://www.selenium.dev/selenium/docs/api/py/api.html) 

### syn-python-selenium-5.1
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-5.1"></a>

**Major dependencies**:
+ Python 3.9
+ Selenium 4.21.0
+ Chromium version 131.0.6778.264

 **Changes in syn-python-selenium-5.1** 
+ Minor updates on metric emission.
+ Supports dry runs for the canary which allows for adhoc executions or performing a safe canary update.

### syn-python-selenium-5.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-5.0"></a>

**Major dependencies**:
+ Python 3.9
+ Selenium 4.21.0
+ Chromium version 131.0.6778.264

**Changes in syn-python-selenium-5.0**:
+ Automatic retry if the browser fails to launch.

### syn-python-selenium-4.1
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-4.1"></a>

**Major dependencies**:
+ Python 3.9
+ Selenium 4.15.1
+ Chromium version 126.0.6478.126

**Changes in syn-python-selenium-4.1**:
+ **Addresses security vulnerability**– This runtime has an update to address the [CVE-2024-39689](https://nvd.nist.gov/vuln/detail/CVE-2024-39689) vulnerability.

### syn-python-selenium-4.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-4.0"></a>

**Major dependencies**:
+ Python 3.9
+ Selenium 4.15.1
+ Chromium version 126.0.6478.126

**Changes in syn-python-selenium-4.0**:
+ **Bug fixes** for errors in HAR parser logging.

## Deprecated runtime versions for Python and Selenium
<a name="Deprecated-python-selenium"></a>

The following earlier runtime versions for Python and Selenium have been deprecated. For information about runtime deprecation dates, see [CloudWatch Synthetics runtime deprecation dates](CloudWatch_Synthetics_Runtime_Support_Policy.md#runtime_deprecation_dates).

### syn-python-selenium-3.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-3.0"></a>

**Major dependencies**:
+ Python 3.8
+ Selenium 4.15.1
+ Chromium version 121.0.6167.139

**Changes in syn-python-selenium-3.0**:
+ **Updated versions of the bundled libraries in Chromium**— The Chromium dependency is updated to a new version.

### syn-python-selenium-2.1
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-2.1"></a>

**Major dependencies**:
+ Python 3.8
+ Selenium 4.15.1
+ Chromium version 111.0.5563.146

**Changes in syn-python-selenium-2.1**:
+ **Updated versions of the bundled libraries in Chromium**— The Chromium and Selenium dependencies are updated to new versions.

### syn-python-selenium-2.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-2.0"></a>

**Major dependencies**:
+ Python 3.8
+ Selenium 4.10.0
+ Chromium version 111.0.5563.146

**Changes in syn-python-selenium-2.0**:
+ **Updated dependencies**— The Chromium and Selenium dependencies are updated to new versions.

**Bug fixes in syn-python-selenium-2.0**:
+ **Timestamp added**— A timestamp has been added to canary logs.
+ **Session re-use**— A bug was fixed so that canaries are now prevented from reusing the session from their previous canary run.

### syn-python-selenium-1.3
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-1.3"></a>

**Major dependencies**:
+ Python 3.8
+ Selenium 3.141.0
+ Chromium version 92.0.4512.0

**Changes in syn-python-selenium-1.3**:
+ **More precise timestamps**— The start time and stop time of canary runs are now precise to the millisecond.

### syn-python-selenium-1.2
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-1.2"></a>

**Major dependencies**:
+ Python 3.8
+ Selenium 3.141.0
+ Chromium version 92.0.4512.0
+ **Updated dependencies**— The only new features in this runtime are the updated dependencies.

### syn-python-selenium-1.1
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-1.1"></a>

**Major dependencies**:
+ Python 3.8
+ Selenium 3.141.0
+ Chromium version 83.0.4103.0

**Features**:
+ **Custom handler function**— You can now use a custom handler function for your canary scripts. Previous runtimes required the script entry point to include `.handler`. 

  You can also put canary scripts in any folder and pass the folder name as part of the handler. For example, `MyFolder/MyScriptFile.functionname` can be used as an entry point.
+ **Configuration options for adding metrics and step failure configurations**— These options were already available in runtimes for Node.js canaries. For more information, see [SyntheticsConfiguration class](CloudWatch_Synthetics_Canaries_Library_Python.md#CloudWatch_Synthetics_Library_SyntheticsConfiguration_Python) .
+ **Custom arguments in Chrome **— You can now open a browser in incognito mode or pass in proxy server configuration. For more information, see [Chrome()](CloudWatch_Synthetics_Canaries_Library_Python.md#CloudWatch_Synthetics_Library_Python_Chrome).
+ **Cross-Region artifact buckets**— A canary can store its artifacts in an Amazon S3 bucket in a different Region.
+ **Bug fixes, including a fix for the `index.py` issue**— With previous runtimes, a canary file named ` index.py` caused exceptions because it conflicted with the name of the library file. This issue is now fixed.

### syn-python-selenium-1.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-python-selenium-1.0"></a>

**Major dependencies**:
+ Python 3.8
+ Selenium 3.141.0
+ Chromium version 83.0.4103.0

**Features**:
+ **Selenium support**— You can write canary scripts using the Selenium test framework. You can bring your Selenium scripts from elsewhere into CloudWatch Synthetics with minimal changes, and they will work with AWS services.

# Runtime versions using Node.js
<a name="CloudWatch_Synthetics_Library_Nodejs"></a>

The following section contains information about the CloudWatch Synthetics runtime versions for Node.js. This runtime does not have any browser or framework included.

The naming convention for these runtime versions is `syn-language -majorversion.minorversion`.

## syn-nodejs-4.1
<a name="CloudWatch_Synthetics_runtimeversion-syn-nodejs-4.1"></a>

**Important**  
Starting Synthetics `syn-nodejs-3.1` and later, Synthetics runtime uses the new namespace. Please migrate the canary script to use the new namespace. Legacy namespace will be deprecated in a future release.  
@amzn/synthetics-core → @aws/synthetics-core

**Major dependencies**:
+ AWS Lambda runtime Node.js 22.x

 **Changes in syn-nodejs-4.1** 
+ Upgrade `fast-xml-parser` to 5.5.7 to address the following CVEs:
  + CVE-2026-25128
  + CVE-2026-25896
  + CVE-2026-26278
  + CVE-2026-27942
  + CVE-2026-33036

## Previous runtime versions for Node.js
<a name="Previousversions-nodejs"></a>

The following earlier runtime versions for Node.js are still supported. 

### syn-nodejs-4.0
<a name="CloudWatch_Synthetics_runtimeversion-syn-nodejs-4.0"></a>

**Major dependencies**:
+ AWS Lambda runtime Node.js 22.x

 **Changes in syn-nodejs-4.0** 
+ Applied security patches. 

### syn-nodejs-3.1
<a name="CloudWatch_Synthetics_runtimeversion-syn-nodejs-3.1"></a>

**Important**  
Starting Synthetics `syn-nodejs-3.1` and later, Synthetics runtime uses the new namespace. Please migrate the canary script to use the new namespace. Legacy namespace will be deprecated in a future release.  
@amzn/synthetics-core → @aws/synthetics-core

**Major dependencies**:
+ AWS Lambda runtime Node.js 20.x

 **Changes in syn-nodejs-3.1** 
+ Synthetics runtime namespace migration. 
+ Type definition is available in [npm Registry](https://www.npmjs.com/package/@aws/synthetics-core). Please ensure the type definition package version matches your canary's runtime version.

### syn-nodejs-3.0
<a name="Synthetics_runtimeversion-syn-nodejs-3.0"></a>

**Major dependencies**:
+ AWS Lambda runtime Node.js 20.x

 **Changes in syn-nodejs-3.0** 
+ Support for multi checks blueprint. 

# Runtime versions support policy
<a name="CloudWatch_Synthetics_Runtime_Support_Policy"></a>

Synthetics runtime versions are subject to maintenance and security updates. When any component of a runtime version is no longer supported, that Synthetics runtime version is deprecated.

You can't create canaries using deprecated runtime versions. Canaries that use deprecated runtimes continue to run. You can stop, start, and delete these canaries. You can update an existing canary that uses a deprecated runtime version by updating the canary to use a supported runtime version.

CloudWatch Synthetics notifies you by email if you have canaries that use runtimes that are scheduled to be deprecated in the next 60 days. We recommend that you migrate your canaries to a supported runtime version to benefit from the new functionality, security, and performance enhancements that are included in more recent releases. 

## CloudWatch Synthetics runtime deprecation dates
<a name="runtime_deprecation_dates"></a>

The following table lists the date of deprecation of each deprecated CloudWatch Synthetics runtime.


| Runtime Version | Deprecation date | 
| --- | --- | 
|   `syn-python-selenium-5.1`   |  February 3, 2026  | 
|   `syn-python-selenium-5.0`   |  February 3, 2026  | 
|   `syn-python-selenium-4.1`   |  February 3, 2026  | 
|   `syn-python-selenium-4.0`   |  February 3, 2026  | 
|   `syn-nodejs-puppeteer-7.0`   |  January 22, 2026  | 
|   `syn-nodejs-puppeteer-6.2`   |  January 22, 2026  | 
|   `syn-nodejs-puppeteer-5.2`   |  January 22, 2026  | 
|   `syn-python-selenium-3.0`   |  January 22, 2026  | 
|   `syn-python-selenium-2.1`   |  January 22, 2026  | 
|   `syn-nodejs-puppeteer-6.1`   |  March 8, 2024  | 
|   `syn-nodejs-puppeteer-6.0`   |  March 8, 2024  | 
|   `syn-nodejs-puppeteer-5.1`   |  March 8, 2024  | 
|   `syn-nodejs-puppeteer-5.0`   |  March 8, 2024  | 
|   `syn-nodejs-puppeteer-4.0`   |  March 8, 2024  | 
|   `syn-nodejs-puppeteer-3.9`   |  January 8, 2024  | 
|   `syn-nodejs-puppeteer-3.8`   |  January 8, 2024  | 
|   `syn-python-selenium-2.0`   |  March 8, 2024  | 
|   `syn-python-selenium-1.3`   |  March 8, 2024  | 
|   `syn-python-selenium-1.2`   |  March 8, 2024  | 
|   `syn-python-selenium-1.1`   |  March 8, 2024  | 
|   `syn-python-selenium-1.0`   |  March 8, 2024  | 
|   `syn-nodejs-puppeteer-3.7`   |  January 8, 2024  | 
|   `syn-nodejs-puppeteer-3.6`   |  January 8, 2024  | 
|   `syn-nodejs-puppeteer-3.5`   |  January 8, 2024  | 
|   `syn-nodejs-puppeteer-3.4`   |  November 13, 2022  | 
|   `syn-nodejs-puppeteer-3.3`   |  November 13, 2022  | 
|   `syn-nodejs-puppeteer-3.2`   |  November 13, 2022  | 
|   `syn-nodejs-puppeteer-3.1`   |  November 13, 2022  | 
|   `syn-nodejs-puppeteer-3.0`   |  November 13, 2022  | 
|   `syn-nodejs-2.2`   |  May 28, 2021  | 
|   `syn-nodejs-2.1`   |  May 28, 2021  | 
|   `syn-nodejs-2.0`   |  May 28, 2021  | 
|   `syn-nodejs-2.0-beta`   |  February 8, 2021  | 
|   `syn-1.0`   |  May 28, 2021  | 

# Runtime versions update
<a name="CloudWatch_Synthetics_Runtime_Version_Update"></a>

You can update a canary’s runtime version by using the CloudWatch console, AWS CloudFormation, the AWS CLI or the AWS SDK. When you use the CloudWatch console, you can update up to five canaries at once by selecting them in the canary list page and then choosing **Actions** , **Update Runtime**.

You can verify the update by testing it first before committing the runtime update. When updating the runtime versions, choose the **Start Dry Run** or **Validate and save later** options in the CloudWatch console to create a dry run of the original canary along with any changes you made to the configuration. The dry run will update and execute the canary to validate whether the runtime update is safe for the canary. Once you have verified your canary with the new runtime version, you can update the runtime version of your canary. For more information, see [Performing safe canary updates](performing-safe-canary-upgrades.md).

Alternatively, you can verify the update by first cloning the canary using the CloudWatch console and updating the runtime version. This creates another canary which is a clone of your original canary. Once you have verified your canary with the new runtime version, you can update the runtime version of your original canary and delete the clone canary.

 You can also update multiple canaries using an upgrade script. For more information, see [Canary runtime upgrade script](#CloudWatch_Synthetics_Canaries_upgrade_script).

If you upgrade a canary and it fails, see [Troubleshooting a failed canary](CloudWatch_Synthetics_Canaries_Troubleshoot.md).

## Canary runtime upgrade script
<a name="CloudWatch_Synthetics_Canaries_upgrade_script"></a>

To upgrade a canary script to a supported runtime version, use the following script.

```
const AWS = require('aws-sdk');

// You need to configure your AWS credentials and Region.
//   https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html
//   https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-region.html

const synthetics = new AWS.Synthetics();

const DEFAULT_OPTIONS = {
  /**
   * The number of canaries to upgrade during a single run of this script.
   */
  count: 10,
  /**
   * No canaries are upgraded unless force is specified.
   */
  force: false
};

/**
 * The number of milliseconds to sleep between GetCanary calls when
 * verifying that an update succeeded.
 */
const SLEEP_TIME = 5000;

(async () => {
  try {
    const options = getOptions();

    const versions = await getRuntimeVersions();
    const canaries = await getAllCanaries();
    const upgrades = canaries
      .filter(canary => !versions.isLatestVersion(canary.RuntimeVersion))
      .map(canary => {
        return {
          Name: canary.Name,
          FromVersion: canary.RuntimeVersion,
          ToVersion: versions.getLatestVersion(canary.RuntimeVersion)
        };
      });

    if (options.force) {
      const promises = [];

      for (const upgrade of upgrades.slice(0, options.count)) {
        const promise = upgradeCanary(upgrade);
        promises.push(promise);
        // Sleep for 100 milliseconds to avoid throttling.
        await usleep(100);
      }

      const succeeded = [];
      const failed = [];
      for (let i = 0; i < upgrades.slice(0, options.count).length; i++) {
        const upgrade = upgrades[i];
        const promise = promises[i];
        try {
          await promise;
          console.log(`The update of ${upgrade.Name} succeeded.`);
          succeeded.push(upgrade.Name);
        } catch (e) {
          console.log(`The update of ${upgrade.Name} failed with error: ${e}`);
          failed.push({
            Name: upgrade.Name,
            Reason: e
          });
        }
      }

      if (succeeded.length) {
        console.group('The following canaries were upgraded successfully.');
        for (const name of succeeded) {
          console.log(name);
        }
        console.groupEnd()
      } else {
        console.log('No canaries were upgraded successfully.');
      }

      if (failed.length) {
        console.group('The following canaries were not upgraded successfully.');
        for (const failure of failed) {
          console.log('\x1b[31m', `${failure.Name}: ${failure.Reason}`, '\x1b[0m');
        }
        console.groupEnd();
      }
    } else {
      console.log('Run with --force [--count <count>] to perform the first <count> upgrades shown. The default value of <count> is 10.')
      console.table(upgrades);
    }
  } catch (e) {
    console.error(e);
  }
})();

function getOptions() {
  const force = getFlag('--force', DEFAULT_OPTIONS.force);
  const count = getOption('--count', DEFAULT_OPTIONS.count);
  return { force, count };

  function getFlag(key, defaultValue) {
    return process.argv.includes(key) || defaultValue;
  }
  function getOption(key, defaultValue) {
    const index = process.argv.indexOf(key);
    if (index < 0) {
      return defaultValue;
    }
    const value = process.argv[index + 1];
    if (typeof value === 'undefined' || value.startsWith('-')) {
      throw `The ${key} option requires a value.`;
    }
    return value;
  }
}

function getAllCanaries() {
  return new Promise((resolve, reject) => {
    const canaries = [];

    synthetics.describeCanaries().eachPage((err, data) => {
      if (err) {
        reject(err);
      } else {
        if (data === null) {
          resolve(canaries);
        } else {
          canaries.push(...data.Canaries);
        }
      }
    });
  });
}

function getRuntimeVersions() {
  return new Promise((resolve, reject) => {
    const jsVersions = [];
    const pythonVersions = [];
    synthetics.describeRuntimeVersions().eachPage((err, data) => {
      if (err) {
        reject(err);
      } else {
        if (data === null) {
          jsVersions.sort((a, b) => a.ReleaseDate - b.ReleaseDate);
          pythonVersions.sort((a, b) => a.ReleaseDate - b.ReleaseDate);
          resolve({
            isLatestVersion(version) {
              const latest = this.getLatestVersion(version);
              return latest === version;
            },
            getLatestVersion(version) {
              if (jsVersions.some(v => v.VersionName === version)) {
                return jsVersions[jsVersions.length - 1].VersionName;
              } else if (pythonVersions.some(v => v.VersionName === version)) {
                return pythonVersions[pythonVersions.length - 1].VersionName;
              } else {
                throw Error(`Unknown version ${version}`);
              }
            }
          });
        } else {
          for (const version of data.RuntimeVersions) {
            if (version.VersionName === 'syn-1.0') {
              jsVersions.push(version);
            } else if (version.VersionName.startsWith('syn-nodejs-2.')) {
              jsVersions.push(version);
            } else if (version.VersionName.startsWith('syn-nodejs-puppeteer-')) {
              jsVersions.push(version);
            } else if (version.VersionName.startsWith('syn-python-selenium-')) {
              pythonVersions.push(version);
            } else {
              throw Error(`Unknown version ${version.VersionName}`);
            }
          }
        }
      }
    });
  });
}

async function upgradeCanary(upgrade) {
  console.log(`Upgrading canary ${upgrade.Name} from ${upgrade.FromVersion} to ${upgrade.ToVersion}`);
  await synthetics.updateCanary({ Name: upgrade.Name, RuntimeVersion: upgrade.ToVersion }).promise();
  while (true) {
    await usleep(SLEEP_TIME);
    console.log(`Getting the state of canary ${upgrade.Name}`);
    const response = await synthetics.getCanary({ Name: upgrade.Name }).promise();
    const state = response.Canary.Status.State;
    console.log(`The state of canary ${upgrade.Name} is ${state}`);
    if (state === 'ERROR' || response.Canary.Status.StateReason) {
      throw response.Canary.Status.StateReason;
    }
    if (state !== 'UPDATING') {
      return;
    }
  }
}

function usleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
```

# Writing a canary script
<a name="CloudWatch_Synthetics_Canaries_WritingCanary"></a>

The following sections explain how to write a canary script and how to integrate a canary with other AWS services and with external dependencies and libraries.

**Topics**
+ [

# Writing a canary script using the Java runtime
](Synthetics_WritingCanary_Java.md)
+ [

# Writing a Node.js canary script using the Playwright runtime
](Synthetics_WritingCanary_Nodejs_Playwright.md)
+ [

# Writing a Node.js canary script using the Puppeteer runtime
](CloudWatch_Synthetics_Canaries_WritingCanary_Nodejs_Pup.md)
+ [

# Writing a Python canary script
](CloudWatch_Synthetics_Canaries_WritingCanary_Python.md)
+ [

# Writing a JSON configuration for Node.js multi Checks blueprint
](CloudWatch_Synthetics_WritingCanary_Multichecks.md)

# Writing a canary script using the Java runtime
<a name="Synthetics_WritingCanary_Java"></a>

**Topics**
+ [

## Java project structure for a canary
](#Synthetics_canary_Java_package)
+ [

## Packaging the project for a canary
](#Synthetics_canary_Java_package_canary)
+ [

## Handler name
](#Synthetics_canary_Java_handler)
+ [

## CloudWatch Synthetics configurations
](#Synthetics_canary_Java_config)
+ [

## CloudWatch Synthetics environment variables
](#Synthetics_canary_Java_variables)

## Java project structure for a canary
<a name="Synthetics_canary_Java_package"></a>

To create a canary in Java, you need to write your code, compile it, and deploy the compiled artifacts to Synthetics. You can initialize a Java Lambda project in various ways. For instance, you can use a standard Java project setup in your preferred IDE, such as IntelliJ IDEA or Visual Studio Code. Alternatively, you can create the required file structure manually.

A Synthetics Java project contains the following general structure:

```
/project-root
    └ src
        └ main
            └ java
                └ canarypackage // name of package
                |    └ ExampleCanary.java // Canary code file
                |    └ other_supporting_classes
                - resources
                     └ synthetics.json // Synthetics configuration file    
     └ build.gradle OR pom.xml
```

You can use either Maven or Gradle to build your project and manage dependencies.

In the above structure, the `ExampleCanary` class is the entry point or handler for the canary.

 **Java canary class example** 

This example is for a canary to make a get request to a URL stored in the * TESTING\$1URL* Lambda environment variable. The canary does not use any of the methods provided by Synthetics runtime.

```
package canarypackage;

import java.net.HttpURLConnection;
import java.net.URL;

// Handler value: canary.ExampleCanary::canaryCode
public class ExampleCanary { 
  public void canaryCode() throws Exception{ 
      URL url = new URL(System.getenv("TESTING_URL"));
      HttpURLConnection con=(HttpURLConnection)url.openConnection();
      con.setRequestMethod("GET");
      con.setConnectTimeout(5000);
      con.setReadTimeout(5000);
      int status=con.getResponseCode();
      if(status!=200){
        throw new Exception("Failed to load " + url + ", status code: " + status);
      }
  }
}
```

It is highly recommended to modularize your canaries using the Synthetics provided library function `executeStep`. The canary makes `get` calls to two separate URLs procured from URL1 and URL2 environment variables.

**Note**  
To use the `executeStep` functionality, the handler method for the canary should take in a parameter of type Synthetics as shown below. 

```
package canarypackage;

import com.amazonaws.synthetics.Synthetics;
import java.net.HttpURLConnection;
import java.net.URL;

// Handler value: canary.ExampleCanary::canaryCode
public class ExampleCanary {
  public void canaryCode(Synthetics synthetics) throws Exception {
    createStep("Step1", synthetics, System.getenv("URL1"));
    createStep("Step2", synthetics, System.getenv("URL2"));
    return;
  }
  
  private void createStep(String stepName, Synthetics synthetics, String url) throws Exception{
    synthetics.executeStep(stepName,()->{
      URL obj=new URL(url);
      HttpURLConnection con=(HttpURLConnection)obj.openConnection();
      con.setRequestMethod("GET");
      con.setConnectTimeout(5000);
      con.setReadTimeout(5000);
      int status=con.getResponseCode();
      if(status!=200){
        throw new Exception("Failed to load" + url + "status code:" + status);
      }
      return null;
    }).get();
  }
}
```

## Packaging the project for a canary
<a name="Synthetics_canary_Java_package_canary"></a>

Synthetics accepts code for a java canary in the *zip* format. The zip consists of the class files for the canary code, the jars for any third party dependencies and the Synthetics configuration file.

A Synthetics Java zip contains the following general structure.

```
example-canary
    └ lib
    |  └ //third party dependency jars
       └ java-canary.jar
    └ synthetics.json
```

To build this zip from the above project structure, you can use gradle (build.gradle) or maven (pom.xml). Here is an example.

For information on compile time dependencies or interfaces for the Synthetics library, see the README under [ aws-cloudwatch-synthetics-sdk-java ](https://github.com/aws/aws-cloudwatch-synthetics-sdk-java/tree/main).

```
plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    // Third party dependencies 
    // example: implementation 'software.amazon.awssdk:s3:2.31.9'
    
    // Declares dependency on Synthetics interfaces for compiling only
    // Refer https://github.com/aws/aws-cloudwatch-synthetics-sdk-java for building from source.
    compileOnly 'software.amazon.synthetics:aws-cloudwatch-synthetics-sdk-java:1.0.0'}

test {
    useJUnitPlatform()
}

// Build the zip to be used as Canary code.
task buildZip(type: Zip) {

    archiveFileName.set("example-canary.zip")
    destinationDirectory.set(file("$buildDir"))
    
    from processResources
    into('lib') {
        from configurations.runtimeClasspath
        from(tasks.named("jar"))
    }
    from "src/main/java/resources/synthetics.json"
    
    doLast {
        println "Artifact written to: ${archiveFile.get().asFile.absolutePath}"
    }
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

tasks.named("build") {
    dependsOn "buildZip"
}
```

## Handler name
<a name="Synthetics_canary_Java_handler"></a>

The handler name is the entry point for the canary. For Java runtime, the handler is in the following format.

```
<<full qualified name for canary class>>::<<name of the method to start the execution from>>
// for above code: canarypackage.ExampleCanary::canaryCode
```

## CloudWatch Synthetics configurations
<a name="Synthetics_canary_Java_config"></a>

You can configure the behavior of the Synthetics Java runtime by providing an optional JSON configuration file named `synthetics.json`. This file should be packaged in the root directory of the package zip. Though a configuration file is optional, if you don't provide a configuration file, or a configuration key is missing, CloudWatch uses the defaults.

The following are supported configuration values, and their defaults.

```
{
    "step": {
        "stepSuccessMetric": true,
        "stepDurationMetric": true,
        "continueOnStepFailure": false,
        "stepsReport": true
    },
    "logging": {
        "logRequest": false,
        "logResponse": false
    },
    "httpMetrics": {
        "metric_2xx": true,
        "metric_4xx": true,
        "metric_5xx": true,
        "aggregated2xxMetric": true,
        "aggregated4xxMetric": true,
        "aggregated5xxMetric": true
    },
    "canaryMetrics": {
        "failedCanaryMetric": true,
        "aggregatedFailedCanaryMetric": true
    }
}
```

 **Step configurations** 
+ *continueOnStepFailure* – Determines if a script should continue even after a step has failed. The default is false.
+ *stepSuccessMetric* – Determines if a step's ` SuccessPercent` metric is emitted. The `SuccessPercent` metric for a step is *100* for the canary run if the step succeeds, and * 0 * if the step fails. The default is *true*.
+ *stepDurationMetric* – Determines if a step's * Duration* metric is emitted. The *Duration* metric is emitted as a duration, in milliseconds, of the step's run. The default is * true*.

 **Logging configurations** 

Applies to logs generated by CloudWatch Synthetics. Controls the verbosity of request and response logs.
+ *logRequest* – Specifies whether to log every request in canary logs. The default is false.
+ *logResponse* – Specifies whether to log every response in canary logs. The default is false.

 **HTTP metric configurations** 

Configurations for metrics related to the count of network requests with different HTTP status codes, emitted by CloudWatch Synthetics for this canary.
+ *metric\$12xx* – Specifies whether to emit the * 2xx* metric (with the CanaryName dimension) for this canary. The default is *true*.
+ *metric\$14xx* – Specifies whether to emit the * 4xx* metric (with the CanaryName dimension) for this canary. The default is *true*.
+ *metric\$15xx* – Specifies whether to emit the * 5xx* metric (with the CanaryName dimension) for this canary. The default is *true*.
+ *aggregated2xxMetric* – Specifies whether to emit the * 2xx* metric (without the CanaryName dimension) for this canary. The default is *true*.
+ *aggregated4xxMetric* – Specifies whether to emit the * 4xx* metric (without the CanaryName dimension) for this canary. The default is *true*.
+ *aggregated5xxMetric* – Specifies whether to emit the * 5xx* metric (without the CanaryName dimension) for this canary. The default is *true*.

 **Canary metric configurations** 

Configurations for other metrics emitted by CloudWatch Synthetics.
+ *failedCanaryMetric* Network Access Analyzer Specifies whether to emit the * Failed* metric (with the CanaryName dimension) for this canary. The default is *true*.
+ *aggregatedFailedCanaryMetric* – Specifies whether to emit the *Failed* metric (without the CanaryName dimension) for this canary. The default is *true*.

## CloudWatch Synthetics environment variables
<a name="Synthetics_canary_Java_variables"></a>

You can configure the logging level and format by using environment variables.

 **Log format** 

The CloudWatch Synthetics Java runtime creates CloudWatch logs for every canary run. Logs are written in JSON format for convenient querying. Optionally, you can change the log format to *TEXT*.
+ *Environment variable name* – CW\$1SYNTHETICS\$1LOG\$1FORMAT
+ *Supported values* – JSON, TEXT
+ *Default* –JSON

 **Log levels** 
+ *Environment variable name* – CW\$1SYNTHETICS\$1LOG\$1LEVEL
+ *Supported values* – TRACE, DEBUG, INFO, WARN, ERROR, FATAL
+ *Default* – INFO

Apart from the above environment variables, there is a default environment variable added for Java runtime, `AWS_LAMBDA-EXEC_WRAPPER` environment variable to your function, and set its value to `/opt/synthetics-otel-instrument`. This environment variable modifies your function's startup behavior for telemetry. If this environment variable already exists, make sure that it's set to the required value.

# Writing a Node.js canary script using the Playwright runtime
<a name="Synthetics_WritingCanary_Nodejs_Playwright"></a>

**Topics**
+ [

## Packaging your Node.js canary files for the Playwright runtime
](#Synthetics_canary_Nodejs_Playwright_package)
+ [

## Changing an existing Playwright script to use as a CloudWatch Synthetics canary
](#CloudWatch_Synthetics_canary_edit_Playwright_script)
+ [

## CloudWatch Synthetics configurations
](#Synthetics_canary_configure_Playwright_script)

## Packaging your Node.js canary files for the Playwright runtime
<a name="Synthetics_canary_Nodejs_Playwright_package"></a>

 Your canary script comprises of a `.js` (CommonJS syntax) or `.mjs` (ES syntax) file containing your Synthetics handler code, together with any additional packages and modules your code depends on. Scripts created in ES (ECMAScript) format should either use .mjs as the extension or include a package.json file with the "type": "module" field set. Unlike other runtimes like Node.js Puppeteer, you are not required to save your scripts in a specific folder structure. You can package your scripts directly. Use your preferred `zip` utility to create a `.zip` file with your handler file at the root. If your canary script depends on additional packages or modules that aren't included in the Synthetics runtime, you can add these dependencies to your `.zip` file. To do so, you can install your function's required libraries in the `node_modules` directory by running the `npm install` command. The following example CLI commands create a `.zip` file named `my_deployment_package.zip` containing the `index.js` or `index.mjs` file (Synthetics handler) and its dependencies. In the example, you install dependencies using the `npm` package manager.

```
~/my_function
├── index.mjs
├── synthetics.json
├── myhelper-util.mjs    
└── node_modules
    ├── mydependency
```

Create a `.zip` file that contains the contents of your project folder at the root. Use the `r` (recursive) option, as shown in the following example, to ensure that `zip` compresses the subfolders.

```
zip -r my_deployment_package.zip .
```

Add a Synthetics configuration file to configure the behavior of CloudWatch Synthetics. You can create a `synthetics.json` file and save it at the same path as your entry point or handler file.

Optionally, you can also store your entry point file in a folder structure of your choice. However, be sure that the folder path is specified in your handler name.

 **Handler name** 

Be sure to set your canary’s script entry point (handler) as ` myCanaryFilename.functionName` to match the file name of your script’s entry point. You can optionally store the canary in a separate folder such as ` myFolder/my_canary_filename.mjs`. If you store it in a separate folder, specify that path in your script entry point, such as ` myFolder/my_canary_filename.functionName`.

## Changing an existing Playwright script to use as a CloudWatch Synthetics canary
<a name="CloudWatch_Synthetics_canary_edit_Playwright_script"></a>

You can edit an existing script for Node.js and Playwright to be used as a canary. For more information about Playwright, see the [Playwright library](https://playwright.dev/docs/api/class-playwright) documentation. 

You can use the following Playwright script that is saved in file ` exampleCanary.mjs`.

```
import { chromium } from 'playwright';
import { expect } from '@playwright/test';

const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com', {timeout: 30000});
await page.screenshot({path: 'example-home.png'});

const title = await page.title();
expect(title).toEqual("Example Domain");
 
await browser.close();
```

Convert the script by performing the following steps:

1. Create and export a `handler` function. The handler is the entry point function for the script. You can choose any name for the handler function, but the function that is used in your script should be the same as in your canary handler. If your script name is `exampleCanary.mjs`, and the handler function name is `myhandler`, your canary handler is named `exampleCanary.myhandler`. In the following example, the handler function name is `handler`.

   ```
   exports.handler = async () => {
     // Your script here
     };
   ```

1. Import the `Synthetics Playwright module` as a dependency.

   ```
   import { synthetics } from '@aws/synthetics-playwright';
   ```

1. Launch a browser using the Synthetics `Launch` function.

   ```
   const browser = await synthetics.launch();
   ```

1. Create a new Playwright page by using the Synthetics `newPage` function.

   ```
   const page = await synthetics.newPage();
   ```

Your script is now ready to be run as a Synthetics canary. The following is the the updated script:

 **Updated script in ES6 format** 

The script file saved with a `.mjs` extension.

```
import { synthetics } from '@aws/synthetics-playwright';
import { expect } from '@playwright/test';

export const handler = async (event, context) => {
  try {
        // Launch a browser
        const browser = await synthetics.launch();
        
        // Create a new page
        const page = await synthetics.newPage(browser);
        
        // Navigate to a website
        await page.goto('https://www.example.com', {timeout: 30000});
        
        // Take screenshot
        await page.screenshot({ path: '/tmp/example.png' });
        
        // Verify the page title
        const title = await page.title();
        expect(title).toEqual("Example Domain");
    } finally {
        // Ensure browser is closed
        await synthetics.close();
    }
};
```

 **Updated script in CommonJS format** 

The script file saved with a `.js` extension.

```
const { synthetics } = require('@aws/synthetics-playwright');
const { expect } = require('@playwright/test');

exports.handler = async (event) => {
  try {
    const browser = await synthetics.launch();
    const page = await synthetics.newPage(browser);
    await page.goto('https://www.example.com', {timeout: 30000});
    await page.screenshot({ path: '/tmp/example.png' });
    const title = await page.title();
    expect(title).toEqual("Example Domain");
  } finally {
    await synthetics.close();
  }
};
```

## CloudWatch Synthetics configurations
<a name="Synthetics_canary_configure_Playwright_script"></a>

You can configure the behavior of the Synthetics Playwright runtime by providing an optional JSON configuration file named `synthetics.json`. This file should be packaged in the same location as the handler file. Though a configuration file is optional, f you don't provide a configuration file, or a configuration key is missing, CloudWatch assumes defaults.

 **Packaging your configuration file** 

The following are supported configuration values, and their defaults.

```
{
    "step": {
        "screenshotOnStepStart": false,
        "screenshotOnStepSuccess": false,
        "screenshotOnStepFailure": false,
        "stepSuccessMetric": true,
        "stepDurationMetric": true,
        "continueOnStepFailure": true,
        "stepsReport": true
    },
    "report": {
        "includeRequestHeaders": true,
        "includeResponseHeaders": true,
        "includeUrlPassword": false,
        "includeRequestBody": true,
        "includeResponseBody": true,
        "restrictedHeaders": ['x-amz-security-token', 'Authorization'], // Value of these headers is redacted from logs and reports
        "restrictedUrlParameters": ['Session', 'SigninToken'] // Values of these url parameters are redacted from logs and reports
    },
    "logging": {
        "logRequest": false,
        "logResponse": false,
        "logResponseBody": false,
        "logRequestBody": false,
        "logRequestHeaders": false,
        "logResponseHeaders": false
    },
    "httpMetrics": {
        "metric_2xx": true,
        "metric_4xx": true,
        "metric_5xx": true,
        "failedRequestsMetric": true,
        "aggregatedFailedRequestsMetric": true,
        "aggregated2xxMetric": true,
        "aggregated4xxMetric": true,
        "aggregated5xxMetric": true
    },
    "canaryMetrics": {
        "failedCanaryMetric": true,
        "aggregatedFailedCanaryMetric": true
    },
    "userAgent": "",
    "har": true
}
```

 **Step configurations** 
+ `screenshotOnStepStart` – Determines if Synthetics should capture a screenshot before the step starts. The default is `true`. 
+ `screenshotOnStepSuccess` – Determines if Synthetics should capture a screenshot after a step has succeeded. The default is `true`. 
+ `screenshotOnStepFailure` – Determines if Synthetics should capture a screenshot after a step has failed. The default is `true`. 
+ `continueOnStepFailure` – Determines if a script should continue even after a step has failed. The default is `false`. 
+ `stepSuccessMetric` – Determines if a step’s ` SuccessPercent` metric is emitted. The `SuccessPercent` metric for a step is `100` for the canary run if the step succeeds, and `0` if the step fails. The default is `true`. 
+ `stepDurationMetric` – Determines if a step's `Duration` metric is emitted. The `Duration` metric is emitted as a duration, in milliseconds, of the step's run. The default is `true`.

 **Report configurations** 

Includes all reports generated by CloudWatch Synthetics, such as a HAR file and a Synthetics steps report. Sensitive data redaction fields `restrictedHeaders` and `restrictedUrlParameters` also apply to logs generated by Synthetics. 
+ `includeRequestHeaders` – Whether to include request headers in the report. The default is `false`. 
+ `includeResponseHeaders` – Whether to include response headers in the report. The default is `false`.
+ `includeUrlPassword` – Whether to include a password that appears in the URL. By default, passwords that appear in URLs are redacted from logs and reports, to prevent the disclosure of sensitive data. The default is `false` . 
+ `includeRequestBody` – Whether to include the request body in the report. The default is `false`. 
+ `includeResponseBody` – Whether to include the response body in the report. The default is `false`. 
+ `restrictedHeaders` – A list of header values to ignore, if headers are included. This applies to both request and response headers. For example, you can hide your credentials by passing `includeRequestHeaders` as true and `restrictedHeaders` as `['Authorization']`. 
+ `restrictedUrlParameters` – A list of URL path or query parameters to redact. This applies to URLs that appear in logs, reports, and errors. The parameter is case-insensitive. You can pass an asterisk (`*`) as a value to redact all URL path and query parameter values. The default is an empty array. 
+ `har` – Determines if an HTTP archive (HAR) should be generated. The default is `true`.

The following is an example of a report configurations file.

```
"includeRequestHeaders": true,
"includeResponseHeaders": true,
"includeUrlPassword": false,
"includeRequestBody": true,
"includeResponseBody": true,
"restrictedHeaders": ['x-amz-security-token', 'Authorization'], // Value of these headers is redacted from logs and reports
"restrictedUrlParameters": ['Session', 'SigninToken'] // Values of these URL parameters are redacted from logs and reports
```

 **Logging configurations** 

Applies to logs generated by CloudWatch Synthetics. Controls the verbosity of request and response logs.
+ `logRequest` – Whether to log every request in canary logs. For UI canaries, this logs each request sent by the browser. The default is ` false`. 
+ `logResponse` – Whether to log every response in canary logs. For UI canaries, this logs every response received by the browser. The default is ` false`. 
+ `logRequestBody` – Whether to log request bodies along with the requests in canary logs. This configuration applies only if `logRequest` is true. The default is `false`. 
+ `logResponseBody` – Whether to log response bodies along with the requests in canary logs. This configuration applies only if `logResponse` is true. The default is `false`. 
+ `logRequestHeaders` – Whether to log request headers along with the requests in canary logs. This configuration applies only if ` logRequest` is true. The default is `false`. 
+ `logResponseHeaders` – Whether to log response headers along with the responses in canary logs. This configuration applies only if ` logResponse` is true. The default is `false`. 

 **HTTP metric configurations** 

Configurations for metrics related to the count of network requests with different HTTP status codes, emitted by CloudWatch Synthetics for this canary.
+ `metric_2xx` – Whether to emit the `2xx` metric (with the `CanaryName` dimension) for this canary. The default is ` true`. 
+ `metric_4xx` – Whether to emit the `4xx` metric (with the `CanaryName` dimension) for this canary. The default is ` true`. 
+ `metric_5xx` – Whether to emit the `5xx` metric (with the `CanaryName` dimension) for this canary. The default is ` true`. 
+ `failedRequestsMetric` – Whether to emit the ` failedRequests` metric (with the `CanaryName` dimension) for this canary. The default is `true`. 
+ `aggregatedFailedRequestsMetric` – Whether to emit the ` failedRequests` metric (without the `CanaryName` dimension) for this canary. The default is `true`. 
+ `aggregated2xxMetric` – Whether to emit the `2xx` metric (without the `CanaryName` dimension) for this canary. The default is `true`. 
+ `aggregated4xxMetric` – Whether to emit the `4xx` metric (without the `CanaryName` dimension) for this canary. The default is `true`. 
+ `aggregated5xxMetric` – Whether to emit the `5xx` metric (without the `CanaryName` dimension) for this canary. The default is `true`. 

 **Canary metric configurations** 

Configurations for other metrics emitted by CloudWatch Synthetics.
+ `failedCanaryMetric` – Whether to emit the `Failed` metric (with the `CanaryName` dimension) for this canary. The default is ` true`. 
+ `aggregatedFailedCanaryMetric` – Whether to emit the ` Failed` metric (without the `CanaryName` dimension) for this canary. The default is `true`. 

 **Other configurations** 
+ `userAgent` – A string to append to the user agent. The user agent is a string that is included in request header, and identifies your browser to websites you visit when you use the headless browser. CloudWatch Synthetics automatically adds `CloudWatchSynthetics/canary-arn to the user agent`. The specified configuration is appended to the generated user agent. The default user agent value to append is an empty string (`""`).

### CloudWatch Synthetics environment variables
<a name="Synthetics_canary_Nodejs_Playwright_script"></a>

Configure the logging level and format by using environment variables.

 **Log format** 

The CloudWatch Synthetics Playwright runtime creates CloudWatch logs for every canary run. Logs are written in JSON format for convenient querying. Optionally, you can change the log format to `TEXT`.
+ `Environment variable name` – CW\$1SYNTHETICS\$1LOG\$1FORMAT 
+ `Supported values` – JSON, TEXT 
+ `Default` – JSON 

 **Log levels** 

Though enabling `Debug` mode increases verbosity, it can be useful for troubleshooting.
+ `Environment variable name` – CW\$1SYNTHETICS\$1LOG\$1LEVEL
+ `Supported values` – TRACE, DEBUG, INFO, WARN, ERROR, FATAL 
+ `Default` – INFO

# Writing a Node.js canary script using the Puppeteer runtime
<a name="CloudWatch_Synthetics_Canaries_WritingCanary_Nodejs_Pup"></a>

**Topics**
+ [

## Creating a CloudWatch Synthetics canary from scratch
](#CloudWatch_Synthetics_Canaries_write_from_scratch)
+ [

## Packaging your Node.js canary files
](#CloudWatch_Synthetics_Canaries_package)
+ [

## Changing an existing Puppeteer script to use as a Synthetics canary
](#CloudWatch_Synthetics_Canaries_modify_puppeteer_script)
+ [

## Environment variables
](#CloudWatch_Synthetics_Environment_Variables)
+ [

## Integrating your canary with other AWS services
](#CloudWatch_Synthetics_Canaries_AWS_integrate)
+ [

## Forcing your canary to use a static IP address
](#CloudWatch_Synthetics_Canaries_staticIP)

## Creating a CloudWatch Synthetics canary from scratch
<a name="CloudWatch_Synthetics_Canaries_write_from_scratch"></a>

Here is an example minimal Synthetics Canary script. This script passes as a successful run, and returns a string. To see what a failing canary looks like, change `let fail = false;` to `let fail = true;`. 

You must define an entry point function for the canary script. To see how files are uploaded to the Amazon S3 location specified as the canary's `ArtifactS3Location`, create these files in the `/tmp` folder. All canary artifacts should be stored in `/tmp`, because it's the only writable directory. Be sure that the screenshot path is set to `/tmp` for any screenshots or other files created by the script. Synthetics automatically uploads files in ` /tmp` to an S3 bucket.

```
/tmp/<name>
```

After the script runs, the pass/fail status and the duration metrics are published to CloudWatch and the files under`/tmp` are uploaded to an S3 bucket.

```
const basicCustomEntryPoint = async function () {

    // Insert your code here

    // Perform multi-step pass/fail check

    // Log decisions made and results to /tmp

    // Be sure to wait for all your code paths to complete 
    // before returning control back to Synthetics.
    // In that way, your canary will not finish and report success
    // before your code has finished executing

    // Throw to fail, return to succeed
    let fail = false;
    if (fail) {
        throw "Failed basicCanary check.";
    }

    return "Successfully completed basicCanary checks.";
};

exports.handler = async () => {
    return await basicCustomEntryPoint();
};
```

Next, we'll expand the script to use Synthetics logging and make a call using the AWS SDK. For demonstration purposes, this script will create an Amazon DynamoDB client and make a call to the DynamoDB listTables API. It logs the response to the request and logs either pass or fail depending on whether the request was successful.

```
const log = require('@aws/synthetics-logger');
const AWS = require('aws-sdk');
// Require any dependencies that your script needs
// Bundle additional files and dependencies into a .zip file with folder structure
// nodejs/node_modules/additional files and folders

const basicCustomEntryPoint = async function () {

    log.info("Starting DynamoDB:listTables canary.");
    
    let dynamodb = new AWS.DynamoDB();
    var params = {};
    let request = await dynamodb.listTables(params);
    try {
        let response = await request.promise();
        log.info("listTables response: " + JSON.stringify(response));
    } catch (err) {
        log.error("listTables error: " + JSON.stringify(err), err.stack);
        throw err;
    }

    return "Successfully completed DynamoDB:listTables canary.";
};

exports.handler = async () => {
    return await basicCustomEntryPoint();
};
```

## Packaging your Node.js canary files
<a name="CloudWatch_Synthetics_Canaries_package"></a>

 **For syn-nodejs-puppeteer-11.0 and above** 

 The older packaging structure (for syn-nodejs-puppeteer-10.0 and below) is still supported in newer versions.

Create a script using one of the following options:
+ .js file (CommonJS syntax)
+ .mjs file (ES modules syntax)

For ES modules, use one of the following options:
+ .js file (CommonJS syntax)
+ .mjs file (ES modules syntax)

The package structure is defined below:
+ Root-level handler file (index.js/index.mjs)
+ Optional configuration file (synthetics.json)
+ Additional dependencies in node\$1modules (if needed)

Packaging structure example:

```
  my_function/
├── index.mjs
├── synthetics.json
├── helper-utils.mjs
└── node_modules/
    └── dependencies
```

To package, follow the steps below:

1. Install dependencies (if any).

   ```
   npm install
   ```

1. Create a .zip package.

   ```
   zip -r my_deployment_package.zip
   ```

 **For syn-nodejs-puppeteer-11.0 and below** 

The following structure is required when using Amazon S3:

```
  nodejs/
└── node_modules/
    └── myCanaryFilename.js
```

 **To add an optional sub-folder support in syn-nodejs-puppeteer-3.4\$1:** 

```
nodejs/
└── node_modules/
    └── myFolder/
        └── myCanaryFilename.js
```

**Note**  
Handler path in configuration must match your file location.

 **Handler name** 

Be sure to set your canary’s script entry point (handler) as ` myCanaryFilename.functionName` to match the file name of your script’s entry point. If you are using a runtime earlier than `syn-nodejs-puppeteer-3.4`, then `functionName` must be `handler`. If you are using ` syn-nodejs-puppeteer-3.4` or later, you can choose any function name as the handler. If you are using `syn-nodejs-puppeteer-3.4` or later, you can also optionally store the canary in a separate folder such as ` nodejs/node_modules/myFolder/my_canary_filename`. If you store it in a separate folder, specify that path in your script entry point, such as ` myFolder/my_canary_filename.functionName`.

## Changing an existing Puppeteer script to use as a Synthetics canary
<a name="CloudWatch_Synthetics_Canaries_modify_puppeteer_script"></a>

This section explains how to take Puppeteer scripts and modify them to run as Synthetics canary scripts. For more information about Puppeteer, see [Puppeteer API v1.14.0](https://github.com/puppeteer/puppeteer/blob/v1.14.0/docs/api.md). 

We'll start with this example Puppeteer script:

```
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();
```

The conversion steps are as follows:
+ Create and export a `handler` function. The handler is the entry point function for the script. If you are using a runtime earlier than ` syn-nodejs-puppeteer-3.4`, the handler function must be named `handler`. If you are using `syn-nodejs-puppeteer-3.4` or later, the function can have any name, but it must be the same name that is used in the script. Also, if you are using `syn-nodejs-puppeteer-3.4` or later, you can store your scripts under any folder and specify that folder as part of the handler name.

  ```
  const basicPuppeteerExample = async function () {};
  
  exports.handler = async () => {
      return await basicPuppeteerExample();
  };
  ```
+ Use the `Synthetics` dependency.

  ```
  var synthetics = require('@aws/synthetics-puppeteer');
  ```
+ Use the `Synthetics.getPage` function to get a Puppeteer `Page` object.

  ```
  const page = await synthetics.getPage();
  ```

  The page object returned by the Synthetics.getPage function has the ** page.on** `request`, `response` and ` requestfailed` events instrumented for logging. Synthetics also sets up HAR file generation for requests and responses on the page, and adds the canary ARN to the user-agent headers of outgoing requests on the page.

The script is now ready to be run as a Synthetics canary. Here is the updated script:

```
var synthetics = require('@aws/synthetics-puppeteer');  // Synthetics dependency

const basicPuppeteerExample = async function () {
    const page = await synthetics.getPage(); // Get instrumented page from Synthetics
    await page.goto('https://example.com');
    await page.screenshot({path: '/tmp/example.png'}); // Write screenshot to /tmp folder
};

exports.handler = async () => {  // Exported handler function 
    return await basicPuppeteerExample();
};
```

## Environment variables
<a name="CloudWatch_Synthetics_Environment_Variables"></a>

You can use environment variables when creating canaries. This allows you to write a single canary script and then use that script with different values to quickly create multiple canaries that have a similar task.

For example, suppose your organization has endpoints such as `prod`, ` dev`, and `pre-release` for the different stages of your software development, and you need to create canaries to test each of these endpoints. You can write a single canary script that tests your software and then specify different values for the endpoint environment variable when you create each of the three canaries. Then, when you create a canary, you specify the script and the values to use for the environment variables.

The names of environment variables can contain letters, numbers, and the underscore character. They must start with a letter and be at least two characters. The total size of your environment variables can't exceed 4 KB. You can't specify any Lambda reserved environment variables as the names of your environment variables. For more information about reserved environment variables, see [ Runtime environment variables](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime).

**Important**  
Environment variable keys and values are encrypted at rest using AWS owned AWS KMS keys. However, the environment variables are not encrypted on the client side. Do not store sensitive information in them.

The following example script uses two environment variables. This script is for a canary that checks whether a webpage is available. It uses environment variables to parameterize both the URL that it checks and the CloudWatch Synthetics log level that it uses. 

The following function sets `LogLevel` to the value of the ` LOG_LEVEL` environment variable.

```
 synthetics.setLogLevel(process.env.LOG_LEVEL);
```

This function sets `URL` to the value of the `URL` environment variable.

```
const URL = process.env.URL;
```

This is the complete script. When you create a canary using this script, you specify values for the `LOG_LEVEL` and `URL` environment variables.

```
var synthetics = require('@aws/synthetics-puppeteer');
const log = require('@aws/synthetics-logger');

const pageLoadEnvironmentVariable = async function () {

    // Setting the log level (0-3)
    synthetics.setLogLevel(process.env.LOG_LEVEL);
    // INSERT URL here
    const URL = process.env.URL;

    let page = await synthetics.getPage();
    //You can customize the wait condition here. For instance,
    //using 'networkidle2' may be less restrictive.
    const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000});
    if (!response) {
        throw "Failed to load page!";
    }
    //Wait for page to render.
    //Increase or decrease wait time based on endpoint being monitored.
    await page.waitFor(15000);
    await synthetics.takeScreenshot('loaded', 'loaded');
    let pageTitle = await page.title();
    log.info('Page title: ' + pageTitle);
    log.debug('Environment variable:' + process.env.URL);

    //If the response status code is not a 2xx success code
    if (response.status() < 200 || response.status() > 299) {
        throw "Failed to load page!";
    }
};

exports.handler = async () => {
    return await pageLoadEnvironmentVariable();
};
```

### Passing environment variables to your script
<a name="CloudWatch_Synthetics_Canaries_pass_variables"></a>

To pass environment variables to your script when you create a canary in the console, specify the keys and values of the environment variables in the **Environment variables** section on the console. For more information, see [Creating a canary](CloudWatch_Synthetics_Canaries_Create.md).

To pass environment variables through the API or AWS CLI, use the ` EnvironmentVariables` parameter in the `RunConfig` section. The following is an example AWS CLI command that creates a canary that uses two environment variables with keys of `Environment` and `Region`.

```
aws synthetics create-canary --cli-input-json '{
   "Name":"nameofCanary",
   "ExecutionRoleArn":"roleArn",
   "ArtifactS3Location":"s3://amzn-s3-demo-bucket-123456789012-us-west-2",
   "Schedule":{
      "Expression":"rate(0 minute)",
      "DurationInSeconds":604800
   },
   "Code":{
      "S3Bucket": "canarycreation",
      "S3Key": "cwsyn-mycanaryheartbeat-12345678-d1bd-1234-abcd-123456789012-12345678-6a1f-47c3-b291-123456789012.zip",
      "Handler":"pageLoadBlueprint.handler"
   },
   "RunConfig": {
      "TimeoutInSeconds":60,
      "EnvironmentVariables": {
         "Environment":"Production",
         "Region": "us-west-1"
      }
   },
   "SuccessRetentionPeriodInDays":13,
   "FailureRetentionPeriodInDays":13,
   "RuntimeVersion":"syn-nodejs-2.0"
}'
```

## Integrating your canary with other AWS services
<a name="CloudWatch_Synthetics_Canaries_AWS_integrate"></a>

All canaries can use the AWS SDK library. You can use this library when you write your canary to integrate the canary with other AWS services.

To do so, you need to add the following code to your canary. For these examples, AWS Secrets Manager is used as the service that the canary is integrating with.
+ Import the AWS SDK.

  ```
  const AWS = require('aws-sdk');
  ```
+ Create a client for the AWS service that you are integrating with.

  ```
  const secretsManager = new AWS.SecretsManager();
  ```
+ Use the client to make API calls to that service.

  ```
  var params = {
    SecretId: secretName
  };
  return await secretsManager.getSecretValue(params).promise();
  ```

The following canary script code snippet demonstrates an example of integration with Secrets Manager in more detail.

```
var synthetics = require('@aws/synthetics-puppeteer');
const log = require('@aws/synthetics-logger');
 
const AWS = require('aws-sdk');
const secretsManager = new AWS.SecretsManager();
 
const getSecrets = async (secretName) => {
    var params = {
        SecretId: secretName
    };
    return await secretsManager.getSecretValue(params).promise();
}
 
const secretsExample = async function () {
    let URL = "<URL>";
    let page = await synthetics.getPage();
    
    log.info(`Navigating to URL: ${URL}`);
    const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000});
    
    // Fetch secrets
    let secrets = await getSecrets("secretname")
   
    /**
    * Use secrets to login. 
    *
    * Assuming secrets are stored in a JSON format like:
    * {
    *   "username": "<USERNAME>",
    *   "password": "<PASSWORD>"
    * }
    **/
    let secretsObj = JSON.parse(secrets.SecretString);
    await synthetics.executeStep('login', async function () {
        await page.type(">USERNAME-INPUT-SELECTOR<", secretsObj.username);
        await page.type(">PASSWORD-INPUT-SELECTOR<", secretsObj.password);
        
        await Promise.all([
          page.waitForNavigation({ timeout: 30000 }),
          await page.click(">SUBMIT-BUTTON-SELECTOR<")
        ]);
    });
   
    // Verify login was successful
    await synthetics.executeStep('verify', async function () {
        await page.waitForXPath(">SELECTOR<", { timeout: 30000 });
    });
};

exports.handler = async () => {
    return await secretsExample();
};
```

## Forcing your canary to use a static IP address
<a name="CloudWatch_Synthetics_Canaries_staticIP"></a>

You can set up a canary so that it uses a static IP address.

**To force a canary to use a static IP address**

1. Create a new VPC. For more information, see [Using DNS with Your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html).

1. Create a new internet gateway. For more information, see [Adding an internet gateway to your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html#working-with-igw).

1. Create a public subnet inside your new VPC.

1. Add a new route table to the VPC.

1. Add a route in the new route table, that goes from `0.0.0.0/0` to the internet gateway.

1. Associate the new route table with the public subnet.

1. Create an elastic IP address. For more information, see [Elastic IP addresses ](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html).

1. Create a new NAT gateway and assign it to the public subnet and the elastic IP address.

1. Create a private subnet inside the VPC.

1. Add a route to the VPC default route table, that goes from `0.0.0.0/0` to the NAT gateway

1. Create your canary. 

# Writing a Python canary script
<a name="CloudWatch_Synthetics_Canaries_WritingCanary_Python"></a>

This script passes as a successful run, and returns a string. To see what a failing canary looks like, change fail = False to fail = True

```
def basic_custom_script():
    # Insert your code here
    # Perform multi-step pass/fail check
    # Log decisions made and results to /tmp
    # Be sure to wait for all your code paths to complete 
    # before returning control back to Synthetics.
    # In that way, your canary will not finish and report success
    # before your code has finished executing
    fail = False
    if fail:
        raise Exception("Failed basicCanary check.")
    return "Successfully completed basicCanary checks."
def handler(event, context):
    return basic_custom_script()
```

## Packaging your Python canary files
<a name="CloudWatch_Synthetics_Canaries_WritingCanary_Python_package"></a>

If you have more than one .py file or your script has a dependency, you can bundle them all into a single ZIP file. If you use the `syn-python-selenium-1.1` runtime, the ZIP file must contain your main canary .py file within a `python` folder, such as `python/my_canary_filename.py`. If you use ` syn-python-selenium-1.1` or later, you can optionally use a different folder , such as `python/myFolder/my_canary_filename.py`.

This ZIP file should contain all necessary folders and files, but the other files do not need to be in the `python` folder.

Be sure to set your canary’s script entry point as ` my_canary_filename.functionName` to match the file name and function name of your script’s entry point. If you are using the `syn-python-selenium-1.0` runtime, then `functionName` must be `handler`. If you are using ` syn-python-selenium-1.1` or later, this handler name restriction doesn't apply, and you can also optionally store the canary in a separate folder such as ` python/myFolder/my_canary_filename.py`. If you store it in a separate folder, specify that path in your script entry point, such as ` myFolder/my_canary_filename.functionName`. 

## Changing an existing Selenium script to use a Synthetics canary
<a name="CloudWatch_Synthetics_Canaries_WritingCanary_Python_Selenium"></a>

You can quickly modify an existing script for Python and Selenium to be used as a canary. For more information about Selenium, see [ www.selenium.dev/](https://www.selenium.dev/).

For this example, we'll start with the following Selenium script:

```
from selenium import webdriver

def basic_selenium_script():
    browser = webdriver.Chrome()
    browser.get('https://example.com')
    browser.save_screenshot('loaded.png')

basic_selenium_script()
```

The conversion steps are as follows.

**To convert a Selenium script to be used as a canary**

1. Change the `import` statement to use Selenium from the ` aws_synthetics` module:

   ```
   from aws_synthetics.selenium import synthetics_webdriver as webdriver
   ```

   The Selenium module from `aws_synthetics` ensures that the canary can emit metrics and logs, generate a HAR file, and work with other CloudWatch Synthetics features.

1. Create a handler function and call your Selenium method. The handler is the entry point function for the script.

   If you are using `syn-python-selenium-1.0`, the handler function must be named `handler`. If you are using `syn-python-selenium-1.1` or later, the function can have any name, but it must be the same name that is used in the script. Also, if you are using `syn-python-selenium-1.1` or later, you can store your scripts under any folder and specify that folder as part of the handler name.

   ```
   def handler(event, context):
       basic_selenium_script()
   ```

The script is now updated to be a CloudWatch Synthetics canary. Here is the updated script:

The `webdriver` is an instance of the class [ SyntheticsWebDriver](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library_Python.html#CloudWatch_Synthetics_Library_Python_SyntheticsWebDriver) and the browser returned by `webdriver.Chrome()` is an instance of [ SyntheticsBrowser](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library_Python.html#CloudWatch_Synthetics_Library_Python_SyntheticsBrowser).

```
from aws_synthetics.selenium import synthetics_webdriver as webdriver

def basic_selenium_script():
    browser = webdriver.Chrome()
    browser.get('https://example.com')
    browser.save_screenshot('loaded.png')

def handler(event, context):
    basic_selenium_script()
```

## Changing an existing Puppeteer Synthetics script to authenticate non-standard certificates
<a name="Canaries_Non-Standard_Certificates"></a>

One important use case for Synthetics canaries is for you to monitor your own endpoints. If you want to monitor an endpoint that isn't ready for external traffic, this monitoring can sometimes mean that you don't have a proper certificate signed by a trusted third-party certificate authority.

Two possible solutions to this scenario are as follows:
+ To authenticate a client certificate, see [ How to validate authentication using Amazon CloudWatch Synthetics – Part 2](https://aws.amazon.com/blogs/mt/how-to-validate-authentication-using-amazon-cloudwatch-synthetics-part-2/).
+ To authenticate a self-signed certificate, see [ How to validate authentication with self-signed certificates in Amazon CloudWatch Synthetics](https://aws.amazon.com/blogs/mt/how-to-validate-authentication-with-self-signed-certificates-in-amazon-cloudwatch-synthetics/)

You are not limited to these two options when you use CloudWatch Synthetics canaries. You can extend these features and add your business logic by extending the canary code.

**Note**  
Synthetics canaries running on Python runtimes innately have the ` --ignore-certificate-errors` flag enabled, so those canaries shouldn't have any issues reaching sites with non-standard certificate configurations.

# Writing a JSON configuration for Node.js multi Checks blueprint
<a name="CloudWatch_Synthetics_WritingCanary_Multichecks"></a>

The Node.js multi checks blueprint allows you to create canaries that perform multiple validation checks within a single canary run. This blueprint is useful when you want to test multiple endpoints, validate different aspects of your application, or perform a series of related checks in sequence. 

**Topics**
+ [

## Root configuration structure
](#root-configuration-structure)
+ [

## Global settings
](#global-settings)
+ [

## Variables and data management
](#variables-data-management)
+ [

## Step definitions
](#step-definitions)
+ [

## Check types
](#check-types)
+ [

## Authentication methods
](#authentication-methods)
+ [

## Assertions and validation
](#assertions-validation)
+ [

## Data extraction
](#data-extraction)

## Root configuration structure
<a name="root-configuration-structure"></a>

The root configuration defines the overall structure of your advanced API blueprint canary.


**Schema properties**  

| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  globalSettings  | Object | No | Default configurations applied to all steps | 
|  variables  | Object | No | Reusable values across steps (max 10) | 
|  steps  | Object |  Yes  | Collection of monitoring steps (1-10 steps) | 

 **Example** 

```
{
  "globalSettings": {
    "stepTimeout": 30000,
    "userAgent": "CloudWatch-Synthetics-Advanced/1.0"
  },
  "variables": {
    "baseUrl": "https://api.example.com",
    "apiVersion": "v1"
  },
  "steps": {
    "1": {
      "stepName": "healthCheck",
      "checkerType": "HTTP",
      "url": "${baseUrl}/health",
      "httpMethod": "GET"
    }
  }
}
```

 **Validation rules** 
+ Must contain at least one step
+ Maximum 10 steps allowed
+ No additional properties allowed beyond `globalSettings`, ` variables`, and `steps`

## Global settings
<a name="global-settings"></a>

Global settings provide default configurations that apply to all steps unless overridden at the step level.

 **Properties** 


**Global setting properties**  

| Property | Type | Default | Range | Description | 
| --- | --- | --- | --- | --- | 
|  stepTimeout  | integer | 30000 | 5000-300000 | Default timeout for all steps (milliseconds) | 

 **Example** 

```
{
  "globalSettings": {
    "stepTimeout": 60000,
            
  }
}
```

## Variables and data management
<a name="variables-data-management"></a>

Variables allow you to define reusable values that can be referenced throughout your configuration using `${variableName}` syntax.

 **Variable properties** 


| Property | Type | Description | 
| --- | --- | --- | 
| Variable names | string | Must match pattern ^[a-zA-Z][a-zA-Z0-9\$1]\$1\$1 | 
| Variable values | string | Any string value | 

 **Limitations** 
+ Maximum 10 variables per configuration
+ Variable names must start with a letter
+ Variable names can contain letters, numbers, and underscores only
+ Maximum length not specified in schema

 **Example** 

```
{
  "variables": {
    "baseUrl": "https://api.example.com",
    "apiKey": "${AWS_SECRET:my-api-key}",
    "timeout": "30000",
    "userEmail": "test@example.com"
  }
}
```

 **Configuration usage** 

```
{
  "steps": {
    "1": {
      "url": "${baseUrl}/users",
      "timeout": "${timeout}",
      "headers": {
        "Authorization": "Bearer ${apiKey}"
      }
    }
  }
}
```

## Step definitions
<a name="step-definitions"></a>

Steps define individual monitoring operations. Each step is numbered from 1 to 10 and contains a specific type of check.

 *Common step properties* 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  stepName  | string |  Yes  | Unique identifier for the step | 
|  checkerType  | string |  Yes  | Type of check: HTTP, DNS, SSL,  TCP | 
|  extractors  | array | No | Data extraction configuration | 

 *Step name validation* 
+ Pattern - ^[a-zA-Z][a-zA-Z0-9\$1-]\$1\$1
+ Maximum length - 64 characters
+ Must start with a letter

 *Step numbering* 
+ Steps are numbered as string keys: "1", "2", ..., "10"
+ Pattern: ^([1-9]\$110)\$1
+ Minimum 1 step required
+ Maximum 10 steps allowed

 *Example* 

```
{
  "steps": {
    "1": {
      "stepName": "loginAPI",
      "checkerType": "HTTP",
      "url": "https://api.example.com/login",
      "httpMethod": "POST"
    },
    "2": {
      "stepName": "dnsCheck",
      "checkerType": "DNS",
      "domain": "example.com"
    }
  }
}
```

## Check types
<a name="check-types"></a>

### HTTP checks
<a name="http-types"></a>

Monitor web endpoints and APIs with comprehensive request and response validation.

 **Required properties** 


| Property | Type | Description | 
| --- | --- | --- | 
|  url  | string | Target URL (must be valid URI format) | 
|  httpMethod  | string | HTTP method: GET, POST, PUT,  PATCH, DELETE, HEAD, OPTIONS | 

 **Optional properties** 


| Property | Type | Default | Range | Description | 
| --- | --- | --- | --- | --- | 
|  timeout  | integer | 30000 | 5000-300000 | Request timeout (milliseconds) | 
|  waitTime  | integer | 0 | 0-60 | Delay before request (seconds) | 
|  headers  | object | - | - | Custom HTTP headers | 
|  body  | string | - | - | Request body for POST/PUT operations | 
|  authentication  | object | - | - | Authentication configuration | 
|  assertions  | array | - | - | Response validation rules | 

 **Example** 

```
{
  "stepName": "createUser",
  "checkerType": "HTTP",
  "url": "https://api.example.com/users",
  "httpMethod": "POST",
  "timeout": 15000,
  "headers": {
    "Content-Type": "application/json",
    "X-API-Version": "v1"
  },
  "body": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}",
  "authentication": {
    "type": "API_KEY",
    "apiKey": "${AWS_SECRET:api-credentials}",
    "headerName": "X-API-Key"
  },
  "assertions": [
    {
      "type": "STATUS_CODE",
      "operator": "EQUALS",
      "value": 201
    }
  ]
}
```

### DNS checks
<a name="dns-types"></a>

Validate DNS resolution and record information.

 **Required properties** 


| Property | Type | Description | 
| --- | --- | --- | 
|  domain  | string | Domain name to query (hostname format) | 

 **Optional properties** 


| Property | Type | Default | Description | 
| --- | --- | --- | --- | 
|  recordType  | string | "A" | DNS record type: A, CNAME, MX,  TXT, NS | 
|  nameserver  | string | - | Specific DNS server to query | 
|  timeout  | integer | 30000 | Query timeout (5000-300000ms) | 
|  port  | integer | 53 | DNS server port (1-65535) | 
|  protocol  | string | "UDP" | Protocol: UDP or TCP | 
|  assertions  | array | - | DNS response validation rules | 

 **Example** 

```
{
  "stepName": "dnsResolution",
  "checkerType": "DNS",
  "domain": "example.com",
  "recordType": "A",
  "nameserver": "8.8.8.8",
  "timeout": 10000,
  "assertions": [
    {
      "type": "RECORD_VALUE",
      "operator": "CONTAINS",
      "value": "192.168"
    }
  ]
}
```

### SSL checks
<a name="ssl-types"></a>

Monitor SSL certificate health and configuration.

 **Required properties** 


| Property | Type | Description | 
| --- | --- | --- | 
|  hostname  | string | Target hostname (hostname format) | 

 **Optional properties** 


| Property | Type | Default | Description | 
| --- | --- | --- | --- | 
|  port  | integer | 443 | SSL port (1-65535) | 
|  timeout  | integer | 30000 | Connection timeout (5000-300000ms) | 
|  sni  | boolean | TRUE | Server Name Indication | 
|  verifyHostname  | boolean | TRUE | Hostname verification | 
|  allowSelfSigned  | boolean | FALSE | Accept self-signed certificates | 
|  assertions  | array | - | Certificate validation rules | 

 **Example** 

```
{
  "stepName": "sslCertCheck",
  "checkerType": "SSL",
  "hostname": "secure.example.com",
  "port": 443,
  "sni": true,
  "verifyHostname": true,
  "assertions": [
    {
      "type": "CERTIFICATE_EXPIRY",
      "operator": "GREATER_THAN",
      "value": 30,
      "unit": "DAYS"
    }
  ]
}
```

### TCP checks
<a name="tcp-types"></a>

Test TCP port connectivity and response validation.

 **Required properties** 


| Property | Type | Description | 
| --- | --- | --- | 
|  hostname  | string | Target hostname (hostname format) | 
|  port  | integer | Target port (1-65535) | 

 **Optional properties** 


| Property | Type | Default | Description | 
| --- | --- | --- | --- | 
|  timeout  | integer | 30000 | Overall timeout (5000-300000ms) | 
|  connectionTimeout  | integer | 3000 | Connection timeout (5000-300000ms) | 
|  readTimeout  | integer | 2000 | Data read timeout (5000-300000ms) | 
|  sendData  | string | - | Data to send after connection | 
|  expectedResponse  | string | - | Expected response data | 
|  encoding  | string | "UTF-8" | Data encoding: UTF-8, ASCII, HEX | 
|  assertions  | array | - | Connection and response validation | 

 **Example** 

```
{
  "stepName": "databaseConnection",
  "checkerType": "TCP",
  "hostname": "db.example.com",
  "port": 3306,
  "connectionTimeout": 5000,
  "sendData": "SELECT 1",
  "expectedResponse": "1",
  "assertions": [
    {
      "type": "CONNECTION_SUCCESSFUL",
      "value": true
    }
  ]
}
```

## Authentication methods
<a name="authentication-methods"></a>

 **No authentication** 

```
{
  "type": "NONE"
}
```

 **Basic authentication** 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  type  | string |  Yes  | Must be "BASIC" | 
|  username  | string |  Yes  | Username for authentication | 
|  password  | string |  Yes  | Password for authentication | 

 **Example** 

```
{
  "type": "BASIC",
  "username": "admin",
  "password": "${AWS_SECRET:basic-auth:password}"
}
```

 **API key authentication** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "API\$1KEY" | 
|  apiKey  | string |  Yes  | - | API key value | 
|  headerName  | string | No | "X-API-Key" | Header name for API key | 

 **Example** 

```
{
  "type": "API_KEY",
  "apiKey": "${AWS_SECRET:api-credentials}",
  "headerName": "Authorization"
}
```

 **OAuth client credentials** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "OAUTH\$1CLIENT\$1CREDENTIALS" | 
|  tokenUrl  | string |  Yes  | - | OAuth token endpoint URL | 
|  clientId  | string |  Yes  | - | OAuth client ID | 
|  clientSecret  | string |  Yes  | - | OAuth client secret | 
|  scope  | string | No | - | OAuth scope | 
|  audience  | string | No | - | OAuth audience | 
|  resource  | string | No | - | OAuth resource | 
|  tokenApiAuth  | array | No | - | Token API auth methods: BASIC\$1AUTH\$1HEADER, REQUEST\$1BODY | 
|  tokenCacheTtl  | integer | No | 3600 | Token cache TTL (minimum 60 seconds) | 

 **Example** 

```
{
  "type": "OAUTH_CLIENT_CREDENTIALS",
  "tokenUrl": "https://auth.example.com/oauth/token",
  "clientId": "${AWS_SECRET:oauth-creds:client_id}",
  "clientSecret": "${AWS_SECRET:oauth-creds:client_secret}",
  "scope": "read write",
  "tokenCacheTtl": 7200
}
```

 **AWS Signature (Version 4)** 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  type  | string |  Yes  | Must be "SIGV4" | 
|  service  | string |  Yes  | Name of the AWS service (for example, "execute-api") | 
|  region  | string |  Yes  | AWS region | 
|  roleArn  | string |  Yes  | IAM role ARN for signing | 

 **Example** 

```
{
  "type": "SIGV4",
  "service": "execute-api",
  "region": "us-east-1",
  "roleArn": "arn:aws:iam::123456789012:role/SyntheticsRole"
}
```

## Assertions and validation
<a name="assertions-validation"></a>

### HTTP assertions
<a name="http-assertions"></a>

 **Status code assertions** 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  type  | string |  Yes  | Must be "STATUS\$1CODE" | 
|  operator  | string |  Yes  | EQUALS, NOT\$1EQUALS, GREATER\$1THAN,  LESS\$1THAN, IN\$1RANGE | 
|  value  | integer | Conditional | HTTP status code (100-599) | 
|  rangeMin  | integer | Conditional | Minimum range value (for IN\$1RANGE) | 
|  rangeMax  | integer | Conditional | Maximum range value (for IN\$1RANGE) | 

```
{
  "type": "STATUS_CODE",
  "operator": "EQUALS",
  "value": 200
}
```

 **Response time assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "RESPONSE\$1TIME" | 
|  operator  | string |  Yes  | - | LESS\$1THAN, GREATER\$1THAN, EQUALS | 
|  value  | number |  Yes  | - | Time value (minimum 0) | 
|  unit  | string | No | "MILLISECONDS" | Must be "MILLISECONDS" | 

```
{
  "type": "RESPONSE_TIME",
  "operator": "LESS_THAN",
  "value": 500,
  "unit": "MILLISECONDS"
}
```

 **Head assertions** 


| Property | Type | Required | Description | 
| --- | --- | --- | --- | 
|  type  | string |  Yes  | Must be "HEADER" | 
|  headerName  | string |  Yes  | Name of header to validate | 
|  operator  | string |  Yes  | EQUALS, NOT\$1EQUALS, CONTAINS,  NOT\$1CONTAINS, REGEX\$1MATCH, EXIST | 
|  value  | string/boolean | Conditional | Expected value (boolean for EXIST operator) | 

```
{
  "type": "HEADER",
  "headerName": "Content-Type",
  "operator": "CONTAINS",
  "value": "application/json"
}
```

 **Body assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "BODY" | 
|  target  | string | No | "JSON" | JSON or TEXT | 
|  path  | string | Conditional | - | JSONPath (required for JSON target) | 
|  operator  | string |  Yes  | - | CONTAINS, NOT\$1CONTAINS, EQUALS,  NOT\$1EQUALS, EXISTS | 
|  value  | string/boolean |  Yes  | - | Expected value (boolean for EXISTS operator) | 

```
{
  "type": "BODY",
  "target": "JSON",
  "path": "$.users[0].name",
  "operator": "EQUALS",
  "value": "John Doe"
}
```

### DNS assertions
<a name="dns-assertions"></a>

 **Record value assertions** 


| Property | Type | Required | Range | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "RECORD\$1VALUE" | 
|  operator  | string |  Yes  | - | EQUALS, NOT\$1EQUALS, CONTAINS,  NOT\$1CONTAINS, REGEX\$1MATCH | 
|  value  | string |  Yes  | - | Expected record value | 

 **Record count assertions** 


| Property | Type | Required | Range | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "RECORD\$1COUNT" | 
|  operator  | string |  Yes  | - | EQUALS, GREATER\$1THAN, LESS\$1THAN | 
|  value  | integer |  Yes  | ≥ 0 | Expected count (minimum 0) | 

 **Authoritative assertions** 


| Property | Type | Required | Range | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "AUTHORITATIVE" | 
|  value  | boolean |  Yes  | - | Expected authoritative status | 

 **TTL assertions** 


| Property | Type | Required | Range | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "TTL" | 
|  operator  | string |  Yes  | - | EQUALS, GREATER\$1THAN, LESS\$1THAN | 
|  value  | integer |  Yes  | ≥ 0 | Expected TTL (minimum 0) | 

### SSL assertions
<a name="ssl-assertions"></a>

 **Certificate expiry assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "CERTIFICATE\$1EXPIRY" | 
|  operator  | string |  Yes  | - | GREATER\$1THAN, LESS\$1THAN | 
|  value  | integer |  Yes  | - | Time value (minimum 0) | 
|  unit  | string | No | "DAYS" | DAYS, HOURS | 

 **Certificate subject assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "CERTIFICATE\$1SUBJECT" | 
|  field  | string |  Yes  | - | Subject field: CN, O, OU, C , ST, L | 
|  operator  | string |  Yes  | - | CONTAINS, EQUALS, REGEX\$1MATCH | 
|  value  | string |  Yes  | - | Expected field value | 

 **Certificate issuer assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "CERTIFICATE\$1ISSUER" | 
|  field  | string |  Yes  | - | Issuer field: CN, O | 
|  operator  | string |  Yes  | - | CONTAINS, EQUALS | 
|  value  | string |  Yes  | - | Expected field value | 

### TCP assertions
<a name="tcp-assertions"></a>

 **Connection success assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "CONNECTION\$1SUCCESSFUL" | 
|  value  | boolean |  Yes  | - | Expected connection status | 

 **Response data assertions** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  type  | string |  Yes  | - | Must be "RESPONSE\$1DATA" | 
|  operator  | string |  Yes  | - | CONTAINS, EQUALS, NOT\$1CONTAINS,  REGEX\$1MATCH, STARTS\$1WITH, ENDS\$1WITH | 
|  value  | string |  Yes  | - | Expected response data | 
|  encoding  | string | No | "UTF-8" | UTF-8, ASCII, HEX | 

## Data extraction
<a name="data-extraction"></a>

Extractors allows you to capture data from responses for use in subsequent steps or for reporting purposes.

 **Extraction properties** 


| Property | Type | Required | Default | Description | 
| --- | --- | --- | --- | --- | 
|  name  | string |  Yes  | - | Variable name for extracted data | 
|  type  | string |  Yes  | - | Extraction type: BODY | 
|  path  | string | No | - | JSONPath for body extraction | 
|  regex  | string | No | - | Regular expression pattern | 
|  regexGroup  | integer | No | 0 | Regex capture group (minimum 0) | 

 **Extraction name validation** 
+ Pattern: `^[a-zA-Z][a-zA-Z0-9_]*$`
+ Must start with a letter
+ Can contain letters, numbers, and underscores

**Limitation** – Substitution does not apply for fields in the schema that have specific ENUM values

 **Extraction types** 

```
{
  "name": "userId",
  "type": "BODY",
  "path": "$.user.id"
}
```

```
{
  "stepName": "loginAndExtract",
  "checkerType": "HTTP",
  "url": "https://api.example.com/login",
  "httpMethod": "POST",
  "body": "{\"username\":\"test\",\"password\":\"pass\"}",
  "extractors": [
    {
      "name": "textVariable",
      "type": "BODY",
      "path": "$.myvalue"
    }
  ]
},
{
  "stepName": "substituteVariable",
  "checkerType": "HTTP",
  "url": "https://api.example.com/get/${textVariable}",
  "httpMethod": "GET",
  "assertions": [
    {
    "type": "BODY",
    "target": "JSON",
    "path": "$.users[0].name",
    "operator": "EQUALS",
    "value": "${textVariable}"
    }
  ]
}
```

# Library functions available for canary scripts
<a name="CloudWatch_Synthetics_Canaries_Function_Library"></a>

CloudWatch Synthetics includes several built-in classes and functions that you can call when writing Node.js scripts to use as canaries.

Some apply to both UI and API canaries. Others apply to UI canaries only. A UI canary is a canary that uses the `getPage()` function and uses Puppeteer as a web driver to navigate and interact with webpages.

**Note**  
Whenever you upgrade a canary to use a new version of the the Synthetics runtime, all Synthetics library functions that your canary uses are also automatically upgraded to the same version of NodeJS that the Synthetics runtime supports.

**Topics**
+ [

# Library functions available for Node.js canary
](Library_function_Nodejs.md)
+ [

# Library functions available for Java canary
](CloudWatch_Synthetics_Canaries_Java.md)
+ [

# Library functions available for Node.js canary scripts using Playwright
](CloudWatch_Synthetics_Canaries_Nodejs_Playwright.md)
+ [

# Library functions available for Node.js canary scripts using Puppeteer
](CloudWatch_Synthetics_Canaries_Library_Nodejs.md)
+ [

# Library functions available for Python canary scripts using Selenium
](CloudWatch_Synthetics_Canaries_Library_Python.md)

# Library functions available for Node.js canary
<a name="Library_function_Nodejs"></a>

This section describes the library functions that are available for canary scripts using the Node.js runtime.

**Topics**
+ [

## addExecutionError(errorMessage, ex);
](#Library_function_Nodejs_addExecutionError_Nodecanary)
+ [

## getCanaryName();
](#Library_function_Nodejs_getCanaryName)
+ [

## getCanaryArn();
](#Library_function_Nodejs_Nodecanary)
+ [

## getCanaryUserAgentString();
](#Library_function_Nodejs_getCanaryUserAgentString_Nodecanary)
+ [

## getRuntimeVersion();
](#Library_function_Nodejs_getRuntimeVersion_Nodecanary)
+ [

## getLogLevel();
](#Library_function_Nodejs_getLogLevel_Nodecanary)
+ [

## setLogLevel();
](#Library_function_Nodejs_setLogLevel_Nodecanary)
+ [

## executeStep(stepName, functionToExecute, [stepConfig])
](#Library_function_Nodejs_executestep_Nodecanary)
+ [

## executeHttpStep(stepName, requestOptions, [callback], [stepConfig])
](#Library_function_Nodejs_executeHttpStep)

## addExecutionError(errorMessage, ex);
<a name="Library_function_Nodejs_addExecutionError_Nodecanary"></a>

`errorMessage` describes the error and `ex` is the exception that is encountered

You can use `addExecutionError` to set execution errors for your canary. It fails the canary without interrupting the script execution. It also doesn't impact your `successPercent` metrics.

You should track errors as execution errors only if they are not important to indicate the success or failure of your canary script.

An example of the use of `addExecutionError` is the following. You are monitoring the availability of your endpoint and taking screenshots after the page has loaded. Because the failure of taking a screenshot doesn't determine availability of the endpoint, you can catch any errors encountered while taking screenshots and add them as execution errors. Your availability metrics will still indicate that the endpoint is up and running, but your canary status will be marked as failed. The following sample code block catches such an error and adds it as an execution error.

```
try {await synthetics.executeStep(stepName, callbackFunc);} catch(ex) {synthetics.addExecutionError('Unable to take screenshot ', ex);}
```

## getCanaryName();
<a name="Library_function_Nodejs_getCanaryName"></a>

Returns the name of the canary.

## getCanaryArn();
<a name="Library_function_Nodejs_Nodecanary"></a>

Returns the ARN of the canary.

## getCanaryUserAgentString();
<a name="Library_function_Nodejs_getCanaryUserAgentString_Nodecanary"></a>

Returns the custom user agent of the canary.

## getRuntimeVersion();
<a name="Library_function_Nodejs_getRuntimeVersion_Nodecanary"></a>

This function is available on runtime version `syn-nodejs-3.0` and later. It returns the Synthetics runtime version of the canary. For example, the return value could be `syn-nodejs-3.0`.

## getLogLevel();
<a name="Library_function_Nodejs_getLogLevel_Nodecanary"></a>

Retrieves the current log level for the Synthetics library. Possible values are the following:
+ `0` – Debug
+ `1` – Info
+ `2` – Warn
+ `3` – Error

Example:

```
let logLevel = synthetics.getLogLevel();
```

## setLogLevel();
<a name="Library_function_Nodejs_setLogLevel_Nodecanary"></a>

Sets the log level for the Synthetics library. Possible values are the following:
+ `0` – Debug
+ `1` – Info
+ `2` – Warn
+ `3` – Error

Example:

```
synthetics.setLogLevel(0);
```

## executeStep(stepName, functionToExecute, [stepConfig])
<a name="Library_function_Nodejs_executestep_Nodecanary"></a>

Executes the provided step, wrapping it with start/pass/fail logging and pass/fail and duration metrics.

The `executeStep` function also does the following:
+ Logs that the step started
+ Starts a timer
+ Executes the provided function
+ When the function returns normally, it counts as passing. If the function throws, it counts as failing
+ Ends the timer
+ Logs whether the step passed or failed
+ Emits the `stepName SuccessPercent` metric, 100 for pass or 0 for failure
+ Emits the `stepName Duration metric`, with a value based on the step start and end times
+ Returns what the functionToExecute returned or re-throws what ` functionToExecute` threw
+ Adds a step execution summary to the canary's report

 **Example** 

```
await synthetics.executeStep(stepName, async function () {
    return new Promise((resolve, reject) => {
        const req = https.request(url, (res) => {
            console.log(`Status: ${res.statusCode}`);
            if (res.statusCode >= 400) {
                reject(new Error(`Request failed with status ${res.statusCode} for ${url}`));
            } else {
                resolve();
            }
        });

        req.on('error', (err) => {
            reject(new Error(`Request failed for ${url}: ${err.message}`));
        });

        req.end();
    });
});
```

## executeHttpStep(stepName, requestOptions, [callback], [stepConfig])
<a name="Library_function_Nodejs_executeHttpStep"></a>

Executes the provided HTTP request as a step, and publishes `SuccessPercent` (pass/fail) and `Duration` metrics.

**executeHttpStep** uses either HTTP or HTTPS native functions under the hood, depending upon the protocol specified in the request.

This function also adds a step execution summary to the canary's report. The summary includes details about each HTTP request, such as the following:
+ Start time
+ End time
+ Status (PASSED/FAILED)
+ Failure reason, if it failed
+ HTTP call details such as request/response headers, body, status code, status message, and performance timings. 

**Topics**
+ [

### Parameters
](#Library_function_Nodejs_executeHttpStep_parameters_Nodecanary)
+ [

### Examples of using executeHttpStep
](#Library_function_Nodejs_executeHttpStep_examples_Nodecanary)

### Parameters
<a name="Library_function_Nodejs_executeHttpStep_parameters_Nodecanary"></a>

 **stepName(*String*)** 

Specifies the name of the step. This name is also used for publishing CloudWatch metrics for this step.

 **requestOptions(*Object or String*)** 

The value of this parameter can be a URL, a URL string, or an object. If it is an object, then it must be a set of configurable options to make an HTTP request. It supports all options in [ http.request(options[, callback])](https://nodejs.org/api/http.html#http_http_request_options_callback) in the Node.js documentation.

In addition to these Node.js options, **requestOptions** supports the additional parameter `body`. You can use the `body` parameter to pass data as a request body.

 **callback(*response*)** 

(Optional) This is a user function which is invoked with the HTTP response. The response is of the type [ Class: http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage).

 **stepConfig(*object*)** 

(Optional) Use this parameter to override global synthetics configurations with a different configuration for this step.

### Examples of using executeHttpStep
<a name="Library_function_Nodejs_executeHttpStep_examples_Nodecanary"></a>

The following series of examples build on each other to illustrate the various uses of this option.

This first example configures request parameters. You can pass a URL as ** requestOptions**:

```
let requestOptions = 'https://www.amazon.com';
```

Or you can pass a set of options:

```
let requestOptions = {
        'hostname': 'myproductsEndpoint.com',
        'method': 'GET',
        'path': '/test/product/validProductName',
        'port': 443,
        'protocol': 'https:'
    };
```

The next example creates a callback function which accepts a response. By default, if you do not specify **callback**, CloudWatch Synthetics validates that the status is between 200 and 299 inclusive.

```
// Handle validation for positive scenario
    const callback = async function(res) {
        return new Promise((resolve, reject) => {
            if (res.statusCode < 200 || res.statusCode > 299) {
                throw res.statusCode + ' ' + res.statusMessage;
            }
     
            let responseBody = '';
            res.on('data', (d) => {
                responseBody += d;
            });
     
            res.on('end', () => {
                // Add validation on 'responseBody' here if required. For ex, your status code is 200 but data might be empty
                resolve();
            });
        });
    };
```

The next example creates a configuration for this step that overrides the global CloudWatch Synthetics configuration. The step configuration in this example allows request headers, response headers, request body (post data), and response body in your report and restrict 'X-Amz-Security-Token' and 'Authorization' header values. By default, these values are not included in the report for security reasons. If you choose to include them, the data is only stored in your S3 bucket.

```
// By default headers, post data, and response body are not included in the report for security reasons. 
// Change the configuration at global level or add as step configuration for individual steps
let stepConfig = {
    includeRequestHeaders: true, 
    includeResponseHeaders: true,
    restrictedHeaders: ['X-Amz-Security-Token', 'Authorization'], // Restricted header values do not appear in report generated.
    includeRequestBody: true,
    includeResponseBody: true
};
```

This final example passes your request to **executeHttpStep** and names the step.

```
await synthetics.executeHttpStep('Verify GET products API', requestOptions, callback, stepConfig);
```

With this set of examples, CloudWatch Synthetics adds the details from each step in your report and produces metrics for each step using **stepName**.

 You will see `successPercent` and `duration` metrics for the `Verify GET products API` step. You can monitor your API performance by monitoring the metrics for your API call steps. 

For a sample complete script that uses these functions, see [Multi-step API canary](CloudWatch_Synthetics_Canaries_Samples.md#CloudWatch_Synthetics_Canaries_Samples_APIsteps).

# Library functions available for Java canary
<a name="CloudWatch_Synthetics_Canaries_Java"></a>

The `executeStep` function is used to modularize the canary code and execute it in steps. In CloudWatch Synthetics, a Synthetics step is a way to break down your canary script into a series of clearly defined actions, allowing you to monitor different parts of your application journey separately. For each step, CloudWatch Synthetics does the following:
+ A report, including a summary of step execution details like the duration of a step, *pass* or *fail* status, and so on, is created for each canary run. When you choose a run in the CloudWatch Synthetics console, you can view execution details of each step on the **Step** tab.
+ *SuccessPercent* and *Duration* CloudWatch metrics are emitted for each step, enabling users to monitor availability and latency of each step.

   **Usage** 

  ```
  synthetics.executeStep(stepName,()->{
      try {
          //step code to be executed
          return null;
      } catch (Exception e) {
          throw e;
      }
  }).get();
  ```

   **Parameters** 
  + *stepName*, String (required) – A descriptive name of the Synthetics step
  + *function to execute*, Callable<T> (required) – Represents the tasks to be executed
  + *stepOptions*, `com.amazonaws.synthetics.StepOptions (optional)` – StepOptions object that can be used to configure the step execution. 

    *stepConfiguration*, ` com.amazonaws.synthetics.StepConfiguration`(required as part of the stepOptions)

 **Returns** 

The value returned is *CompletableFuture<T>*.

**Note**  
Synthetics only supports sequential steps. Make sure to call the `.get()` method as shown in the example to ensure that the step completes before proceeding to the subsequent step.

# Library functions available for Node.js canary scripts using Playwright
<a name="CloudWatch_Synthetics_Canaries_Nodejs_Playwright"></a>

This section describes the library functions that are available for canary scripts using the Node.js Playwright runtime.

**Topics**
+ [

## launch
](#Synthetics_Library_Nodejs_Playwright_functions)
+ [

## newPage
](#Synthetics_Library_Nodejs_Playwright_function_newPage)
+ [

## close
](#Synthetics_Library_Nodejs_Playwright_function_close)
+ [

## getDefaultLaunchOptions
](#Synthetics_Library_Nodejs_Playwright_function_getDefaultLaunchOptions)
+ [

## executeStep
](#Synthetics_Library_Nodejs_Playwright_function_executeStep)

## launch
<a name="Synthetics_Library_Nodejs_Playwright_functions"></a>

This function launches a Chromium browser using a Playwright launch function, and returns the browser object. It decompresses browser binaries and launches the chromium browser by using default options suitable for a headless browser. For more information about the `launch` function, see [https://playwright.dev/docs/api/class-browsertype#browser-type-launch](https://playwright.dev/docs/api/class-browsertype#browser-type-launch) in the Playwright documentation.

 **Usage** 

```
const browser = await synthetics.launch();
```

 **Arguments** 

`options` [options](https://playwright.dev/docs/api/class-browsertype#browser-type-launch) (optional) is a configurable set of options for the browser.

 **Returns** 

Promise `<Browser>` where [Browser](https://playwright.dev/docs/api/class-browser) is a Playwright browser instance.

If this function is called again, a previously-opened browser is closed before initiating a new browser. You can override launch parameters used by CloudWatch Synthetics, and pass additional parameters when launching the browser. For example, the following code snippet launches a browser with default arguments and a default executable path, but with a viewport of 800 x 600 pixels. For more information, see [Playwright launch options](https://playwright.dev/docs/api/class-browsertype#browser-type-launch) in the Playwright documentation.

```
const browser = await synthetics.launch({
  defaultViewport: { 
      "deviceScaleFactor": 1, 
      "width": 800,
      "height": 600 
}});
```

 You can also add or override Chromium flags passed on by default to the browser. For example, you can disable web security by adding a `--disable-web-security` flag to arguments in the CloudWatch Synthetics launch parameters: 

```
// This function adds the --disable-web-security flag to the launch parameters
const defaultOptions = await synthetics.getDefaultLaunchOptions();
const launchArgs = [...defaultOptions.args, '--disable-web-security'];
const browser = await synthetics.launch({
    args: launchArgs
  });
```

## newPage
<a name="Synthetics_Library_Nodejs_Playwright_function_newPage"></a>

The `newPage()` function creates and returns a new Playwright page. Synthetics automatically sets up a Chrome DevTools Protocol (CDP) connection to enable network captures for HTTP archive (HAR) generation.

 **Usage** 

Use `newPage()` in either of the following ways:

 **1. Creating a new page in a new browser context:** 

```
const page = await synthetics.newPage(browser);
```

 **2. Creating a new page in a specified browser context:** 

```
// Create a new browser context
const browserContext = await browser.newContext();

// Create a new page in the specified browser context
const page = await synthetics.newPage(browserContext)
```

 **Arguments** 

Accepts either Playwright [Browser](https://playwright.dev/docs/api/class-browser) instance or Playwright [ BrowserContext](https://playwright.dev/docs/api/class-browsercontext) instance. 

 **Returns** 

Promise <Page> where Page is a Playwright [Page](https://playwright.dev/docs/api/class-page) instance.

## close
<a name="Synthetics_Library_Nodejs_Playwright_function_close"></a>

Closes the currently-opened browser.

 **Usage** 

```
await synthetics.close();
```

It is recommended to close the browser in a `finally` block of your script.

 **Arguments** 

None 

 **Returns** 

Returns Promise<void> used by the Synthetics launch function for launching the browser.

## getDefaultLaunchOptions
<a name="Synthetics_Library_Nodejs_Playwright_function_getDefaultLaunchOptions"></a>

The `getDefaultLaunchOptions()` function returns the browser launch options that are used by CloudWatch Synthetics.

 **Usage** 

```
const defaultOptions = await synthetics.getDefaultLaunchOptions();
```

 **Arguments** 

None 

 **Returns** 

Returns Playwright [ launch options](https://playwright.dev/docs/api/class-browsertype#browser-type-launch) used by the Synthetics `launch` function for launching the browser.

## executeStep
<a name="Synthetics_Library_Nodejs_Playwright_function_executeStep"></a>

The `executeStep` function is used to execute a step in a Synthetics script. In CloudWatch Synthetics, a Synthetics step is a way to break down your canary script into a series of clearly defined actions, allowing you to monitor different parts of your application journey separately. For each step, CloudWatch Synthetics does the following:
+ Automatically captures a screenshot before step starts and after a step is complete. You can also capture screenshots inside a step. Screenshots are captured by default, but can be turned off by using Synthetics configurations.
+ A report, including a summary, of step execution details like the duration of a step, `pass` or `fail` status, source and destination page URLs, associated screenshots, etc. is created for each canary run. When you choose a run in the CloudWatch Synthetics console, you can view execution details of each step on the **Step** tab.
+ `SuccessPercent` and `Duration` CloudWatch metrics are emitted for each step, enabling users to monitor availability and latency of each step.

 **Usage** 

```
await synthetics.executeStep("mystepname", async function () {
  await page.goto(url, { waitUntil: 'load', timeout: 30000 });
}
```

**Note**  
Steps should run sequentially. Be sure to use `await` on promises.

 **Arguments** 
+ `stepName` string (required) (boolean)— Name of the Synthetics step. 
+ `functionToExecute` async function (required)— The function that you want Synthetics to run. This function should contain the logic for the step.
+ `stepConfig` object (optional)— Step configuration overrides the global Synthetics configuration for this step.
  + `continueOnStepFailure` boolean (optional) — Whether to continue running the canary script after this step fails. 
  + `screenshotOnStepStart` boolean (optional) — Whether to take a screenshot at the start of this step. 
  + `screenshotOnStepSuccess` boolean (optional) — Whether to take a screenshot if this step succeeds. 
  + `screenshotOnStepFailure` boolean (optional) — Whether to take a screenshot if this step fails. 
+ `page` — Playwright page object (optional)

  A Playwright page object. Synthetics uses this page object to capture screenshots and URLs. By default, Synthetics uses the Playwright page created when the `synthetics.newPage()` function is called for capturing page details like screenshots and URLs.

 **Returns** 

Returns a Promise that resolves with the value returned by the ` functionToExecute` function. For an example script, see [Sample code for canary scripts](CloudWatch_Synthetics_Canaries_Samples.md) in this guide.

# Library functions available for Node.js canary scripts using Puppeteer
<a name="CloudWatch_Synthetics_Canaries_Library_Nodejs"></a>

This section describes the library functions available for Node.js canary scripts.

**Topics**
+ [

## Node.js library classes and functions that apply to all canaries
](#CloudWatch_Synthetics_Library_allcanaries)
+ [

## Node.js library classes and functions that apply to UI canaries only
](#CloudWatch_Synthetics_Library_UIcanaries)
+ [

## Node.js library classes and functions that apply to API canaries only
](#CloudWatch_Synthetics_Library_APIcanaries)

## Node.js library classes and functions that apply to all canaries
<a name="CloudWatch_Synthetics_Library_allcanaries"></a>

The following CloudWatch Synthetics library functions for Node.js are useful for all canaries.

**Topics**
+ [

### Synthetics class
](#CloudWatch_Synthetics_Library_Synthetics_Class_all)
+ [

### SyntheticsConfiguration class
](#CloudWatch_Synthetics_Library_SyntheticsConfiguration)
+ [

### Synthetics logger
](#CloudWatch_Synthetics_Library_SyntheticsLogger)
+ [

### SyntheticsLogHelper class
](#CloudWatch_Synthetics_Library_SyntheticsLogHelper)

### Synthetics class
<a name="CloudWatch_Synthetics_Library_Synthetics_Class_all"></a>

The following functions for all canaries are in the Synthetics class.

**Topics**
+ [

#### addExecutionError(errorMessage, ex);
](#CloudWatch_Synthetics_Library_addExecutionError)
+ [

#### getCanaryName();
](#CloudWatch_Synthetics_Library_getCanaryName)
+ [

#### getCanaryArn();
](#CloudWatch_Synthetics_Library_getCanaryARN)
+ [

#### getCanaryUserAgentString();
](#CloudWatch_Synthetics_Library_getCanaryUserAgentString)
+ [

#### getRuntimeVersion();
](#CloudWatch_Synthetics_Library_getRuntimeVersion)
+ [

#### getLogLevel();
](#CloudWatch_Synthetics_Library_getLogLevel)
+ [

#### setLogLevel();
](#CloudWatch_Synthetics_Library_setLogLevel)

#### addExecutionError(errorMessage, ex);
<a name="CloudWatch_Synthetics_Library_addExecutionError"></a>

`errorMessage` describes the error and `ex` is the exception that is encountered

You can use `addExecutionError` to set execution errors for your canary. It fails the canary without interrupting the script execution. It also doesn't impact your `successPercent` metrics.

You should track errors as execution errors only if they are not important to indicate the success or failure of your canary script.

An example of the use of `addExecutionError` is the following. You are monitoring the availability of your endpoint and taking screenshots after the page has loaded. Because the failure of taking a screenshot doesn't determine availability of the endpoint, you can catch any errors encountered while taking screenshots and add them as execution errors. Your availability metrics will still indicate that the endpoint is up and running, but your canary status will be marked as failed. The following sample code block catches such an error and adds it as an execution error.

```
try {
    await synthetics.takeScreenshot(stepName, "loaded");
} catch(ex) {
    synthetics.addExecutionError('Unable to take screenshot ', ex);
}
```

#### getCanaryName();
<a name="CloudWatch_Synthetics_Library_getCanaryName"></a>

Returns the name of the canary.

#### getCanaryArn();
<a name="CloudWatch_Synthetics_Library_getCanaryARN"></a>

Returns the ARN of the canary.

#### getCanaryUserAgentString();
<a name="CloudWatch_Synthetics_Library_getCanaryUserAgentString"></a>

Returns the custom user agent of the canary.

#### getRuntimeVersion();
<a name="CloudWatch_Synthetics_Library_getRuntimeVersion"></a>

This function is available in runtime version `syn-nodejs-puppeteer-3.0` and later. It returns the Synthetics runtime version of the canary. For example, the return value could be `syn-nodejs-puppeteer-3.0`.

#### getLogLevel();
<a name="CloudWatch_Synthetics_Library_getLogLevel"></a>

Retrieves the current log level for the Synthetics library. Possible values are the following:
+ `0` – Debug
+ `1` – Info
+ `2` – Warn
+ `3` – Error

Example:

```
let logLevel = synthetics.getLogLevel();
```

#### setLogLevel();
<a name="CloudWatch_Synthetics_Library_setLogLevel"></a>

Sets the log level for the Synthetics library. Possible values are the following:
+ `0` – Debug
+ `1` – Info
+ `2` – Warn
+ `3` – Error

Example:

```
synthetics.setLogLevel(0);
```

### SyntheticsConfiguration class
<a name="CloudWatch_Synthetics_Library_SyntheticsConfiguration"></a>

This class is available only in the `syn-nodejs-2.1` runtime version or later.

You can use the `SyntheticsConfiguration` class to configure the behavior of Synthetics library functions. For example, you can use this class to configure the `executeStep()` function to not capture screenshots.

You can set CloudWatch Synthetics configurations at the global level, which are applied to all steps of canaries. You can also override these configurations at the step level by passing configuration key and value pairs.

You can pass in options at the step level. For examples, see [async executeStep(stepName, functionToExecute, [stepConfig]);](#CloudWatch_Synthetics_Library_executeStep) and [executeHttpStep(stepName, requestOptions, [callback], [stepConfig])](#CloudWatch_Synthetics_Library_executeHttpStep)

**Topics**
+ [

#### setConfig(options)
](#CloudWatch_Synthetics_Library_setConfig)
+ [

#### Visual monitoring
](#CloudWatch_Synthetics_Library_SyntheticsLogger_VisualTesting)

#### setConfig(options)
<a name="CloudWatch_Synthetics_Library_setConfig"></a>

` options ` is an object, which is a set of configurable options for your canary. The following sections explain the possible fields in ` options `.

##### setConfig(options) for all canaries
<a name="CloudWatch_Synthetics_Library_setConfigall"></a>

For canaries using `syn-nodejs-puppeteer-3.2` or later, the ** (options)** for **setConfig** can include the following parameters:
+ `includeRequestHeaders` (boolean)— Whether to include request headers in the report. The default is `false`.
+ `includeResponseHeaders` (boolean)— Whether to include response headers in the report. The default is `false`.
+ `restrictedHeaders` (array)— A list of header values to ignore, if headers are included. This applies to both request and response headers. For example, you can hide your credentials by passing ** includeRequestHeaders** as `true` and ** restrictedHeaders** as `['Authorization']`. 
+ `includeRequestBody` (boolean)— Whether to include the request body in the report. The default is `false`.
+ `includeResponseBody` (boolean)— Whether to include the response body in the report. The default is `false`.
**Important**  
If you enable either `includeResponseBody` or ` logResponseBody`, the data object is not returned in the response from some APIs, such as aws-sdk v3 clients. This is because of a limitation of Node.js and the type of response object used.

 **setConfig(options) regarding CloudWatch metrics** 

For canaries using `syn-nodejs-puppeteer-3.1` or later, the ** (options)** for **setConfig** can include the following Boolean parameters that determine which metrics are published by the canary. The default for each of these options is `true`. The options that start with `aggregated` determine whether the metric is emitted without the ` CanaryName` dimension. You can use these metrics to see the aggregated results for all of your canaries. The other options determine whether the metric is emitted with the `CanaryName` dimension. You can use these metrics to see results for each individual canary.

For a list of CloudWatch metrics emitted by canaries, see [CloudWatch metrics published by canaries](CloudWatch_Synthetics_Canaries_metrics.md).
+ `failedCanaryMetric` (boolean)— Whether to emit the ` Failed` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `failedRequestsMetric` (boolean)— Whether to emit the `Failed requests` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `_2xxMetric` (boolean)— Whether to emit the `2xx` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `_4xxMetric` (boolean)— Whether to emit the `4xx` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `_5xxMetric` (boolean)— Whether to emit the `5xx` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `stepDurationMetric` (boolean)— Whether to emit the `Step duration` metric (with the `CanaryName` `StepName` dimensions) for this canary. The default is `true`.
+ `stepSuccessMetric` (boolean)— Whether to emit the `Step success` metric (with the `CanaryName` `StepName` dimensions) for this canary. The default is `true`.
+ `aggregatedFailedCanaryMetric` (boolean)— Whether to emit the `Failed` metric (without the `CanaryName` dimension) for this canary. The default is `true`.
+ `aggregatedFailedRequestsMetric` (boolean)— Whether to emit the `Failed Requests` metric (without the `CanaryName` dimension) for this canary. The default is `true`.
+ `aggregated2xxMetric` (boolean)— Whether to emit the ` 2xx` metric (without the `CanaryName` dimension) for this canary. The default is `true`.
+ `aggregated4xxMetric` (boolean)— Whether to emit the ` 4xx` metric (without the `CanaryName` dimension) for this canary. The default is `true`.
+ `aggregated5xxMetric` (boolean)— Whether to emit the ` 5xx` metric (without the `CanaryName` dimension) for this canary. The default is `true`.
+ `visualMonitoringSuccessPercentMetric` (boolean)— Whether to emit the `visualMonitoringSuccessPercent` metric for this canary. The default is `true`.
+ `visualMonitoringTotalComparisonsMetric` (boolean)— Whether to emit the `visualMonitoringTotalComparisons` metric for this canary. The default is `false`.
+ `includeUrlPassword` (boolean)— Whether to include a password that appears in the URL. By default, passwords that appear in URLs are redacted from logs and reports, to prevent disclosing sensitive data. The default is `false`.
+ `restrictedUrlParameters` (array)— A list of URL path or query parameters to redact. This applies to URLs appearing in logs, reports, and errors. The parameter is case-insensitive. You can pass an asterisk (\$1) as a value to redact all URL path and query parameter values. The default is an empty array.
+ `logRequest` (boolean)— Whether to log every request in canary logs. For UI canaries, this logs each request sent by the browser. The default is `true`.
+ `logResponse` (boolean)— Whether to log every response in canary logs. For UI canaries, this logs every response received by the browser. The default is `true`.
+ `logRequestBody` (boolean)— Whether to log request bodies along with the requests in canary logs. This configuration applies only if `logRequest` is `true`. The default is `false` .
+ `logResponseBody` (boolean)— Whether to log response bodies along with the responses in canary logs. This configuration applies only if `logResponse` is `true`. The default is ` false`.
**Important**  
If you enable either `includeResponseBody` or ` logResponseBody`, the data object is not returned in the response from some APIs, such as aws-sdk v3 clients. This is because of a limitation of Node.js and the type of response object used.
+ `logRequestHeaders` (boolean)— Whether to log request headers along with the requests in canary logs. This configuration applies only if `logRequest` is `true`. The default is ` false`.

  Note that `includeRequestHeaders` enables headers in artifacts.
+ `logResponseHeaders` (boolean)— Whether to log response headers along with the responses in canary logs. This configuration applies only if `logResponse` is `true`. The default is ` false`.

  Note that `includeResponseHeaders` enables headers in artifacts.

**Note**  
The `Duration` and `SuccessPercent` metrics are always emitted for each canary, both with and without the `CanaryName` metric.

##### Methods to enable or disable metrics
<a name="CloudWatch_Synthetics_Library_setConfig_metrics"></a>

 **disableAggregatedRequestMetrics()** 

Disables the canary from emitting all request metrics that are emitted with no `CanaryName` dimension.

 **disableRequestMetrics()** 

Disables all request metrics, including both per-canary metrics and metrics aggregated across all canaries.

 **disableStepMetrics()** 

Disables all step metrics, including both step success metrics and step duration metrics.

 **enableAggregatedRequestMetrics()** 

Enables the canary to emit all request metrics that are emitted with no ` CanaryName` dimension.

 **enableRequestMetrics()** 

Enables all request metrics, including both per-canary metrics and metrics aggregated across all canaries.

 **enableStepMetrics()** 

Enables all step metrics, including both step success metrics and step duration metrics.

 **get2xxMetric()** 

Returns whether the canary emits a `2xx` metric with the ` CanaryName` dimension.

 **get4xxMetric()** 

Returns whether the canary emits a `4xx` metric with the ` CanaryName` dimension.

 **get5xxMetric()** 

Returns whether the canary emits a `5xx` metric with the ` CanaryName` dimension.

 **getAggregated2xxMetric()** 

Returns whether the canary emits a `2xx` metric with no dimension.

 **getAggregated4xxMetric()** 

Returns whether the canary emits a `4xx` metric with no dimension.

 **getAggregatedFailedCanaryMetric()** 

Returns whether the canary emits a `Failed` metric with no dimension.

 **getAggregatedFailedRequestsMetric()** 

Returns whether the canary emits a `Failed requests` metric with no dimension.

 **getAggregated5xxMetric()** 

Returns whether the canary emits a `5xx` metric with no dimension.

 **getFailedCanaryMetric()** 

Returns whether the canary emits a `Failed` metric with the ` CanaryName` dimension.

 **getFailedRequestsMetric()** 

Returns whether the canary emits a `Failed requests` metric with the `CanaryName` dimension.

 **getStepDurationMetric()** 

Returns whether the canary emits a `Duration` metric with the ` CanaryName` dimension for this canary.

 **getStepSuccessMetric()** 

Returns whether the canary emits a `StepSuccess` metric with the ` CanaryName` dimension for this canary.

 **with2xxMetric(\$12xxMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `2xx` metric with the `CanaryName` dimension for this canary.

 **with4xxMetric(\$14xxMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `4xx` metric with the `CanaryName` dimension for this canary.

 **with5xxMetric(\$15xxMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `5xx` metric with the `CanaryName` dimension for this canary.

 **withAggregated2xxMetric(aggregated2xxMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `2xx` metric with no dimension for this canary.

 **withAggregated4xxMetric(aggregated4xxMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `4xx` metric with no dimension for this canary.

 **withAggregated5xxMetric(aggregated5xxMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `5xx` metric with no dimension for this canary.

 ** withAggregatedFailedCanaryMetric(aggregatedFailedCanaryMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `Failed` metric with no dimension for this canary.

 ** withAggregatedFailedRequestsMetric(aggregatedFailedRequestsMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `Failed requests` metric with no dimension for this canary.

 **withFailedCanaryMetric(failedCanaryMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `Failed` metric with the `CanaryName` dimension for this canary.

 **withFailedRequestsMetric(failedRequestsMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `Failed requests` metric with the `CanaryName` dimension for this canary.

 **withStepDurationMetric(stepDurationMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `Duration` metric with the `CanaryName` dimension for this canary.

 **withStepSuccessMetric(stepSuccessMetric)** 

Accepts a Boolean argument, which specifies whether to emit a ` StepSuccess` metric with the `CanaryName` dimension for this canary.

##### Methods to enable or disable other features
<a name="CloudWatch_Synthetics_Library_setConfig_methods"></a>

 **withHarFile()** 

Accepts a Boolean argument, which specifies whether to create a HAR file for this canary.

 **withStepsReport()** 

Accepts a Boolean argument, which specifies whether to report a step execution summary for this canary.

 **withIncludeUrlPassword()** 

Accepts a Boolean argument, which specifies whether to include passwords that appear in URLs in logs and reports.

 **withRestrictedUrlParameters()** 

Accepts an array of URL path or query parameters to redact. This applies to URLs appearing in logs, reports, and errors. You can pass an asterisk (\$1) as a value to redact all URL path and query parameter values

 **withLogRequest()** 

Accepts a Boolean argument, which specifies whether to log every request in the canary's logs.

 **withLogResponse()** 

Accepts a Boolean argument, which specifies whether to log every response in the canary's logs.

 **withLogRequestBody()** 

Accepts a Boolean argument, which specifies whether to log every request body in the canary's logs.

 **withLogResponseBody()** 

Accepts a Boolean argument, which specifies whether to log every response body in the canary's logs.

 **withLogRequestHeaders()** 

Accepts a Boolean argument, which specifies whether to log every request header in the canary's logs.

 **withLogResponseHeaders()** 

Accepts a Boolean argument, which specifies whether to log every response header in the canary's logs.

 **getHarFile()** 

Returns whether the canary creates a HAR file.

 **getStepsReport()** 

Returns whether the canary reports a step execution summary.

 **getIncludeUrlPassword()** 

Returns whether the canary includes passwords that appear in URLs in logs and reports.

 **getRestrictedUrlParameters()** 

Returns whether the canary redacts URL path or query parameters.

 **getLogRequest()** 

Returns whether the canary logs every request in the canary's logs.

 **getLogResponse()** 

Returns whether the canary logs every response in the canary's logs.

 **getLogRequestBody()** 

Returns whether the canary logs every request body in the canary's logs.

 **getLogResponseBody()** 

Returns whether the canary logs every response body in the canary's logs.

 **getLogRequestHeaders()** 

Returns whether the canary logs every request header in the canary's logs.

 **getLogResponseHeaders()** 

Returns whether the canary logs every response header in the canary's logs.

 **Functions for all canaries** 
+ `withIncludeRequestHeaders`(includeRequestHeaders)
+ `withIncludeResponseHeaders`(includeResponseHeaders)
+ `withRestrictedHeaders`(restrictedHeaders)
+ `withIncludeRequestBody`(includeRequestBody)
+ `withIncludeResponseBody`(includeResponseBody)
+ `enableReportingOptions`()— Enables all reporting options-- **includeRequestHeaders**, ** includeResponseHeaders**, **includeRequestBody**, and **includeResponseBody**, .
+ `disableReportingOptions`()— Disables all reporting options-- **includeRequestHeaders**, ** includeResponseHeaders**, **includeRequestBody**, and **includeResponseBody**, .

##### setConfig(options) for UI canaries
<a name="CloudWatch_Synthetics_Library_setConfigUI"></a>

For UI canaries, **setConfig** can include the following Boolean parameters:
+ `continueOnStepFailure` (boolean)— Whether to continue with running the canary script after a step fails (this refers to the ** executeStep** function). If any steps fail, the canary run will still be marked as failed. The default is `false`.
+ `harFile` (boolean)— Whether to create a HAR file. The default is `True`.
+ `screenshotOnStepStart` (boolean)— Whether to take a screenshot before starting a step.
+ `screenshotOnStepSuccess` (boolean)— Whether to take a screenshot after completing a successful step.
+ `screenshotOnStepFailure` (boolean)— Whether to take a screenshot after a step fails.

##### Methods to enable or disable screenshots
<a name="CloudWatch_Synthetics_Library_setConfig_screenshots"></a>

 **disableStepScreenshots()** 

Disables all screenshot options (screenshotOnStepStart, screenshotOnStepSuccess, and screenshotOnStepFailure).

 **enableStepScreenshots()** 

Enables all screenshot options (screenshotOnStepStart, screenshotOnStepSuccess, and screenshotOnStepFailure). By default, all these methods are enabled.

 **getScreenshotOnStepFailure()** 

Returns whether the canary takes a screenshot after a step fails.

 **getScreenshotOnStepStart()** 

Returns whether the canary takes a screenshot before starting a step.

 **getScreenshotOnStepSuccess()** 

Returns whether the canary takes a screenshot after completing a step successfully.

 **withScreenshotOnStepStart(screenshotOnStepStart)** 

Accepts a Boolean argument, which indicates whether to take a screenshot before starting a step.

 **withScreenshotOnStepSuccess(screenshotOnStepSuccess)** 

Accepts a Boolean argument, which indicates whether to take a screenshot after completing a step successfully.

 **withScreenshotOnStepFailure(screenshotOnStepFailure)** 

Accepts a Boolean argument, which indicates whether to take a screenshot after a step fails.

 **Usage in UI canaries** 

First, import the synthetics dependency and fetch the configuration.

```
// Import Synthetics dependency
const synthetics = require('@aws/synthetics-puppeteer');

// Get Synthetics configuration
const synConfig = synthetics.getConfiguration();
```

Then, set the configuration for each option by calling the setConfig method using one of the following options.

```
// Set configuration values
    synConfig.setConfig({
        screenshotOnStepStart: true, 
        screenshotOnStepSuccess: false,
        screenshotOnStepFailure: false
    });
```

Or

```
synConfig.withScreenshotOnStepStart(false).withScreenshotOnStepSuccess(true).withScreenshotOnStepFailure(true)
```

To disable all screenshots, use the `disableStepScreenshots()` function as in this example.

```
synConfig.disableStepScreenshots();
```

You can enable and disable screenshots at any point in the code. For example, to disable screenshots only for one step, disable them before running that step and then enable them after the step.

##### setConfig(options) for API canaries
<a name="CloudWatch_Synthetics_Library_setConfigAPI"></a>

For API canaries, **setConfig** can include the following Boolean parameters:
+ `continueOnHttpStepFailure` (boolean)— Whether to continue with running the canary script after an HTTP step fails (this refers to the **executeHttpStep** function). If any steps fail, the canary run will still be marked as failed. The default is `true`.

#### Visual monitoring
<a name="CloudWatch_Synthetics_Library_SyntheticsLogger_VisualTesting"></a>

Visual monitoring compares screenshots taken during a canary run with screenshots taken during a baseline canary run. If the discrepancy between the two screenshots is beyond a threshold percentage, the canary fails and you can see the areas with differences highlighted in color in the canary run report. Visual monitoring is supported in canaries running **syn-puppeteer-node-3.2** and later. It is not currently supported in canaries running Python and Selenium.

To enable visual monitoring, add the following line of code to the canary script. For more details, see [SyntheticsConfiguration class](#CloudWatch_Synthetics_Library_SyntheticsConfiguration).

```
syntheticsConfiguration.withVisualCompareWithBaseRun(true);
```

The first time that the canary runs successfully after this line is added to the script, it uses the screenshots taken during that run as the baseline for comparison. After that first canary run, you can use the CloudWatch console to edit the canary to do any of the following:
+ Set the next run of the canary as the new baseline.
+ Draw boundaries on the current baseline screenshot to designate areas of the screenshot to ignore during visual comparisons.
+ Remove a screenshot from being used for visual monitoring.

For more information about using the CloudWatch console to edit a canary, see [Edit or delete a canary](synthetics_canaries_deletion.md).

 **Other options for visual monitoring** 

 ** syntheticsConfiguration.withVisualVarianceThresholdPercentage(desiredPercentage)** 

Set the acceptable percentage for screenshot variance in visual comparisons.

 ** syntheticsConfiguration.withVisualVarianceHighlightHexColor("\$1fafa00")** 

Set the highlight color that designates variance areas when you look at canary run reports that use visual monitoring.

 ** syntheticsConfiguration.withFailCanaryRunOnVisualVariance(failCanary)** 

Set whether or not the canary fails when there is a visual difference that is more than the threshold. The default is to fail the canary.

### Synthetics logger
<a name="CloudWatch_Synthetics_Library_SyntheticsLogger"></a>

SyntheticsLogger writes logs out to both the console and to a local log file at the same log level. This log file is written to both locations only if the log level is at or below the desired logging level of the log function that was called.

The logging statements in the local log file are prepended with "DEBUG: ", "INFO: ", and so on to match the log level of the function that was called.

You can use the SyntheticsLogger, assuming you want to run the Synthetics Library at the same log level as your Synthetics canary logging.

Using the SyntheticsLogger is not required to create a log file that is uploaded to your S3 results location. You could instead create a different log file in the ` /tmp` folder. Any files created under the `/tmp` folder are uploaded to the results location in S3 as artifacts. 

To use the Synthetics Library logger:

```
const log = require('@aws/synthetics-logger');
```

Useful function definitions:

 **log.debug(*message*, *ex* );** 

Parameters: *message* is the message to log. * ex* is the exception, if any, to log.

Example:

```
log.debug("Starting step - login.");
```

 **log.error(*message*, *ex* );** 

Parameters: *message* is the message to log. * ex* is the exception, if any, to log.

Example:

```
try {
  await login();
catch (ex) {
  log.error("Error encountered in step - login.", ex);
}
```

 **log.info(*message*, *ex* );** 

Parameters: *message* is the message to log. * ex* is the exception, if any, to log.

Example:

```
log.info("Successfully completed step - login.");
```

 **log.log(*message*, *ex* );** 

This is an alias for `log.info`. 

Parameters: *message* is the message to log. * ex* is the exception, if any, to log.

Example:

```
 log.log("Successfully completed step - login.");
```

 **log.warn(*message*, *ex* );** 

Parameters: *message* is the message to log. * ex* is the exception, if any, to log.

Example:

```
log.warn("Exception encountered trying to publish CloudWatch Metric.", ex);
```

### SyntheticsLogHelper class
<a name="CloudWatch_Synthetics_Library_SyntheticsLogHelper"></a>

The `SyntheticsLogHelper` class is available in the runtime ` syn-nodejs-puppeteer-3.2` and later runtimes. It is already initialized in the CloudWatch Synthetics library and is configured with Synthetics configuration. You can add this as a dependency in your script. This class enables you to sanitize URLs, headers, and error messages to redact sensitive information.

**Note**  
Synthetics sanitizes all URLs and error messages it logs before including them in logs, reports, HAR files, and canary run errors based on the Synthetics configuration setting `restrictedUrlParameters`. You have to use ` getSanitizedUrl` or `getSanitizedErrorMessage` only if you are logging URLs or errors in your script. Synthetics does not store any canary artifacts except for canary errors thrown by the script. Canary run artifacts are stored in your customer account. For more information, see [Security considerations for Synthetics canaries](servicelens_canaries_security.md).

**Topics**
+ [

#### getSanitizedUrl(url, stepConfig = null)
](#CloudWatch_Synthetics_Library_getSanitizedUrl)
+ [

#### getSanitizedErrorMessage
](#CloudWatch_Synthetics_Library_getSanitizedErrorMessage)
+ [

#### getSanitizedHeaders(headers, stepConfig=null)
](#CloudWatch_Synthetics_Library_getSanitizedHeaders)

#### getSanitizedUrl(url, stepConfig = null)
<a name="CloudWatch_Synthetics_Library_getSanitizedUrl"></a>

This function is available in `syn-nodejs-puppeteer-3.2` and later. It returns sanitized url strings based on the configuration. You can choose to redact sensitive URL parameters such as password and access\$1token by setting the property `restrictedUrlParameters`. By default, passwords in URLs are redacted. You can enable URL passwords if needed by setting `includeUrlPassword` to true. 

This function throws an error if the URL passed in is not a valid URL.

 **Parameters ** 
+ *url* is a string and is the URL to sanitize.
+  *stepConfig* (Optional) overrides the global Synthetics configuration for this function. If `stepConfig` is not passed in, the global configuration is used to sanitize the URL.

 **Example ** 

This example uses the following sample URL: ` https://example.com/learn/home?access_token=12345&token_type=Bearer&expires_in=1200`. In this example, `access_token` contains your sensitive information which shouldn't be logged. Note that the Synthetics services doesn't store any canary run artifacts. Artifacts such as logs, screenshots, and reports are all stored in an Amazon S3 bucket in your customer account.

The first step is to set the Synthetics configuration.

```
// Import Synthetics dependency
const synthetics = require('@aws/synthetics-puppeteer');

// Import Synthetics logger for logging url
const log = require('@aws/synthetics-logger');

// Get Synthetics configuration
const synConfig = synthetics.getConfiguration();

// Set restricted parameters
synConfig.setConfig({
   restrictedUrlParameters: ['access_token'];
});
// Import SyntheticsLogHelper dependency
const syntheticsLogHelper = require('@aws/synthetics-log-helper');

const sanitizedUrl = syntheticsLogHelper.getSanitizedUrl('URL');



const urlConfig = {
   restrictedUrlParameters = ['*']
};
const sanitizedUrl = syntheticsLogHelper.getSanitizedUrl('URL', urlConfig);
logger.info('My example url is: ' + sanitizedUrl);
```

Next, sanitize and log the URL

```
// Import SyntheticsLogHelper dependency
const syntheticsLogHelper = require('@aws/synthetics-log-helper');

const sanitizedUrl = syntheticsLogHelper.getSanitizedUrl('https://example.com/learn/home?access_token=12345&token_type=Bearer&expires_in=1200');
```

This logs the following in your canary log.

```
My example url is: https://example.com/learn/home?access_token=REDACTED&token_type=Bearer&expires_in=1200
```

You can override the Synthetics configuration for a URL by passing in an optional parameter containing Synthetics configuration options, as in the following example.

```
const urlConfig = {
   restrictedUrlParameters = ['*']
};
const sanitizedUrl = syntheticsLogHelper.getSanitizedUrl('https://example.com/learn/home?access_token=12345&token_type=Bearer&expires_in=1200', urlConfig);
logger.info('My example url is: ' + sanitizedUrl);
```

The preceding example redacts all query parameters, and is logged as follows:

```
My example url is: https://example.com/learn/home?access_token=REDACTED&token_type=REDACTED&expires_in=REDACTED
```

#### getSanitizedErrorMessage
<a name="CloudWatch_Synthetics_Library_getSanitizedErrorMessage"></a>

This function is available in `syn-nodejs-puppeteer-3.2` and later. It returns sanitized error strings by sanitizing any URLs present based on the Synthetics configuration. You can choose to override the global Synthetics configuration when you call this function by passing an optional `stepConfig` parameter. 

 **Parameters ** 
+ *error* is the error to sanitize. It can be an Error object or a string.
+  *stepConfig* (Optional) overrides the global Synthetics configuration for this function. If `stepConfig` is not passed in, the global configuration is used to sanitize the URL.

 **Example ** 

This example uses the following error: ` Failed to load url: https://example.com/learn/home?access_token=12345&token_type=Bearer&expires_in=1200`

The first step is to set the Synthetics configuration.

```
// Import Synthetics dependency
const synthetics = require('@aws/synthetics-puppeteer');

// Import Synthetics logger for logging url
const log = require('@aws/synthetics-logger');

// Get Synthetics configuration
const synConfig = synthetics.getConfiguration();

// Set restricted parameters
synConfig.setConfig({
   restrictedUrlParameters: ['access_token'];
});
```

Next, sanitize and log the error message

```
// Import SyntheticsLogHelper dependency
const syntheticsLogHelper = require('@aws/synthetics-log-helper');

try {
   // Your code which can throw an error containing url which your script logs
} catch (error) {
    const sanitizedErrorMessage = syntheticsLogHelper.getSanitizedErrorMessage(errorMessage);
    logger.info(sanitizedErrorMessage);
}
```

This logs the following in your canary log.

```
Failed to load url: https://example.com/learn/home?access_token=REDACTED&token_type=Bearer&expires_in=1200
```

#### getSanitizedHeaders(headers, stepConfig=null)
<a name="CloudWatch_Synthetics_Library_getSanitizedHeaders"></a>

This function is available in `syn-nodejs-puppeteer-3.2` and later. It returns sanitized headers based on the `restrictedHeaders` property of ` syntheticsConfiguration`. The headers specified in the `restrictedHeaders` property are redacted from logs, HAR files, and reports. 

 **Parameters ** 
+ *headers* is an object containing the headers to sanitize.
+ *stepConfig* (Optional) overrides the global Synthetics configuration for this function. If `stepConfig` is not passed in, the global configuration is used to sanitize the headers.

## Node.js library classes and functions that apply to UI canaries only
<a name="CloudWatch_Synthetics_Library_UIcanaries"></a>

The following CloudWatch Synthetics library functions for Node.js are useful only for UI canaries.

**Topics**
+ [

### Synthetics class
](#CloudWatch_Synthetics_Library_Synthetics_Class)
+ [

### BrokenLinkCheckerReport class
](#CloudWatch_Synthetics_Library_BrokenLinkCheckerReport)
+ [

### SyntheticsLink class
](#CloudWatch_Synthetics_Library_SyntheticsLink)

### Synthetics class
<a name="CloudWatch_Synthetics_Library_Synthetics_Class"></a>

The following functions are in the Synthetics class.

**Topics**
+ [

#### async addUserAgent(page, userAgentString);
](#CloudWatch_Synthetics_Library_addUserAgent)
+ [

#### async executeStep(stepName, functionToExecute, [stepConfig]);
](#CloudWatch_Synthetics_Library_executeStep)
+ [

#### getDefaultLaunchOptions();
](#CloudWatch_Synthetics_Library_getDefaultLaunchOptions)
+ [

#### getPage();
](#CloudWatch_Synthetics_Library_getPage)
+ [

#### getRequestResponseLogHelper();
](#CloudWatch_Synthetics_Library_getRequestResponseLogHelper)
+ [

#### launch(options)
](#CloudWatch_Synthetics_Library_LaunchOptions)
+ [

#### RequestResponseLogHelper class
](#CloudWatch_Synthetics_Library_RequestResponseLogHelper)
+ [

#### setRequestResponseLogHelper();
](#CloudWatch_Synthetics_Library_setRequestResponseLogHelper)
+ [

#### async takeScreenshot(name, suffix);
](#CloudWatch_Synthetics_Library_takeScreenshot)

#### async addUserAgent(page, userAgentString);
<a name="CloudWatch_Synthetics_Library_addUserAgent"></a>

This function appends *userAgentString* to the specified page's user-agent header.

Example:

```
await synthetics.addUserAgent(page, "MyApp-1.0");
```

Results in the page’s user-agent header being set to ` browsers-user-agent-header-valueMyApp-1.0`

#### async executeStep(stepName, functionToExecute, [stepConfig]);
<a name="CloudWatch_Synthetics_Library_executeStep"></a>

Executes the provided step, wrapping it with start/pass/fail logging, start/pass/fail screenshots, and pass/fail and duration metrics.

**Note**  
If you are using the `syn-nodejs-2.1` or later runtime, you can configure whether and when screenshots are taken. For more information, see [SyntheticsConfiguration class](#CloudWatch_Synthetics_Library_SyntheticsConfiguration).

The `executeStep` function also does the following:
+ Logs that the step started.
+ Takes a screenshot named `<stepName>-starting`.
+ Starts a timer.
+ Executes the provided function.
+ If the function returns normally, it counts as passing. If the function throws, it counts as failing.
+ Ends the timer.
+ Logs whether the step passed or failed
+ Takes a screenshot named `<stepName>-succeeded` or ` <stepName>-failed`.
+ Emits the `stepName` `SuccessPercent` metric, 100 for pass or 0 for failure.
+ Emits the `stepName` `Duration` metric, with a value based on the step start and end times.
+ Finally, returns what the `functionToExecute` returned or re-throws what `functionToExecute` threw.

If the canary uses the `syn-nodejs-2.0` runtime or later, this function also adds a step execution summary to the canary's report. The summary includes details about each step, such as start time, end time, status (PASSED/FAILED), failure reason (if failed), and screenshots captured during the execution of each step.

Example:

```
await synthetics.executeStep('navigateToUrl', async function (timeoutInMillis = 30000) {
           await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis});});
```

Response:

Returns what `functionToExecute` returns.

 **Updates with syn-nodejs-2.2** 

Starting with `syn-nodejs-2.2`, you can optionally pass step configurations to override CloudWatch Synthetics configurations at the step level. For a list of options that you can pass to `executeStep`, see [SyntheticsConfiguration class](#CloudWatch_Synthetics_Library_SyntheticsConfiguration).

The following example overrides the default `false` configuration for ` continueOnStepFailure` to `true` and specifies when to take screenthots.

```
var stepConfig = {
    'continueOnStepFailure': true,
    'screenshotOnStepStart': false,
    'screenshotOnStepSuccess': true,
    'screenshotOnStepFailure': false
}

await executeStep('Navigate to amazon', async function (timeoutInMillis = 30000) {
      await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis});
 }, stepConfig);
```

#### getDefaultLaunchOptions();
<a name="CloudWatch_Synthetics_Library_getDefaultLaunchOptions"></a>

The `getDefaultLaunchOptions()` function returns the browser launch options that are used by CloudWatch Synthetics. For more information, see [Launch options type](https://pptr.dev/browsers-api/browsers.launchoptions/) 

```
// This function returns default launch options used by Synthetics.
const defaultOptions = await synthetics.getDefaultLaunchOptions();
```

#### getPage();
<a name="CloudWatch_Synthetics_Library_getPage"></a>

Returns the current open page as a Puppeteer object. For more information, see [Puppeteer API v1.14.0](https://github.com/puppeteer/puppeteer/blob/v1.14.0/docs/api.md).

Example:

```
let page = await synthetics.getPage();
```

Response:

The page (Puppeteer object) that is currently open in the current browser session.

#### getRequestResponseLogHelper();
<a name="CloudWatch_Synthetics_Library_getRequestResponseLogHelper"></a>

**Important**  
In canaries that use the `syn-nodejs-puppeteer-3.2` runtime or later, this function is deprecated along with the `RequestResponseLogHelper` class. Any use of this function causes a warning to appear in your canary logs. This function will be removed in future runtime versions. If you are using this function, use [RequestResponseLogHelper class](#CloudWatch_Synthetics_Library_RequestResponseLogHelper) instead. 

Use this function as a builder pattern for tweaking the request and response logging flags.

Example:

```
synthetics.setRequestResponseLogHelper(getRequestResponseLogHelper().withLogRequestHeaders(false));;
```

Response:

```
{RequestResponseLogHelper}
```

#### launch(options)
<a name="CloudWatch_Synthetics_Library_LaunchOptions"></a>

The options for this function are available only in the `syn-nodejs-2.1` runtime version or later.

This function is used only for UI canaries. It closes the existing browser and launches a new one.

**Note**  
CloudWatch Synthetics always launches a browser before starting to run your script. You don't need to call launch() unless you want to launch a new browser with custom options.

(options) is a configurable set of options to set on the browser. For more information, [Launch options type](https://pptr.dev/browsers-api/browsers.launchoptions/) .

If you call this function with no options, Synthetics launches a browser with default arguments, `executablePath`, and `defaultViewport`. The default viewport in CloudWatch Synthetics is 1920 by 1080.

You can override launch parameters used by CloudWatch Synthetics and pass additional parameters when launching the browser. For example, the following code snippet launches a browser with default arguments and a default executable path, but with a viewport of 800 x 600.

```
await synthetics.launch({
        defaultViewport: { 
            "deviceScaleFactor": 1, 
            "width": 800,
            "height": 600 
    }});
```

The following sample code adds a new `ignoreHTTPSErrors` parameter to the CloudWatch Synthetics launch parameters:

```
await synthetics.launch({
        ignoreHTTPSErrors: true
 });
```

You can disable web security by adding a `--disable-web-security` flag to args in the CloudWatch Synthetics launch parameters:

```
// This function adds the --disable-web-security flag to the launch parameters
const defaultOptions = await synthetics.getDefaultLaunchOptions();
const launchArgs = [...defaultOptions.args, '--disable-web-security'];
await synthetics.launch({
     args: launchArgs
  });
```

#### RequestResponseLogHelper class
<a name="CloudWatch_Synthetics_Library_RequestResponseLogHelper"></a>

**Important**  
In canaries that use the `syn-nodejs-puppeteer-3.2` runtime or later, this class is deprecated. Any use of this class causes a warning to appear in your canary logs. This function will be removed in future runtime versions. If you are using this function, use [RequestResponseLogHelper class](#CloudWatch_Synthetics_Library_RequestResponseLogHelper) instead.

Handles the fine-grained configuration and creation of string representations of request and response payloads. 

```
class RequestResponseLogHelper {
 
    constructor () {
        this.request = {url: true, resourceType: false, method: false, headers: false, postData: false};
        this.response = {status: true, statusText: true, url: true, remoteAddress: false, headers: false};
    }
 
    withLogRequestUrl(logRequestUrl);
    
    withLogRequestResourceType(logRequestResourceType);
    
    withLogRequestMethod(logRequestMethod);
    
    withLogRequestHeaders(logRequestHeaders);
    
    withLogRequestPostData(logRequestPostData);

        
    withLogResponseStatus(logResponseStatus);
    
    withLogResponseStatusText(logResponseStatusText);
   
    withLogResponseUrl(logResponseUrl);
 
    withLogResponseRemoteAddress(logResponseRemoteAddress);
    
    withLogResponseHeaders(logResponseHeaders);
```

Example:

```
synthetics.setRequestResponseLogHelper(getRequestResponseLogHelper()
.withLogRequestPostData(true)
.withLogRequestHeaders(true)
.withLogResponseHeaders(true));
```

Response:

```
{RequestResponseLogHelper}
```

#### setRequestResponseLogHelper();
<a name="CloudWatch_Synthetics_Library_setRequestResponseLogHelper"></a>

**Important**  
In canaries that use the `syn-nodejs-puppeteer-3.2` runtime or later, this function is deprecated along with the `RequestResponseLogHelper` class. Any use of this function causes a warning to appear in your canary logs. This function will be removed in future runtime versions. If you are using this function, use [RequestResponseLogHelper class](#CloudWatch_Synthetics_Library_RequestResponseLogHelper) instead. 

Use this function as a builder pattern for setting the request and response logging flags.

Example:

```
synthetics.setRequestResponseLogHelper().withLogRequestHeaders(true).withLogResponseHeaders(true);
```

Response:

```
{RequestResponseLogHelper}
```

#### async takeScreenshot(name, suffix);
<a name="CloudWatch_Synthetics_Library_takeScreenshot"></a>

Takes a screenshot (.PNG) of the current page with name and suffix (optional).

Example:

```
await synthetics.takeScreenshot("navigateToUrl", "loaded")
```

This example captures and uploads a screenshot named ` 01-navigateToUrl-loaded.png` to the canary's S3 bucket.

You can take a screenshot for a particular canary step by passing the ` stepName` as the first parameter. Screenshots are linked to the canary step in your reports, to help you track each step while debugging.

CloudWatch Synthetics canaries automatically take screenshots before starting a step (the `executeStep` function) and after the step completion (unless you configure the canary to disable screenshots). You can take more screenshots by passing in the step name in the `takeScreenshot` function.

The following example takes screenshot with the `signupForm` as the value of the `stepName`. The screenshot will be named ` 02-signupForm-address` and will be linked to the step named ` signupForm` in the canary report.

```
await synthetics.takeScreenshot('signupForm', 'address')
```

### BrokenLinkCheckerReport class
<a name="CloudWatch_Synthetics_Library_BrokenLinkCheckerReport"></a>

This class provides methods to add a synthetics link. It's supported only on canaries that use the `syn-nodejs-2.0-beta` version of the runtime or later. 

To use `BrokenLinkCheckerReport`, include the following lines in the script:

```
const BrokenLinkCheckerReport = require('@aws/synthetics-broken-link-checker-report');
            
const brokenLinkCheckerReport = new BrokenLinkCheckerReport();
```

Useful function definitions:

 **addLink(*syntheticsLink*, isBroken)** 

` syntheticsLink ` is a ` SyntheticsLink` object representing a link. This function adds the link according to the status code. By default, it considers a link to be broken if the status code is not available or the status code is 400 or higher. You can override this default behavior by passing in the optional parameter `isBrokenLink` with a value of `true` or `false`.

This function does not have a return value.

 **getLinks()** 

This function returns an array of `SyntheticsLink` objects that are included in the broken link checker report.

 **getTotalBrokenLinks()** 

This function returns a number representing the total number of broken links.

 **getTotalLinksChecked()** 

This function returns a number representing the total number of links included in the report.

 **How to use BrokenLinkCheckerReport** 

The following canary script code snippet demonstrates an example of navigating to a link and adding it to the broken link checker report.

1. Import `SyntheticsLink`, `BrokenLinkCheckerReport`, and ` Synthetics`.

   ```
   const BrokenLinkCheckerReport = require('@aws/synthetics-broken-link-checker-report');
   const SyntheticsLink = require('@aws/synthetics-link');
   
   // Synthetics dependency
   const synthetics = require('@aws/synthetics-puppeteer');
   ```

1. To add a link to the report, create an instance of ` BrokenLinkCheckerReport`.

   ```
   let brokenLinkCheckerReport = new BrokenLinkCheckerReport();
   ```

1. Navigate to the URL and add it to the broken link checker report.

   ```
   let url = "https://amazon.com";
   
   let syntheticsLink = new SyntheticsLink(url);
   
   // Navigate to the url.
   let page = await synthetics.getPage();
   
   // Create a new instance of Synthetics Link
   let link = new SyntheticsLink(url)
   
   try {
       const response = await page.goto(url, {waitUntil: 'domcontentloaded', timeout: 30000});
   } catch (ex) {
       // Add failure reason if navigation fails.
       link.withFailureReason(ex);
   }
   
   if (response) {
       // Capture screenshot of destination page
       let screenshotResult = await synthetics.takeScreenshot('amazon-home', 'loaded');
      
       // Add screenshot result to synthetics link
       link.addScreenshotResult(screenshotResult);
   
       // Add status code and status description to the link
       link.withStatusCode(response.status()).withStatusText(response.statusText())
   }
   
   // Add link to broken link checker report.
   brokenLinkCheckerReport.addLink(link);
   ```

1. Add the report to Synthetics. This creates a JSON file named ` BrokenLinkCheckerReport.json` in your S3 bucket for each canary run. You can see a links report in the console for each canary run along with screenshots, logs, and HAR files.

   ```
   await synthetics.addReport(brokenLinkCheckerReport);
   ```

### SyntheticsLink class
<a name="CloudWatch_Synthetics_Library_SyntheticsLink"></a>

This class provides methods to wrap information. It's supported only on canaries that use the `syn-nodejs-2.0-beta` version of the runtime or later. 

To use `SyntheticsLink`, include the following lines in the script:

```
const SyntheticsLink = require('@aws/synthetics-link');

const syntheticsLink = new SyntheticsLink("https://www.amazon.com");
```

This function returns `syntheticsLinkObject`

Useful function definitions:

 **withUrl(*url*)** 

` url ` is a URL string. This function returns `syntheticsLinkObject`

 **withText(*text*)** 

` text ` is a string representing anchor text. This function returns `syntheticsLinkObject`. It adds anchor text corresponding to the link.

 **withParentUrl(*parentUrl*)** 

` parentUrl ` is a string representing the parent (source page) URL. This function returns `syntheticsLink Object`

 **withStatusCode(*statusCode*)** 

` statusCode ` is a string representing the status code. This function returns `syntheticsLinkObject`

 **withFailureReason(*failureReason*)** 

` failureReason ` is a string representing the failure reason. This function returns `syntheticsLink Object`

 **addScreenshotResult(*screenshotResult*)** 

` screenshotResult ` is an object. It is an instance of `ScreenshotResult` that was returned by the Synthetics function `takeScreenshot`. The object includes the following:
+ `fileName`— A string representing the ` screenshotFileName`
+ `pageUrl` (optional)
+ `error` (optional)

## Node.js library classes and functions that apply to API canaries only
<a name="CloudWatch_Synthetics_Library_APIcanaries"></a>

The following CloudWatch Synthetics library functions for Node.js are useful only for API canaries.

**Topics**
+ [

### executeHttpStep(stepName, requestOptions, [callback], [stepConfig])
](#CloudWatch_Synthetics_Library_executeHttpStep)

### executeHttpStep(stepName, requestOptions, [callback], [stepConfig])
<a name="CloudWatch_Synthetics_Library_executeHttpStep"></a>

Executes the provided HTTP request as a step, and publishes `SuccessPercent` (pass/fail) and `Duration` metrics.

**executeHttpStep** uses either HTTP or HTTPS native functions under the hood, depending upon the protocol specified in the request.

This function also adds a step execution summary to the canary's report. The summary includes details about each HTTP request, such as the following:
+ Start time
+ End time
+ Status (PASSED/FAILED)
+ Failure reason, if it failed
+ HTTP call details such as request/response headers, body, status code, status message, and performance timings. 

**Topics**
+ [

#### Parameters
](#CloudWatch_Synthetics_Library_executeHttpStep_parameters)
+ [

#### Examples of using executeHttpStep
](#CloudWatch_Synthetics_Library_executeHttpStep_examples)

#### Parameters
<a name="CloudWatch_Synthetics_Library_executeHttpStep_parameters"></a>

 **stepName(*String*)** 

Specifies the name of the step. This name is also used for publishing CloudWatch metrics for this step.

 **requestOptions(*Object or String*)** 

The value of this parameter can be a URL, a URL string, or an object. If it is an object, then it must be a set of configurable options to make an HTTP request. It supports all options in [ http.request(options[, callback])](https://nodejs.org/api/http.html#http_http_request_options_callback) in the Node.js documentation.

In addition to these Node.js options, **requestOptions** supports the additional parameter `body`. You can use the `body` parameter to pass data as a request body.

 **callback(*response*)** 

(Optional) This is a user function which is invoked with the HTTP response. The response is of the type [ Class: http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage).

 **stepConfig(*object*)** 

(Optional) Use this parameter to override global synthetics configurations with a different configuration for this step.

#### Examples of using executeHttpStep
<a name="CloudWatch_Synthetics_Library_executeHttpStep_examples"></a>

The following series of examples build on each other to illustrate the various uses of this option.

This first example configures request parameters. You can pass a URL as ** requestOptions**:

```
let requestOptions = 'https://www.amazon.com';
```

Or you can pass a set of options:

```
let requestOptions = {
        'hostname': 'myproductsEndpoint.com',
        'method': 'GET',
        'path': '/test/product/validProductName',
        'port': 443,
        'protocol': 'https:'
    };
```

The next example creates a callback function which accepts a response. By default, if you do not specify **callback**, CloudWatch Synthetics validates that the status is between 200 and 299 inclusive.

```
// Handle validation for positive scenario
    const callback = async function(res) {
        return new Promise((resolve, reject) => {
            if (res.statusCode < 200 || res.statusCode > 299) {
                throw res.statusCode + ' ' + res.statusMessage;
            }
     
            let responseBody = '';
            res.on('data', (d) => {
                responseBody += d;
            });
     
            res.on('end', () => {
                // Add validation on 'responseBody' here if required. For ex, your status code is 200 but data might be empty
                resolve();
            });
        });
    };
```

The next example creates a configuration for this step that overrides the global CloudWatch Synthetics configuration. The step configuration in this example allows request headers, response headers, request body (post data), and response body in your report and restrict 'X-Amz-Security-Token' and 'Authorization' header values. By default, these values are not included in the report for security reasons. If you choose to include them, the data is only stored in your S3 bucket.

```
// By default headers, post data, and response body are not included in the report for security reasons. 
// Change the configuration at global level or add as step configuration for individual steps
let stepConfig = {
    includeRequestHeaders: true, 
    includeResponseHeaders: true,
    restrictedHeaders: ['X-Amz-Security-Token', 'Authorization'], // Restricted header values do not appear in report generated.
    includeRequestBody: true,
    includeResponseBody: true
};
```

This final example passes your request to **executeHttpStep** and names the step.

```
await synthetics.executeHttpStep('Verify GET products API', requestOptions, callback, stepConfig);
```

With this set of examples, CloudWatch Synthetics adds the details from each step in your report and produces metrics for each step using **stepName**.

 You will see `successPercent` and `duration` metrics for the `Verify GET products API` step. You can monitor your API performance by monitoring the metrics for your API call steps. 

For a sample complete script that uses these functions, see [Multi-step API canary](CloudWatch_Synthetics_Canaries_Samples.md#CloudWatch_Synthetics_Canaries_Samples_APIsteps).

# Library functions available for Python canary scripts using Selenium
<a name="CloudWatch_Synthetics_Canaries_Library_Python"></a>

This section lists the Selenium library functions available for Python canary scripts.

**Topics**
+ [

## Python and Selenium library classes and functions that apply to all canaries
](#CloudWatch_Synthetics_Library_allcanaries_Python)
+ [

## Python and Selenium library classes and functions that apply to UI canaries only
](#CloudWatch_Synthetics_Library_Python_UIcanaries)

## Python and Selenium library classes and functions that apply to all canaries
<a name="CloudWatch_Synthetics_Library_allcanaries_Python"></a>

The following CloudWatch Synthetics Selenium library functions for Python are useful for all canaries.

**Topics**
+ [

### SyntheticsConfiguration class
](#CloudWatch_Synthetics_Library_SyntheticsConfiguration_Python)
+ [

### SyntheticsLogger class
](#CloudWatch_Synthetics_Library_SyntheticsLogger_Python)

### SyntheticsConfiguration class
<a name="CloudWatch_Synthetics_Library_SyntheticsConfiguration_Python"></a>

You can use the SyntheticsConfiguration class to configure the behavior of Synthetics library functions. For example, you can use this class to configure the ` executeStep()` function to not capture screenshots.

You can set CloudWatch Synthetics configurations at the global level.

Function definitions:

#### set\$1config(options)
<a name="CloudWatch_Synthetics_Library_setConfig_Python"></a>

```
from aws_synthetics.common import synthetics_configuration
```

` options ` is an object, which is a set of configurable options for your canary. The following sections explain the possible fields in ` options `.
+ `screenshot_on_step_start` (boolean)— Whether to take a screenshot before starting a step.
+ `screenshot_on_step_success` (boolean)— Whether to take a screenshot after completing a successful step.
+ `screenshot_on_step_failure` (boolean)— Whether to take a screenshot after a step fails.

 **with\$1screenshot\$1on\$1step\$1start(screenshot\$1on\$1step\$1start)** 

Accepts a Boolean argument, which indicates whether to take a screenshot before starting a step.

 **with\$1screenshot\$1on\$1step\$1success(screenshot\$1on\$1step\$1success)** 

Accepts a Boolean argument, which indicates whether to take a screenshot after completing a step successfully.

 **with\$1screenshot\$1on\$1step\$1failure(screenshot\$1on\$1step\$1failure)** 

Accepts a Boolean argument, which indicates whether to take a screenshot after a step fails.

 **get\$1screenshot\$1on\$1step\$1start()** 

Returns whether to take a screenshot before starting a step.

 **get\$1screenshot\$1on\$1step\$1success()** 

Returns whether to take a screenshot after completing a step successfully.

 **get\$1screenshot\$1on\$1step\$1failure()** 

Returns whether to take a screenshot after a step fails.

 **disable\$1step\$1screenshots()** 

Disables all screenshot options (get\$1screenshot\$1on\$1step\$1start, get\$1screenshot\$1on\$1step\$1success, and get\$1screenshot\$1on\$1step\$1failure).

 **enable\$1step\$1screenshots()** 

Enables all screenshot options (get\$1screenshot\$1on\$1step\$1start, get\$1screenshot\$1on\$1step\$1success, and get\$1screenshot\$1on\$1step\$1failure). By default, all these methods are enabled.

 **setConfig(options) regarding CloudWatch metrics** 

For canaries using `syn-python-selenium-1.1` or later, the ** (options)** for **setConfig** can include the following Boolean parameters that determine which metrics are published by the canary. The default for each of these options is `true`. The options that start with ` aggregated` determine whether the metric is emitted without the ` CanaryName` dimension. You can use these metrics to see the aggregated results for all of your canaries. The other options determine whether the metric is emitted with the `CanaryName` dimension. You can use these metrics to see results for each individual canary.

For a list of CloudWatch metrics emitted by canaries, see [CloudWatch metrics published by canaries](CloudWatch_Synthetics_Canaries_metrics.md).
+ `failed_canary_metric` (boolean)— Whether to emit the ` Failed` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `failed_requests_metric` (boolean)— Whether to emit the `Failed requests` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `2xx_metric` (boolean)— Whether to emit the `2xx` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `4xx_metric` (boolean)— Whether to emit the `4xx` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `5xx_metric` (boolean)— Whether to emit the `5xx` metric (with the `CanaryName` dimension) for this canary. The default is `true`.
+ `step_duration_metric` (boolean)— Whether to emit the `Step duration` metric (with the `CanaryName` `StepName` dimensions) for this canary. The default is `true`.
+ `step_success_metric` (boolean)— Whether to emit the `Step success` metric (with the `CanaryName` `StepName` dimensions) for this canary. The default is `true`.
+ `aggregated_failed_canary_metric` (boolean)— Whether to emit the `Failed` metric (without the `CanaryName` dimension) for this canary. The default is `true`.
+ `aggregated_failed_requests_metric` (boolean)— Whether to emit the `Failed Requests` metric (without the `CanaryName` dimension) for this canary. The default is `true`.
+ `aggregated_2xx_metric` (boolean)— Whether to emit the ` 2xx` metric (without the `CanaryName` dimension) for this canary. The default is `true`.
+ `aggregated_4xx_metric` (boolean)— Whether to emit the ` 4xx` metric (without the `CanaryName` dimension) for this canary. The default is `true`.
+ `aggregated_5xx_metric` (boolean)— Whether to emit the ` 5xx` metric (without the `CanaryName` dimension) for this canary. The default is `true`.

 **with\$12xx\$1metric(2xx\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `2xx` metric with the `CanaryName` dimension for this canary.

 **with\$14xx\$1metric(4xx\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `4xx` metric with the `CanaryName` dimension for this canary.

 **with\$15xx\$1metric(5xx\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `5xx` metric with the `CanaryName` dimension for this canary.

 **withAggregated2xxMetric(aggregated2xxMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `2xx` metric with no dimension for this canary.

 **withAggregated4xxMetric(aggregated4xxMetric)** 

Accepts a Boolean argument, which specifies whether to emit a `4xx` metric with no dimension for this canary.

 **with\$1aggregated\$15xx\$1metric(aggregated\$15xx\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `5xx` metric with no dimension for this canary.

 ** with\$1aggregated\$1failed\$1canary\$1metric(aggregated\$1failed\$1canary\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `Failed` metric with no dimension for this canary.

 ** with\$1aggregated\$1failed\$1requests\$1metric(aggregated\$1failed\$1requests\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `Failed requests` metric with no dimension for this canary.

 **with\$1failed\$1canary\$1metric(failed\$1canary\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `Failed` metric with the `CanaryName` dimension for this canary.

 **with\$1failed\$1requests\$1metric(failed\$1requests\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `Failed requests` metric with the `CanaryName` dimension for this canary.

 **with\$1step\$1duration\$1metric(step\$1duration\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `Duration` metric with the `CanaryName` dimension for this canary.

 **with\$1step\$1success\$1metric(step\$1success\$1metric)** 

Accepts a Boolean argument, which specifies whether to emit a `StepSuccess` metric with the `CanaryName` dimension for this canary.

##### Methods to enable or disable metrics
<a name="CloudWatch_Synthetics_Python_setConfig_metrics"></a>

 **disable\$1aggregated\$1request\$1metrics()** 

Disables the canary from emitting all request metrics that are emitted with no ` CanaryName` dimension.

 **disable\$1request\$1metrics()** 

Disables all request metrics, including both per-canary metrics and metrics aggregated across all canaries.

 **disable\$1step\$1metrics()** 

Disables all step metrics, including both step success metrics and step duration metrics.

 **enable\$1aggregated\$1request\$1metrics()** 

Enables the canary to emit all request metrics that are emitted with no ` CanaryName` dimension.

 **enable\$1request\$1metrics()** 

Enables all request metrics, including both per-canary metrics and metrics aggregated across all canaries.

 **enable\$1step\$1metrics()** 

Enables all step metrics, including both step success metrics and step duration metrics.

 **Usage in UI canaries** 

First, import the synthetics dependency and fetch the configuration. Then, set the configuration for each option by calling the setConfig method using one of the following options.

```
from aws_synthetics.common import synthetics_configuration

synthetics_configuration.set_config(
     {
        "screenshot_on_step_start": False,
        "screenshot_on_step_success": False,
        "screenshot_on_step_failure": True
     }
)

or
```

Or

```
synthetics_configuration.with_screenshot_on_step_start(False).with_screenshot_on_step_success(False).with_screenshot_on_step_failure(True)
```

To disable all screenshots, use the disableStepScreenshots() function as in this example.

```
synthetics_configuration.disable_step_screenshots()
```

You can enable and disable screenshots at any point in the code. For example, to disable screenshots only for one step, disable them before running that step and then enable them after the step.

##### set\$1config(options) for UI canaries
<a name="CloudWatch_Synthetics_Library_Python_UI"></a>

Starting with `syn-python-selenium-1.1`, for UI canaries, ` set_config` can include the following Boolean parameters:
+ `continue_on_step_failure` (boolean)— Whether to continue with running the canary script after a step fails (this refers to the ** executeStep** function). If any steps fail, the canary run will still be marked as failed. The default is `false`.

### SyntheticsLogger class
<a name="CloudWatch_Synthetics_Library_SyntheticsLogger_Python"></a>

`synthetics_logger` writes logs out to both the console and to a local log file at the same log level. This log file is written to both locations only if the log level is at or below the desired logging level of the log function that was called.

The logging statements in the local log file are prepended with "DEBUG: ", "INFO: ", and so on to match the log level of the function that was called.

Using `synthetics_logger` is not required to create a log file that is uploaded to your Amazon S3 results location. You could instead create a different log file in the `/tmp` folder. Any files created under the `/tmp` folder are uploaded to the results location in the S3 bucket as artifacts.

To use `synthetics_logger`:

```
from aws_synthetics.common import synthetics_logger
```

****Useful function definitions:

Get log level:

```
log_level = synthetics_logger.get_level()
```

Set log level:

```
synthetics_logger.set_level()
```

Log a message with a specified level. The level can be `DEBUG`, ` INFO`, `WARN`, or `ERROR`, as in the following syntax examples:

```
synthetics_logger.debug(message, *args, **kwargs)
```

```
synthetics_logger.info(message, *args, **kwargs)
```

```
synthetics_logger.log(message, *args, **kwargs)
```

```
synthetics_logger.warning(message, *args, **kwargs)
```

```
synthetics_logger.error(message, *args, **kwargs)
```

For information about debug parameters, see the standard Python documentation at [logging.debug](https://docs.python.org/3/library/logging.html#logging.debug)

In these logging functions, the `message` is the message format string. The `args` are the arguments that are merged into `msg` using the string formatting operator.

There are three keyword arguments in `kwargs`:
+ `exc_info`– If not evaluated as false, adds exception information to the logging message.
+ `stack_info`– defaults to false. If true, adds stack information to the logging message, including the actual logging call.
+ `extra`– The third optional keyword argument, which you can use to pass in a dictionary that is used to populate the `__dict__` of the `LogRecord` created for the logging event with user-defined attributes.

Examples:

Log a message with the level `DEBUG`:

```
synthetics_logger.debug('Starting step - login.')
```

Log a message with the level `INFO`. `logger.log` is a synonym for `logger.info`:

```
synthetics_logger.info('Successfully completed step - login.')
```

or

```
synthetics_logger.log('Successfully completed step - login.')
```

Log a message with the level `WARN`:

```
synthetics_logger.warning('Warning encountered trying to publish %s', 'CloudWatch Metric')
```

Log a message with the level `ERROR`:

```
synthetics_logger.error('Error encountered trying to publish %s', 'CloudWatch Metric')
```

Log an exception:

```
synthetics_logger.exception(message, *args, **kwargs)
```

Logs a message with level `ERROR`. Exception information is added to the logging message. You should call this function only from an exception handler.

For information about exception parameters, see the standard Python documentation at [ logging.exception](https://docs.python.org/3/library/logging.html#logging.exception)

The `message` is the message format string. The `args` are the arguments, which are merged into `msg` using the string formatting operator.

There are three keyword arguments in `kwargs`:
+ `exc_info`– If not evaluated as false, adds exception information to the logging message.
+ `stack_info`– defaults to false. If true, adds stack information to the logging message, including the actual logging call.
+ `extra`– The third optional keyword argument, which you can use to pass in a dictionary that is used to populate the `__dict__` of the `LogRecord` created for the logging event with user-defined attributes.

Example:

```
synthetics_logger.exception('Error encountered trying to publish %s', 'CloudWatch Metric')
```

## Python and Selenium library classes and functions that apply to UI canaries only
<a name="CloudWatch_Synthetics_Library_Python_UIcanaries"></a>

The following CloudWatch Synthetics Selenium library functions for Python are useful only for UI canaries.

**Topics**
+ [

### SyntheticsBrowser class
](#CloudWatch_Synthetics_Library_Python_SyntheticsBrowser)
+ [

### SyntheticsWebDriver class
](#CloudWatch_Synthetics_Library_Python_SyntheticsWebDriver)

### SyntheticsBrowser class
<a name="CloudWatch_Synthetics_Library_Python_SyntheticsBrowser"></a>

**Note**  
`SyntheticsBrowser` is supported only on the Chrome browser.

When you create a browser instance by calling `synthetics_webdriver.Chrome()`, the returned browser instance is of the type `SyntheticsBrowser`. The ` SyntheticsBrowser` class inherits the WebDriver class and provides access to all the methods exposed by the [WebDriver](https://www.selenium.dev/documentation/webdriver/). It controls the ChromeDriver, and enables the canary script to drive the browser, allowing the Selenium WebDriver to work with Synthetics.

**Note**  
Synthetics overrides the WebDriver [ quit](https://www.selenium.dev/selenium/docs/api/py/selenium_webdriver_firefox/selenium.webdriver.firefox.webdriver.html) method to take no action. You don't need to worry about quitting the browser, as Synthetics handles that for you.

In addition to the standard Selenium methods, it also provides the following methods. 

**Topics**
+ [

#### set\$1viewport\$1size(width, height)
](#CloudWatch_Synthetics_Library_set_viewport_size)
+ [

#### save\$1screenshot(filename, suffix)
](#CloudWatch_Synthetics_Library_save_screenshot)

#### set\$1viewport\$1size(width, height)
<a name="CloudWatch_Synthetics_Library_set_viewport_size"></a>

Sets the viewport of the browser. Example:

```
browser.set_viewport_size(1920, 1080)
```

#### save\$1screenshot(filename, suffix)
<a name="CloudWatch_Synthetics_Library_save_screenshot"></a>

Saves screenshots to the `/tmp` directory. The screenshots are uploaded from there to the canary artifacts folder in the S3 bucket.

*filename* is the file name for the screenshot, and * suffix* is an optional string to be used for naming the screenshot.

Example:

```
browser.save_screenshot('loaded.png', 'page1')
```

### SyntheticsWebDriver class
<a name="CloudWatch_Synthetics_Library_Python_SyntheticsWebDriver"></a>

To use this class, use the following in your script:

```
from aws_synthetics.selenium import synthetics_webdriver
```

**Topics**
+ [

#### add\$1execution\$1error(errorMessage, ex);
](#CloudWatch_Synthetics_Library_Python_addExecutionError)
+ [

#### add\$1user\$1agent(user\$1agent\$1str)
](#CloudWatch_Synthetics_Library_add_user_agent)
+ [

#### execute\$1step(step\$1name, function\$1to\$1execute)
](#CloudWatch_Synthetics_Library_Python_execute_step)
+ [

#### get\$1http\$1response(url)
](#CloudWatch_Synthetics_Library_Python_get_http_response)
+ [

#### Chrome()
](#CloudWatch_Synthetics_Library_Python_Chrome)

#### add\$1execution\$1error(errorMessage, ex);
<a name="CloudWatch_Synthetics_Library_Python_addExecutionError"></a>

`errorMessage` describes the error and `ex` is the exception that is encountered

You can use `add_execution_error` to set execution errors for your canary. It fails the canary without interrupting the script execution. It also doesn't impact your `successPercent` metrics.

You should track errors as execution errors only if they are not important to indicate the success or failure of your canary script.

An example of the use of `add_execution_error` is the following. You are monitoring the availability of your endpoint and taking screenshots after the page has loaded. Because the failure of taking a screenshot doesn't determine availability of the endpoint, you can catch any errors encountered while taking screenshots and add them as execution errors. Your availability metrics will still indicate that the endpoint is up and running, but your canary status will be marked as failed. The following sample code block catches such an error and adds it as an execution error.

```
try:
    browser.save_screenshot("loaded.png")  
except Exception as ex:
   self.add_execution_error("Unable to take screenshot", ex)
```

#### add\$1user\$1agent(user\$1agent\$1str)
<a name="CloudWatch_Synthetics_Library_add_user_agent"></a>

Appends the value of `user_agent_str` to the browser's user agent header. You must assign `user_agent_str` before creating the browser instance.

Example:

```
await synthetics_webdriver.add_user_agent('MyApp-1.0')
```

`add_user_agent` should be used inside an `async` function.

#### execute\$1step(step\$1name, function\$1to\$1execute)
<a name="CloudWatch_Synthetics_Library_Python_execute_step"></a>

Processes one function. It also does the following:
+ Logs that the step started.
+ Takes a screenshot named `<stepName>-starting`.
+ Starts a timer.
+ Executes the provided function.
+ If the function returns normally, it counts as passing. If the function throws, it counts as failing.
+ Ends the timer.
+ Logs whether the step passed or failed
+ Takes a screenshot named `<stepName>-succeeded` or ` <stepName>-failed`.
+ Emits the `stepName` `SuccessPercent` metric, 100 for pass or 0 for failure.
+ Emits the `stepName` `Duration` metric, with a value based on the step start and end times.
+ Finally, returns what the `functionToExecute` returned or re-throws what `functionToExecute` threw.

Example:

```
from selenium.webdriver.common.by import By

def custom_actions():
        #verify contains
        browser.find_element(By.XPATH, "//*[@id=\"id_1\"][contains(text(),'login')]")
        #click a button
        browser.find_element(By.XPATH, '//*[@id="submit"]/a').click()

    await synthetics_webdriver.execute_step("verify_click", custom_actions)
```

#### get\$1http\$1response(url)
<a name="CloudWatch_Synthetics_Library_Python_get_http_response"></a>

Makes an HTTP request to the provided URL and returns the response code of the HTTP request. If an exception occurred during the HTTP request, a string with value "error" is returned instead.

Example:

```
response_code = syn_webdriver.get_http_response(url)
if not response_code or response_code == "error" or response_code < 200 or response_code > 299:
    raise Exception("Failed to load page!")
```

#### Chrome()
<a name="CloudWatch_Synthetics_Library_Python_Chrome"></a>

Launches an instance of the Chromium browser and returns the created instance of the browser.

Example:

```
browser = synthetics_webdriver.Chrome()
browser.get("https://example.com/)
```

To launch a browser in incognito mode, use the following:

```
add_argument('——incognito')
```

To add proxy settings, use the following:

```
add_argument('--proxy-server=%s' % PROXY)
```

Example:

```
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("——incognito")
browser = syn_webdriver.Chrome(chrome_options=chrome_options)
```

# Scheduling canary runs using cron
<a name="CloudWatch_Synthetics_Canaries_cron"></a>

Using a cron expression gives you flexibility when you schedule a canary. Cron expressions contain five or six fields in the order listed in the following table. The fields are separated by spaces. The syntax differs depending on whether you are using the CloudWatch console to create the canary, or the AWS CLI or AWS SDKs. When you use the console, you specify only the first five fields. When you use the AWS CLI or AWS SDKs, you specify all six fields, and you must specify `*` for the `Year` field.


|  **Field**  |  **Allowed values**  |  **Allowed special characters**  | 
| --- | --- | --- | 
|  Minutes  |  0-59  |  , - \$1 /  | 
|  Hours  |  0-23  |  , - \$1 /  | 
|  Day-of-month  |  1-31  |  , - \$1 ? / L W  | 
|  Month  |  1-12 or JAN-DEC  |  , - \$1 /  | 
|  Day-of-week  |  1-7 or SUN-SAT  |  , - \$1 ? L \$1  | 
|  Year  |  \$1  |    | 

**Special characters**
+ The **,** (comma) includes multiple values in the expression for a field. For example, in the Month field, JAN,FEB,MAR would include January, February, and March.
+ The **-** (dash) special character specifies ranges. In the Day field, 1-15 would include days 1 through 15 of the specified month.
+ The **\$1** (asterisk) special character includes all values in the field. In the Hours field, **\$1** includes every hour. You cannot use ** \$1** in both the Day-of-month and Day-of-week fields in the same expression. If you use it in one, you must use **?** in the other.
+ The **/** (forward slash) specifies increments. In the Minutes field, you can enter 1/10 to specify every tenth minute, starting from the first minute of the hour (for example, the eleventh, twenty-first, and thirty-first minute, and so on).
+ The **?** (question mark) specifies one or another. If you enter ** 7** in the Day-of-month field and you don't care what day of the week the seventh is, you can enter **?** in the Day-of-week field.
+ The **L** wildcard in the Day-of-month or Day-of-week fields specifies the last day of the month or week.
+ The **W** wildcard in the Day-of-month field specifies a weekday. In the Day-of-month field, **3W** specifies the weekday closest to the third day of the month.
+ The **\$1** wildcard in the Day-of-week field specifies a certain instance of the specified day of the week within a month. For example, 3\$12 is the second Tuesday of the month. The 3 refers to Tuesday because it is the third day of each week, and the 2 refers to the second day of that type within the month.

**Limitations**
+ You can't specify the Day-of-month and Day-of-week fields in the same cron expression. If you specify a value or `*` (asterisk) in one of the fields, you must use a **?** (question mark) in the other.
+ Cron expressions that lead to rates faster than one minute are not supported.
+ You can't set a canary to wait for more than a year before running, so you can specify only `*` in the `Year` field.

**Examples**  
You can refer to the following sample cron strings when you create a canary. The following examples are the correct syntax for using the AWS CLI or AWS SDKs to create or update a canary. If you are using the CloudWatch console, omit the final `*` in each example.


| Expression | Meaning | 
| --- | --- | 
|   `0 10 * * ? *`   |  Run at 10:00 am (UTC) every day  | 
|   `15 12 * * ? *`   |  Run at 12:15 pm (UTC) every day  | 
|   `0 18 ? * MON-FRI *`   |  Run at 6:00 pm (UTC) every Monday through Friday  | 
|   `0 8 1 * ? *`   |  Run at 8:00 am (UTC) on the first day of each month  | 
|   `0/10 * ? * MON-SAT *`   |  Run every 10 minutes Monday through Saturday of each week  | 
|   `0/5 8-17 ? * MON-FRI *`   |  Run every five minutes Monday through Friday between 8:00 am and 5:55 pm (UTC)   | 

# Configuring your canary to retry automatically
<a name="CloudWatch_Synthetics_Canaries_autoretry"></a>

When you create or update a canary, you can configure your canaries to automatically attempt additional runs when the scheduled one fails. This helps differentiate between genuine failures and temporary glitches, providing more reliable results. This feature is ideal for building more resilient monitoring systems while reducing false alarms and manual intervention.

**To create a auto retry canary**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Application Signals**, **Synthetics Canaries**.

1. Choose **Create Canary**.

1. Under **Additional configuration**, **Auto-retry,** select the desired maximum retry number.

**To update the maximum retry number for a canary**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Application Signals**, **Synthetics Canaries**.

1. You can do one of the following:
   + Select the canary and choose **Actions**, **Enable auto-retry**, and adjust the maximum retries.
   + Select the canary and choose **Actions**, **Edit**. In the **Edit detail** page, under **Additional configuration**, **Auto-retry**, adjust the retry configuration.

 **Limitations** 

Here are the limitations to configure auto retry.
+ Supported only on runtime versions `syn-nodejs-puppeteer-10.0 `or newer, ` syn-nodejs-playwright-2.0` or newer, or `syn-python-selenium-5.1` or newer, or `syn-nodejs-3.0` or newer.
+ Long running canaries which timeout after ten minutes are limited to one retry. All other canaries can support upto two retries

# Using dependencies with CloudWatch Synthetics canaries
<a name="CloudWatch_Synthetics_Canaries_dependencies"></a>

This section explains how to use `Dependencies` in CloudWatch Synthetics canaries. The `Dependencies` field allows you to specify dependencies for your canaries, enabling you to include additional libraries or custom code that your canary scripts can use.

## Overview
<a name="overview"></a>

CloudWatch Synthetics canaries support specifying Lambda layers as dependencies. This feature allows you to:
+ Share common code across multiple canaries
+ Manage dependencies separately from your canary script code
+ Reduce the size of your canary script by moving dependencies to a Lambda layer

## Supported APIs
<a name="supported-apis"></a>

The `Dependencies` field is supported in the following APIs:
+  [CreateCanary](https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_CreateCanary.html) 
+  [UpdateCanary](https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_UpdateCanary.html) 
+  [ StartCanaryDryRun](https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_StartCanaryDryRun.html) 

## Syntax
<a name="syntax"></a>

The `Dependencies` field is part of the code structure in the request syntax:

```
"Code": { 
  "Handler": "string",
  "S3Bucket": "string",
  "S3Key": "string",
  "S3Version": "string",
  "ZipFile": blob,
  "Dependencies": [
    {
      "Type": "LambdaLayer",
      "Reference": "string"
    }
  ]
}
```

## Using dependencies
<a name="usage"></a>

Here are some examples and instructions for using the `Dependencies` field in different scenarios.

### Creating a Canary with dependencies
<a name="creating-canary"></a>

When creating a canary, you can specify a Lambda layer as a dependency:

```
{
  "Name": "my-canary",
  "Code": {
    "Handler": "pageLoadBlueprint.handler",
    "S3Bucket": "my-bucket",
    "S3Key": "my-canary-script.zip",
    "Dependencies": [
      {
        "Type": "LambdaLayer",
        "Reference": "arn:aws:lambda:us-west-2:123456789012:layer:my-custom-layer:1"
      }
    ]
  },
  "ArtifactS3Location": "s3://my-bucket/artifacts/",
  "ExecutionRoleArn": "arn:aws:iam::123456789012:role/my-canary-role",
  "Schedule": {
    "Expression": "rate(5 minutes)"
  },
  "RuntimeVersion": "syn-nodejs-puppeteer-3.9"
}
```

### Updating a Canary's dependencies
<a name="updating-canary"></a>

You can update a canary's dependencies using the UpdateCanary API:

```
{
  "Name": "my-canary",
  "Code": {
    "Dependencies": [
      {
        "Type": "LambdaLayer",
        "Reference": "arn:aws:lambda:us-west-2:123456789012:layer:my-updated-layer:2"
      }
    ]
  }
}
```

### Removing dependencies
<a name="removing-dependencies"></a>

To remove dependencies from a canary, provide an empty array for the Dependencies field:

```
{
  "Name": "my-canary",
  "Code": {
    "Dependencies": []
  }
}
```

### Testing dependencies with StartCanaryDryRun
<a name="testing-dependencies"></a>

Before updating a canary with new dependencies, you can test them using the StartCanaryDryRun API:

```
{
  "Name": "my-canary",
  "Code": {
    "Dependencies": [
      {
        "Type": "LambdaLayer",
        "Reference": "arn:aws:lambda:us-west-2:123456789012:layer:my-test-layer:3"
      }
    ]
  }
}
```

## Limitations and considerations
<a name="limitations"></a>
+ Only one Lambda layer can be specified as a dependency
+ The role being used to create a canary with dependencies should have ` lambda:GetLayerVersion` access to the dependency layer in addition to the [necessary roles and permissions](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Roles.html)

## Creating compatible Lambda layers
<a name="creating-compatible-layers"></a>

For information on how to create and package layers, see [Managing Lambda dependencies with layers ](https://docs.aws.amazon.com/lambda/latest/dg/chapter-layers.html) and to understand the packaging structure of a canary check based on the canary packing structure, see [Writing a canary script](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_WritingCanary.html).

# Groups
<a name="CloudWatch_Synthetics_Groups"></a>

You can create *groups* to associate canaries with each other, including cross-Region canaries. Using groups can help you with managing and automating your canaries, and you can also view aggregated run results and statistics for all canaries in a group. 

Groups are global resources. When you create a group, it is replicated across all AWS Regions that support groups, and you can add canaries from any of these Regions to it, and view it in any of these Regions. Although the group ARN format reflects the Region name where it was created, a group is not constrained to any Region. This means that you can put canaries from multiple Regions into the same group, and then use that group to view and manage all of those canaries in a single view.

Groups are supported in all Regions except the Regions that are disabled by default. For more information about these Regions, see [Enabling a Region ](https://docs.aws.amazon.com/general/latest/gr/rande-manage.html#rande-manage-enable).

Each group can contain as many as 10 canaries. You can have as many as 20 groups in your account. Any single canary can be a member of up to 10 groups.

**To create a group**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Application Signals**, **Synthetics Canaries**.

   

1. Choose **Create Group**.

1. Under **Group Name**, enter a name for the group. 

1. Select canaries to associate with this group. To select a canary, type its complete name in **Exact canary name** and choose **Search**. Then select the check box next to the canary name. If there are multiple canaries with the same name in different Regions, be sure to select the canaries that you want.

   You can repeat this step to associate as many as 10 canaries with the group.

1. (Optional) Under **Tags**, add one or more key-value pairs as tags for this group. Tags can help you identify and organize your AWS resources and track your AWS costs. For more information, see [Tagging your Amazon CloudWatch resources](CloudWatch-Tagging.md).

1. Choose **Create Group**.

# Test a canary locally
<a name="CloudWatch_Synthetics_Debug_Locally"></a>

This section explains how to modify, test, and debug CloudWatch Synthetics canaries directly within the Microsoft Visual Studio code editor or the JetBrains IDE code editor. The local debugging environment uses a Serverless Application Model (SAM) container to simulate a Lambda function to emulate the behavior of a Synthetics canary. 

**Note**  
It is impractical to perform locally debug canaries that rely on visual monitoring. Visual monitoring rely on capturing base screenshots during an initial run, and then comparing these screenshots to the screenshots from subsequent runs. In a local development environment, runs are not stored or tracked, and each iteration is an independent, standalone run. The absence of a canary run history makes it impractical to debug canaries that rely on visual monitoring.

 **Prerequisites** 

1. Choose or create an Amazon S3 bucket to use to store artifacts from local canary test runs, such as HAR files and screenshots. This requires you to be provisioned with IAM. If you skip setting up Amazon S3 buckets you can still test your canary locally, but you will see an error message about the missing bucket and you won't have access to canary artifacts.

   If you use an Amazon S3 bucket, we recommend that you set the bucket lifecycle to delete objects after a few days, to save costs. For more information, see [Managing your storage lifecycle](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html).

1. Set up a default AWS profile for your AWS account. For more information, see [Configuration and credential file settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html).

1. Set the debug environment's default AWS Region to your preferred Region, such as ` us-west-2`.

1. Install the AWS SAM CLI. For more information, see [Installing the AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html).

1. Install Visual Studio Code Editor or JetBrains IDE. For more information, see [https://code.visualstudio.com/](https://code.visualstudio.com/) or [https://www.jetbrains.com/ides/](https://www.jetbrains.com/ides/)

1. Install Docker to work with the AWS SAM CLI. Make sure to start the docker daemon. For more information, see [Installing  Docker to use with the AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-docker.html).

   Alternatively, You can install other container management software such as  Rancher, as long as it uses the Docker runtime.

1. Install an AWS toolkit extension for your preferred editor. For more information, see [Installing the AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/setup-toolkit.html) or [Installing the AWS Toolkit for JetBrains](https://docs.aws.amazon.com/toolkit-for-jetbrains/latest/userguide/setup-toolkit.html).

**Topics**
+ [

## Set up the testing and debugging environment
](#CloudWatch_Synthetics_Debug_Environment)
+ [

## Use Visual Studio Code IDE
](#CloudWatch_Synthetics_Debug_VS)
+ [

## Use JetBrains IDE
](#CloudWatch_Synthetics_Debug_JetBrains)
+ [

## Run a canary locally with the SAM CLI
](#CloudWatch_Synthetics_Run_Locally)
+ [

## Integrate your local testing environment into an existing canary package
](#CloudWatch_Synthetics_Debug_Integrate)
+ [

## Change the CloudWatch Synthetics runtime
](#CloudWatch_Synthetics_Debug_DifferentRuntime)
+ [

## Common errors
](#CloudWatch_Synthetics_Debug_Errors)

## Set up the testing and debugging environment
<a name="CloudWatch_Synthetics_Debug_Environment"></a>

First, clone the Github repository that AWS provides by entering the following command. The repository contains code samples for both Node.js canaries and Python canaries. 

```
git clone https://github.com/aws-samples/synthetics-canary-local-debugging-sample.git
```

Then do one of the following, depending on the language of your canaries.

**For Node.js canaries**

1. Go to the Node.js canary source directory by entering the following command.

   ```
   cd synthetics-canary-local-debugging-sample/nodejs-canary/src
   ```

1. Enter the following command to install canary dependencies.

   ```
   npm install
   ```

**For Python canaries**

1. Go to the Python canary source directory by entering the following command.

   ```
   cd synthetics-canary-local-debugging-sample/python-canary/src
   ```

1. Enter the following command to install canary dependencies.

   ```
   pip3 install -r requirements.txt -t .
   ```

## Use Visual Studio Code IDE
<a name="CloudWatch_Synthetics_Debug_VS"></a>

The Visual Studio launch configuration file is located at ` .vscode/launch.json`. It contains configurations to allow the template file to be discovered by Visual Studio code. It defines a Lambda payload with required parameters to invoke the canary successfully. Here’s the launch configuration for a Node.js canary: 

```
{
            ...
            ...
            "lambda": {
                "payload": {
                    "json": {
                        // Canary name. Provide any name you like.
                        "canaryName": "LocalSyntheticsCanary", 
                        // Canary artifact location
                        "artifactS3Location": {
                            "s3Bucket": "cw-syn-results-123456789012-us-west-2",
                            "s3Key": "local-run-artifacts",
                        },
                        // Your canary handler name
                        "customerCanaryHandlerName": "heartbeat-canary.handler"
                    }
                },
                // Environment variables to pass to the canary code
                "environmentVariables": {}
            }
        }
    ]
}
```

You can also optionally provide the following fields in the payload JSON:
+ `s3EncryptionMode` Valid values: `SSE_S3` \$1 `SSE_KMS`
+ `s3KmsKeyArn` Valid value: *KMS Key ARN*
+ `activeTracing` Valid values: `true` \$1 `false`
+ `canaryRunId` Valid value: *UUID* This parameter is required if active tracing is enabled.

To debug the canary in Visual Studio, add breakpoints in the canary code where you want to pause execution. To add a breakpoint, choose the editor margin and go to **Run and Debug** mode in the editor. Run the canary by clicking on the play button. When the canary runs, the logs will be tailed in the debug console, providing you with real-time insights into the canary's behavior. If you added breakpoints, the canary execution will pause at each breakpoint, allowing you to step through code and inspect variable values, instance methods, object attributes, and the function call stack.

There is no cost incurred for running and debugging canaries locally, except for the artifacts stored in the Amazon S3 bucket and the CloudWatch metrics generated by each local run.

![\[Visual Studio Code interface showing JavaScript code for a heartbeat canary function.\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/images/DebugCanaryVS.png)


## Use JetBrains IDE
<a name="CloudWatch_Synthetics_Debug_JetBrains"></a>

After you have the AWS Toolkit for JetBrains extension installed, be sure that the Node.js plugin and JavaScript debugger are enabled to run, if you are debugging a Node.js canary. Then follow these steps.

**Debug a canary using JetBrains IDE**

1. In the left navigation pane of JetBrains IDE, choose **Lambda**, then choose the local configuration template.

1. Enter a name for the run configuration, such as **LocalSyntheticsCanary**

1. Choose **From template**, choose the file browser in the template field, then select the **template.yml** file from the project, either from the **nodejs** directory or the **python** directory.

1. In the **Input** section, enter the payload for the canary as shown in the following screen.

   ```
   {
    "canaryName": "LocalSyntheticsCanary",
    "artifactS3Location": {
        "s3Bucket": "cw-syn-results-123456789012-us-west-2",
        "s3Key": "local-run-artifacts"
    },
    "customerCanaryHandlerName": "heartbeat-canary.handler"
   }
   ```

   You can also set other environment variables in the payload JSON, as listed in [Use Visual Studio Code IDE](#CloudWatch_Synthetics_Debug_VS).

![\[Run/Debug Configurations interface for AWS Lambda with LocalSyntheticsCanary settings.\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/images/DebugCanaryIntellij.png)


## Run a canary locally with the SAM CLI
<a name="CloudWatch_Synthetics_Run_Locally"></a>

Use the one of the following procedures to run your canary locally using the Serverless Application Model (SAM) CLI. Be sure to specify your own Amazon S3 bucket name for `s3Bucket` in `event.json`

**To use the SAM CLI to run a Node.js canary**

1. Go to the source directory by entering the following command.

   ```
   cd synthetics-canary-local-debugging-sample/nodejs-canary
   ```

1. Enter the following commands.

   ```
   sam build
   sam local invoke -e ../event.json
   ```

**To use the SAM CLI to run a Python canary**

1. Go to the source directory by entering the following command.

   ```
   cd synthetics-canary-local-debugging-sample/python-canary
   ```

1. Enter the following commands.

   ```
   sam build
   sam local invoke -e ../event.json
   ```

## Integrate your local testing environment into an existing canary package
<a name="CloudWatch_Synthetics_Debug_Integrate"></a>

You can integrate local canary debugging into your existing canary package by copying three files:
+ Copy the `template.yml` file into your canary package root. Be sure to modify the path for `CodeUri` to point to the directory where your canary code exists.
+ If you're working with a Node.js canary, copy the `cw-synthetics.js` file to your canary source directory. If you're working with a Python canary, copy the ` cw-synthetics.py` to your canary source directory.
+ Copy the launch configuration file .`vscode/launch.json` into the package root. Make sure to put it inside the `.vscode` directory; create it if it doesn't exist already.

## Change the CloudWatch Synthetics runtime
<a name="CloudWatch_Synthetics_Debug_DifferentRuntime"></a>

As part of your debugging, you might want to try running a canary with a different CloudWatch Synthetics runtime, instead of the latest runtime. To do so, find the runtime that you want to use from one of the following tables. Be sure to select the runtime for the correct Region. Then paste the ARN for that runtime into the appropriate place in your ` template.yml` file, and then run the canary.

### Node.js and Puppeteer runtimes
<a name="Synthetics_NodeJS_Puppeteer_Runtime_ARNs"></a>

#### ARNs for syn-nodejs-puppeteer-15.0
<a name="syn-nodejs-puppeteer-15.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-15.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-puppeteer-14.0
<a name="syn-nodejs-puppeteer-14.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-14.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-puppeteer-13.1
<a name="syn-nodejs-puppeteer-13.1"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-13.1` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-puppeteer-13.0
<a name="syn-nodejs-puppeteer-13.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-13.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-puppeteer-12.0
<a name="syn-nodejs-puppeteer-12.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-12.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-puppeteer-11.0
<a name="syn-nodejs-puppeteer-11.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-11.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-puppeteer-10.0
<a name="syn-nodejs-puppeteer-10.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-10.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics:58`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics:61`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics:59`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics:61`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics:59`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics:59`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics:34`   | 
|  Asia Pacific (Jakarta)  |   `arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics:41`   | 
|  Asia Pacific (Malaysia)  |   `arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics:15`   | 
|  Asia Pacific (Melbourne)  |   `arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics:32`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics:59`   | 
|  Asia Pacific (New Zealand)  |   `arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics:18`   | 
|  Asia Pacific (Osaka)  |   `arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics:45`   | 
|  Asia Pacific (Seoul)  |   `arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics:62`   | 
|  Asia Pacific (Singapore)  |   `arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics:63`   | 
|  Asia Pacific (Sydney)  |   `arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics:58`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics:24`   | 
|  Asia Pacific (Thailand)  |   `arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics:6`   | 
|  Asia Pacific (Tokyo)  |   `arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics:59`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics:59`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics:90`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics:58`   | 
|  China (Ningxia);  |   `arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics:59`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics:59`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics:60`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics:58`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics:60`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics:59`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics:34`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics:59`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics:33`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics:31`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics:7`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics:58`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics:34`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics:60`   | 
|  AWS GovCloud (US-East)  |   `arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics:54`   | 
|  AWS GovCloud (US-West)  |   `arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics:55`   | 

#### ARNs for syn-nodejs-puppeteer-9.1
<a name="syn-nodejs-puppeteer-9.1"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-9.1` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics:53`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics:56`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics:54`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics:56`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics:54`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics:54`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics:29`   | 
|  Asia Pacific (Jakarta)  |   `arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics:36`   | 
|  Asia Pacific (Malaysia)  |   `arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics:10`   | 
|  Asia Pacific (Melbourne)  |   `arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics:27`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics:54`   | 
|  Asia Pacific (New Zealand)  |   `arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics:17`   | 
|  Asia Pacific (Osaka)  |   `arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics:40`   | 
|  Asia Pacific (Seoul)  |   `arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics:57`   | 
|  Asia Pacific (Singapore)  |   `arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics:58`   | 
|  Asia Pacific (Sydney)  |   `arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics:53`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics:25`   | 
|  Asia Pacific (Thailand)  |   `arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics:1`   | 
|  Asia Pacific (Tokyo)  |   `arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics:54`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics:54`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics:85`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics:54`   | 
|  China (Ningxia);  |   `arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics:55`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics:54`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics:55`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics:53`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics:55`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics:54`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics:29`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics:54`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics:28`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics:26`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics:3`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics:53`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics:29`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics:55`   | 
|  AWS GovCloud (US-East)  |   `arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics:50`   | 
|  AWS GovCloud (US-West)  |   `arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics:51`   | 

#### ARNs for syn-nodejs-puppeteer-9.0
<a name="syn-nodejs-puppeteer-9.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-9.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics:51`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics:54`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics:52`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics:54`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics:52`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics:52`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics:27`   | 
|  Asia Pacific (Jakarta)  |   `arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics:34`   | 
|  Asia Pacific (Malaysia)  |   `arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics:8`   | 
|  Asia Pacific (Melbourne)  |   `arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics:25`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics:52`   | 
|  Asia Pacific (New Zealand)  |   `arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics:16`   | 
|  Asia Pacific (Osaka)  |   `arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics:38`   | 
|  Asia Pacific (Seoul)  |   `arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics:55`   | 
|  Asia Pacific (Singapore)  |   `arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics:56`   | 
|  Asia Pacific (Sydney)  |   `arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics:51`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics:26`   | 
|  Asia Pacific (Tokyo)  |   `arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics:52`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics:52`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics:83`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics:52`   | 
|  China (Ningxia);  |   `arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics:53`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics:52`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics:53`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics:51`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics:53`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics:52`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics:27`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics:52`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics:26`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics:24`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics:51`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics:27`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics:53`   | 
|  AWS GovCloud (US-East)  |   `arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics:48`   | 
|  AWS GovCloud (US-West)  |   `arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics:49`   | 

#### ARNs for syn-nodejs-puppeteer-8.0
<a name="syn-nodejs-puppeteer-8.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-8.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics:48`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics:50`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics:48`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics:51`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics:48`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics:49`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics:24`   | 
|  Asia Pacific (Jakarta)  |   `arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics:30`   | 
|  Asia Pacific (Melbourne)  |   `arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics:22`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics:48`   | 
|  Asia Pacific (New Zealand)  |   `arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics:15`   | 
|  Asia Pacific (Osaka)  |   `arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics:34`   | 
|  Asia Pacific (Seoul)  |   `arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics:51`   | 
|  Asia Pacific (Singapore)  |   `arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics:53`   | 
|  Asia Pacific (Sydney)  |   `arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics:48`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics:23`   | 
|  Asia Pacific (Tokyo)  |   `arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics:48`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics:48`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics:80`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics:49`   | 
|  China (Ningxia);  |   `arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics:50`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics:48`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics:50`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics:48`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics:49`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics:48`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics:24`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics:48`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics:23`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics:21`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics:48`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics:23`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics:49`   | 
|  AWS GovCloud (US-East)  |   `arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics:45`   | 
|  AWS GovCloud (US-West)  |   `arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics:46`   | 

#### ARNs for syn-nodejs-puppeteer-7.0
<a name="syn-nodejs-puppeteer-7.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-7.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics:44`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics:46`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics:44`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics:47`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics:44`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics:45`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics:20`   | 
|  Asia Pacific (Jakarta)  |   `arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics:26`   | 
|  Asia Pacific (Malaysia)  |   `arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics:7`   | 
|  Asia Pacific (Melbourne)  |   `arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics:18`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics:44`   | 
|  Asia Pacific (Osaka)  |   `arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics:30`   | 
|  Asia Pacific (Seoul)  |   `arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics:46`   | 
|  Asia Pacific (Singapore)  |   `arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics:49`   | 
|  Asia Pacific (Sydney)  |   `arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics:44`   | 
|  Asia Pacific (Thailand)  |   `arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics:3`   | 
|  Asia Pacific (Tokyo)  |   `arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics:44`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics:44`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics:76`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics:45`   | 
|  China (Ningxia);  |   `arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics:46`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics:44`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics:46`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics:44`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics:45`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics:44`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics:20`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics:44`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics:19`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics:17`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics:4`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics:44`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics:19`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics:45`   | 
|  AWS GovCloud (US-East)  |   `arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics:41`   | 
|  AWS GovCloud (US-West)  |   `arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics:42`   | 

#### ARNs for syn-nodejs-puppeteer-6.2
<a name="syn-nodejs-puppeteer-6.2"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-6.2` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics:41`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics:43`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics:41`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics:44`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics:41`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics:42`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics:17`   | 
|  Asia Pacific (Jakarta)  |   `arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics:23`   | 
|  Asia Pacific (Melbourne)  |   `arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics:15`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics:41`   | 
|  Asia Pacific (Osaka)  |   `arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics:27`   | 
|  Asia Pacific (Seoul)  |   `arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics:42`   | 
|  Asia Pacific (Singapore)  |   `arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics:46`   | 
|  Asia Pacific (Sydney)  |   `arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics:41`   | 
|  Asia Pacific (Tokyo)  |   `arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics:41`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics:41`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics:73`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics:42`   | 
|  China (Ningxia);  |   `arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics:43`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics:41`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics:43`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics:41`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics:42`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics:41`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics:17`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics:41`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics:16`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics:14`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics:41`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics:16`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics:42`   | 
|  AWS GovCloud (US-East)  |   `arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics:39`   | 
|  AWS GovCloud (US-West)  |   `arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics:39`   | 

#### ARNs for syn-nodejs-puppeteer-5.2
<a name="syn-nodejs-puppeteer-5.2"></a>

The following table lists the ARNs to use for version ` syn-nodejs-puppeteer-5.2` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics:42`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics:44`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics:42`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics:45`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics:42`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics:43`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics:18`   | 
|  Asia Pacific (Jakarta)  |   `arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics:24`   | 
|  Asia Pacific (Melbourne)  |   `arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics:16`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics:42`   | 
|  Asia Pacific (Osaka)  |   `arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics:28`   | 
|  Asia Pacific (Seoul)  |   `arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics:44`   | 
|  Asia Pacific (Singapore)  |   `arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics:47`   | 
|  Asia Pacific (Sydney)  |   `arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics:42`   | 
|  Asia Pacific (Tokyo)  |   `arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics:42`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics:42`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics:74`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics:43`   | 
|  China (Ningxia);  |   `arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics:44`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics:42`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics:44`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics:42`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics:43`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics:42`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics:18`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics:42`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics:17`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics:15`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics:42`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics:17`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics:43`   | 
|  AWS GovCloud (US-East)  |   `arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics:40`   | 
|  AWS GovCloud (US-West)  |   `arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics:40`   | 

### Node.js and Playwright runtimes
<a name="Synthetics_Playwright_Runtime_ARNs"></a>

#### ARNs for syn-nodejs-playwright-6.0
<a name="syn-nodejs-playwright-6.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-playwright-6.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-playwright-5.1
<a name="syn-nodejs-playwright-5.1"></a>

The following table lists the ARNs to use for version ` syn-nodejs-playwright-5.1` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-playwright-5.0
<a name="syn-nodejs-playwright-5.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-playwright-5.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-playwright-4.0
<a name="syn-nodejs-playwright-4.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-playwright-4.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-playwright-3.0
<a name="syn-nodejs-playwright-3.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-playwright-3.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Debug_Locally.html)

#### ARNs for syn-nodejs-playwright-2.0
<a name="syn-nodejs-playwright-2.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-playwright-2.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   ` arn:aws:lambda:us-east-1:378653112637:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  US East (Ohio)  |   ` arn:aws:lambda:us-east-2:772927465453:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  US West (N. California)  |   ` arn:aws:lambda:us-west-1:332033056316:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  US West (Oregon)  |   ` arn:aws:lambda:us-west-2:760325925879:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Africa (Cape Town)  |   ` arn:aws:lambda:af-south-1:461844272066:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Hong Kong)  |   ` arn:aws:lambda:ap-east-1:129828061636:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Hyderabad)  |   ` arn:aws:lambda:ap-south-2:280298676434:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Mumbai)  |   ` arn:aws:lambda:ap-south-1:724929286329:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:AWS-CW-SyntheticsNodeJsPlaywright:7`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Asia Pacific (Taipei)  |   ` arn:aws:lambda:ap-east-2:471112897378:layer:AWS-CW-SyntheticsNodeJsPlaywright:9`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:AWS-CW-SyntheticsNodeJsPlaywright:3`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Canada (Central)  |   ` arn:aws:lambda:ca-central-1:236629016841:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Canada West (Calgary)  |   ` arn:aws:lambda:ca-west-1:944448206667:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  China (Beijing)  |   ` arn:aws-cn:lambda:cn-north-1:422629156088:layer:AWS-CW-SyntheticsNodeJsPlaywright:3`   | 
|  China (Ningxia);  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:AWS-CW-SyntheticsNodeJsPlaywright:3`   | 
|  Europe (Frankfurt)  |   ` arn:aws:lambda:eu-central-1:122305336817:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Europe (Ireland)  |   ` arn:aws:lambda:eu-west-1:563204233543:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Europe (London)  |   ` arn:aws:lambda:eu-west-2:565831452869:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Europe (Milan)  |   ` arn:aws:lambda:eu-south-1:525618516618:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Europe (Paris)  |   ` arn:aws:lambda:eu-west-3:469466506258:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Europe (Spain)  |   ` arn:aws:lambda:eu-south-2:029793053121:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Europe (Stockholm)  |   ` arn:aws:lambda:eu-north-1:162938142733:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Europe (Zurich)  |   ` arn:aws:lambda:eu-central-2:224218992030:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Israel (Tel Aviv)  |   ` arn:aws:lambda:il-central-1:313249807427:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Mexico (Central)  |   ` arn:aws:lambda:mx-central-1:654654265476:layer:AWS-CW-SyntheticsNodeJsPlaywright:5`   | 
|  Middle East (Bahrain)  |   ` arn:aws:lambda:me-south-1:823195537320:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  Middle East (UAE)  |   ` arn:aws:lambda:me-central-1:239544149032:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  South America (São Paulo)  |   ` arn:aws:lambda:sa-east-1:783765544751:layer:AWS-CW-SyntheticsNodeJsPlaywright:4`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:AWS-CW-SyntheticsNodeJsPlaywright:3`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:AWS-CW-SyntheticsNodeJsPlaywright:3`   | 

#### ARNs for syn-nodejs-playwright-1.0
<a name="syn-nodejs-playwright-1.0"></a>

The following table lists the ARNs to use for version ` syn-nodejs-playwright-1.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   ` arn:aws:lambda:us-east-1:378653112637:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  US East (Ohio)  |   ` arn:aws:lambda:us-east-2:772927465453:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  US West (N. California)  |   ` arn:aws:lambda:us-west-1:332033056316:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  US West (Oregon)  |   ` arn:aws:lambda:us-west-2:760325925879:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Africa (Cape Town)  |   ` arn:aws:lambda:af-south-1:461844272066:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Hong Kong)  |   ` arn:aws:lambda:ap-east-1:129828061636:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Hyderabad)  |   ` arn:aws:lambda:ap-south-2:280298676434:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Mumbai)  |   ` arn:aws:lambda:ap-south-1:724929286329:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:AWS-CW-SyntheticsNodeJsPlaywright:8`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Taipei)  |   ` arn:aws:lambda:ap-east-2:471112897378:layer:AWS-CW-SyntheticsNodeJsPlaywright:10`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Canada (Central)  |   ` arn:aws:lambda:ca-central-1:236629016841:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Canada West (Calgary)  |   ` arn:aws:lambda:ca-west-1:944448206667:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  China (Beijing)  |   ` arn:aws-cn:lambda:cn-north-1:422629156088:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  China (Ningxia);  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Europe (Frankfurt)  |   ` arn:aws:lambda:eu-central-1:122305336817:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Europe (Ireland)  |   ` arn:aws:lambda:eu-west-1:563204233543:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Europe (London)  |   ` arn:aws:lambda:eu-west-2:565831452869:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Europe (Milan)  |   ` arn:aws:lambda:eu-south-1:525618516618:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Europe (Paris)  |   ` arn:aws:lambda:eu-west-3:469466506258:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Europe (Spain)  |   ` arn:aws:lambda:eu-south-2:029793053121:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Europe (Stockholm)  |   ` arn:aws:lambda:eu-north-1:162938142733:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Europe (Zurich)  |   ` arn:aws:lambda:eu-central-2:224218992030:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Israel (Tel Aviv)  |   ` arn:aws:lambda:il-central-1:313249807427:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Mexico (Central)  |   ` arn:aws:lambda:mx-central-1:654654265476:layer:AWS-CW-SyntheticsNodeJsPlaywright:3`   | 
|  Middle East (Bahrain)  |   ` arn:aws:lambda:me-south-1:823195537320:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  Middle East (UAE)  |   ` arn:aws:lambda:me-central-1:239544149032:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  South America (São Paulo)  |   ` arn:aws:lambda:sa-east-1:783765544751:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:AWS-CW-SyntheticsNodeJsPlaywright:1`   | 

### Node.js runtimes
<a name="Synthetics_NodeJS_Runtime_ARNs"></a>

#### ARNs for syn-nodejs-4.1
<a name="syn-nodejs-4.1"></a>

The following table lists the ARNs to use for version `syn-nodejs-4.1` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Africa (Cape Town)  |   ` arn:aws:lambda:af-south-1:461844272066:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Hyderabad)  |   ` arn:aws:lambda:ap-south-2:280298676434:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Mumbai)  |   ` arn:aws:lambda:ap-south-1:724929286329:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Canada (Central)  |   ` arn:aws:lambda:ca-central-1:236629016841:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  China (Beijing)  |   ` arn:aws-cn:lambda:cn-north-1:422629156088:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  China (Ningxia)  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Europe (Frankfurt)  |   ` arn:aws:lambda:eu-central-1:122305336817:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Europe (Milan)  |   ` arn:aws:lambda:eu-south-1:525618516618:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Europe (Spain)  |   ` arn:aws:lambda:eu-south-2:029793053121:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Europe (Stockholm)  |   ` arn:aws:lambda:eu-north-1:162938142733:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Europe (Zurich)  |   ` arn:aws:lambda:eu-central-2:224218992030:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Israel (Tel Aviv)  |   ` arn:aws:lambda:il-central-1:313249807427:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  Mexico (Central)  |   ` arn:aws:lambda:mx-central-1:654654265476:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:AWS-CW-SyntheticsNodeJs:12`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:AWS-CW-SyntheticsNodeJs:12`   | 

#### ARNs for syn-nodejs-4.0
<a name="syn-nodejs-4.0"></a>

The following table lists the ARNs to use for version `syn-nodejs-4.0` of the CloudWatch Synthetics runtimein each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Africa (Cape Town)  |   ` arn:aws:lambda:af-south-1:461844272066:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Hyderabad)  |   ` arn:aws:lambda:ap-south-2:280298676434:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Mumbai)  |   ` arn:aws:lambda:ap-south-1:724929286329:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Canada (Central)  |   ` arn:aws:lambda:ca-central-1:236629016841:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  China (Beijing)  |   ` arn:aws-cn:lambda:cn-north-1:422629156088:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  China (Ningxia)  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Europe (Frankfurt)  |   ` arn:aws:lambda:eu-central-1:122305336817:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Europe (Milan)  |   ` arn:aws:lambda:eu-south-1:525618516618:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Europe (Spain)  |   ` arn:aws:lambda:eu-south-2:029793053121:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Europe (Stockholm)  |   ` arn:aws:lambda:eu-north-1:162938142733:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Europe (Zurich)  |   ` arn:aws:lambda:eu-central-2:224218992030:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Israel (Tel Aviv)  |   ` arn:aws:lambda:il-central-1:313249807427:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  Mexico (Central)  |   ` arn:aws:lambda:mx-central-1:654654265476:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:AWS-CW-SyntheticsNodeJs:11`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:AWS-CW-SyntheticsNodeJs:11`   | 

#### ARNs for syn-nodejs-3.1
<a name="syn-nodejs-3.1"></a>

The following table lists the ARNs to use for version `syn-nodejs-3.1` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Canada (Central)  |   ` arn:aws:lambda:ca-central-1:236629016841:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  China (Beijing)  |   ` arn:aws-cn:lambda:cn-north-1:422629156088:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  China (Ningxia)  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Europe (Frankfurt)  |   ` arn:aws:lambda:eu-central-1:122305336817:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Europe (Zurich)  |   ` arn:aws:lambda:eu-central-2:224218992030:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Israel (Tel Aviv)  |   ` arn:aws:lambda:il-central-1:313249807427:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Mexico (Central)  |   ` arn:aws:lambda:mx-central-1:654654265476:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  Middle East (UAE)  |   ` arn:aws:lambda:me-central-1:239544149032:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:AWS-CW-SyntheticsNodeJs:9`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:AWS-CW-SyntheticsNodeJs:9`   | 

#### ARNs for syn-nodejs-3.0
<a name="syn-nodejs-3.0"></a>

The following table lists the ARNs to use for version `syn-nodejs-3.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Canada (Central)  |   ` arn:aws:lambda:ca-central-1:236629016841:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  China (Beijing)  |   ` arn:aws-cn:lambda:cn-north-1:422629156088:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  China (Ningxia)  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Europe (Frankfurt)  |   ` arn:aws:lambda:eu-central-1:122305336817:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Europe (Zurich)  |   ` arn:aws:lambda:eu-central-2:224218992030:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Israel (Tel Aviv)  |   ` arn:aws:lambda:il-central-1:313249807427:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Mexico (Central)  |   ` arn:aws:lambda:mx-central-1:654654265476:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  Middle East (UAE)  |   ` arn:aws:lambda:me-central-1:239544149032:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:AWS-CW-SyntheticsNodeJs:1`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:AWS-CW-SyntheticsNodeJs:1`   | 

### Python and Selenium runtimes
<a name="Synthetics_Python_Runtime_ARNs"></a>

#### ARNs for syn-python-selenium-10.0
<a name="syn-python-selenium-10.0"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-10.0` of the CloudWatch Synthetics runtimein each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:62`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:65`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:63`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:64`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:63`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:62`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:50`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:57`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:32`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:48`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:63`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics_Selenium:38`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:61`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:66`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:67`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:62`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics_Selenium:25`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics_Selenium:23`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:63`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:63`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:106`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:61`   | 
|  China (Ningxia)  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:61`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:63`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:64`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:62`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:64`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:63`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:50`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:63`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:49`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:47`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics_Selenium:24`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:64`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:59`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:60`   | 

#### ARNs for syn-python-selenium-9.0
<a name="syn-python-selenium-9.0"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-9.0` of the CloudWatch Synthetics runtimein each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:61`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:64`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:62`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:63`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:62`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:61`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:49`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:56`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:31`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:47`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:62`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics_Selenium:37`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:60`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:65`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:66`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:61`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics_Selenium:24`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics_Selenium:22`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:62`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:62`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:105`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:60`   | 
|  China (Ningxia)  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:60`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:62`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:63`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:61`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:63`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:62`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:49`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:62`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:48`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:46`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics_Selenium:23`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics_Selenium:61`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics_Selenium:49`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:63`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:58`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:59`   | 

#### ARNs for syn-python-selenium-8.0
<a name="syn-python-selenium-8.0"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-8.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:57`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:60`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:58`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:59`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:58`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:57`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:45`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:52`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:27`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:43`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:58`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics_Selenium:33`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:56`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:61`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:62`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:57`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics_Selenium:20`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics_Selenium:18`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:58`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:58`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:101`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:56`   | 
|  China (Ningxia)  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:56`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:58`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:59`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:57`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:59`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:58`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:45`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:58`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:44`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:42`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics_Selenium:19`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics_Selenium:57`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics_Selenium:45`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:59`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:54`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:55`   | 

#### ARNs for syn-python-selenium-7.0
<a name="syn-python-selenium-7.0"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-7.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:49`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:52`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:50`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:51`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:50`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:49`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:37`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:44`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:19`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:35`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:50`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics_Selenium:25`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:48`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:53`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:54`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:49`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics_Selenium:12`   | 
|  Asia Pacific (Thailand)  |   ` arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics_Selenium:10`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:50`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:50`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:93`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:48`   | 
|  China (Ningxia)  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:48`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:50`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:51`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:49`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:51`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:50`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:37`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:50`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:36`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:34`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics_Selenium:11`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics_Selenium:49`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics_Selenium:37`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:51`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:46`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:47`   | 

#### ARNs for syn-python-selenium-6.0
<a name="syn-python-selenium-6.0"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-6.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:47`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:50`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:48`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:49`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:48`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:47`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:35`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:42`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:17`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:33`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:48`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics_Selenium:25`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:46`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:51`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:52`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:47`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics_Selenium:10`   | 
|  Asia Pacific (Thailand)  |   `arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics_Selenium:8`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:48`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:48`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:91`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:46`   | 
|  China (Ningxia)  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:46`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:48`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:49`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:47`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:49`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:48`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:35`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:48`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:34`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:32`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics_Selenium:9`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics_Selenium:47`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics_Selenium:35`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:49`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:44`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:45`   | 

#### ARNs for syn-python-selenium-5.1
<a name="syn-python-selenium-5.1"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-5.1` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:45`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:48`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:46`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:47`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:46`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:45`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:33`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:40`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:15`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:31`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:46`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics_Selenium:24`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:44`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:49`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:50`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:45`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics_Selenium:8`   | 
|  Asia Pacific (Thailand)  |   `arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics_Selenium:6`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:46`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:44`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:89`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:44`   | 
|  China (Ningxia);  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:44`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:46`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:47`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:45`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:47`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:46`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:33`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:46`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:32`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:30`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics_Selenium:7`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics_Selenium:45`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics_Selenium:33`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:47`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:42`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:43`   | 

#### ARNs for syn-python-selenium-5.0
<a name="syn-python-selenium-5.0"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-5.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:43`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:46`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:44`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:45`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:44`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:43`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:31`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:38`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:13`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:29`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:44`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics_Selenium:23`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:42`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:47`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:48`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:43`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics_Selenium:3`   | 
|  Asia Pacific (Thailand)  |   `arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics_Selenium:4`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:44`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:44`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:87`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:43`   | 
|  China (Ningxia);  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:43`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:44`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:45`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:43`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:45`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:44`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:31`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:44`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:30`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:28`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics_Selenium:5`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics_Selenium:43`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics_Selenium:31`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:45`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:41`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:42`   | 

#### ARNs for syn-python-selenium-4.1
<a name="syn-python-selenium-4.1"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-4.1` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:40`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:43`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:41`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:42`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:41`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:40`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:28`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:35`   | 
|  Asia Pacific (Malaysia)  |   ` arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:10`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:26`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:41`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics_Selenium:22`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:39`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:44`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:45`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:40`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics_Selenium:4`   | 
|  Asia Pacific (Thailand)  |   `arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics_Selenium:1`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:41`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:41`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:84`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:40`   | 
|  China (Ningxia);  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:40`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:41`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:42`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:40`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:42`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:41`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:28`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:41`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:27`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:25`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics_Selenium:3`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics_Selenium:40`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics_Selenium:28`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:42`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:38`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:39`   | 

#### ARNs for syn-python-selenium-4.0
<a name="syn-python-selenium-4.0"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-4.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:38`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:41`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:39`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:40`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:39`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:38`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:26`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:33`   | 
|  Asia Pacific (Malaysia)  |   `arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:8`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:24`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:39`   | 
|  Asia Pacific (New Zealand)  |   ` arn:aws:lambda:ap-southeast-6:779414629109:layer:Synthetics_Selenium:21`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:37`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:42`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:43`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:38`   | 
|  Asia Pacific (Taipei)  |   `arn:aws:lambda:ap-east-2:471112897378:layer:Synthetics_Selenium:5`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:39`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:39`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:82`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:38`   | 
|  China (Ningxia);  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:38`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:39`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:40`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:38`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:40`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:39`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:26`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:39`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:25`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:23`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics_Selenium:38`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics_Selenium:26`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:40`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:36`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:37`   | 

#### ARNs for syn-python-selenium-3.0
<a name="syn-python-selenium-3.0"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-3.0` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics_Selenium:32`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics_Selenium:34`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics_Selenium:32`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics_Selenium:34`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics_Selenium:32`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics_Selenium:32`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics_Selenium:20`   | 
|  Asia Pacific (Jakarta)  |   ` arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics_Selenium:26`   | 
|  Asia Pacific (Malaysia)  |   `arn:aws:lambda:ap-southeast-5:035872523913:layer:Synthetics_Selenium:7`   | 
|  Asia Pacific (Melbourne)  |   ` arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics_Selenium:18`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics_Selenium:32`   | 
|  Asia Pacific (Osaka)  |   ` arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics_Selenium:30`   | 
|  Asia Pacific (Seoul)  |   ` arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics_Selenium:34`   | 
|  Asia Pacific (Singapore)  |   ` arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics_Selenium:37`   | 
|  Asia Pacific (Sydney)  |   ` arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics_Selenium:32`   | 
|  Asia Pacific (Thailand)  |   `arn:aws:lambda:ap-southeast-7:851725245975:layer:Synthetics_Selenium:3`   | 
|  Asia Pacific (Tokyo)  |   ` arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics_Selenium:32`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics_Selenium:32`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics_Selenium:76`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics_Selenium:32`   | 
|  China (Ningxia);  |   ` arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics_Selenium:32`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics_Selenium:32`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics_Selenium:34`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics_Selenium:32`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics_Selenium:33`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics_Selenium:32`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics_Selenium:20`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics_Selenium:32`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics_Selenium:19`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics_Selenium:17`   | 
|  Mexico (Central)  |   `arn:aws:lambda:mx-central-1:654654265476:layer:Synthetics_Selenium:4`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics_Selenium:32`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics_Selenium:19`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics_Selenium:33`   | 
|  AWS GovCloud (US-East)  |   ` arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics_Selenium:30`   | 
|  AWS GovCloud (US-West)  |   ` arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics_Selenium:31`   | 

#### ARNs for syn-python-selenium-2.1
<a name="syn-python-selenium-2.1"></a>

The following table lists the ARNs to use for version ` syn-python-selenium-2.1` of the CloudWatch Synthetics runtime in each AWS Region where it is available.


| Region | ARN | 
| --- | --- | 
|  US East (N. Virginia)  |   `arn:aws:lambda:us-east-1:378653112637:layer:Synthetics:29`   | 
|  US East (Ohio)  |   `arn:aws:lambda:us-east-2:772927465453:layer:Synthetics:31`   | 
|  US West (N. California)  |   `arn:aws:lambda:us-west-1:332033056316:layer:Synthetics:29`   | 
|  US West (Oregon)  |   `arn:aws:lambda:us-west-2:760325925879:layer:Synthetics:31`   | 
|  Africa (Cape Town)  |   `arn:aws:lambda:af-south-1:461844272066:layer:Synthetics:29`   | 
|  Asia Pacific (Hong Kong)  |   `arn:aws:lambda:ap-east-1:129828061636:layer:Synthetics:29`   | 
|  Asia Pacific (Hyderabad)  |   `arn:aws:lambda:ap-south-2:280298676434:layer:Synthetics:17`   | 
|  Asia Pacific (Jakarta)  |   `arn:aws:lambda:ap-southeast-3:246953257743:layer:Synthetics:23`   | 
|  Asia Pacific (Melbourne)  |   `arn:aws:lambda:ap-southeast-4:200724813040:layer:Synthetics:15`   | 
|  Asia Pacific (Mumbai)  |   `arn:aws:lambda:ap-south-1:724929286329:layer:Synthetics:29`   | 
|  Asia Pacific (Osaka)  |   `arn:aws:lambda:ap-northeast-3:608016332111:layer:Synthetics:27`   | 
|  Asia Pacific (Seoul)  |   `arn:aws:lambda:ap-northeast-2:989515803484:layer:Synthetics:30`   | 
|  Asia Pacific (Singapore)  |   `arn:aws:lambda:ap-southeast-1:068035103298:layer:Synthetics:34`   | 
|  Asia Pacific (Sydney)  |   `arn:aws:lambda:ap-southeast-2:584677157514:layer:Synthetics:29`   | 
|  Asia Pacific (Tokyo)  |   `arn:aws:lambda:ap-northeast-1:172291836251:layer:Synthetics:29`   | 
|  Canada (Central)  |   `arn:aws:lambda:ca-central-1:236629016841:layer:Synthetics:29`   | 
|  Canada West (Calgary)  |   `arn:aws:lambda:ca-west-1:944448206667:layer:Synthetics:73`   | 
|  China (Beijing)  |   `arn:aws-cn:lambda:cn-north-1:422629156088:layer:Synthetics:29`   | 
|  China (Ningxia);  |   `arn:aws-cn:lambda:cn-northwest-1:474974519687:layer:Synthetics:29`   | 
|  Europe (Frankfurt)  |   `arn:aws:lambda:eu-central-1:122305336817:layer:Synthetics:29`   | 
|  Europe (Ireland)  |   `arn:aws:lambda:eu-west-1:563204233543:layer:Synthetics:31`   | 
|  Europe (London)  |   `arn:aws:lambda:eu-west-2:565831452869:layer:Synthetics:29`   | 
|  Europe (Milan)  |   `arn:aws:lambda:eu-south-1:525618516618:layer:Synthetics:30`   | 
|  Europe (Paris)  |   `arn:aws:lambda:eu-west-3:469466506258:layer:Synthetics:29`   | 
|  Europe (Spain)  |   `arn:aws:lambda:eu-south-2:029793053121:layer:Synthetics:17`   | 
|  Europe (Stockholm)  |   `arn:aws:lambda:eu-north-1:162938142733:layer:Synthetics:29`   | 
|  Europe (Zurich)  |   `arn:aws:lambda:eu-central-2:224218992030:layer:Synthetics:16`   | 
|  Israel (Tel Aviv)  |   `arn:aws:lambda:il-central-1:313249807427:layer:Synthetics:14`   | 
|  Middle East (Bahrain)  |   `arn:aws:lambda:me-south-1:823195537320:layer:Synthetics:29`   | 
|  Middle East (UAE)  |   `arn:aws:lambda:me-central-1:239544149032:layer:Synthetics:16`   | 
|  South America (São Paulo)  |   `arn:aws:lambda:sa-east-1:783765544751:layer:Synthetics:30`   | 
|  AWS GovCloud (US-East)  |   `arn:aws-us-gov:lambda:us-gov-east-1:946759330430:layer:Synthetics:29`   | 
|  AWS GovCloud (US-West)  |   `arn:aws-us-gov:lambda:us-gov-west-1:946807836238:layer:Synthetics:29`   | 

## Common errors
<a name="CloudWatch_Synthetics_Debug_Errors"></a>

 **Error: Running AWS SAM projects locally requires Docker. Have you got it installed and running?** 

Make sure to start Docker on your computer.

 **SAM local invoke failed: An error occurred (ExpiredTokenException) when calling the GetLayerVersion operation: The security token included in the request is expired** 

Make sure that the AWS default profile is set up.

 **More common errors** 

For more information about common errors with the SAM, see [AWS SAM CLI troubleshooting ](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-troubleshooting.html).

# Troubleshooting a failed canary
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot"></a>

If your canary fails, check the following for troubleshooting.

 **General troubleshooting** 
+ Use the canary details page to find more information. In the CloudWatch console, choose ** Canaries** in the navigation pane and then choose the name of the canary to open the canary details page. In the **Availability** tab, check the ** SuccessPercent** metric to see whether the problem is constant or intermittent.

  While still in the **Availability** tab, choose a failed data point to see screenshots, logs, and step reports (if available) for that failed run.

  If a step report is available because steps are part of your script, check to see which step has failed and see the associated screenshots to see the issue that your customers are seeing.

  You can also check the HAR files to see if one or more requests are failing. You can dig deeper by using logs to drill down on failed requests and errors. Finally, you can compare these artifacts with the artifacts from a successful canary run to pinpoint the issue.

  By default, CloudWatch Synthetics captures screenshots for each step in a UI canary. However, your script might be configured to disable screenshots. During debugging, you may want to enable screenshots again. Similarly, for API canaries you might want to see HTTP request and response headers and body during debugging. For information about how to include this data in the report, see [executeHttpStep(stepName, requestOptions, [callback], [stepConfig])](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_executeHttpStep).
+ If you had a recent deployment to your application, roll it back and then debug later.
+ Connect to your endpoint manually to see if you can reproduce the same issue.

**Topics**
+ [

## Canary fails after Lambda environment update
](#Troubleshoot_upgradeLambda)
+ [

## My canary is blocked by AWS WAF
](#Canary_Blocked_WAF)
+ [

## Waiting for an element to appear
](#CloudWatch_Synthetics_Canaries_Troubleshoot_waiting)
+ [

## Node is either not visible or not an HTMLElement for page.click()
](#CloudWatch_Synthetics_Canaries_Troubleshoot_notvisible)
+ [

## Unable to upload artifacts to S3, Exception: Unable to fetch S3 bucket location: Access Denied
](#CloudWatch_Synthetics_Canaries_Troubleshoot_noupload)
+ [

## Error: Protocol error (Runtime.callFunctionOn): Target closed.
](#CloudWatch_Synthetics_Canaries_Troubleshoot_protocolError)
+ [

## Canary Failed. Error: No datapoint - Canary Shows timeout error
](#CloudWatch_Synthetics_Canaries_Troubleshoot_nodatapoint)
+ [

## Trying to access an internal endpoint
](#CloudWatch_Synthetics_Canaries_Troubleshoot_internalendpoint)
+ [

## Canary runtime version upgrade and downgrade issues
](#CloudWatch_Synthetics_Canaries_Troubleshoot_upgradeissues)
+ [

## Cross-origin request sharing (CORS) issue
](#CloudWatch_Synthetics_Canaries_CORS)
+ [

## Canary race condition issues
](#CloudWatch_Synthetics_Canaries_RaceCondition)
+ [

## Troubleshooting a canary on a VPC
](#CloudWatch_Synthetics_Canaries_VPC_troubleshoot)
+ [

## Troubleshooting an auto retry canary
](#CloudWatch_Synthetics_Canaries_autoretry)

## Canary fails after Lambda environment update
<a name="Troubleshoot_upgradeLambda"></a>

CloudWatch Synthetics canaries are implemented as Lambda functions in your account. These Lambda functions are subject to regular Lambda runtime updates containing security updates, bug fixes, and other improvements. Lambda strives to provide runtime updates that are backward-compatible with existing functions. However, as with software patching, there are rare cases in which a runtime update can negatively impact an existing function. If you believe your canary has been impacted by a Lambda runtime update, you can use the Lambda runtime management manual mode (in supported Regions) to temporarily roll back the Lambda runtime version. This keeps your canary function working and minimizes disruption, providing time to remedy the incompatibility before returning to the latest runtime version.

If your canary is failing after a Lambda runtime update, the best solution is to upgrade to one of the newest Synthetics runtimes. For more information about the latest runtimes, see [Synthetics runtime versions](CloudWatch_Synthetics_Canaries_Library.md).

As an alternative solution, in Regions where Lambda runtime management controls are available, you can revert a canary back to an older Lambda managed runtime, using manual mode for runtime management controls. You can set manual mode using either the AWS CLI or by using the Lambda console, using the steps below in the following sections.

**Warning**  
When you change the runtime settings to manual mode, your Lambda function won't receive automatic security updates until it is reverted back to Auto mode. During this period, your Lambda function might be susceptible to security vulnerabilities.

 **Prerequisites** 
+ Install [ jq](https://jqlang.github.io/jq/)
+ Install the latest version of the AWS CLI. For more information, see [AWS CLI install and update instructions ](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions).

### Step 1: Obtain the Lambda function ARN
<a name="UpgradeLambda_ObtainFunctionARN"></a>

Run the following command to retrieve the `EngineArn` field from the response. This `EngineArn` is the ARN of the Lambda function that is associated with the canary. You will use this ARN in the following steps.

```
aws synthetics get-canary --name my-canary | jq '.Canary.EngineArn'
```

Example output of `EngingArn`:

```
"arn:aws:lambda:us-west-2:123456789012:function:cwsyn-my-canary-dc5015c2-db17-4cb5-afb1-EXAMPLE991:8"
```

### Step 2: Obtain the last good Lambda runtime version ARN
<a name="UpgradeLambda_RuntimeARN"></a>

To help understand whether your canary was impacted by a Lambda runtime update, check whether the date and time when the Lambda runtime version ARN changes in your logs appeared to the date and time when you saw impact to your canary. If they do not match, it is probably not a Lambda runtime update that is causing your issues.

If your canary is impacted by a Lambda runtime update, you must identify the ARN of the working Lambda runtime version that you were previously using. Follow the instructions in [Identifying runtime version changes ](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-update.html#runtime-management-identify.html) to find the ARN of the previous runtime. Record the runtime version ARN, and continue to Step 3. for setting the runtime management configuration.

If your canary has not yet been impacted by a Lambda environment update, then you can find the ARN of the Lambda runtime version that you are currently using. Run the following command to retrieve the `RuntimeVersionArn` of the Lambda function from the response. 

```
aws lambda get-function-configuration \
--function-name "arn:aws:lambda:us-west-2:123456789012:function:cwsyn-my-canary-dc5015c2-db17-4cb5-afb1-EXAMPLE991:8" | jq '.RuntimeVersionConfig.RuntimeVersionArn'
```

Example output of `RuntimeVersionArn`:

```
"arn:aws:lambda:us-west-2::runtime:EXAMPLE647b82f490a45d7ddd96b557b916a30128d9dcab5f4972911ec0f"
```

### Step 3: Updating the Lambda runtime management configuration
<a name="UpgradeLambda_Update"></a>

You can use either the AWS CLI or the Lambda console to update the runtime management configuration.

 **To set Lambda runtime management configuration manual mode using the AWS CLI** 

Enter the following command to change the runtime management of the Lambda function to manual mode. Be sure to replace the *function-name* and * qualifier* with the Lambda function ARN and Lambda function version number respectively, using the values you found in Step 1. Also replace the the * runtime-version-arn* with the version ARN that you found in Step 2. 

```
aws lambda put-runtime-management-config \
    --function-name "arn:aws:lambda:us-west-2:123456789012:function:cwsyn-my-canary-dc5015c2-db17-4cb5-afb1-EXAMPLE991" \
    --qualifier 8 \
    --update-runtime-on "Manual" \
    --runtime-version-arn "arn:aws:lambda:us-west-2::runtime:a993d90ea43647b82f490a45d7ddd96b557b916a30128d9dcab5f4972911ec0f"
```

**To change a canary to manual mode using the Lambda console**

1. Open the AWS Lambda console at [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Choose the **Versions** tab, choose the version number link that corresponds to your ARN, and choose the **Code** tab.

1. Scroll down to **Runtime settings**, expand **Runtime management configuration**, and copy the the **Runtime version ARN** .  
![\[Shows the Runtime settings section of the screen, and shows where the Runtime version ARN appears in this section.\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/images/SyntheticsManual1.png)

1. Choose **Edit runtime management configuration**, choose ** Manual**, paste the runtime version ARN that you copied earlier into the **Runtime version ARN** field. Then choose **Save**.  
![\[Shows the Runtime management configuration screen, and shows where the to paste the Runtime version ARN that you previousl copied..\]](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/images/SyntheticsManual2.png)

## My canary is blocked by AWS WAF
<a name="Canary_Blocked_WAF"></a>

To allow canary traffic through AWS WAF,create a AWS WAF string match condition that allows a custom string that you specify. For more information, see [Working with string match conditions ](https://docs.aws.amazon.com/waf/latest/developerguide/classic-web-acl-string-conditions.html) in the AWS WAF documentation.

We strongly recommend that you use your own custom user-agent string instead of using default values. This provides better control over AWS WAF filtering and improves security.

To set a custom user-agent string, do the following:
+ For Playwright runtimes, you can append your AWS WAF approved custom user-agent string using the Synthetics configuration file. For more information, see [CloudWatch Synthetics configurations](Synthetics_WritingCanary_Nodejs_Playwright.md#Synthetics_canary_configure_Playwright_script).
+ For Puppeteer or Selenium runtimes, you can add your custom user-agent string using supported library functions. For Puppeteer runtimes, see [async addUserAgent(page, userAgentString);](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_addUserAgent). For Selenium runtimes, see [add\$1user\$1agent(user\$1agent\$1str)](CloudWatch_Synthetics_Canaries_Library_Python.md#CloudWatch_Synthetics_Library_add_user_agent).

## Waiting for an element to appear
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_waiting"></a>

After analyzing your logs and screenshots, if you see that your script is waiting for an element to appear on screen and times out, check the relevant screenshot to see if the element appears on the page. Verify your `xpath` to make sure that it is correct.

For Puppetteer-related issues, check [ Puppeteer's GitHub page](https://github.com/puppeteer/puppeteer/issues) or internet forums.

## Node is either not visible or not an HTMLElement for page.click()
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_notvisible"></a>

If a node is not visible or is not an `HTMLElement` for `page.click()`, first verify the `xpath` that you are using to click the element. Also, if your element is at the bottom of the screen, adjust your viewport. CloudWatch Synthetics by default uses a viewport of 1920 \$1 1080. You can set a different viewport when you launch the browser or by using the Puppeteer function `page.setViewport`.

## Unable to upload artifacts to S3, Exception: Unable to fetch S3 bucket location: Access Denied
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_noupload"></a>

If your canary fails because of an Amazon S3 error, CloudWatch Synthetics was unable to upload screenshots, logs, or reports created for the canary because of permission issues. Check the following:
+ Check that the canary's IAM role has the `s3:ListAllMyBuckets` permission, the `s3:GetBucketLocation` permission for the correct Amazon S3 bucket, and the `s3:PutObject` permission for the bucket where the canary stores its artifacts. If the canary performs visual monitoring, the role also needs the ` s3:GetObject` permission for the bucket. These same permissions are also required in the Amazon VPC S3 Gateway Endpoint Policy, if the canary is deployed in a VPC with a VPC endpoint.
+  If the canary uses an AWS KMS customer managed key for encryption instead of the standard AWS managed key (default), the canary's IAM role might not have the permission to encrypt or decrypt using that key. For more information, see [Encrypting canary artifacts](CloudWatch_Synthetics_artifact_encryption.md).
+ Your bucket policy might not allow the encryption mechanism that the canary uses. For example, if your bucket policy mandates to use a specific encryption mechanism or KMS key, then you must select the same encryption mode for your canary.

If the canary performs visual monitoring, see [Updating artifact location and encryption when using visual monitoring](CloudWatch_Synthetics_artifact_encryption.md#CloudWatch_Synthetics_artifact_encryption_visual) for more information.

## Error: Protocol error (Runtime.callFunctionOn): Target closed.
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_protocolError"></a>

This error appears if there are some network requests after the page or browser is closed. You might have forgotten to wait for an asynchronous operation. After executing your script, CloudWatch Synthetics closes the browser. The execution of any asynchronous operation after the browser is closed might cause `target closed error`. 

## Canary Failed. Error: No datapoint - Canary Shows timeout error
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_nodatapoint"></a>

This means that your canary run exceeded the timeout. The canary execution stopped before CloudWatch Synthetics could publish success percent CloudWatch metrics or update artifacts such as HAR files, logs and screenshots. If your timeout is too low, you can increase it.

By default, a canary timeout value is equal to its frequency. You can manually adjust the timeout value to be less than or equal to the canary frequency. If your canary frequency is low, you must increase the frequency to increase the timeout. You can adjust both the frequency and the timeout value under **Schedule** when you create or update a canary by using the CloudWatch Synthetics console.

Be sure that your canary timeout value is no shorter than 15 seconds to allow for Lambda cold starts and the time it takes to boot up the canary instrumentation.

Canary artifacts are not available to view in the CloudWatch Synthetics console when this error happens. You can use CloudWatch Logs to see the canary's logs.

**To use CloudWatch Logs to see the logs for a canary**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the left navigation pane, choose **Log groups**.

1. Find the log group by typing the canary name in the filter box. Log groups for canaries have the name **/aws/lambda/cwsyn-*canaryName* -randomId**.

## Trying to access an internal endpoint
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_internalendpoint"></a>

If you want your canary to access an endpoint on your internal network, we recommend that you set up CloudWatch Synthetics to use VPC. For more information, see [Running a canary on a VPC](CloudWatch_Synthetics_Canaries_VPC.md).

## Canary runtime version upgrade and downgrade issues
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_upgradeissues"></a>

If you recently upgraded the canary from runtime version `syn-1.0` to a later version, it may be a cross-origin request sharing (CORS) issue. For more information, see [Cross-origin request sharing (CORS) issue](#CloudWatch_Synthetics_Canaries_CORS).

If you recently downgraded the canary to an older runtime version, check to make sure that the CloudWatch Synthetics functions that you are using are available in the older runtime version that you downgraded to. For example, the `executeHttpStep` function is available for runtime version `syn-nodejs-2.2` and later. To check on the availability of functions, see [Writing a canary script](CloudWatch_Synthetics_Canaries_WritingCanary.md). 

**Note**  
When you plan to upgrade or downgrade the runtime version for a canary, we recommend that you first clone the canary and update the runtime version in the cloned canary. Once you have verified that the clone with the new runtime version works, you can update the runtime version of your original canary and delete the clone.

## Cross-origin request sharing (CORS) issue
<a name="CloudWatch_Synthetics_Canaries_CORS"></a>

In a UI canary, if some network requests are failing with `403` or ` net::ERR_FAILED`, check whether the canary has active tracing enabled and also uses the Puppeteer function `page.setExtraHTTPHeaders` to add headers. If so, the failed network requests might be caused by cross-origin request sharing (CORS) restrictions. You can confirm whether this is the case by disabling active tracing or removing the extra HTTP headers.

 **Why does this happen?** 

When active tracing is used, an extra header is added to all outgoing requests to trace the call. Modifying the request headers by adding a trace header or adding extra headers using Puppeteer’s `page.setExtraHTTPHeaders` causes a CORS check for XMLHttpRequest (XHR) requests.

If you don't want to disable active tracing or remove the extra headers, you can update your web application to allow cross-origin access or you can disable web security by using the `disable-web-security` flag when you launch the Chrome browser in your script.

You can override launch parameters used by CloudWatch Synthetics and pass additional ` disable-web-security` flag parameters by using the CloudWatch Synthetics launch function. For more information, see [Library functions available for Node.js canary scripts using Puppeteer](CloudWatch_Synthetics_Canaries_Library_Nodejs.md).

**Note**  
You can override launch parameters used by CloudWatch Synthetics when you use runtime version `syn-nodejs-2.1` or later.

## Canary race condition issues
<a name="CloudWatch_Synthetics_Canaries_RaceCondition"></a>

For the best experience when using CloudWatch Synthetics, ensure that the code written for the canaries is idempotent. Otherwise, in rare cases, canary runs may encounter race conditions when the canary interacts with the same resource across different runs.

## Troubleshooting a canary on a VPC
<a name="CloudWatch_Synthetics_Canaries_VPC_troubleshoot"></a>

If you have issues after creating or updating a canary on a VPC, one of the following sections might help you troubleshoot the problem.

### New canary in error state or canary can't be updated
<a name="CloudWatch_Synthetics_Canaries_VPC_troubleshoot_errorstate"></a>

If you create a canary to run on a VPC and it immediately goes into an error state, or you can't update a canary to run on a VPC, the canary's role might not have the right permissions. To run on a VPC, a canary must have the permissions ` ec2:CreateNetworkInterface`, `ec2:DescribeNetworkInterfaces`, and ` ec2:DeleteNetworkInterface`. These permissions are all contained in the ` AWSLambdaVPCAccessExecutionRole` managed policy. For more information, see [Execution Role and User Permissions](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html#vpc-permissions).

If this issue happened when you created a canary, you must delete the canary, and create a new one. If you use the CloudWatch console to create the new canary, under **Access Permissions**, select **Create a new role**. A new role that includes all permissions required to run the canary is created.

If this issue happens when you update a canary, you can update the canary again and provide a new role that has the required permissions.

### "No test result returned" error
<a name="CloudWatch_Synthetics_Canaries_VPC_troubleshoot_noresult"></a>

If a canary displays a "no test result returned" error, one of the following issues might be the cause: 
+ If your VPC does not have internet access, you must use VPC endpoints to give the canary access to CloudWatch and Amazon S3. You must enable the **DNS resolution** and **DNS hostname** options in the VPC for these endpoint addresses to resolve correctly. For more information, see [Using DNS with Your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html) and [Using CloudWatch and CloudWatch Synthetics with interface VPC endpoints ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-and-interface-VPC.html) .
+ Canaries must run in private subnets within a VPC. To check this, open the ** Subnets** page in the VPC console. Check the subnets that you selected when configuring the canary. If they have a path to an internet gateway (**igw-**), they are not private subnets.

To help you troubleshoot these issues, see the logs for the canary.

**To see the log events from a canary**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Log groups**.

1. Choose the name of the canary's log group. The log group name starts with ` /aws/lambda/cwsyn-canary-name`.

## Troubleshooting an auto retry canary
<a name="CloudWatch_Synthetics_Canaries_autoretry"></a>

To understand why your canary is failing or to analyze specific failed attempts, follow these troubleshooting steps.

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Application Signals**, **Synthetics Canaries**.

1. Choose the **Canary**.

1. Under the **Availability** tab, you can examine the run details by either:
   + Selecting a specific point on the Canary Runs graph
   + Under **Issues**, selecting a record. Note that retry attempts are tagged and share timestamps with their scheduled runs

   You can view additional information under **Steps**, ** Screenshot**, **Logs**, **HAR file**, or **Traces (if active tracing is enabled)**.

1. Under **Canary artifacts and Amazon S3 location**, you can access the artifact and navigate to the Amazon S3 folders or buckets through the available links.

1. The **Canary runs** graph uses different colored points to indicate various status:
   + Blue Points – Indicates successful scheduled runs with a consistent value of 100%
   + Red Points – Displays failure of both scheduled runs and all retries, marked at 0%
   + Orange Points – Displays either 0% or 100%. 0% indicates ongoing retry following previous attempt failures and 100% means success was achieved after retrying

# Sample code for canary scripts
<a name="CloudWatch_Synthetics_Canaries_Samples"></a>

This section contains code samples that illustrate some possible functions for CloudWatch Synthetics canary scripts.

## Samples for Node.js and Playwright
<a name="Synthetics_Canaries_Samples_nodejs_playwright"></a>

### Playwright canary with multiple steps
<a name="Synthetics_canary_example_nodejs_playwright_multistep"></a>

The following script is an example of a Node.js Playwright canary with multiple steps.

```
import { synthetics } from '@aws/synthetics-playwright';

export async function handler(event, context) {
  try {
    console.log('Running Synthetics Playwright canary');
    const browser = await synthetics.launch();
    const browserContext = await browser.newContext();
    const page = await synthetics.getPage(browserContext);
    

    // Add steps
    // Step 1
    await synthetics.executeStep("home-page", async () => {
      console.log("Verify home page loads")
      await page.goto('https://www.amazon.com', {waitUntil: "load"});
      await new Promise(r => setTimeout(r, 5000));
    });
    
    // Step 2
    await synthetics.executeStep("search", async () => {
      console.log("Searching for a product")
      const searchInput = page.getByPlaceholder("Search Amazon").first();
      await searchInput.click()
      await searchInput.fill('Amazon echo');
      const btn = page.getByRole('button', { name: 'Go' }).first()
      await btn.click({ timeout: 15000 })
      console.log("Clicked search button")
    });

    // Step 3
    await synthetics.executeStep("search-results", async () => {
      console.log("Verifying search results")
      const resultsHeading = page.getByText("Results", {exact: true}).first()
      await resultsHeading.highlight();
      await new Promise(r => setTimeout(r, 5000));
    });

  } finally {
    // Close all browser contexts and browser
    await synthetics.close();
  }
}
```

### Playwright canaries setting cookies
<a name="Synthetics_canaries_nodejs_playwright_cookies"></a>

The following script is an example of a Node.js Playwright canary setting three cookies.

```
import { synthetics } from '@aws/synthetics-playwright';

export const handler = async (event, context) => {
  try {
    let url = "http://smile.amazon.com/";
    const browser = await synthetics.launch();
    const page = await synthetics.getPage(browser);
    const cookies = [{
        'name': 'cookie1',
        'value': 'val1',
        'url': url
    },
    {
        'name': 'cookie2',
        'value': 'val2',
        'url': url
    },
    {
        'name': 'cookie3',
        'value': 'val3',
        'url': url
    }
   ];
   await page.context().addCookies(cookies);
   await page.goto(url, {waitUntil: 'load', timeout: 30000});
   await page.screenshot({ path: '/tmp/smile.png' });
    
  } finally {
    await synthetics.close();
  }
};
```

## Samples for Node.js and Puppeteer
<a name="CloudWatch_Synthetics_Canaries_Samples_nodejspup"></a>

### Setting cookies
<a name="CloudWatch_Synthetics_Canaries_Samples_cookies"></a>

Web sites rely on cookies to provide custom functionality or track users. By setting cookies in CloudWatch Synthetics scripts, you can mimic this custom behavior and validate it.

For example, a web site might display a **Login** link for a revisiting user instead of a **Register** link.

```
var synthetics = require('@aws/synthetics-puppeteer');
const log = require('@aws/synthetics-logger');

const pageLoadBlueprint = async function () {

    let url = "http://smile.amazon.com/";

    let page = await synthetics.getPage();

    // Set cookies.  I found that name, value, and either url or domain are required fields.
    const cookies = [{
      'name': 'cookie1',
      'value': 'val1',
      'url': url
    },{
      'name': 'cookie2',
      'value': 'val2',
      'url': url
    },{
      'name': 'cookie3',
      'value': 'val3',
      'url': url
    }];
    
    await page.setCookie(...cookies);

    // Navigate to the url
    await synthetics.executeStep('pageLoaded_home', async function (timeoutInMillis = 30000) {
        
        var response = await page.goto(url, {waitUntil: ['load', 'networkidle0'], timeout: timeoutInMillis});

        // Log cookies for this page and this url
        const cookiesSet = await page.cookies(url);
        log.info("Cookies for url: " + url + " are set to: " + JSON.stringify(cookiesSet));
    });

};

exports.handler = async () => {
    return await pageLoadBlueprint();
};
```

### Device emulation
<a name="CloudWatch_Synthetics_Canaries_Samples_device"></a>

You can write scripts that emulate various devices so that you can approximate how a page looks and behaves on those devices.

The following sample emulates an iPhone 6 device. For more information about emulation, see [ page.emulate(options)](https://pptr.dev/#?product=Puppeteer&version=v5.3.1&show=api-pageemulateoptions) in the Puppeteer documentation.

```
var synthetics = require('@aws/synthetics-puppeteer');
const log = require('@aws/synthetics-logger');
const puppeteer = require('puppeteer-core');

const pageLoadBlueprint = async function () {
    
    const iPhone = puppeteer.devices['iPhone 6'];

    // INSERT URL here
    const URL = "https://amazon.com";

    let page = await synthetics.getPage();
    await page.emulate(iPhone);

    //You can customize the wait condition here. For instance,
    //using 'networkidle2' may be less restrictive.
    const response = await page.goto(URL, {waitUntil: 'domcontentloaded', timeout: 30000});
    if (!response) {
        throw "Failed to load page!";
    }
    
    await page.waitFor(15000);

    await synthetics.takeScreenshot('loaded', 'loaded');
    
    //If the response status code is not a 2xx success code
    if (response.status() < 200 || response.status() > 299) {
        throw "Failed to load page!";
    }
};

exports.handler = async () => {
    return await pageLoadBlueprint();
};
```

### Multi-step API canary
<a name="CloudWatch_Synthetics_Canaries_Samples_APIsteps"></a>

This sample code demonstrates an API canary with two HTTP steps: testing the same API for positive and negative test cases. The step configuration is passed to enable reporting of request/response headers. Additionally, it hides the Authorization header and X-Amz-Security-Token, because they contain user credentials. 

When this script is used as a canary, you can view details about each step and the associated HTTP requests such as step pass/fail, duration, and performance metrics like DNS look up time and first byte time. You can view the number of 2xx, 4xx and 5xx for your canary run. 

```
var synthetics = require('@aws/synthetics-puppeteer');
const log = require('@aws/synthetics-logger');

const apiCanaryBlueprint = async function () {
    
    // Handle validation for positive scenario
    const validatePositiveCase = async function(res) {
        return new Promise((resolve, reject) => {
            if (res.statusCode < 200 || res.statusCode > 299) {
                throw res.statusCode + ' ' + res.statusMessage;
            }
     
            let responseBody = '';
            res.on('data', (d) => {
                responseBody += d;
            });
     
            res.on('end', () => {
                // Add validation on 'responseBody' here if required. For ex, your status code is 200 but data might be empty
                resolve();
            });
        });
    };
    
    // Handle validation for negative scenario
    const validateNegativeCase = async function(res) {
        return new Promise((resolve, reject) => {
            if (res.statusCode < 400) {
                throw res.statusCode + ' ' + res.statusMessage;
            }
            
            resolve();
        });
    };
    
    let requestOptionsStep1 = {
        'hostname': 'myproductsEndpoint.com',
        'method': 'GET',
        'path': '/test/product/validProductName',
        'port': 443,
        'protocol': 'https:'
    };
    
    let headers = {};
    headers['User-Agent'] = [synthetics.getCanaryUserAgentString(), headers['User-Agent']].join(' ');
    
    requestOptionsStep1['headers'] = headers;

    // By default headers, post data and response body are not included in the report for security reasons. 
    // Change the configuration at global level or add as step configuration for individual steps
    let stepConfig = {
        includeRequestHeaders: true, 
        includeResponseHeaders: true,
        restrictedHeaders: ['X-Amz-Security-Token', 'Authorization'], // Restricted header values do not appear in report generated.
        includeRequestBody: true,
        includeResponseBody: true
    };
       

    await synthetics.executeHttpStep('Verify GET products API with valid name', requestOptionsStep1, validatePositiveCase, stepConfig);
    
    let requestOptionsStep2 = {
        'hostname': 'myproductsEndpoint.com',
        'method': 'GET',
        'path': '/test/canary/InvalidName(',
        'port': 443,
        'protocol': 'https:'
    };
    
    headers = {};
    headers['User-Agent'] = [synthetics.getCanaryUserAgentString(), headers['User-Agent']].join(' ');
    
    requestOptionsStep2['headers'] = headers;

    // By default headers, post data and response body are not included in the report for security reasons. 
    // Change the configuration at global level or add as step configuration for individual steps
    stepConfig = {
        includeRequestHeaders: true, 
        includeResponseHeaders: true,
        restrictedHeaders: ['X-Amz-Security-Token', 'Authorization'], // Restricted header values do not appear in report generated.
        includeRequestBody: true,
        includeResponseBody: true
    };
    
    await synthetics.executeHttpStep('Verify GET products API with invalid name', requestOptionsStep2, validateNegativeCase, stepConfig);
    
};

exports.handler = async () => {
    return await apiCanaryBlueprint();
};
```

## Samples for Python and Selenium
<a name="CloudWatch_Synthetics_Canaries_Samples_pythonsel"></a>

The following sample Selenium code is a canary that fails with a custom error message when a target element is not loaded.

```
from aws_synthetics.selenium import synthetics_webdriver as webdriver
from aws_synthetics.common import synthetics_logger as logger
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

def custom_selenium_script():
    # create a browser instance
    browser = webdriver.Chrome()
    browser.get('https://www.example.com/')
    logger.info('navigated to home page')
    # set cookie
    browser.add_cookie({'name': 'foo', 'value': 'bar'})
    browser.get('https://www.example.com/')
    # save screenshot
    browser.save_screenshot('signed.png')
    # expected status of an element
    button_condition = EC.element_to_be_clickable((By.CSS_SELECTOR, '.submit-button'))
    # add custom error message on failure
    WebDriverWait(browser, 5).until(button_condition, message='Submit button failed to load').click()
    logger.info('Submit button loaded successfully')
    # browser will be quit automatically at the end of canary run, 
    # quit action is not necessary in the canary script
    browser.quit()

# entry point for the canary
def handler(event, context):
    return custom_selenium_script()
```

# Canaries and X-Ray tracing
<a name="CloudWatch_Synthetics_Canaries_tracing"></a>

You can choose to enable active AWS X-Ray tracing on canaries that use the ` syn-nodejs-2.0` or later runtime. With tracing enabled, traces are sent for all calls made by the canary that use the browser, the AWS SDK, or HTTP or HTTPS modules. Canaries with tracing enabled appear on the [X-Ray Trace Map](https://docs.aws.amazon.com/xray/latest/devguide/xray-console-servicemap.html), and within [Application Signals](CloudWatch-Application-Monitoring-Sections.md) after you have enabled it for your application. 

**Note**  
Activating X-Ray tracing on canaries is not yet supported in Asia Pacific (Jakarta).  
X-Ray tracing is not supported with Firefox browser canaries.

When a canary appears on the X-Ray trace map, it appears as a new client node type. You can hover on a canary node to see data about latency, requests, and faults. You can also choose the canary node to see more data at the bottom of the page. From this area of the page, you can choose **View in Synthetics** to jump to the CloudWatch Synthetics console for more details about the canary, or choose **View Traces** to see more details about the traces from this canary's runs.

A canary with tracing enabled also has a **Tracing** tab in its details page, with details about traces and segments from the canary's runs.

Enabling tracing increases canary run time by 2.5% to 7%.

A canary with tracing enabled must use a role with the following permissions. If you use the console to create the role when you create the canary, it is given these permissions.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "Sid230934",
            "Effect": "Allow",
            "Action": [
                "xray:PutTraceSegments"
            ],
            "Resource": "*"
        }
    ]
}
```

------

Traces generated by canaries incur charges. For more information about X-Ray pricing, see [AWS X-Ray Pricing](https://aws.amazon.com/xray/pricing/).

# Running a canary on a VPC
<a name="CloudWatch_Synthetics_Canaries_VPC"></a>

You can run canaries on endpoints on a VPC and public internal endpoints. To run a canary on a VPC, you must have both the **DNS Resolution** and ** DNS hostnames** options enabled on the VPC. For more information, see [Using DNS with Your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html).

When you run a canary on a VPC endpoint, you must provide a way for it to send its metrics to CloudWatch and its artifacts to Amazon S3. If the VPC is already enabled for internet access, there's nothing more for you to do. The canary executes in your VPC, but can access the internet to upload its metrics and artifacts.

If the VPC is not already enabled for internet access, you have two options:
+ Enable IPv4 internet access to allow the canary to send metrics to CloudWatch and Amazon S3. For more information, see the following section [Giving internet access to your canary on a VPC](#CloudWatch_Synthetics_VPC_Internet).
+ If you want to keep your VPC private, you can configure the canary to send its data to CloudWatch and Amazon S3 through private VPC endpoints. If you have not already done so, you must create a VPC endpoint for CloudWatch (com.amazonaws.*region*.monitoring) and a gateway endpoint for Amazon S3. For more information, see [Using CloudWatch, CloudWatch Synthetics, and CloudWatch Network Monitoring with interface VPC endpoints](cloudwatch-and-interface-VPC.md) and [Amazon VPC Endpoints for Amazon S3](https://docs.aws.amazon.com/glue/latest/dg/vpc-endpoints-s3.html). 

## Giving internet access to your canary on a VPC
<a name="CloudWatch_Synthetics_VPC_Internet"></a>

Follow these steps to give internet access to your VPC canary, or to assign your canary a static IP address

**To give internet access (IPv4) to a canary on a VPC**

1. Create a NAT gateway in a public subnet on the VPC. For instructions, see [Create a NAT gateway](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html#nat-gateway-creating).

1. Add a new route to the route table in the private subnet where the canary is launched. Specify the following:
   + For **Destination**, enter **0.0.0.0/0**
   + For **Target**, choose **NAT Gateway**, and then choose the ID of the NAT gateway that you created.
   + Choose **Save routes**.

   For more information about adding the route to the route table, see [Add and remove routes from a route table](https://docs.aws.amazon.com/vpc/latest/userguide/WorkWithRouteTables.html#AddRemoveRoutes).

**To give internet access (IPv6) to a canary on a VPC**

1. Configure your VPC to have Dualstack subnets. You must add an Egress-Only Internet Gateway to the VPC, update the route tables to allow traffic to the Internet Gateway, and allow outbound access from the associated Security Groups. For more information, see [Add IPv6 support for your VPC ](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6-add.html).

1. Set the `Ipv6AllowedForDualstack ` in your canary VPC configuration using the `CreateCanary` or `UpdateCanary` API. For more information, see [VpcConfigInput](https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_VpcConfigInput.html) .

   To enable outbound IPv6 traffic from your canary, the VPC subnets attached to the canary must be enabled for Dualstack.

**Note**  
Be sure that the routes to your NAT gateway are in an **active** status. If the NAT gateway is deleted and you haven't updated the routes, they're in a black hole status. For more information, see [Work with NAT gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html#nat-gateway-working-with).

# Encrypting canary artifacts
<a name="CloudWatch_Synthetics_artifact_encryption"></a>

CloudWatch Synthetics stores canary artifacts such as screenshots, HAR files, and reports in your Amazon S3 bucket. By default, these artifacts are encrypted at rest using an AWS managed key. For more information, see [Customer keys and AWS keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-mgmt.html) . 

You can choose to use a different encryption option. CloudWatch Synthetics supports the following:
+ **SSE-S3**– Server-side encryption (SSE) with an Amazon S3-managed key.
+ **SSE-KMS**– Server-side encryption (SSE) with an AWS KMS customer managed key.

If you want to use the default encryption option with an AWS managed key, you don't need any additional permissions. 

To use SSE-S3 encryption, you specify **SSE\$1S3** as the encryption mode when you create or update your canary. You do not need any additional permissions to use this encryption mode. For more information, see [Protecting data using server-side encryption with Amazon S3-managed encryption keys (SSE-S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingServerSideEncryption.html).

To use an AWS KMS customer managed key, you specify **SSE-KMS** as the encryption mode when you create or update your canary, and you also provide the Amazon Resource Name (ARN) of your key. You can also use a cross-account KMS key.

To use a customer managed key, you need the following settings:
+ The IAM role for your canary must have permission to encrypt your artifacts using your key. If you are using visual monitoring, you must also give it permission to decrypt artifacts.

------
#### [ JSON ]

****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "AllowKMSKeyUsage",
              "Effect": "Allow",
              "Action": [
                  "kms:GenerateDataKey",
                  "kms:Decrypt"
              ],
              "Resource": "arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"
          }
      ]
  }
  ```

------
+ Instead of adding permissions to your IAM role, you can add your IAM role to your key policy. If you use the same role for multiple canaries, you should consider this approach.

  ```
  {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
          "AWS": "Your synthetics IAM role ARN"
      },
      "Action": [
          "kms:GenerateDataKey",
          "kms:Decrypt"
      ],
      "Resource": "*"
  }
  ```
+ If you are using a cross-account KMS key, see [Allowing users in other accounts to use a KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-modifying-external-accounts.html).

 **Viewing encrypted canary artifacts when using a customer managed key** 

To view canary artifacts, update your customer managed key to give AWS KMS the decrypt permission to the user viewing the artifacts. Alternatively, add decrypt permissions to the user or IAM role that is viewing the artifacts.

The default AWS KMS policy enables IAM policies in the account to allow access to the KMS keys. If you are using a cross-account KMS key, see [Why are cross-account users getting Access Denied errors when they try to access Amazon S3 objects encrypted by a custom AWS KMS key?](https://aws.amazon.com/premiumsupport/knowledge-center/cross-account-access-denied-error-s3/). 

For more information about troubleshooting access denied issues because of a KMS key, see [Troubleshooting key access](https://docs.aws.amazon.com/kms/latest/developerguide/policy-evaluation.html). 

## Updating artifact location and encryption when using visual monitoring
<a name="CloudWatch_Synthetics_artifact_encryption_visual"></a>

To perform visual monitoring, CloudWatch Synthetics compares your screenshots with baseline screenshots acquired in the run selected as the baseline. If you update your artifact location or encryption option, you must do one of the following:
+ Ensure that your IAM role has sufficient permission for both the previous Amazon S3 location and the new Amazon S3 location for artifacts. Also ensure that it has permission for both the previous and new encryption methods and KMS keys.
+ Create a new baseline by selecting the next canary run as a new baseline. If you use this option, you only need to ensure that your IAM role has sufficient permissions for the new artifact location and encryption option.

We recommend the second option of selecting the next run as the new baseline. This avoids having a dependency on an artifact location or encryption option that you're not using anymore for the canary.

For example, suppose that your canary uses artifact location A and KMS key K for uploading artifacts. If you update your canary to artifact location B and KMS key L, you can ensure that your IAM role has permissions to both of the artifact locations (A and B) and both of the KMS keys (K and L). Alternatively, you can select the next run as the new baseline and ensure that your canary IAM role has permissions to artifact location B and KMS key L. 

# Viewing canary statistics and details
<a name="CloudWatch_Synthetics_Canaries_Details"></a>

You can view details about your canaries and see statistics about their runs.

To be able to see all the details about your canary run results, you must be logged on to an account that has sufficient permissions. For more information, see [Required roles and permissions for CloudWatch canaries](CloudWatch_Synthetics_Canaries_Roles.md).

**To view canary statistics and details**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Application Signals**, **Synthetics Canaries**.

   In the details about the canaries that you have created:
   + **Status** visually shows how many of your canaries have passed their most recent runs.
   + **Groups** displays the groups you have created, and displays how many of them have failing or alarming canaries.
   + **Slowest performers** displays the group and the Region with the slowest-performing canaries. These are calculated by adding up the average duration of all canaries (across the time span selected) within a group or Region and dividing it by the number of canaries in the group or Region. If you choose the metric for Slowest group, the table is filtered to display only the slowest groups and their canaries. The table is sorted by Average Duration.
   + Near the bottom of the page is a table displaying all canaries. You can use the filtering bar to filter the table to show canaries by specific canary names, last run results, success percentage, alarms, run rates, canary state, runtimes, and unique tags. 

     For the alarms column, only alarms that conform to the naming standard for canary alarms are displayed. This standard is `Synthetics-Alarm-canaryName -index`. Canary alarms that you create in the ** Synthetics** section of the CloudWatch console automatically use this naming convention. If you create canary alarms in the **Alarms** section of the CloudWatch console or by using AWS CloudFormation, and you don't use this naming convention, the alarms work but they do not appear in this list.

1. To see more details about a single canary, choose the name of the canary in the ** Canaries** table.

   In the details about that canary:
   + The **Availability** tab displays information about the recent runs of this canary.

     Under **Canary runs**, you can choose one of the lines to see details about that run.

     Under the graph, you can choose **Steps**, **Screenshot** , **Logs**, or **HAR file** to see these types of details. If the canary has active tracing enabled, you can also choose ** Traces** to see tracing information from the canary's runs.

     The logs for canary runs are stored in S3 buckets and in CloudWatch Logs.

     Screenshots show how your customers view your webpages. You can use the HAR files (HTTP Archive files) to view detailed performance data about the webpages. You can analyze the list of web requests and catch performance issues such as time to load for an item. Log files show the record of interactions between the canary run and the webpage and can be used to identify details of errors.

     If the canary uses the `syn-nodejs-2.0-beta` runtime or later, you can sort the HAR files by status code, request size, or duration.

     The **Steps** tab displays a list of the canary's steps, each step's status, failure reason, URL after step execution, screenshots, and duration of step execution. For API canaries with HTTP steps, you can view steps and corresponding HTTP requests if you are using runtime `syn-nodejs-2.2` or later.

     Choose the **HTTP Requests** tab to view the log of each HTTP request made by the canary. You can view request/response headers, response body, status code, error and performance timings (total duration, TCP connection time, TLS handshake time, first byte time, and content transfer time). All HTTP requests which use the HTTP/HTTPS module under the hood are captured here.

     By default in API canaries, the request header, response header, request body, and response body are not included in the report for security reasons. If you choose to include them, the data is stored only in your S3 bucket. For information about how to include this data in the report, see [executeHttpStep(stepName, requestOptions, [callback], [stepConfig])](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_executeHttpStep).

     Response body content types of text, HTML and JSON are supported. Content types like text/HTML, text/plain, application/JSON and application/x-amz-json-1.0 are supported. Compressed responses are not supported. 
   + The **Monitoring** tab displays graphs of the CloudWatch metrics published by this canary. For more information about these metrics, see [CloudWatch metrics published by canaries](CloudWatch_Synthetics_Canaries_metrics.md).

     Below the CloudWatch graphics published by the canary are graphs of Lambda metrics related to the canary's Lambda code.
   + The **Configuration** tab displays configuration and schedule information about the canary.
   + The **Groups** tab displays the groups that this canary is associated with, if any.
   + The **Tags** tab displays the tags associated with the canary.

# CloudWatch metrics published by canaries
<a name="CloudWatch_Synthetics_Canaries_metrics"></a>

Canaries publish the following metrics to CloudWatch in the `CloudWatchSynthetics` namespace. For more information about viewing CloudWatch metrics, see [View available metrics](viewing_metrics_with_cloudwatch.md) .

**Note**  
For multi-browser canaries, browser-dimension metrics are enabled by default to provide visibility into performance across browsers like Chrome, Firefox and other browsers. To disable browser metrics, set `browserDimension` to `false`.  
For single-browser canaries, browser-dimension metrics are disabled by default to avoid redundancy. To see metrics broken down by browser, set `browserDimension` to ` true`.


| Metric | Description | 
| --- | --- | 
|   `2xx`   |  The number of network requests performed by the canary that returned OK responses, with response codes between 200 and 299. This metric is reported for UI canaries that use runtime version ` syn-nodejs-2.0` or later, and is reported for API canaries that use runtime version `syn-nodejs-2.2` or later. Valid Dimensions: CanaryName, Browser Valid Statistic: Sum Units: Count  | 
|   `4xx`   |  The number of network requests performed by the canary that returned Error responses, with response codes between 400 and 499. This metric is reported for UI canaries that use runtime version ` syn-nodejs-2.0` or later, and is reported for API canaries that use runtime version `syn-nodejs-2.2` or later. Valid Dimensions: CanaryName, Browser Valid Statistic: Sum Units: Count  | 
|   `5xx`   |  The number of network requests performed by the canary that returned Fault responses, with response codes between 500 and 599. This metric is reported for UI canaries that use runtime version ` syn-nodejs-2.0` or later, and is reported for API canaries that use runtime version `syn-nodejs-2.2` or later. Valid Dimensions: CanaryName, Browser Valid Statistic: Sum Units: Count  | 
|   `Duration`   |  The duration in milliseconds of the canary run. Valid Dimensions: CanaryName, Browser Valid Statistic: Average Units: Milliseconds  | 
|   `DurationDryRun`   |  The duration of DryRun executions.  Valid Dimensions: CanaryName, Browser Valid Statistic: Average Units: Milliseconds  | 
|   `EphemeralStorageUsagePercent`   |  The maximum percentage of ephemeral storage used compared to total ephemeral storage configured. This metric is collected at every 10 second interval.  | 
|   `Failed`   |  The number of canary runs that failed to execute. These failures are related to the canary itself. Valid Dimensions: CanaryName, Browser Valid Statistic: Sum Units: Count  | 
|   `Failed requests`   |  The number of HTTP requests executed by the canary on the target website that failed with no response. Valid Dimensions: CanaryName, Browser Valid Statistic: Sum Units: Count  | 
|   `RetryCount`   |  The number of times your canary retried. This metric is only displayed when there are retries. Valid Dimensions: CanaryName, Browser Valid Statistic: Sum Units: Count  | 
|   `SuccessPercent`   |  The percentage of the runs of this canary that succeed and find no failures. Valid Dimensions: CanaryName, Browser Valid Statistic: Average Units: Percent  | 
|   `SuccessPercentDryRun`   |  The success percentage of DryRun executions. Valid Dimensions: CanaryName, Browser Valid Statistic: Average Units: Percent  | 
|   `SuccessPercentWithRetries`   |  The percentage of the runs of this canary that succeed after all attempts. Valid Dimensions: CanaryName, Browser Valid Statistic: Average Units: Percent  | 
|   `VisualMonitoringSuccessPercent`   |  The percentage of visual comparisons that successfully matched the baseline screenshots during a canary run. Valid Dimensions: CanaryName, Browser Valid Statistic: Average Units: Percent  | 
|   `VisualMonitoringTotalComparisons`   |  The total number of visual comparisons that happened during a canary run. Valid Dimensions: CanaryName, Browser Units: Count  | 

**Note**  
Canaries that use either the `executeStep()` or `executeHttpStep()` methods from the Synthetics library also publish `SuccessPercent` and ` Duration` metrics with the dimensions `CanaryName` and `StepName` for each step.

 

# Edit or delete a canary
<a name="synthetics_canaries_deletion"></a>

You can edit or delete an existing canary.

 **Edit canary** 

When you edit a canary, even if you don't change its schedule, the schedule is reset corresponding to when you edit the canary. For example, if you have a canary that runs every hour, and you edit that canary, the canary will run immediately after the edit is completed and then every hour after that.

**To edit or update a canary**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Application Signals**, **Synthetics Canaries**.

1. Select the button next to the canary name, and choose **Actions**, ** Edit**.

1. (Optional) If this canary performs visual monitoring of screenshots and you want to set the next run of the canary as the baseline, select **Set next run as new baseline**.

1. (Optional) If this canary performs visual monitoring of screenshots and you want to remove a screenshot from visual monitoring or you want to designate parts of the screenshot to be ignored during visual comparisons, under **Visual Monitoring** choose **Edit Baseline**.

   The screenshot appears, and you can do one of the following:
   + To remove the screenshot from being used for visual monitoring, select **Remove screenshot from visual test baseline**.
   + To designate parts of the screenshot to be ignored during visual comparisons, click and drag to draw areas of the screen to ignore. Once you have done this for all the areas that you want to ignore during comparisons, choose **Save** .

1. Under **Script editor**, **Runtime version**, select a synthetics runtime version to execute the canary. For information on synthetics runtime versions, see [Synthetics runtime versions ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html).

   Under **Browser configuration**, you can enable the browser to test the canary. You must select at least one browser.

1. Make any other changes to the canary that you'd like, and choose **Save** .

 **Delete canary** 

When you delete a canary, you can choose whether to also delete other resources used and created by the canary. If the canary’s `ProvisionedResourceCleanup` field is set to ` AUTOMATIC` or `DeleteLambda` is specified as `true` when you delete the canary, CloudWatch Synthetics will automatically delete the Lambda functions and layers that are used by the canary.

When you delete a canary, you should also delete the following:
+ Lambda functions and layers used by this canary. Their prefix is `cwsyn- MyCanaryName`.
+ CloudWatch alarms created for this canary. These alarms have a name that starts with ` Synthetics-Alarm-MyCanaryName`. For more information about deleting alarms, see [Edit or delete a CloudWatch alarm](Edit-CloudWatch-Alarm.md).
+ Amazon S3 objects and buckets, such as the canary's results location and artifact location.
+ IAM roles created for the canary. These have the name ` role/service-role/CloudWatchSyntheticsRole-MyCanaryName`. 
+ Log groups in CloudWatch Logs created for the canary. These logs groups have the following names: `/aws/lambda/cwsyn-MyCanaryName-randomId` . 

Before you delete a canary, you might want to view the canary details and make note of this information. That way, you can delete the correct resources after you delete the canary.

**To delete a canary**

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Application Signals**, **Synthetics Canaries**.

1. If the canary is currently in the `RUNNING` state, you must stop it. Only canaries in the `STOPPED`, `READY(NOT_STARTED)`, or `ERROR` states can be deleted.

   To stop the canary, select the button next to the canary name, and choose ** Actions**, **Stop**.

1. Select the button next to the canary name, and choose **Actions**, ** Delete**.

1. Choose whether to also delete the other resources created for and used by the canary. Lambda functions and layers will be deleted alongside the canary, but you can additionally choose to delete the canary's IAM role and IAM policy.

   Enter **Delete** into the box and choose **Delete** .

1. Delete the other resources used by and created for the canary, as listed earlier in this section.

# Start, stop, delete, or update runtime for multiple canaries
<a name="synthetics_canaries_multi-action"></a>

You can stop, start, delete, or update the runtime of as many as five canaries with one action. If you update the runtime of a canary, it is updated to the latest runtime available for the language and framework that the canary uses.

If you select multiple canaries and only some of them are in a state that is valid for the action that you select, the action is performed only on the canaries where that action is valid. For example, if you select some canaries that are currently running and some that are not, and you select to start the canaries, the canaries that weren't already running will start, and the canaries that were already running are not affected.

If none of the canaries that you select are valid for an action, that action will not be available in the menu.

1. Open the CloudWatch console at [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/).

1. In the navigation pane, choose **Application Signals**, **Synthetics Canaries**.

1. Select the check boxes next to the canaries that you want to stop, start, or delete.

1. Choose **Actions** and then choose either **Start**, ** Stop**, **Delete**, **Start Dry Run**, or **Update Runtime**.

   In addition, when choosing **Update Runtime**, you can choose to dry run the runtime update first before committing the change.

# Monitoring canary events with Amazon EventBridge
<a name="monitoring-events-eventbridge"></a>

Amazon EventBridge event rules can notify you when canaries change status or complete runs. EventBridge delivers a near-real-time stream of system events that describe changes in AWS resources. CloudWatch Synthetics sends these events to EventBridge on a *best effort* basis. Best effort delivery means that CloudWatch Synthetics attempts to send all events to EventBridge, but in some rare cases an event might not be delivered. EventBridge processes all received events at least once. Additionally, your event listeners might not receive the events in the order that the events occurred.

**Note**  
Amazon EventBridge is an event bus service that you can use to connect your applications with data from a variety of sources. For more information, see [What is Amazon EventBridge?](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) in the *Amazon EventBridge User Guide*.

CloudWatch Synthetics emits an event when a canary changes state or completes a run. You can create an EventBridge rule that includes an event pattern to match all event types sent from CloudWatch Synthetics, or that matches only specific event types. When a canary triggers a rule, EventBridge invokes the target actions defined in the rule. This allows you to send notifications, capture event information, and take corrective action, in response to a canary state change or the completion of a canary run. For example, you can create rules for the following use cases:
+ Investigating when a canary run fails
+ Investigating when a canary has gone into the `ERROR` state
+ Tracking a canary's life cycle
+ Monitoring canary run success or failure as part of a workflow

## Example events from CloudWatch Synthetics
<a name="synthetics-event-examples"></a>

This section lists example events from CloudWatch Synthetics. For more information about event format, see [ Events and Event Patterns in EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-and-event-patterns.html). 

 **Canary status change** 

In this event type, the values of `current-state` and `previous-state` can be the following:

`CREATING` \$1 `READY` \$1 `STARTING` \$1 `RUNNING` \$1 `UPDATING` \$1 `STOPPING` \$1 `STOPPED` \$1 `ERROR`

```
{
                "version": "0",
                "id": "8a99ca10-1e97-2302-2d64-316c5dedfd61",
                "detail-type": "Synthetics Canary Status Change",
                "source": "aws.synthetics",
                "account": "123456789012",
                "time": "2021-02-09T22:19:43Z",
                "region": "us-east-1",
                "resources": [],
                "detail": {
                                "account-id": "123456789012",
                                "canary-id": "EXAMPLE-dc5a-4f5f-96d1-989b75a94226",
                                "canary-name": "events-bb-1",
                                "current-state": "STOPPED",
                                "previous-state": "UPDATING",
                                "source-location": "NULL",
                                "updated-on": 1612909161.767,
                                "changed-config": {
                                                "executionArn": {
                                                                "previous-value": "arn:aws:lambda:us-east-1:123456789012:function:cwsyn-events-bb-1-af3e3a05-dc5a-4f5f-96d1-989EXAMPLE:1",
                                                                "current-value": "arn:aws:lambda:us-east-1:123456789012:function:cwsyn-events-bb-1-af3e3a05-dc5a-4f5f-96d1-989EXAMPLE:2"
                                                },
                                                "vpcId": {
                                                                "current-value": "NULL"
                                                },
                                                "testCodeLayerVersionArn": {
                                                                "previous-value": "arn:aws:lambda:us-east-1:123456789012:layer:cwsyn-events-bb-1-af3e3a05-dc5a-4f5f-96d1-989EXAMPLE:1",
                                                                "current-value": "arn:aws:lambda:us-east-1:123456789012:layer:cwsyn-events-bb-1-af3e3a05-dc5a-4f5f-96d1-989EXAMPLE:2"
                                                }
                                },
                                "message": "Canary status has changed"
                }
}
```

 **Successful canary run completed** 

```
{
                "version": "0",
                "id": "989EXAMPLE-f4a5-57a7-1a8f-d9cc768a1375",
                "detail-type": "Synthetics Canary TestRun Successful",
                "source": "aws.synthetics",
                "account": "123456789012",
                "time": "2021-02-09T22:24:01Z",
                "region": "us-east-1",
                "resources": [],
                "detail": {
                                "account-id": "123456789012",
                                "canary-id": "989EXAMPLE-dc5a-4f5f-96d1-989b75a94226",
                                "canary-name": "events-bb-1",
                                "canary-run-id": "c6c39152-8f4a-471c-9810-989EXAMPLE",
                                "artifact-location": "cw-syn-results-123456789012-us-east-1/canary/us-east-1/events-bb-1-ec3-28ddbe266797/2021/02/09/22/23-41-200",
                                "test-run-status": "PASSED",
                                "state-reason": "null",
                                "canary-run-timeline": {
                                                "started": 1612909421,
                                                "completed": 1612909441
                                },
                                "message": "Test run result is generated successfully"
                }
}
```

 **Failed canary run completed** 

```
{
                "version": "0",
                "id": "2644b18f-3e67-5ebf-cdfd-bf9f91392f41",
                "detail-type": "Synthetics Canary TestRun Failure",
                "source": "aws.synthetics",
                "account": "123456789012",
                "time": "2021-02-09T22:24:27Z",
                "region": "us-east-1",
                "resources": [],
                "detail": {
                                "account-id": "123456789012",
                                "canary-id": "af3e3a05-dc5a-4f5f-96d1-9989EXAMPLE",
                                "canary-name": "events-bb-1",
                                "canary-run-id": "0df3823e-7e33-4da1-8194-b04e4d4a2bf6",
                                "artifact-location": "cw-syn-results-123456789012-us-east-1/canary/us-east-1/events-bb-1-ec3-989EXAMPLE/2021/02/09/22/24-21-275",
                                "test-run-status": "FAILED",
                                "state-reason": "\"Error: net::ERR_NAME_NOT_RESOLVED \""
                                "canary-run-timeline": {
                                                "started": 1612909461,
                                                "completed": 1612909467
                                },
                                "message": "Test run result is generated successfully"
                }
}
```

It's possible that events might be duplicated or out of order. To determine the order of events, use the `time` property.

## Prerequisites for creating EventBridge rules
<a name="create-events-rule-prereqs"></a>

Before you create an EventBridge rule for CloudWatch Synthetics, you should do the following:
+ Familiarize yourself with events, rules, and targets in EventBridge.
+ Create and configure the targets invoked by your EventBridge rules. Rules can invoke many types of targets, including:
  + Amazon SNS topics
  + AWS Lambda functions
  + Kinesis streams
  + Amazon SQS queues

For more information, see [What is Amazon EventBridge?](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) and [Getting started with Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-getting-set-up.html) in the *Amazon EventBridge User Guide*.

## Create an EventBridge rule (CLI)
<a name="create-events-rule-cli"></a>

The steps in the following example create an EventBridge rule that publishes an Amazon SNS topic when the canary named `my-canary-name` in `us-east-1` completes a run or changes state.

1. Create the rule.

   ```
   aws events put-rule \
     --name TestRule \
     --region us-east-1 \ 
     --event-pattern "{\"source\": [\"aws.synthetics\"], \"detail\": {\"canary-name\": [\"my-canary-name\"]}}"
   ```

   Any properties you omit from the pattern are ignored.

1. Add the topic as a rule target.
   + Replace *topic-arn* with the Amazon Resource Name (ARN) of your Amazon SNS topic.

   ```
   aws events put-targets \
     --rule TestRule \
     --targets "Id"="1","Arn"="topic-arn"
   ```
**Note**  
To allow Amazon EventBridge to call your target topic, you must add a resource-based policy to your topic. For more information, see [Amazon SNS permissions](https://docs.aws.amazon.com/eventbridge/latest/userguide/resource-based-policies-eventbridge.html#sns-permissions) in the *Amazon EventBridge User Guide*.

For more information, see [Events and event patterns in EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-and-event-patterns.html) in the *Amazon EventBridge User Guide*.

# Performing safe canary updates
<a name="performing-safe-canary-upgrades"></a>

CloudWatch synthetics safe canary updates allows you to test the updates on your existing canaries before applying the changes. This feature helps you validate canary compatibility with new run times and other configuration changes such as code or memory changes. This will help minimize potential monitoring disruptions caused by erroneous updates.

By using canary safe updates on runtime version updates, configuration changes, and code script modifications, you can mitigate risk, maintain uninterrupted monitoring, verify the changes before committing, update, and reduce downtime.

**Topics**
+ [

## Prerequisites
](#performing-safe-canary-upgrades-prereq)
+ [

## Best practices
](#performing-safe-canary-upgrades-best-practices)
+ [

## Testing canary using dry run
](#performing-safe-canary-upgrades-getting-started)
+ [

## Limitations
](#performing-safe-canary-upgrades-limitations)

## Prerequisites
<a name="performing-safe-canary-upgrades-prereq"></a>

Make sure the prequisites are complete.
+ AWS account with CloudWatch synthetics permissions
+ Existing canary on the supported runtime versions (see [Limitations](#performing-safe-canary-upgrades-limitations) for compatible runtimes)
+ Include compatible runtimes when performing a dry run (see [Limitations](#performing-safe-canary-upgrades-limitations) for compatible runtimes)

## Best practices
<a name="performing-safe-canary-upgrades-best-practices"></a>

Here are some best practices to follow while performing a canary .
+ Execute a dry run to validate a runtime update
+ Perform dry runs before production updates to canary
+ Review canary logs and artifacts after a dry run
+ Use dry runs to validate dependencies and library compatibility

## Testing canary using dry run
<a name="performing-safe-canary-upgrades-getting-started"></a>

You can test the canary update using the following options:

 **Using the AWS Management Console's Edit workflow** 

1. Go the CloudWatch synthetics console.

1. Select the canary you want to update.

1. From the **Actions** drop down, choose **Edit**.

   Update the canary with the changes you want to test. For example, changing runtime version or editing the script’s code.

1. Under **Canary script**, choose **Start Dry Run** to test and view the results immediately or choose **Validate and save later** at the bottom of the page to start the test and view the results later in your **Canary Details** page.

1. After the dry run succeeds, choose **Submit** to commit your canary updates.

 **Using the AWS Management Console for updating canaries in a batch** 

1. Go the CloudWatch synthetics console.

1. Choose the **Synthetics** list page.

1. Select upto five canaries for which you want to update the runtime.

1. From the **Actions** drop down, choose **Update Runtime** .

1. Choose **Start dry run for new runtime** to start the dry run and test your changes before an update.

1. On the **Synthetics** list page, you will see a text next to the ** Runtime** version for the canary that displays the progress of the dry run (this is only displayed for dry runs involving a runtime update).

   Once the dry run succeeds, you will see an **Initiate Update** text.

1. Choose **Initiate Update** to commit the runtime update.

1. If the dry run fails, you will see an **Update dry run failed** text. Choose the text to view the debug link to the canary details page.

 **Using the AWS CLI or SDK** 

The API starts the dry run for the provided canary name `MyCanary` and updates the runtime version to `syn-nodejs-puppeteer-10.0`.

```
aws synthetics start-canary-dry-run \
    --name MyCanary \
    --runtime-version syn-nodejs-puppeteer-10.0
      
      // Or if you wanted to update other configurations:

aws synthetics start-canary-dry-run \
    --name MyCanary \
    --execution-role-arn arn:aws:iam::123456789012:role/NewRole
```

The API will return the `DryRunId` inside the `DryRunConfigOutput` .

Call `GetCanary` with the provided `DryRunId` to receive the canary’s dry run configurations and an additional field `DryRunConfig` which contains the status of the dry run listed as `LastDryRunExecutionStatus`.

```
aws synthetics get-canary \
    --name MyCanary \
    --dry-run-id XXXX-XXXX-XXXX-XXXX
```

For more details, use `GetCanaryRuns` with the provided `DryRunId` to retrieve the run and additional information.

```
aws synthetics get-canary-runs \
    --name MyCanary \
    --dry-run-id XXXX-XXXX-XXXX-XXXX
```

After a successful dry run, you can then use `UpdateCanary` with the provided ` DryRunId` in order to commit your changes.

```
aws synthetics update-canary \
    --name MyCanary \
    --dry-run-id XXXX-XXXX-XXXX-XXXX
```

When it fails for any reason (result from GetCanaryRuns will have the details), the result from `GetCanaryRuns` has an artifact location that contains logs to debug. When there are no logs, the dry run failed to be created. You can validate by using ` GetCanary`.

```
aws synthetics get-canary \
    --name MyCanary \
    --dry-run-id XXXX-XXXX-XXXX-XXXX
```

The *State*, *StateReason*, and * StateReasonCode* displays the status of the dry run.

 **Using CloudFormation** 

In your template for a Synthetics Canary, provide the field `DryRunAndUpdate` which accepts a boolean value `true` or `false`.

when the value is `true` every update executes a dry run to validate the changes before automatically updating the canary. When the dry run fails, the canary does not update and fails the deployment and CloudFormation deployment with a valid reason. To debug this issue, use the [AWS Synthetics console ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Troubleshoot.html) or if using an API, get the `ArtifactS3Location` using the `GetCanaryRuns` API, and download the `*-log.txt` files to review the canary log executions for errors. After validation, modify the CloudFormation template and retry the deployment or use the above API to validate.

When the value is `false`, synthetics will not execute a dry run to validate changes and will directly commit your updates.

For information on troubleshooting a failed canary, see [Troubleshooting a failed canary](CloudWatch_Synthetics_Canaries_Troubleshoot.md).

An example template.

```
SyntheticsCanary:
    Type: 'AWS::Synthetics::Canary'
    Properties:
      Name: MyCanary
      RuntimeVersion: syn-nodejs-puppeteer-10.0
      Schedule: {Expression: 'rate(5 minutes)', DurationInSeconds: 3600}
      ...
      DryRunAndUpdate: true
```

## Limitations
<a name="performing-safe-canary-upgrades-limitations"></a>
+ Supports runtime versions – syn-nodejs-puppeteer-10.0\$1, syn-nodejs-playwright-2.0\$1, syn-python-selenium-5.1\$1, and syn-nodejs-3.0\$1
+ You can only execute one dry run per canary at a time
+ When a dry run fails, you cannot update the canary
+ Dry run cannot test any **Schedule** field changes

**Note**  
When you initiate a dry run with code changes for a Playwright canary and you want to update the canary without providing the associated `DryRunId`, you must explicitly specify the code parameters.