@hasna/uptime 0.1.13 → 0.1.15
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 +18 -0
- package/Dockerfile.package +6 -4
- package/dist/cli/index.js +1 -1
- package/dist/cloud-plan.js +1 -1
- package/dist/index.js +1 -1
- package/infra/aws/README.md +7 -0
- package/infra/aws/main.tf +26 -0
- package/infra/aws/terraform.tfvars.example +2 -1
- package/infra/aws/variables.tf +18 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,24 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.1.15] - 2026-06-28
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Changed the packaged production Dockerfile to use Docker Official
|
|
14
|
+
`node:22-slim` from Amazon ECR Public and install Bun inside the image. This
|
|
15
|
+
avoids Docker Hub unauthenticated pull-rate limits during AWS CodeBuild image
|
|
16
|
+
builds.
|
|
17
|
+
|
|
18
|
+
## [0.1.14] - 2026-06-28
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Added explicit Terraform NAT task egress support. Infra owners can set
|
|
23
|
+
`enable_nat_task_egress = true` to allow web and non-public worker task
|
|
24
|
+
security groups to reach AWS public APIs through a private subnet NAT route on
|
|
25
|
+
TCP/443 when private VPC endpoints are not the approved egress model.
|
|
26
|
+
|
|
9
27
|
## [0.1.13] - 2026-06-28
|
|
10
28
|
|
|
11
29
|
### Added
|
package/Dockerfile.package
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
# syntax=docker/dockerfile:1
|
|
2
2
|
|
|
3
|
-
FROM
|
|
3
|
+
FROM public.ecr.aws/docker/library/node:22-slim AS runtime
|
|
4
4
|
ENV NODE_ENV=production \
|
|
5
5
|
HASNA_UPTIME_MODE=hosted
|
|
6
6
|
WORKDIR /app
|
|
7
7
|
|
|
8
|
-
RUN
|
|
9
|
-
&&
|
|
8
|
+
RUN npm install -g bun@1.3.13 \
|
|
9
|
+
&& groupadd --system --gid 10001 uptime \
|
|
10
|
+
&& useradd --system --uid 10001 --gid uptime --home-dir /app --shell /usr/sbin/nologin uptime
|
|
10
11
|
|
|
11
12
|
COPY package.json ./package.json
|
|
12
13
|
COPY dist ./dist
|
|
13
14
|
|
|
14
|
-
RUN bun install --production
|
|
15
|
+
RUN bun install --production \
|
|
16
|
+
&& chown -R uptime:uptime /app
|
|
15
17
|
|
|
16
18
|
USER uptime
|
|
17
19
|
EXPOSE 3899
|
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.
|
|
6935
|
+
const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.15");
|
|
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}`;
|
package/dist/cloud-plan.js
CHANGED
|
@@ -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.
|
|
24
|
+
const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.15");
|
|
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.
|
|
4341
|
+
const runtimePackageVersion = clean(options.runtimePackageVersion, "0.1.15");
|
|
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}`;
|
package/infra/aws/README.md
CHANGED
|
@@ -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.
|
|
19
|
+
runtime_package_version = "0.1.15"
|
|
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
|
|
package/infra/aws/variables.tf
CHANGED
|
@@ -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.
|
|
119
|
+
default = "0.1.15"
|
|
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