Repository navigation
hardening(deploy): runtime override, robust env vars, smoke test - #8
Closed
karthikeyangs9 wants to merge 1 commit into
Closed
karthikeyangs9 wants to merge 1 commit into
karthikeyangs9 wants to merge 1 commit into
Conversation
Three quality-of-life improvements that build on the idempotency fixes
in the parent commit. Each addresses a real (though lower-severity)
failure mode observed or anticipated.
1. Configurable Lambda runtime (RUNTIME env var, default python3.13).
Runtime was hardcoded — when AWS deprecates the version, every
redeploy starts erroring. The update path now also passes --runtime
so existing functions migrate (e.g. RUNTIME=python3.14 ./deploy.sh)
instead of needing delete + recreate.
2. Robust environment variable serialization via python json.dumps.
The shorthand "Variables={k=v,k=v}" syntax breaks if any value
contains '=' or ',' — possible for custom JWT tokens and comma-bearing
service names. Switching to "--environment file://path.json" with a
properly JSON-encoded file handles every character class. Temp file
is registered with the existing trap.
3. Post-deploy smoke test (SMOKE_TEST=1, default on).
The previous deploy printed "✓ Deployed" even when runtime errors
existed (a customer's IAM-policy-drift bug only surfaced on manual
invoke). The smoke test invokes the function once, captures the
FunctionError field via --query/--output text (returns "None" for
null — reliable string comparison, avoids brittle JSON grep), and
exits 1 with a hint message if the Lambda returned an error.
Set SMOKE_TEST=0 to skip — useful for CI deploys that don't have
permission to invoke or where the smoke run would charge Cost Explorer
API fees outside the daily cron budget.
prathamesh-sonpatki
added a commit
that referenced
this pull request
Apr 30, 2026
…test Integrates hardening from #7 + #8 into the idempotent deploy work: - trap-based temp file cleanup (BUILD_DIR, ZIP_PATH, ENV_FILE) - wait function-updated before update-function-code (handles in-flight state from a prior crashed/concurrent run) - wait function-active after create-function (newly created Lambdas start in Pending; add-permission requires Active) - selective ResourceConflictException handling on add-permission so unrelated failures (regional, IAM, throttling) surface instead of being swallowed by `2>/dev/null || true` - RUNTIME override (default python3.13) on both create-function and update-function-configuration - JSON env vars via python json.dumps — fixes shorthand breakage when any value contains '=' or ',' (Last9 OTLP tokens, comma-bearing service names) - SMOKE_TEST=1 opt-in post-deploy lambda invoke that fails the script on FunctionError. Default 0 to avoid spurious data points on every deploy during initial setup. Co-Authored-By: karthikeyangs9 <174431822+karthikeyangs9@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 tasks
prathamesh-sonpatki
added a commit
that referenced
this pull request
Apr 30, 2026
* fix(deploy): always reapply IAM policy so existing roles pick up new perms Previously put-role-policy only ran on initial role creation. Customers re-running deploy.sh after a new code release (e.g., PR #5 added ce:GetDimensionValues) hit AccessDeniedException at runtime because the existing role wasn't patched. put-role-policy and attach-role-policy are idempotent — always reapply. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(deploy): wait for in-flight Lambda updates; document troubleshooting deploy.sh: Add `aws lambda wait function-updated` before and between update-function-code / update-function-configuration calls. Without these waits, back-to-back deploys hit ResourceConflictException ("An update is in progress for resource: ..."). README: Add Troubleshooting section covering the four errors seen in customer rollouts: missing CE IAM permissions, in-flight Lambda update conflict, stale GroupBy 3-dim build, and the old mktemp zip failure. Also clarify that AWS_REGION controls Lambda placement only — Cost Explorer is global — so users override it via env var rather than editing the script. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * simplify: drop redundant Lambda waits and clean up role flag - Drop pre-update wait (defensive, no prior async mutation in this path) - Drop trailing wait after update-function-configuration (EventBridge put-rule/put-targets don't read Lambda update state) - Keep the wait between update-function-code and update-function-configuration (the actual race that caused ResourceConflictException) - ROLE_CREATED flag → simpler NEW_ROLE empty/non-empty test - Trim narrating comments Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(deploy): harden Lambda update flow, JSON env vars, opt-in smoke test Integrates hardening from #7 + #8 into the idempotent deploy work: - trap-based temp file cleanup (BUILD_DIR, ZIP_PATH, ENV_FILE) - wait function-updated before update-function-code (handles in-flight state from a prior crashed/concurrent run) - wait function-active after create-function (newly created Lambdas start in Pending; add-permission requires Active) - selective ResourceConflictException handling on add-permission so unrelated failures (regional, IAM, throttling) surface instead of being swallowed by `2>/dev/null || true` - RUNTIME override (default python3.13) on both create-function and update-function-configuration - JSON env vars via python json.dumps — fixes shorthand breakage when any value contains '=' or ',' (Last9 OTLP tokens, comma-bearing service names) - SMOKE_TEST=1 opt-in post-deploy lambda invoke that fails the script on FunctionError. Default 0 to avoid spurious data points on every deploy during initial setup. Co-Authored-By: karthikeyangs9 <174431822+karthikeyangs9@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: karthikeyangs9 <174431822+karthikeyangs9@users.noreply.github.com>
Member
|
Integrated into #9 (squash-merged as 65b6452). Thanks @karthikeyangs9! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three follow-up improvements to
deploy.shafter the idempotency fixes in #7. Each addresses a real (or anticipated) lower-severity failure mode.python3.13Variables={k=v,k=v}shorthand=or,— possible for custom JWTs and unusualOTEL_SERVICE_NAMEvalues.lambda invokeafter deploy "succeeded" — would have been caught at deploy time with a smoke test.Fixes
1. Configurable runtime
RUNTIME="${RUNTIME:-python3.13}"Used in both
create-functionandupdate-function-configurationpaths. Existing customers can migrate runtimes via:2. JSON-encoded environment via temp file
Replaces:
With a python
json.dumps-built JSON file passed viafile://:Python is already a hard dependency of this Lambda (the runtime itself), so no new tooling. JSON escapes every character class correctly. Temp file is registered with the existing
trap.3. Smoke test (default on,
SMOKE_TEST=1)Catches IAM permission gaps, OTLP endpoint typos, and network egress blocks at deploy time instead of silently shipping a broken Lambda. Uses
--output text(returns literal"None"for null) for reliable comparison instead of JSON grep.SMOKE_TEST=0 ./deploy.shopts out — useful for CI roles withoutlambda:InvokeFunctionpermission, or to avoid extra Cost Explorer API charges outside the daily cron budget.Test plan
bash -n deploy.sh— syntax OKgrep '"FunctionError"'(matchesnulltoo) → reliable[[ "$VAR" != "None" ]]RUNTIME=python3.14 ./deploy.shagainst existing function — confirm runtime upgrade appliesOTEL_EXPORTER_OTLP_HEADERS='Authorization=Bearer token=with=equals,and,commas'— confirm Lambda env vars are correct in consoleFunctionError: UnhandledmessageSMOKE_TEST=0 ./deploy.sh— confirm script ends without invoking