@hasna/uptime 0.1.13 → 0.1.14

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 CHANGED
@@ -6,6 +6,15 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.14] - 2026-06-28
10
+
11
+ ### Added
12
+
13
+ - Added explicit Terraform NAT task egress support. Infra owners can set
14
+ `enable_nat_task_egress = true` to allow web and non-public worker task
15
+ security groups to reach AWS public APIs through a private subnet NAT route on
16
+ TCP/443 when private VPC endpoints are not the approved egress model.
17
+
9
18
  ## [0.1.13] - 2026-06-28
10
19
 
11
20
  ### Added
package/dist/cli/index.js CHANGED
@@ -6932,7 +6932,7 @@ function buildAwsDeploymentPlan(options = {}) {
6932
6932
  const image = clean(options.image, `${imageRepositoryUri}@sha256:<image-digest>`);
6933
6933
  const evidenceBucket = clean(options.evidenceBucket, `hasna-${stage}-${prefix}-evidence`);
6934
6934
  const hostedSqliteDbPath = clean(options.hostedSqliteDbPath, DEFAULT_HOSTED_SQLITE_DB);
6935
- const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.13");
6935
+ const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.14");
6936
6936
  const protectedAccessMode = options.protectedAccessMode ?? DEFAULT_PROTECTED_ACCESS_MODE;
6937
6937
  const protectedAccessUrl = protectedAccessMode === "cloudfront_default_domain" ? "https://<cloudfront-domain>" : `https://${hostname}`;
6938
6938
  const cluster = `${prefix}-${stage}`;
@@ -21,7 +21,7 @@ function buildAwsDeploymentPlan(options = {}) {
21
21
  const image = clean(options.image, `${imageRepositoryUri}@sha256:<image-digest>`);
22
22
  const evidenceBucket = clean(options.evidenceBucket, `hasna-${stage}-${prefix}-evidence`);
23
23
  const hostedSqliteDbPath = clean(options.hostedSqliteDbPath, DEFAULT_HOSTED_SQLITE_DB);
24
- const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.13");
24
+ const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.14");
25
25
  const protectedAccessMode = options.protectedAccessMode ?? DEFAULT_PROTECTED_ACCESS_MODE;
26
26
  const protectedAccessUrl = protectedAccessMode === "cloudfront_default_domain" ? "https://<cloudfront-domain>" : `https://${hostname}`;
27
27
  const cluster = `${prefix}-${stage}`;
package/dist/index.js CHANGED
@@ -4338,7 +4338,7 @@ function buildAwsDeploymentPlan(options = {}) {
4338
4338
  const image = clean(options.image, `${imageRepositoryUri}@sha256:<image-digest>`);
4339
4339
  const evidenceBucket = clean(options.evidenceBucket, `hasna-${stage}-${prefix}-evidence`);
4340
4340
  const hostedSqliteDbPath = clean(options.hostedSqliteDbPath, DEFAULT_HOSTED_SQLITE_DB);
4341
- const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.13");
4341
+ const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.14");
4342
4342
  const protectedAccessMode = options.protectedAccessMode ?? DEFAULT_PROTECTED_ACCESS_MODE;
4343
4343
  const protectedAccessUrl = protectedAccessMode === "cloudfront_default_domain" ? "https://<cloudfront-domain>" : `https://${hostname}`;
4344
4344
  const cluster = `${prefix}-${stage}`;
@@ -64,6 +64,13 @@ Endpoint policies are scoped to the Open Uptime repository, log groups,
64
64
  configured secret refs, KMS key, evidence bucket, and the regional ECR layer
65
65
  bucket.
66
66
 
67
+ If private endpoints are not approved yet, infra owners can instead set
68
+ `enable_nat_task_egress = true` to allow web and non-public worker task security
69
+ groups to reach AWS public APIs through the private subnet NAT route on TCP/443.
70
+ Keep this disabled when private endpoints are the approved egress path. Runtime
71
+ scale-up still requires ECS task evidence for image pull, secret injection, log
72
+ delivery, S3 access, and EFS mount behavior.
73
+
67
74
  Interface endpoint private DNS is VPC-wide. In shared VPCs, either keep endpoint
68
75
  creation in the approved networking root, or pass
69
76
  `additional_vpc_endpoint_source_security_group_ids` for every workload that must
package/infra/aws/main.tf CHANGED
@@ -399,6 +399,32 @@ resource "aws_security_group_rule" "worker_egress" {
399
399
  cidr_blocks = each.key == "public-probe" ? ["0.0.0.0/0"] : [data.aws_vpc.target.cidr_block]
400
400
  }
401
401
 
402
+ resource "aws_security_group_rule" "web_nat_https_egress" {
403
+ count = var.enable_nat_task_egress ? 1 : 0
404
+
405
+ type = "egress"
406
+ description = "HTTPS egress through approved NAT path"
407
+ security_group_id = aws_security_group.web.id
408
+ from_port = 443
409
+ to_port = 443
410
+ protocol = "tcp"
411
+ cidr_blocks = var.nat_task_egress_cidr_blocks
412
+ }
413
+
414
+ resource "aws_security_group_rule" "worker_nat_https_egress" {
415
+ for_each = var.enable_nat_task_egress ? {
416
+ for key, value in aws_security_group.worker : key => value if key != "public-probe"
417
+ } : {}
418
+
419
+ type = "egress"
420
+ description = "HTTPS egress through approved NAT path"
421
+ security_group_id = each.value.id
422
+ from_port = 443
423
+ to_port = 443
424
+ protocol = "tcp"
425
+ cidr_blocks = var.nat_task_egress_cidr_blocks
426
+ }
427
+
402
428
  resource "aws_security_group_rule" "web_s3_gateway_egress" {
403
429
  count = local.s3_gateway_endpoint_enabled ? 1 : 0
404
430
 
@@ -16,7 +16,7 @@ alb_ingress_cidr_blocks = []
16
16
  private_subnet_ids = ["subnet-replace-private-a", "subnet-replace-private-b"]
17
17
  private_route_table_ids = ["rtb-replace-private"]
18
18
  container_image = "123456789012.dkr.ecr.us-east-1.amazonaws.com/open-uptime@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19
- runtime_package_version = "0.1.13"
19
+ runtime_package_version = "0.1.14"
20
20
  certificate_arn = null
21
21
  hosted_zone_id = null
22
22
  app_env_secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret:open-uptime/prod/app/env"
@@ -26,6 +26,7 @@ reporting_secret_arn = "arn:aws:secretsmanager:us-east-1:123456789012:secret
26
26
  kms_key_arn = "arn:aws:kms:us-east-1:123456789012:key/00000000-0000-0000-0000-000000000000"
27
27
  alarm_actions = []
28
28
  monthly_budget_limit_usd = 0
29
+ enable_nat_task_egress = false
29
30
  enable_private_vpc_endpoints = false
30
31
  additional_vpc_endpoint_source_security_group_ids = []
31
32
 
@@ -116,7 +116,7 @@ variable "container_image" {
116
116
  variable "runtime_package_version" {
117
117
  description = "Published @hasna/uptime package version that CodeBuild should build into the ECR image."
118
118
  type = string
119
- default = "0.1.13"
119
+ default = "0.1.14"
120
120
 
121
121
  validation {
122
122
  condition = can(regex("^[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?$", var.runtime_package_version))
@@ -238,6 +238,23 @@ variable "budget_alert_email_addresses" {
238
238
  default = []
239
239
  }
240
240
 
241
+ variable "enable_nat_task_egress" {
242
+ description = "Allow web and non-public worker tasks to reach AWS public APIs through NAT on TCP/443. Keep false when private VPC endpoints are the approved egress path."
243
+ type = bool
244
+ default = false
245
+ }
246
+
247
+ variable "nat_task_egress_cidr_blocks" {
248
+ description = "CIDR blocks allowed for NAT-backed HTTPS egress when enable_nat_task_egress is true."
249
+ type = list(string)
250
+ default = ["0.0.0.0/0"]
251
+
252
+ validation {
253
+ condition = length(var.nat_task_egress_cidr_blocks) > 0
254
+ error_message = "nat_task_egress_cidr_blocks must not be empty when NAT task egress is enabled."
255
+ }
256
+ }
257
+
241
258
  variable "enable_private_vpc_endpoints" {
242
259
  description = "Create private VPC endpoints for ECS access to AWS APIs. Requires private subnet ids; S3 gateway endpoint also requires private_route_table_ids."
243
260
  type = bool
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/uptime",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
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",