chore: import upstream snapshot with attribution
regression / regression-shards (style-16-prod style-9-prod style-17-prod iframe-render-compat variables-prod mp4-h265-sdr, shard-4) (push) Has been cancelled
regression / regression-shards (style-4-prod style-11-prod style-2-prod animejs-adapter typegpu-adapter parallel-capture-regression, shard-5) (push) Has been cancelled
regression / regression-shards (style-7-prod style-8-prod style-10-prod css-spinner-render-compat webm-transparency mp4-h264-sdr webm-vp9, shard-3) (push) Has been cancelled
regression / regression-shards (sub-composition-video style-18-prod raf-ball-render-compat font-variant-numeric sub-comp-t0 sub-comp-id-selector, shard-7) (push) Has been cancelled
Windows render verification / Detect changes (push) Has been cancelled
Windows render verification / Preflight (lint + format) (push) Has been cancelled
Windows render verification / Render on windows-latest (push) Has been cancelled
Windows render verification / Tests on windows-latest (push) Has been cancelled
CI / Detect changes (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Fallow audit (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Producer: integration tests (push) Has been cancelled
CI / Producer: unit tests (push) Has been cancelled
CI / File size check (push) Has been cancelled
CI / Test: skills (push) Has been cancelled
CI / Skills: manifest in sync (push) Has been cancelled
CI / CLI: npx shim (macos-latest) (push) Has been cancelled
CI / CLI: npx shim (ubuntu-latest) (push) Has been cancelled
CI / CLI: npx shim (windows-latest) (push) Has been cancelled
CI / SDK: unit + contract + smoke (push) Has been cancelled
CI / Test: runtime contract (push) Has been cancelled
CI / Studio: load smoke (push) Has been cancelled
CI / Smoke: global install (push) Has been cancelled
CI / CLI smoke (required) (push) Has been cancelled
CI / Semantic PR title (push) Has been cancelled
Player perf / Detect changes (push) Has been cancelled
Player perf / Preflight (lint + format) (push) Has been cancelled
Player perf / player-perf (push) Has been cancelled
Player perf / Perf: drift (push) Has been cancelled
Player perf / Perf: fps (push) Has been cancelled
Player perf / Perf: parity (push) Has been cancelled
Player perf / Perf: scrub (push) Has been cancelled
Player perf / Perf: load (push) Has been cancelled
preview-regression / Detect changes (push) Has been cancelled
preview-regression / Preflight (lint + format) (push) Has been cancelled
preview-regression / Preview parity (push) Has been cancelled
preview-regression / preview-regression (push) Has been cancelled
regression / regression (push) Has been cancelled
regression / Detect changes (push) Has been cancelled
regression / Preflight (lint + format) (push) Has been cancelled
regression / regression-shards (hdr-regression style-5-prod style-3-prod mov-prores, shard-1) (push) Has been cancelled
regression / regression-shards (overlay-montage-prod style-12-prod chat missing-host-comp-id png-sequence portrait-edge-bleed, shard-6) (push) Has been cancelled
regression / regression-shards (style-13-prod style-6-prod vignelli-stacking gsap-letters-render-compat audio-mux-parity, shard-8) (push) Has been cancelled
regression / regression-shards (style-15-prod hdr-hlg-regression style-1-prod many-cuts vfr-screen-recording render-symlinked-assets, shard-2) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Docs / Validate docs (push) Has been cancelled
Sync skills to ClawHub / Publish changed skills (push) Has been cancelled
regression / regression-shards (style-16-prod style-9-prod style-17-prod iframe-render-compat variables-prod mp4-h265-sdr, shard-4) (push) Has been cancelled
regression / regression-shards (style-4-prod style-11-prod style-2-prod animejs-adapter typegpu-adapter parallel-capture-regression, shard-5) (push) Has been cancelled
regression / regression-shards (style-7-prod style-8-prod style-10-prod css-spinner-render-compat webm-transparency mp4-h264-sdr webm-vp9, shard-3) (push) Has been cancelled
regression / regression-shards (sub-composition-video style-18-prod raf-ball-render-compat font-variant-numeric sub-comp-t0 sub-comp-id-selector, shard-7) (push) Has been cancelled
Windows render verification / Detect changes (push) Has been cancelled
Windows render verification / Preflight (lint + format) (push) Has been cancelled
Windows render verification / Render on windows-latest (push) Has been cancelled
Windows render verification / Tests on windows-latest (push) Has been cancelled
CI / Detect changes (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Fallow audit (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Producer: integration tests (push) Has been cancelled
CI / Producer: unit tests (push) Has been cancelled
CI / File size check (push) Has been cancelled
CI / Test: skills (push) Has been cancelled
CI / Skills: manifest in sync (push) Has been cancelled
CI / CLI: npx shim (macos-latest) (push) Has been cancelled
CI / CLI: npx shim (ubuntu-latest) (push) Has been cancelled
CI / CLI: npx shim (windows-latest) (push) Has been cancelled
CI / SDK: unit + contract + smoke (push) Has been cancelled
CI / Test: runtime contract (push) Has been cancelled
CI / Studio: load smoke (push) Has been cancelled
CI / Smoke: global install (push) Has been cancelled
CI / CLI smoke (required) (push) Has been cancelled
CI / Semantic PR title (push) Has been cancelled
Player perf / Detect changes (push) Has been cancelled
Player perf / Preflight (lint + format) (push) Has been cancelled
Player perf / player-perf (push) Has been cancelled
Player perf / Perf: drift (push) Has been cancelled
Player perf / Perf: fps (push) Has been cancelled
Player perf / Perf: parity (push) Has been cancelled
Player perf / Perf: scrub (push) Has been cancelled
Player perf / Perf: load (push) Has been cancelled
preview-regression / Detect changes (push) Has been cancelled
preview-regression / Preflight (lint + format) (push) Has been cancelled
preview-regression / Preview parity (push) Has been cancelled
preview-regression / preview-regression (push) Has been cancelled
regression / regression (push) Has been cancelled
regression / Detect changes (push) Has been cancelled
regression / Preflight (lint + format) (push) Has been cancelled
regression / regression-shards (hdr-regression style-5-prod style-3-prod mov-prores, shard-1) (push) Has been cancelled
regression / regression-shards (overlay-montage-prod style-12-prod chat missing-host-comp-id png-sequence portrait-edge-bleed, shard-6) (push) Has been cancelled
regression / regression-shards (style-13-prod style-6-prod vignelli-stacking gsap-letters-render-compat audio-mux-parity, shard-8) (push) Has been cancelled
regression / regression-shards (style-15-prod hdr-hlg-regression style-1-prod many-cuts vfr-screen-recording render-symlinked-assets, shard-2) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Docs / Validate docs (push) Has been cancelled
Sync skills to ClawHub / Publish changed skills (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,503 @@
|
||||
AWSTemplateFormatVersion: "2010-09-09"
|
||||
Transform: AWS::Serverless-2016-10-31
|
||||
Description: >-
|
||||
HyperFrames distributed rendering — Step Functions standard workflow with
|
||||
one Lambda function handling Plan, RenderChunk (fan-out via Map state),
|
||||
and Assemble. One S3 bucket, alarms for runaway concurrency, Lambda
|
||||
errors, and Step Functions execution failures.
|
||||
|
||||
Built from the handler ZIP at packages/aws-lambda/dist/handler.zip.
|
||||
|
||||
See:
|
||||
- packages/aws-lambda/README.md (handler architecture)
|
||||
- examples/aws-lambda/README.md (this directory's deploy guide)
|
||||
|
||||
Parameters:
|
||||
ProjectName:
|
||||
Type: String
|
||||
Default: hyperframes
|
||||
Description: Name prefix applied to all created resources.
|
||||
|
||||
LambdaMemoryMb:
|
||||
Type: Number
|
||||
Default: 10240
|
||||
AllowedValues: [2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240]
|
||||
Description: >-
|
||||
Lambda memory in MB. Render workloads are CPU-bound; bumping memory
|
||||
proportionally bumps the CPU share Lambda gives the function. 10 GB
|
||||
(the max) is recommended for 1080p renders.
|
||||
|
||||
LambdaTimeoutSec:
|
||||
Type: Number
|
||||
Default: 900
|
||||
MinValue: 60
|
||||
MaxValue: 900
|
||||
Description: >-
|
||||
Per-invocation Lambda timeout. Render chunks at the default
|
||||
chunkSize=240 frames complete in seconds; 15 minutes is the Lambda
|
||||
hard ceiling and the default here to absorb cold-start variance.
|
||||
|
||||
ReservedConcurrency:
|
||||
Type: Number
|
||||
Default: -1
|
||||
Description: >-
|
||||
Lambda reserved concurrency cap. Set to a positive integer to bound
|
||||
simultaneous chunk renders (e.g. 50 to limit cost). -1 means
|
||||
unreserved (account default).
|
||||
|
||||
ChromeSource:
|
||||
Type: String
|
||||
Default: sparticuz
|
||||
AllowedValues: [sparticuz, chrome-headless-shell]
|
||||
Description: >-
|
||||
Which Chrome runtime the bundled ZIP was built with. Must match the
|
||||
`--source=` flag passed to `build-zip.ts`. The handler reads this
|
||||
via the HYPERFRAMES_LAMBDA_CHROME_SOURCE env var at boot.
|
||||
|
||||
ChunkInvocationAlarmThreshold:
|
||||
Type: Number
|
||||
Default: 1000
|
||||
Description: >-
|
||||
CloudWatch alarm threshold for total RenderChunk invocations per
|
||||
hour. The runaway-Map state pathology would fan out far more
|
||||
chunks than expected; an alarm at 10× the typical workload
|
||||
protects against billing surprises.
|
||||
|
||||
Conditions:
|
||||
HasReservedConcurrency: !Not [!Equals [!Ref ReservedConcurrency, -1]]
|
||||
|
||||
Globals:
|
||||
Function:
|
||||
Runtime: nodejs22.x
|
||||
MemorySize: !Ref LambdaMemoryMb
|
||||
Timeout: !Ref LambdaTimeoutSec
|
||||
# x86_64 is required for @sparticuz/chromium — its prebuilt
|
||||
# Chromium ships x86_64-only. Adopters who switch to a custom
|
||||
# ARM-built chrome-headless-shell can change this to `arm64`, but
|
||||
# the default ZIP build will fail to launch on Graviton.
|
||||
Architectures: [x86_64]
|
||||
# Lambda function-level X-Ray tracing. The state machine already
|
||||
# has Tracing.Enabled: true; without this, X-Ray traces would
|
||||
# terminate at the Step Functions → Lambda boundary instead of
|
||||
# following into per-function spans.
|
||||
Tracing: Active
|
||||
# Cost-allocation tags. Setting these at the Globals level applies
|
||||
# to every AWS::Serverless::Function in the template — there's
|
||||
# only one today, but the contract is portable to multi-function
|
||||
# variants. Bucket + state-machine carry the same tags resource-
|
||||
# locally because Globals only covers functions.
|
||||
Tags:
|
||||
Project: !Ref ProjectName
|
||||
HyperFramesComponent: lambda-renderer
|
||||
Environment:
|
||||
Variables:
|
||||
NODE_OPTIONS: "--enable-source-maps"
|
||||
HYPERFRAMES_LAMBDA_CHROME_SOURCE: !Ref ChromeSource
|
||||
|
||||
Resources:
|
||||
# ── S3 bucket for plan tarballs, chunk outputs, and final renders ───────
|
||||
RenderBucket:
|
||||
Type: AWS::S3::Bucket
|
||||
DeletionPolicy: Retain
|
||||
UpdateReplacePolicy: Retain
|
||||
Properties:
|
||||
# BucketName omitted — CloudFormation generates a unique name like
|
||||
# "<stack-name>-renderbucket-<random>". S3 bucket names are capped at
|
||||
# 63 chars; a static !Sub expression including ProjectName +
|
||||
# AWS::AccountId + AWS::Region trips that limit when ProjectName
|
||||
# carries a timestamp (e.g. the smoke script's per-run stack name).
|
||||
PublicAccessBlockConfiguration:
|
||||
BlockPublicAcls: true
|
||||
BlockPublicPolicy: true
|
||||
IgnorePublicAcls: true
|
||||
RestrictPublicBuckets: true
|
||||
VersioningConfiguration:
|
||||
# `Suspended` keeps storage costs flat — versions are not
|
||||
# retained on overwrites. Tradeoff: if an adopter writes their
|
||||
# final rendered mp4 to this bucket and a re-render overwrites
|
||||
# the same key, the prior version is gone. Adopters who treat
|
||||
# the final mp4 as user-keepable should set this to `Enabled`
|
||||
# (intermediates under `renders/` still expire via the
|
||||
# lifecycle rule below regardless).
|
||||
Status: Suspended
|
||||
LifecycleConfiguration:
|
||||
Rules:
|
||||
- Id: ExpireIntermediates
|
||||
Status: Enabled
|
||||
Prefix: renders/
|
||||
# Plan tarballs and chunk outputs are intermediate artifacts.
|
||||
# Users keep the final mp4 (different key prefix); the rest
|
||||
# can age out after a week to keep storage costs flat.
|
||||
ExpirationInDays: 7
|
||||
Tags:
|
||||
- Key: Project
|
||||
Value: !Ref ProjectName
|
||||
- Key: HyperFramesComponent
|
||||
Value: lambda-renderer
|
||||
|
||||
# ── Single Lambda function handling all three roles ──────────────────────
|
||||
RenderFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
FunctionName: !Sub "${ProjectName}-render"
|
||||
Description: >-
|
||||
HyperFrames distributed render handler. Dispatches on event.Action.
|
||||
Handler: handler.handler
|
||||
# Local path is resolved by `sam build` + `sam deploy --resolve-s3`
|
||||
# (or `--s3-bucket`); the resulting CodeUri rewrites to s3://.
|
||||
CodeUri: ../../packages/aws-lambda/dist/handler.zip
|
||||
PackageType: Zip
|
||||
ReservedConcurrentExecutions: !If
|
||||
- HasReservedConcurrency
|
||||
- !Ref ReservedConcurrency
|
||||
- !Ref AWS::NoValue
|
||||
EphemeralStorage:
|
||||
Size: 10240
|
||||
Environment:
|
||||
Variables:
|
||||
# Lambda's Node 22 runtime sets these by default; explicit for
|
||||
# clarity + so users can override during local SAM invoke.
|
||||
TMPDIR: /tmp
|
||||
Policies:
|
||||
- S3CrudPolicy:
|
||||
BucketName: !Ref RenderBucket
|
||||
# CloudWatch Logs perms are covered by SAM's default
|
||||
# AWSLambdaBasicExecutionRole — explicit `CloudWatchLogsFullAccess`
|
||||
# would be overscope (`logs:*` on `*`, including DeleteLogGroup +
|
||||
# CreateExportTask). Reference templates shouldn't leak overbroad
|
||||
# IAM into adopters' accounts.
|
||||
|
||||
# ── CloudWatch log group for the state machine ──────────────────────────
|
||||
# SAM doesn't auto-create one when `LoggingConfiguration` is set, so we
|
||||
# define it explicitly — that way the IAM grant on the state-machine
|
||||
# role has a destination to write to.
|
||||
RenderStateMachineLogGroup:
|
||||
Type: AWS::Logs::LogGroup
|
||||
Properties:
|
||||
LogGroupName: !Sub "/aws/states/${ProjectName}-render"
|
||||
RetentionInDays: 30
|
||||
|
||||
# ── Step Functions state machine: Plan → Map(N) RenderChunk → Assemble ──
|
||||
RenderStateMachine:
|
||||
Type: AWS::Serverless::StateMachine
|
||||
Properties:
|
||||
Name: !Sub "${ProjectName}-render"
|
||||
Type: STANDARD
|
||||
Tracing:
|
||||
Enabled: true
|
||||
Logging:
|
||||
# Without this, the `WriteCloudwatchLogs` grant on the state
|
||||
# machine role would be unused — operators would see zero
|
||||
# execution history outside the Step Functions console.
|
||||
# `Level: ERROR` keeps log volume low; bump to `ALL` for
|
||||
# heavy debugging.
|
||||
Level: ERROR
|
||||
IncludeExecutionData: false
|
||||
Destinations:
|
||||
- CloudWatchLogsLogGroup:
|
||||
LogGroupArn: !GetAtt RenderStateMachineLogGroup.Arn
|
||||
Definition:
|
||||
Comment: >-
|
||||
HyperFrames distributed render orchestration: Plan → Map(N)
|
||||
RenderChunk → Assemble.
|
||||
# Defensive 1-hour ceiling on the whole choreography. The
|
||||
# individual states already have retries + per-task timeouts;
|
||||
# this catches pathological runaways (Plan-retry storm,
|
||||
# stuck-state-machine bugs) at the top before per-task budgets
|
||||
# compound into a multi-hour execution. The longest legitimate
|
||||
# render observed in PR 880's eval was ~3 minutes.
|
||||
TimeoutSeconds: 3600
|
||||
StartAt: Plan
|
||||
States:
|
||||
Plan:
|
||||
Type: Task
|
||||
Resource: arn:aws:states:::lambda:invoke
|
||||
Parameters:
|
||||
FunctionName: !GetAtt RenderFunction.Arn
|
||||
Payload:
|
||||
Action: plan
|
||||
ProjectS3Uri.$: "$.ProjectS3Uri"
|
||||
PlanOutputS3Prefix.$: "$.PlanOutputS3Prefix"
|
||||
Config.$: "$.Config"
|
||||
ResultSelector:
|
||||
PlanS3Uri.$: "$.Payload.PlanS3Uri"
|
||||
PlanHash.$: "$.Payload.PlanHash"
|
||||
ChunkCount.$: "$.Payload.ChunkCount"
|
||||
Format.$: "$.Payload.Format"
|
||||
HasAudio.$: "$.Payload.HasAudio"
|
||||
AudioS3Uri.$: "$.Payload.AudioS3Uri"
|
||||
ResultPath: $.Plan
|
||||
Retry:
|
||||
- ErrorEquals:
|
||||
# These error names are thrown by the producer's plan
|
||||
# stage when retrying can never help — version skew,
|
||||
# determinism violations, GPU misconfiguration, font
|
||||
# fetch failures, plan-size cap, unsupported format.
|
||||
# Fail fast rather than burning ~120s of retry budget.
|
||||
- FFMPEG_VERSION_MISMATCH
|
||||
- PLAN_HASH_MISMATCH
|
||||
- BROWSER_GPU_NOT_SOFTWARE
|
||||
- FONT_FETCH_FAILED
|
||||
- PLAN_TOO_LARGE
|
||||
- FORMAT_NOT_SUPPORTED_IN_DISTRIBUTED
|
||||
MaxAttempts: 0
|
||||
- ErrorEquals: [States.ALL]
|
||||
IntervalSeconds: 2
|
||||
MaxAttempts: 4
|
||||
BackoffRate: 2
|
||||
MaxDelaySeconds: 60
|
||||
Next: BuildChunkList
|
||||
|
||||
BuildChunkList:
|
||||
# Translate ChunkCount into an array `[0, 1, ..., N-1]` so the
|
||||
# Map state below has something to iterate. Range is the
|
||||
# idiomatic Step Functions intrinsic for this; no Lambda call
|
||||
# required.
|
||||
Type: Pass
|
||||
Parameters:
|
||||
ChunkIndexes.$: "States.ArrayRange(0, States.MathAdd($.Plan.ChunkCount, -1), 1)"
|
||||
ResultPath: $.Iterator
|
||||
Next: AssertChunkCount
|
||||
|
||||
AssertChunkCount:
|
||||
# Defensive gate: `resolveChunkPlan` guarantees ChunkCount ≥ 1,
|
||||
# but if some future regression let a zero-chunk plan through,
|
||||
# `RenderChunks` (Map state) would iterate zero times and
|
||||
# `Assemble` would receive an empty `ChunkS3Uris` array — silently
|
||||
# producing an empty output. Fail fast instead.
|
||||
Type: Choice
|
||||
Choices:
|
||||
- Variable: $.Plan.ChunkCount
|
||||
NumericGreaterThan: 0
|
||||
Next: RenderChunks
|
||||
Default: PlanProducedZeroChunks
|
||||
|
||||
PlanProducedZeroChunks:
|
||||
Type: Fail
|
||||
Error: PLAN_TOO_LARGE
|
||||
Cause: Plan returned ChunkCount=0 — non-retryable producer-side invariant violation.
|
||||
|
||||
RenderChunks:
|
||||
Type: Map
|
||||
ItemsPath: $.Iterator.ChunkIndexes
|
||||
ItemSelector:
|
||||
ChunkIndex.$: "$$.Map.Item.Value"
|
||||
PlanS3Uri.$: "$.Plan.PlanS3Uri"
|
||||
PlanHash.$: "$.Plan.PlanHash"
|
||||
ChunkOutputS3Prefix.$: "$.PlanOutputS3Prefix"
|
||||
Format.$: "$.Plan.Format"
|
||||
# Map fan-out cap derives from the Plan's chunkCount so
|
||||
# caller-supplied `Config.maxParallelChunks` (which
|
||||
# `plan()` honours when sizing the chunk list) is the
|
||||
# single source of truth. A hardcoded value here would
|
||||
# silently throttle adopters who scale up the chunk count
|
||||
# in their event payload.
|
||||
MaxConcurrencyPath: $.Plan.ChunkCount
|
||||
ResultPath: $.Chunks
|
||||
ItemProcessor:
|
||||
ProcessorConfig:
|
||||
Mode: INLINE
|
||||
StartAt: RenderChunk
|
||||
States:
|
||||
RenderChunk:
|
||||
Type: Task
|
||||
Resource: arn:aws:states:::lambda:invoke
|
||||
Parameters:
|
||||
FunctionName: !GetAtt RenderFunction.Arn
|
||||
Payload:
|
||||
Action: renderChunk
|
||||
ChunkIndex.$: "$.ChunkIndex"
|
||||
PlanS3Uri.$: "$.PlanS3Uri"
|
||||
PlanHash.$: "$.PlanHash"
|
||||
ChunkOutputS3Prefix.$: "$.ChunkOutputS3Prefix"
|
||||
Format.$: "$.Format"
|
||||
ResultSelector:
|
||||
ChunkS3Uri.$: "$.Payload.ChunkS3Uri"
|
||||
ChunkIndex.$: "$.Payload.ChunkIndex"
|
||||
Sha256.$: "$.Payload.Sha256"
|
||||
Retry:
|
||||
- ErrorEquals:
|
||||
- FFMPEG_VERSION_MISMATCH
|
||||
- PLAN_HASH_MISMATCH
|
||||
- BROWSER_GPU_NOT_SOFTWARE
|
||||
MaxAttempts: 0
|
||||
- ErrorEquals: [States.ALL]
|
||||
IntervalSeconds: 2
|
||||
MaxAttempts: 4
|
||||
BackoffRate: 2
|
||||
MaxDelaySeconds: 60
|
||||
End: true
|
||||
Next: Assemble
|
||||
|
||||
Assemble:
|
||||
Type: Task
|
||||
Resource: arn:aws:states:::lambda:invoke
|
||||
Parameters:
|
||||
FunctionName: !GetAtt RenderFunction.Arn
|
||||
Payload:
|
||||
Action: assemble
|
||||
PlanS3Uri.$: "$.Plan.PlanS3Uri"
|
||||
ChunkS3Uris.$: "$.Chunks[*].ChunkS3Uri"
|
||||
AudioS3Uri.$: "$.Plan.AudioS3Uri"
|
||||
OutputS3Uri.$: "$.OutputS3Uri"
|
||||
Format.$: "$.Plan.Format"
|
||||
ResultSelector:
|
||||
OutputS3Uri.$: "$.Payload.OutputS3Uri"
|
||||
FramesEncoded.$: "$.Payload.FramesEncoded"
|
||||
FileSize.$: "$.Payload.FileSize"
|
||||
ResultPath: $.Output
|
||||
Retry:
|
||||
- ErrorEquals:
|
||||
# Same non-retryable error names as the Plan state's
|
||||
# gate — these surface at assemble time too because
|
||||
# ffmpeg-driven concat picks up version drift and we
|
||||
# re-verify plan hash + format at assemble. Skip the
|
||||
# retry storm; fail fast.
|
||||
- FFMPEG_VERSION_MISMATCH
|
||||
- PLAN_HASH_MISMATCH
|
||||
- FORMAT_NOT_SUPPORTED_IN_DISTRIBUTED
|
||||
MaxAttempts: 0
|
||||
- ErrorEquals: [States.ALL]
|
||||
IntervalSeconds: 2
|
||||
MaxAttempts: 4
|
||||
BackoffRate: 2
|
||||
MaxDelaySeconds: 60
|
||||
End: true
|
||||
Role: !GetAtt RenderStateMachineRole.Arn
|
||||
|
||||
RenderStateMachineRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: states.amazonaws.com
|
||||
Action: sts:AssumeRole
|
||||
Policies:
|
||||
- PolicyName: InvokeRenderFunction
|
||||
PolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action: lambda:InvokeFunction
|
||||
Resource: !GetAtt RenderFunction.Arn
|
||||
- PolicyName: WriteCloudwatchLogs
|
||||
PolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- logs:CreateLogDelivery
|
||||
- logs:GetLogDelivery
|
||||
- logs:UpdateLogDelivery
|
||||
- logs:DeleteLogDelivery
|
||||
- logs:ListLogDeliveries
|
||||
- logs:PutResourcePolicy
|
||||
- logs:DescribeResourcePolicies
|
||||
- logs:DescribeLogGroups
|
||||
Resource: "*"
|
||||
- PolicyName: XRayTracing
|
||||
PolicyDocument:
|
||||
Version: "2012-10-17"
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- xray:PutTraceSegments
|
||||
- xray:PutTelemetryRecords
|
||||
Resource: "*"
|
||||
|
||||
# ── CloudWatch alarm: runaway chunk invocations ─────────────────────────
|
||||
RenderChunkInvocationAlarm:
|
||||
Type: AWS::CloudWatch::Alarm
|
||||
Properties:
|
||||
AlarmName: !Sub "${ProjectName}-runaway-chunk-invocations"
|
||||
AlarmDescription: >-
|
||||
Fires if RenderChunk Lambda invocations exceed the configured
|
||||
threshold in a 1-hour window. The Map state's MaxConcurrency cap
|
||||
protects against simultaneous fan-out, but a runaway state
|
||||
machine that triggers many sequential renders would still rack
|
||||
up cost; this alarm catches that pattern.
|
||||
Namespace: AWS/Lambda
|
||||
MetricName: Invocations
|
||||
Dimensions:
|
||||
- Name: FunctionName
|
||||
Value: !Ref RenderFunction
|
||||
Statistic: Sum
|
||||
Period: 3600
|
||||
EvaluationPeriods: 1
|
||||
Threshold: !Ref ChunkInvocationAlarmThreshold
|
||||
ComparisonOperator: GreaterThanThreshold
|
||||
TreatMissingData: notBreaching
|
||||
|
||||
# ── CloudWatch alarm: Lambda function errors ────────────────────────────
|
||||
# Fires on any non-zero error rate. The invocation alarm above catches
|
||||
# *too many calls*; this catches *calls that failed*. Without it,
|
||||
# silent per-chunk failures (a non-retryable error inside the
|
||||
# producer) would only surface by reading Step Functions execution
|
||||
# history.
|
||||
RenderFunctionErrorsAlarm:
|
||||
Type: AWS::CloudWatch::Alarm
|
||||
Properties:
|
||||
AlarmName: !Sub "${ProjectName}-render-function-errors"
|
||||
AlarmDescription: >-
|
||||
Fires if the render Lambda reports any errors in a 5-minute
|
||||
window. Set EvaluationPeriods=1 so a single failure pages.
|
||||
Namespace: AWS/Lambda
|
||||
MetricName: Errors
|
||||
Dimensions:
|
||||
- Name: FunctionName
|
||||
Value: !Ref RenderFunction
|
||||
Statistic: Sum
|
||||
Period: 300
|
||||
EvaluationPeriods: 1
|
||||
Threshold: 1
|
||||
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||
TreatMissingData: notBreaching
|
||||
|
||||
# ── CloudWatch alarm: Step Functions execution failures ─────────────────
|
||||
# Fires when a state-machine execution reaches a terminal failure
|
||||
# state (typed non-retryable, retry-exhausted, or top-level timeout).
|
||||
# Complementary to the Lambda Errors alarm: SFN failures include
|
||||
# Choice-state Fail branches (PlanProducedZeroChunks) that bypass
|
||||
# Lambda entirely, plus retry-exhaustion of transient errors that
|
||||
# individual Lambda invocations counted as successful "retries".
|
||||
RenderStateMachineFailedAlarm:
|
||||
Type: AWS::CloudWatch::Alarm
|
||||
Properties:
|
||||
AlarmName: !Sub "${ProjectName}-render-state-machine-failed"
|
||||
AlarmDescription: >-
|
||||
Fires when the render state machine reports a failed
|
||||
execution. Catches retry-exhaustion + typed non-retryable +
|
||||
TimeoutSeconds cases that the Lambda Errors metric misses.
|
||||
Namespace: AWS/States
|
||||
MetricName: ExecutionsFailed
|
||||
Dimensions:
|
||||
- Name: StateMachineArn
|
||||
Value: !Ref RenderStateMachine
|
||||
Statistic: Sum
|
||||
Period: 300
|
||||
EvaluationPeriods: 1
|
||||
Threshold: 1
|
||||
ComparisonOperator: GreaterThanOrEqualToThreshold
|
||||
TreatMissingData: notBreaching
|
||||
|
||||
Outputs:
|
||||
RenderBucketName:
|
||||
Description: S3 bucket for plan tarballs, chunk outputs, and final renders.
|
||||
Value: !Ref RenderBucket
|
||||
Export:
|
||||
Name: !Sub "${AWS::StackName}-RenderBucket"
|
||||
|
||||
RenderFunctionArn:
|
||||
Description: ARN of the Lambda function. Pass to `aws lambda invoke` for local testing.
|
||||
Value: !GetAtt RenderFunction.Arn
|
||||
Export:
|
||||
Name: !Sub "${AWS::StackName}-RenderFunctionArn"
|
||||
|
||||
RenderStateMachineArn:
|
||||
Description: ARN of the Step Functions state machine. Pass to `aws stepfunctions start-execution`.
|
||||
Value: !Ref RenderStateMachine
|
||||
Export:
|
||||
Name: !Sub "${AWS::StackName}-RenderStateMachineArn"
|
||||
Reference in New Issue
Block a user