Promotion 2026-09-08 prod (#8291) - #8295
Open
nadove-ucsc wants to merge 121 commits into
Open
Conversation
Add `azul_lambda_image_platforms` environment variable to control which platforms are built, defaulting to amd64 first (determining Lambda architecture) with arm64 second. Make targets now iterate dynamically over this variable. Add `lambda_image_platforms` and `lambda_architecture` config properties with Docker-to-Lambda arch mapping for use in Terraform. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Patch Chalice-generated TF config to use `package_type = "Image"` with `image_uri` and `architectures` instead of ZIP-based `filename`, `source_code_hash`, `runtime`, and `handler` - Remove Lambda layer assignment and runtime management config (both are baked into the Docker image now) - Add `replace_triggered_by` lifecycle rule on Lambda aliases to handle the ZIP-to-Image transition - Move image URI generation and architecture mapping from `azul.config` to `azul.docker` (as module-level functions) - Add `Platform.tag_suffix` property and inline `platform_tag_suffix()` in `manage_images.py` Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove create_before_destroy from Lambda permissions. It was added when aliases were introduced, ostensibly to ensure old permissions aren't deleted before new ones are created during alias replacement. But aliases are updated in place (only function_version changes), never replaced, so the permissions are never replaced either and CBD never triggers. Worse, during the Zip-to-Image migration, the function replacement cascades into the permission (whose function_name references the function ARN), and CBD on the permission propagates back to the function, causing a 409 "already exists" error. Remove replace_triggered_by from aliases and suppress the Lambda layer resource, neither of which is needed for image-based Lambda functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
No longer needed now that Lambda functions use Docker images instead of the AWS-managed Python runtime. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a Lambda function is replaced (e.g., Zip to Image migration), AWS cascade-deletes the function's aliases. Terraform doesn't know about the cascade and tries to update the now-gone alias, resulting in a 404. Add replace_triggered_by on the alias referencing the function's package_type so the alias is also replaced when the function is replaced. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The .pyc files from chalice package have vendor/ relative paths as co_filename, causing truncated tracebacks in the container. Strip them and recompile in the image so tracebacks resolve to /var/task/ sources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
awslambdaric's StandardLogSink delimits CloudWatch log events by newline. Multi-line log records (e.g., with tracebacks from exc_info) were split into separate CloudWatch events. A custom formatter now replaces newlines with carriage returns within each record, appending a single newline at the end as the event delimiter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
With Docker image deployment, runtime dependencies are installed directly in the image via pip. The Lambda layer that previously provided shared dependencies to ZIP-based functions is no longer needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Lambda dependencies are now installed via pip inside the Docker image build, so the checked-in wheels and the azul_chalice_bin machinery are no longer needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The GitLab executor image configures per-registry credential helpers via credHelpers rather than the global credsStore. Handle that case when resolving Lambda image digests during Terraform template rendering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
#8245 (comment) Derive HTTP timeout from Lambda context's remaining time Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e on anvilprod (#8258) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#7466) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#8245 (comment) Add RateLimitingCacheService Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…size (DataBiosphere/azul-private#414) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ate#377) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both places that construct an Access assert that the URL's scheme matches that of the access method, so the combination in this fixture cannot occur in production. The test got away with it because it patches DRSObject.get, bypassing the code that enforces the invariant, and consequently asserted that a client is redirected to a gs:// URL. While here, compose the URL with furl instead of interpolating it into a string. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rivate#412) The secret is passed as a multipart form field to the token endpoint, and LoggingHttpClient logs the request body, so no pattern matching it meant it appeared in full. Asserting its redactability before the request is what turns a future gap in the pattern into a visible failure instead of a silent disclosure. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…DataBiosphere/azul-private#412) The secret for sandbox was stored with a leading space, which Google rejects and which no redaction pattern matches. Catching that where the secret enters the system beats discovering it when a user fails to sign in. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A header value, a query parameter and a string value in logged JSON were only redacted if the value in its entirety was a secret. Redact any secret occurring in such a value instead. This is a prerequisite for redacting the signature of a signed URL, which is only ever a part of the value carrying it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e#390) Add the redaction pattern so that it is detected where redactions are currently applied A signed URL is a bearer capability, but it is never a secret in its entirety, so redact() only redacted one when the URL appeared inside a larger string. Header and JSON values are redacted with fullmatch, which is why the Location header of a redirect to a signed URL was logged in the clear. Only the signature is redacted, leaving the rest of the URL to be of use in the log. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e#390) Don't rely on a mapping's type to redact it when logging Redaction of the logged query parameters and request headers relied on _LogJSONEncoder.default, which json only invokes for values it cannot serialize natively. It therefore worked only because Chalice happens to represent them as MultiDict and CaseInsensitiveMapping. Were either a plain dict, json would serialize it directly, the encoder would never be consulted and the values would be logged verbatim, without any indication that redaction was skipped. Redact both explicitly instead, which leaves the logged output unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e#390) Redact response headers, too A repository file download answers with a 302 whose Location is a signed URL, a bearer capability that anyone reading the log could use until it expires. The response headers were the only logged request or response property that was exempt from redaction. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ng (#8282) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
7 tasks
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## prod #8295 +/- ##
==========================================
+ Coverage 84.43% 84.79% +0.35%
==========================================
Files 169 168 -1
Lines 24925 25201 +276
==========================================
+ Hits 21045 21368 +323
+ Misses 3880 3833 -47 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
hannes-ucsc
approved these changes
Sep 11, 2026
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.
Linked issue: #8291
Checklist
Author
prodpromotions/yyyy-mm-dd-prodPromotion yyyy-mm-ddprodAuthor (reindex)
reindex:prodor the changes introduced by it will not require reindexing ofprodreindex:partialand its description documents the specific reindexing procedure forprodor requires a full reindex or is not labeledreindex:prodAuthor (mirror)
mirror:prodor the changes introduced by it will not require mirroring ofprodmirror:partialand its description documents the specific mirroring procedure forprodor requires a full mirroring or is not labeledmirror:prodAuthor (upgrading deployments)
upgradeor does not require upgrading deploymentsdeploy:sharedor does not modifydocker_images.json, and does not require deploying thesharedcomponent for any other reasondeploy:gitlabor does not require deploying thegitlabcomponentdeploy:runneror does not require deploying therunnerimageAuthor (before every review)
prodinto PR branch to integrate upstream changes)System administrator (after approval)
no sandboxN reviewslabel is accurateOperator
Operator (deploy
.sharedand.gitlabcomponents)_select prod.shared && CI_COMMIT_REF_NAME=prod make -C terraform/shared apply_keep_unusedor this PR is not labeleddeploy:shared_select prod.gitlab && python scripts/create_gitlab_snapshot.py --no-restart(see operator manual for details) or this PR is not labeledbackup:gitlab_select prod.gitlab && CI_COMMIT_REF_NAME=prod make -C terraform/gitlab apply(an error from _login_docker_gitlab is benign if the instance was stopped for backup) or this PR is not labeleddeploy:gitlabdeploy:gitlabdeploy:gitlabSystem administrator (post-deploy of
.gitlabcomponent)prod.gitlabare complete or this PR is not labeleddeploy:gitlabOperator (deploy runner image)
_select prod.gitlab && make -C terraform/gitlab/runneror this PR is not labeleddeploy:runnerOperator (merge the branch)
ptagsOperator (main build)
prodprodprodprodor this PR is not labeledupgrade, or upgrade instructions do not apply toprod_select prod.shared && make -C terraform/shared applyor this PR is not labeleddeploy:shared1 Promoted issues and PRs are referenced in the titles of the commits
that the promotion branch introduces to the stable branch. Prior to the
promotion, the status of promoted issues (PRs) is Lower (Merged lower).
Promoted PRs in status Done do not need to be moved.
Operator (reindex)
prod, deleted the catalogs specified in the notes or this PR is missing either thereindex:partialor thereindex:prodlabel, or bothprod, deindexed the sources sepcified in the notes or this PR is missing either thereindex:partialor thereindex:prodlabel, or bothprod, indexed the sources specified in the notes or this PR is missing either thereindex:partialor thereindex:prodlabel, or bothprod, indexed the catalogs specified in the notes or this PR is missing either thereindex:partialor thereindex:prodlabel, or bothprodor this PR is not labeledreindex:prodor it is labeled reindex:partialprodor this PR is not labeledreindex:prodor it is labeled reindex:partialprodor this PR is not labeledreindex:prodor it is labeled reindex:partialprodor this PR is not labeledreindex:prodprodor this PR is not labeledreindex:proddeploy_browserjob in the GitLab pipeline for this PR inprodor this PR is not labeledreindex:prodOperator (mirroring)
prodor this PR is not labelledmirror:prodprodor this PR is not labelledmirror:prodprodor this PR is not labelledmirror:prodOperator
System administrator
Shorthand for review comments
Lline is too longWline wrapping is wrongQbad quotesFother formatting problem