@hasna/uptime 0.1.23 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/Dockerfile.package +2 -2
- package/NOTICE +1 -1
- package/README.md +9 -3
- package/THIRD_PARTY_NOTICES.md +4 -1
- package/bun.lock +221 -0
- package/dist/api.js +111 -33
- package/dist/cli/index.js +169 -43
- package/dist/cloud-plan.d.ts +14 -1
- package/dist/cloud-plan.d.ts.map +1 -1
- package/dist/cloud-plan.js +27 -7
- package/dist/index.js +138 -40
- package/dist/mcp/index.js +111 -33
- package/dist/service.d.ts +19 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +111 -33
- package/docs/aws-deployment-runbook.md +40 -14
- package/docs/aws-runtime-security.md +25 -10
- package/docs/cloud-source-of-truth.md +10 -7
- package/docs/deployment-metadata.example.json +4 -2
- package/infra/aws/README.md +26 -11
- package/infra/aws/main.tf +116 -34
- package/infra/aws/outputs.tf +8 -0
- package/infra/aws/terraform.tfvars.example +4 -1
- package/infra/aws/variables.tf +54 -5
- package/package.json +2 -1
package/infra/aws/main.tf
CHANGED
|
@@ -17,16 +17,21 @@ data "aws_caller_identity" "current" {}
|
|
|
17
17
|
data "aws_partition" "current" {}
|
|
18
18
|
|
|
19
19
|
locals {
|
|
20
|
-
prefix
|
|
21
|
-
container_port
|
|
22
|
-
evidence_bucket
|
|
23
|
-
efs_uid
|
|
24
|
-
efs_gid
|
|
25
|
-
hosted_sqlite_db_path
|
|
26
|
-
efs_enabled_services
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
prefix = "${var.service_name}-${var.stage}"
|
|
21
|
+
container_port = 3899
|
|
22
|
+
evidence_bucket = "hasna-${var.stage}-${var.service_name}-evidence"
|
|
23
|
+
efs_uid = 10001
|
|
24
|
+
efs_gid = 10001
|
|
25
|
+
hosted_sqlite_db_path = "/data/uptime/uptime.db"
|
|
26
|
+
efs_enabled_services = toset(["web"])
|
|
27
|
+
expected_runtime_package_integrity = coalesce(var.runtime_package_integrity, "")
|
|
28
|
+
use_alb_https = var.protected_access_mode == "alb_https_cert"
|
|
29
|
+
use_cloudfront = var.protected_access_mode == "cloudfront_default_domain"
|
|
30
|
+
cloudfront_https_origin = (
|
|
31
|
+
local.use_cloudfront && var.cloudfront_origin_protocol_policy == "https-only"
|
|
32
|
+
)
|
|
33
|
+
alb_https_listener_enabled = local.use_alb_https || local.cloudfront_https_origin
|
|
34
|
+
use_origin_verify = local.use_cloudfront && var.enable_cloudfront_origin_verify_header
|
|
30
35
|
services = {
|
|
31
36
|
web = {
|
|
32
37
|
desired_count = lookup(var.desired_counts, "web", 0)
|
|
@@ -236,9 +241,18 @@ resource "aws_codebuild_project" "image_builder" {
|
|
|
236
241
|
- aws ecr get-login-password --region ${var.region} | docker login --username AWS --password-stdin ${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.region}.amazonaws.com
|
|
237
242
|
build:
|
|
238
243
|
commands:
|
|
239
|
-
-
|
|
244
|
+
- EXPECTED_RUNTIME_PACKAGE_INTEGRITY='${local.expected_runtime_package_integrity}'
|
|
245
|
+
- PACKAGE_TARBALL=$(npm pack @hasna/uptime@${var.runtime_package_version} --silent)
|
|
246
|
+
- PACKAGE_INTEGRITY=$(npm view @hasna/uptime@${var.runtime_package_version} dist.integrity --json | tr -d '"')
|
|
247
|
+
- test -n "$PACKAGE_INTEGRITY"
|
|
248
|
+
- |
|
|
249
|
+
if [ -n "$EXPECTED_RUNTIME_PACKAGE_INTEGRITY" ] && [ "$PACKAGE_INTEGRITY" != "$EXPECTED_RUNTIME_PACKAGE_INTEGRITY" ]; then
|
|
250
|
+
echo "runtime package integrity mismatch" >&2
|
|
251
|
+
exit 1
|
|
252
|
+
fi
|
|
253
|
+
- printf 'runtime package integrity %s\n' "$PACKAGE_INTEGRITY"
|
|
240
254
|
- mkdir package
|
|
241
|
-
- tar -xzf
|
|
255
|
+
- tar -xzf "$PACKAGE_TARBALL" -C package --strip-components=1
|
|
242
256
|
- cd package
|
|
243
257
|
- docker build -f Dockerfile.package -t ${aws_ecr_repository.open_uptime.repository_url}:${var.runtime_package_version} .
|
|
244
258
|
- docker push ${aws_ecr_repository.open_uptime.repository_url}:${var.runtime_package_version}
|
|
@@ -366,8 +380,19 @@ resource "aws_security_group_rule" "alb_https_ingress" {
|
|
|
366
380
|
cidr_blocks = var.alb_ingress_cidr_blocks
|
|
367
381
|
}
|
|
368
382
|
|
|
383
|
+
resource "aws_security_group_rule" "alb_https_from_cloudfront" {
|
|
384
|
+
count = local.cloudfront_https_origin ? 1 : 0
|
|
385
|
+
type = "ingress"
|
|
386
|
+
description = "HTTPS from CloudFront origin-facing ranges"
|
|
387
|
+
security_group_id = aws_security_group.alb.id
|
|
388
|
+
from_port = 443
|
|
389
|
+
to_port = 443
|
|
390
|
+
protocol = "tcp"
|
|
391
|
+
prefix_list_ids = [data.aws_ec2_managed_prefix_list.cloudfront_origin_facing[0].id]
|
|
392
|
+
}
|
|
393
|
+
|
|
369
394
|
resource "aws_security_group_rule" "alb_http_from_cloudfront" {
|
|
370
|
-
count = local.use_cloudfront ? 1 : 0
|
|
395
|
+
count = local.use_cloudfront && !local.cloudfront_https_origin ? 1 : 0
|
|
371
396
|
type = "ingress"
|
|
372
397
|
description = "HTTP from CloudFront origin-facing ranges"
|
|
373
398
|
security_group_id = aws_security_group.alb.id
|
|
@@ -881,21 +906,37 @@ resource "aws_lb_target_group" "web" {
|
|
|
881
906
|
}
|
|
882
907
|
|
|
883
908
|
resource "aws_lb_listener" "https" {
|
|
884
|
-
count = local.
|
|
909
|
+
count = local.alb_https_listener_enabled ? 1 : 0
|
|
885
910
|
load_balancer_arn = aws_lb.open_uptime.arn
|
|
886
911
|
port = 443
|
|
887
912
|
protocol = "HTTPS"
|
|
888
913
|
certificate_arn = var.certificate_arn
|
|
889
914
|
tags = local.tags
|
|
890
915
|
|
|
891
|
-
default_action {
|
|
892
|
-
|
|
893
|
-
|
|
916
|
+
dynamic "default_action" {
|
|
917
|
+
for_each = local.cloudfront_https_origin && local.use_origin_verify ? [] : [1]
|
|
918
|
+
content {
|
|
919
|
+
type = "forward"
|
|
920
|
+
target_group_arn = aws_lb_target_group.web.arn
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
dynamic "default_action" {
|
|
925
|
+
for_each = local.cloudfront_https_origin && local.use_origin_verify ? [1] : []
|
|
926
|
+
content {
|
|
927
|
+
type = "fixed-response"
|
|
928
|
+
|
|
929
|
+
fixed_response {
|
|
930
|
+
content_type = "text/plain"
|
|
931
|
+
message_body = "forbidden"
|
|
932
|
+
status_code = "403"
|
|
933
|
+
}
|
|
934
|
+
}
|
|
894
935
|
}
|
|
895
936
|
}
|
|
896
937
|
|
|
897
938
|
resource "aws_lb_listener" "http_cloudfront" {
|
|
898
|
-
count = local.use_cloudfront ? 1 : 0
|
|
939
|
+
count = local.use_cloudfront && !local.cloudfront_https_origin ? 1 : 0
|
|
899
940
|
load_balancer_arn = aws_lb.open_uptime.arn
|
|
900
941
|
port = 80
|
|
901
942
|
protocol = "HTTP"
|
|
@@ -924,7 +965,7 @@ resource "aws_lb_listener" "http_cloudfront" {
|
|
|
924
965
|
}
|
|
925
966
|
|
|
926
967
|
resource "aws_lb_listener_rule" "http_cloudfront_origin_verify" {
|
|
927
|
-
count = local.use_origin_verify ? 1 : 0
|
|
968
|
+
count = local.use_origin_verify && !local.cloudfront_https_origin ? 1 : 0
|
|
928
969
|
listener_arn = aws_lb_listener.http_cloudfront[0].arn
|
|
929
970
|
priority = var.cloudfront_origin_verify_listener_rule_priority
|
|
930
971
|
tags = local.tags
|
|
@@ -942,6 +983,25 @@ resource "aws_lb_listener_rule" "http_cloudfront_origin_verify" {
|
|
|
942
983
|
}
|
|
943
984
|
}
|
|
944
985
|
|
|
986
|
+
resource "aws_lb_listener_rule" "https_cloudfront_origin_verify" {
|
|
987
|
+
count = local.use_origin_verify && local.cloudfront_https_origin ? 1 : 0
|
|
988
|
+
listener_arn = aws_lb_listener.https[0].arn
|
|
989
|
+
priority = var.cloudfront_origin_verify_listener_rule_priority
|
|
990
|
+
tags = local.tags
|
|
991
|
+
|
|
992
|
+
action {
|
|
993
|
+
type = "forward"
|
|
994
|
+
target_group_arn = aws_lb_target_group.web.arn
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
condition {
|
|
998
|
+
http_header {
|
|
999
|
+
http_header_name = var.cloudfront_origin_verify_header_name
|
|
1000
|
+
values = [var.cloudfront_origin_verify_header_value]
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
945
1005
|
resource "aws_cloudfront_distribution" "open_uptime" {
|
|
946
1006
|
count = local.use_cloudfront ? 1 : 0
|
|
947
1007
|
enabled = true
|
|
@@ -951,7 +1011,7 @@ resource "aws_cloudfront_distribution" "open_uptime" {
|
|
|
951
1011
|
tags = local.tags
|
|
952
1012
|
|
|
953
1013
|
origin {
|
|
954
|
-
domain_name = aws_lb.open_uptime.dns_name
|
|
1014
|
+
domain_name = local.cloudfront_https_origin ? var.cloudfront_origin_domain_name : aws_lb.open_uptime.dns_name
|
|
955
1015
|
origin_id = "${local.prefix}-alb"
|
|
956
1016
|
|
|
957
1017
|
dynamic "custom_header" {
|
|
@@ -965,7 +1025,7 @@ resource "aws_cloudfront_distribution" "open_uptime" {
|
|
|
965
1025
|
custom_origin_config {
|
|
966
1026
|
http_port = 80
|
|
967
1027
|
https_port = 443
|
|
968
|
-
origin_protocol_policy =
|
|
1028
|
+
origin_protocol_policy = var.cloudfront_origin_protocol_policy
|
|
969
1029
|
origin_ssl_protocols = ["TLSv1.2"]
|
|
970
1030
|
}
|
|
971
1031
|
}
|
|
@@ -1000,7 +1060,12 @@ resource "aws_cloudfront_distribution" "open_uptime" {
|
|
|
1000
1060
|
cloudfront_default_certificate = true
|
|
1001
1061
|
}
|
|
1002
1062
|
|
|
1003
|
-
depends_on = [
|
|
1063
|
+
depends_on = [
|
|
1064
|
+
aws_lb_listener.http_cloudfront,
|
|
1065
|
+
aws_lb_listener.https,
|
|
1066
|
+
aws_lb_listener_rule.http_cloudfront_origin_verify,
|
|
1067
|
+
aws_lb_listener_rule.https_cloudfront_origin_verify,
|
|
1068
|
+
]
|
|
1004
1069
|
}
|
|
1005
1070
|
|
|
1006
1071
|
resource "aws_route53_record" "open_uptime" {
|
|
@@ -1016,6 +1081,19 @@ resource "aws_route53_record" "open_uptime" {
|
|
|
1016
1081
|
}
|
|
1017
1082
|
}
|
|
1018
1083
|
|
|
1084
|
+
resource "aws_route53_record" "cloudfront_origin" {
|
|
1085
|
+
count = local.cloudfront_https_origin && var.hosted_zone_id != null ? 1 : 0
|
|
1086
|
+
zone_id = var.hosted_zone_id
|
|
1087
|
+
name = var.cloudfront_origin_domain_name
|
|
1088
|
+
type = "A"
|
|
1089
|
+
|
|
1090
|
+
alias {
|
|
1091
|
+
name = aws_lb.open_uptime.dns_name
|
|
1092
|
+
zone_id = aws_lb.open_uptime.zone_id
|
|
1093
|
+
evaluate_target_health = true
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1019
1097
|
data "aws_iam_policy_document" "ecs_assume_role" {
|
|
1020
1098
|
statement {
|
|
1021
1099
|
actions = ["sts:AssumeRole"]
|
|
@@ -1194,12 +1272,14 @@ resource "aws_ecs_task_definition" "service" {
|
|
|
1194
1272
|
}
|
|
1195
1273
|
|
|
1196
1274
|
resource "aws_ecs_service" "web" {
|
|
1197
|
-
name
|
|
1198
|
-
cluster
|
|
1199
|
-
task_definition
|
|
1200
|
-
desired_count
|
|
1201
|
-
launch_type
|
|
1202
|
-
|
|
1275
|
+
name = "${local.prefix}-web"
|
|
1276
|
+
cluster = aws_ecs_cluster.open_uptime.id
|
|
1277
|
+
task_definition = aws_ecs_task_definition.service["web"].arn
|
|
1278
|
+
desired_count = local.services.web.desired_count
|
|
1279
|
+
launch_type = "FARGATE"
|
|
1280
|
+
enable_ecs_managed_tags = true
|
|
1281
|
+
propagate_tags = "SERVICE"
|
|
1282
|
+
tags = local.tags
|
|
1203
1283
|
|
|
1204
1284
|
deployment_circuit_breaker {
|
|
1205
1285
|
enable = true
|
|
@@ -1226,12 +1306,14 @@ resource "aws_ecs_service" "worker" {
|
|
|
1226
1306
|
for key, value in local.services : key => value if key != "web" && key != "migration"
|
|
1227
1307
|
}
|
|
1228
1308
|
|
|
1229
|
-
name
|
|
1230
|
-
cluster
|
|
1231
|
-
task_definition
|
|
1232
|
-
desired_count
|
|
1233
|
-
launch_type
|
|
1234
|
-
|
|
1309
|
+
name = "${local.prefix}-${each.key}"
|
|
1310
|
+
cluster = aws_ecs_cluster.open_uptime.id
|
|
1311
|
+
task_definition = aws_ecs_task_definition.service[each.key].arn
|
|
1312
|
+
desired_count = each.value.desired_count
|
|
1313
|
+
launch_type = "FARGATE"
|
|
1314
|
+
enable_ecs_managed_tags = true
|
|
1315
|
+
propagate_tags = "SERVICE"
|
|
1316
|
+
tags = local.tags
|
|
1235
1317
|
|
|
1236
1318
|
deployment_circuit_breaker {
|
|
1237
1319
|
enable = true
|
package/infra/aws/outputs.tf
CHANGED
|
@@ -18,6 +18,14 @@ output "cloudfront_domain_name" {
|
|
|
18
18
|
value = try(aws_cloudfront_distribution.open_uptime[0].domain_name, null)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
output "cloudfront_origin_protocol_policy" {
|
|
22
|
+
value = local.use_cloudfront ? var.cloudfront_origin_protocol_policy : null
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
output "cloudfront_origin_domain_name" {
|
|
26
|
+
value = local.use_cloudfront ? (local.cloudfront_https_origin ? var.cloudfront_origin_domain_name : aws_lb.open_uptime.dns_name) : null
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
output "protected_access_url" {
|
|
22
30
|
value = var.protected_access_mode == "cloudfront_default_domain" ? "https://${aws_cloudfront_distribution.open_uptime[0].domain_name}" : "https://${var.hostname}"
|
|
23
31
|
}
|
|
@@ -11,6 +11,8 @@ workspace_id = "workspace-id"
|
|
|
11
11
|
vpc_id = "vpc-xxxxxxxx"
|
|
12
12
|
ecr_repository_name = "open-uptime"
|
|
13
13
|
protected_access_mode = "cloudfront_default_domain"
|
|
14
|
+
cloudfront_origin_protocol_policy = "http-only"
|
|
15
|
+
cloudfront_origin_domain_name = null
|
|
14
16
|
enable_cloudfront_origin_verify_header = false
|
|
15
17
|
cloudfront_origin_verify_header_name = "X-Open-Uptime-Origin-Verify"
|
|
16
18
|
cloudfront_origin_verify_header_value = null
|
|
@@ -19,7 +21,8 @@ alb_ingress_cidr_blocks = []
|
|
|
19
21
|
private_subnet_ids = ["subnet-replace-private-a", "subnet-replace-private-b"]
|
|
20
22
|
private_route_table_ids = ["rtb-replace-private"]
|
|
21
23
|
container_image = "123456789012.dkr.ecr.us-east-1.amazonaws.com/open-uptime@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
22
|
-
runtime_package_version
|
|
24
|
+
runtime_package_version = "0.1.25"
|
|
25
|
+
runtime_package_integrity = null
|
|
23
26
|
certificate_arn = null
|
|
24
27
|
hosted_zone_id = null
|
|
25
28
|
app_env_secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:open-uptime/prod/app/env"
|
package/infra/aws/variables.tf
CHANGED
|
@@ -77,7 +77,7 @@ variable "ecr_repository_name" {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
variable "protected_access_mode" {
|
|
80
|
-
description = "Protected web access mode. cloudfront_default_domain uses the CloudFront HTTPS default domain and restricts ALB
|
|
80
|
+
description = "Protected web access mode. cloudfront_default_domain uses the CloudFront HTTPS default domain and restricts the ALB origin to CloudFront origin-facing ranges. alb_https_cert uses an ALB HTTPS listener with certificate_arn."
|
|
81
81
|
type = string
|
|
82
82
|
default = "cloudfront_default_domain"
|
|
83
83
|
|
|
@@ -87,6 +87,40 @@ variable "protected_access_mode" {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
variable "cloudfront_origin_protocol_policy" {
|
|
91
|
+
description = "CloudFront-to-ALB origin protocol policy. Keep http-only until an origin hostname and matching ACM certificate are approved; set https-only with cloudfront_origin_domain_name and certificate_arn before token-bearing live traffic."
|
|
92
|
+
type = string
|
|
93
|
+
default = "http-only"
|
|
94
|
+
|
|
95
|
+
validation {
|
|
96
|
+
condition = contains(["http-only", "https-only"], var.cloudfront_origin_protocol_policy)
|
|
97
|
+
error_message = "cloudfront_origin_protocol_policy must be http-only or https-only."
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
variable "cloudfront_origin_domain_name" {
|
|
102
|
+
description = "DNS hostname CloudFront uses for the ALB custom origin when cloudfront_origin_protocol_policy is https-only. The hostname must resolve to the ALB and match certificate_arn. Leave null for the default HTTP-origin bridge."
|
|
103
|
+
type = string
|
|
104
|
+
default = null
|
|
105
|
+
nullable = true
|
|
106
|
+
|
|
107
|
+
validation {
|
|
108
|
+
condition = (
|
|
109
|
+
var.cloudfront_origin_domain_name == null
|
|
110
|
+
|| can(regex("^[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$", var.cloudfront_origin_domain_name))
|
|
111
|
+
)
|
|
112
|
+
error_message = "cloudfront_origin_domain_name must be null or a valid DNS hostname."
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
validation {
|
|
116
|
+
condition = (
|
|
117
|
+
!(var.protected_access_mode == "cloudfront_default_domain" && var.cloudfront_origin_protocol_policy == "https-only")
|
|
118
|
+
|| var.cloudfront_origin_domain_name != null
|
|
119
|
+
)
|
|
120
|
+
error_message = "cloudfront_origin_domain_name is required when CloudFront HTTPS origin is enabled."
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
90
124
|
variable "enable_cloudfront_origin_verify_header" {
|
|
91
125
|
description = "When true in cloudfront_default_domain mode, CloudFront sends a private origin header and the ALB listener rejects requests missing the matching value."
|
|
92
126
|
type = bool
|
|
@@ -201,7 +235,7 @@ variable "container_image" {
|
|
|
201
235
|
variable "runtime_package_version" {
|
|
202
236
|
description = "Published @hasna/uptime package version that CodeBuild should build into the ECR image."
|
|
203
237
|
type = string
|
|
204
|
-
default = "0.1.
|
|
238
|
+
default = "0.1.25"
|
|
205
239
|
|
|
206
240
|
validation {
|
|
207
241
|
condition = can(regex("^[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?$", var.runtime_package_version))
|
|
@@ -209,8 +243,20 @@ variable "runtime_package_version" {
|
|
|
209
243
|
}
|
|
210
244
|
}
|
|
211
245
|
|
|
246
|
+
variable "runtime_package_integrity" {
|
|
247
|
+
description = "Optional expected npm dist.integrity value for @hasna/uptime@runtime_package_version. When set, CodeBuild verifies the registry tarball integrity before building the image."
|
|
248
|
+
type = string
|
|
249
|
+
default = null
|
|
250
|
+
nullable = true
|
|
251
|
+
|
|
252
|
+
validation {
|
|
253
|
+
condition = var.runtime_package_integrity == null || can(regex("^sha512-[A-Za-z0-9+/=]+$", var.runtime_package_integrity))
|
|
254
|
+
error_message = "runtime_package_integrity must be null or an npm sha512 integrity string."
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
212
258
|
variable "certificate_arn" {
|
|
213
|
-
description = "ACM certificate ARN for ALB HTTPS mode. Leave null when
|
|
259
|
+
description = "ACM certificate ARN for ALB HTTPS mode or CloudFront HTTPS-origin mode. Leave null only when the ALB is not serving HTTPS."
|
|
214
260
|
type = string
|
|
215
261
|
default = null
|
|
216
262
|
|
|
@@ -220,8 +266,11 @@ variable "certificate_arn" {
|
|
|
220
266
|
}
|
|
221
267
|
|
|
222
268
|
validation {
|
|
223
|
-
condition
|
|
224
|
-
|
|
269
|
+
condition = (
|
|
270
|
+
!(var.protected_access_mode == "alb_https_cert" || (var.protected_access_mode == "cloudfront_default_domain" && var.cloudfront_origin_protocol_policy == "https-only"))
|
|
271
|
+
|| var.certificate_arn != null
|
|
272
|
+
)
|
|
273
|
+
error_message = "certificate_arn is required when protected_access_mode is alb_https_cert or CloudFront HTTPS origin is enabled."
|
|
225
274
|
}
|
|
226
275
|
}
|
|
227
276
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/uptime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "Local-first uptime and downtime monitoring service with CLI, MCP, SDK, SQLite persistence, and a dashboard.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"Dockerfile",
|
|
27
27
|
"Dockerfile.package",
|
|
28
28
|
".dockerignore",
|
|
29
|
+
"bun.lock",
|
|
29
30
|
"infra/aws/README.md",
|
|
30
31
|
"infra/aws/.terraform.lock.hcl",
|
|
31
32
|
"infra/aws/*.tf",
|