This Terraform module deploys a prober service to AWS App Runner with integrated uptime monitoring using CloudWatch Synthetics. It's the AWS equivalent of the GCP prober module.
- Automated Prober Deployment: Deploys Go-based prober applications to AWS App Runner
- Shared Secret Authentication: Generates a random password for authorization headers to prevent abuse
- CloudWatch Synthetics Integration: Optional canary monitoring for uptime checks
- CloudWatch Alarms: Configurable alerting on uptime check failures
- Automatic IAM Setup: Creates all necessary IAM roles and policies automatically
- VPC Support: Optional VPC connector for accessing private resources
- X-Ray Tracing: Optional AWS X-Ray integration for observability
module "my_prober" {
source = "./modules/aws/prober"
name = "api-health"
team = "platform"
product = "monitoring"
importpath = "github.com/my-org/my-prober"
working_dir = "${path.module}/prober"
# Environment variables for the prober
env = {
TARGET_URL = "https://api.example.com"
CHECK_TYPE = "http"
}
# Enable CloudWatch Synthetics for uptime monitoring
cloudwatch_synthetics_enabled = true
canary_schedule = "rate(5 minutes)"
# Enable alerting
enable_alert = true
notification_channels = [aws_sns_topic.alerts.arn]
}For probers that need to access private resources:
# Create VPC connector
resource "aws_apprunner_vpc_connector" "prober" {
vpc_connector_name = "prober-vpc-connector"
subnets = var.private_subnet_ids
security_groups = [aws_security_group.prober.id]
}
module "internal_prober" {
source = "./modules/aws/prober"
name = "internal-api-health"
team = "platform"
product = "monitoring"
importpath = "github.com/my-org/my-prober"
working_dir = "${path.module}/prober"
# VPC configuration for private resource access
egress = "VPC"
vpc_connector_arn = aws_apprunner_vpc_connector.prober.arn
env = {
TARGET_URL = "https://internal-api.private.example.com"
}
}For probers that need access to secrets:
# Create secrets
resource "aws_secretsmanager_secret" "api_key" {
name = "prober-api-key"
}
resource "aws_secretsmanager_secret_version" "api_key" {
secret_id = aws_secretsmanager_secret.api_key.id
secret_string = "your-secret-key"
}
module "authenticated_prober" {
source = "./modules/aws/prober"
name = "authenticated-api-health"
team = "platform"
product = "monitoring"
importpath = "github.com/my-org/my-prober"
working_dir = "${path.module}/prober"
env = {
TARGET_URL = "https://api.example.com"
}
# Mount secrets as environment variables
secret_env = {
API_KEY = aws_secretsmanager_secret.api_key.arn
}
}module "heavy_prober" {
source = "./modules/aws/prober"
name = "load-test-prober"
team = "platform"
product = "monitoring"
importpath = "github.com/my-org/my-prober"
working_dir = "${path.module}/prober"
# Increase resources for heavy workloads
cpu = 2048 # 2 vCPU
memory = 4096 # 4 GB
# Adjust scaling
scaling = {
min_instances = 2
max_instances = 10
max_instance_request_concurrency = 50
}
}- Prober Service: Deploys your Go prober application to AWS App Runner
- Shared Secret: Generates a random authorization token that's passed to both:
- The prober service as an environment variable (
AUTHORIZATION) - The CloudWatch Synthetics canary as a custom header
- The prober service as an environment variable (
- Uptime Check: CloudWatch Synthetics canary periodically hits the prober endpoint with the authorization header
- Alerting: CloudWatch Alarms monitor the canary success rate and send notifications on failures
Your prober application should:
- Listen on port 8080
- Respond to GET requests on
/ - Verify the
Authorizationheader matches the shared secret - Return HTTP 200 on success, non-200 on failure
Example Go prober:
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func main() {
expectedAuth := os.Getenv("AUTHORIZATION")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Verify authorization
if r.Header.Get("Authorization") != expectedAuth {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// Perform your health checks here
if err := checkTargetHealth(); err != nil {
http.Error(w, err.Error(), http.StatusServiceUnavailable)
return
}
fmt.Fprintf(w, "OK")
})
log.Fatal(http.ListenAndServe(":8080", nil))
}The module uses CloudWatch Synthetics to create a canary that:
- Runs on a configurable schedule (default: every 5 minutes)
- Makes HTTPS requests to the prober endpoint
- Includes the authorization header
- Reports success/failure metrics to CloudWatch
The canary publishes metrics to CloudWatch under the CloudWatchSynthetics namespace:
SuccessPercent: Percentage of successful checksDuration: Time taken for each checkFailed: Number of failed checks
When enable_alert = true, the module creates a CloudWatch alarm that:
- Monitors the
SuccessPercentmetric - Triggers when success rate drops below 90% for 2 evaluation periods
- Sends notifications to configured SNS topics
No requirements.
| Name | Version |
|---|---|
| archive | n/a |
| aws | n/a |
| random | n/a |
| Name | Source | Version |
|---|---|---|
| this | ../apprunner-regional-go-service | n/a |
| Name | Type |
|---|---|
| aws_cloudwatch_metric_alarm.uptime_alert | resource |
| aws_iam_role.canary | resource |
| aws_iam_role_policy.canary_permissions | resource |
| aws_iam_role_policy_attachment.canary_xray | resource |
| aws_s3_bucket.canary_artifacts | resource |
| aws_synthetics_canary.uptime_check | resource |
| random_password.secret | resource |
| archive_file.canary_script | data source |
| aws_caller_identity.current | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| alarm_comparison_operator | The arithmetic operation to use when comparing the specified statistic and threshold. Valid values: GreaterThanOrEqualToThreshold, GreaterThanThreshold, LessThanThreshold, LessThanOrEqualToThreshold. | string |
"LessThanThreshold" |
no |
| alarm_datapoints_to_alarm | The number of datapoints that must be breaching to trigger the alarm. Defaults to evaluation_periods if not set. | number |
null |
no |
| alarm_evaluation_periods | The number of periods over which data is compared to the specified threshold. | number |
2 |
no |
| alarm_statistic | The statistic to apply to the alarm's associated metric. Valid values: SampleCount, Average, Sum, Minimum, Maximum. | string |
"Average" |
no |
| alarm_threshold | The value against which the specified statistic is compared. For SuccessPercent, this is the percentage (0-100). | number |
90 |
no |
| alarm_treat_missing_data | How to handle missing data points. Valid values: missing, ignore, breaching, notBreaching. | string |
"notBreaching" |
no |
| alert_description | Alert documentation. Use this to link to playbooks or give additional context. | string |
"An uptime check has failed." |
no |
| base_image | The base image to use for the prober. | string |
null |
no |
| canary_runtime_version | CloudWatch Synthetics runtime version. | string |
"syn-nodejs-puppeteer-13.0" |
no |
| canary_schedule | CloudWatch Synthetics canary schedule expression. | string |
"rate(5 minutes)" |
no |
| cloudwatch_synthetics_enabled | Enable CloudWatch Synthetics canary for uptime monitoring. | bool |
true |
no |
| cpu | The CPU units for the prober. Valid values: 256, 512, 1024, 2048, 4096 | number |
1024 |
no |
| create_instance_role | Whether to create the IAM instance role for the running containers. If false, you must provide instance_role_arn. | bool |
true |
no |
| egress | Network egress configuration. DEFAULT for internet, VPC for private resources | string |
"DEFAULT" |
no |
| enable_alert | If true, alert on failures. Outputs will return the alert ID for notification and dashboards. | bool |
false |
no |
| enable_profiler | Enable cloud profiler (AWS X-Ray). | bool |
false |
no |
| env | A map of custom environment variables (e.g. key=value) | map(string) |
{} |
no |
| importpath | The import path that contains the prober application. | string |
n/a | yes |
| ingress | Network ingress configuration. PUBLIC for internet access, PRIVATE for VPC only | string |
"PUBLIC" |
no |
| instance_role_arn | The ARN of the IAM role that the running service will assume. Required if create_instance_role is false. | string |
"" |
no |
| memory | The memory in MB for the prober. Valid values: 512, 1024, 2048, 3072, 4096, 6144, 8192, 10240, 12288 | number |
2048 |
no |
| name | Name to prefix to created resources. | string |
n/a | yes |
| notification_channels | A list of SNS topic ARNs to send alerts to. | list(string) |
[] |
no |
| period | The period for the prober in seconds. Supported values: 60s (1 minute), 300s (5 minutes), 600s (10 minutes), and 900s (15 minutes) | string |
"300s" |
no |
| product | Product label to apply to the service. | string |
n/a | yes |
| scaling | The scaling configuration for the service. | object({ |
{} |
no |
| secret_env | A map of secrets to mount as environment variables from AWS Secrets Manager or SSM Parameter Store (e.g. secret_key=secret_arn) | map(string) |
{} |
no |
| start_canary | Automatically start the canary after creation. Set to false to create the canary in a stopped state. | bool |
true |
no |
| tags | Additional tags to apply to resources | map(string) |
{} |
no |
| team | Team label to apply to resources. | string |
n/a | yes |
| timeout | The timeout for the prober in seconds. Supported values 1-60s | string |
"60s" |
no |
| uptime_alert_duration | Duration for uptime alert policy. | string |
"600s" |
no |
| vpc_connector_arn | Optional VPC connector ARN for private resource access (required if egress is VPC). | string |
null |
no |
| working_dir | The working directory that contains the importpath. | string |
n/a | yes |
| Name | Description |
|---|---|
| alarm_arn | CloudWatch alarm ARN (if enabled) |
| authorization_secret | The shared secret used for authorization (sensitive) |
| canary_arn | CloudWatch Synthetics canary ARN (if enabled) |
| canary_name | CloudWatch Synthetics canary name (if enabled) |
| instance_role_arn | IAM instance role ARN used by the running containers |
| instance_role_name | IAM instance role name (if created by module) |
| service_arn | App Runner service ARN |
| service_name | App Runner service name |
| service_url | App Runner service URL |