Skip to content

Add enable_lf_grants for opt-in LF TableWildcard grants#104

Open
drernie wants to merge 2 commits intomainfrom
2026-04-11-enable-lf-grants
Open

Add enable_lf_grants for opt-in LF TableWildcard grants#104
drernie wants to merge 2 commits intomainfrom
2026-04-11-enable-lf-grants

Conversation

@drernie
Copy link
Copy Markdown
Member

@drernie drernie commented Apr 12, 2026

Summary

  • Adds enable_lf_grants variable (bool, default false) to the modules/quilt module
  • Maps to EnableLakeFormationGrants CFT parameter (Enabled/Disabled)
  • Documents the variable in VARIABLES.md

Context

Per-role Lake Formation TableWildcard grants require the CloudFormation execution
role to be a Lake Formation administrator. Without this gate, deploys fail with
AccessDeniedException on any account where the deploying role isn't on the LF
admin list — which includes all new installs and accounts without LF enforcement.

This makes the grants opt-in so operators must explicitly enable them after
completing the LF admin bootstrap (adding the deploying role to the LF admin list).

Companion changes needed

  • deployment repo: Add EnableLakeFormationGrants CFT parameter and
    LakeFormationGrantsEnabled condition to gate _DYNAMIC_DB_ROLE_GRANTS
    in lakeformation.py

Test plan

  • terraform fmt -check passes
  • terraform validate passes
  • Existing deployments unaffected (default false → parameter omitted or Disabled)
  • Verify CFT accepts EnableLakeFormationGrants parameter after deployment-side changes

🤖 Generated with Claude Code

Greptile Summary

This PR adds an enable_lf_grants boolean variable (default false) to the modules/quilt module, wiring it to the EnableLakeFormationGrants CloudFormation parameter so that per-role Lake Formation TableWildcard grants are opt-in rather than always-on.

  • EnableLakeFormationGrants is unconditionally sent as \"Disabled\" when the feature is off, instead of null. Passing an unrecognized parameter to CloudFormation raises an error, so any terraform apply on a deployment whose CFT template hasn't yet received the companion parameter change will fail immediately.

Confidence Score: 4/5

Not safe to merge as-is — will break existing deployments if applied before the companion CFT change.

One P1 finding: the parameter is always sent as "Disabled" rather than null, creating a hard dependency on the companion CFT template change being deployed first. A one-line fix (null instead of "Disabled") aligns with the existing null pattern in the file and makes the rollout order-independent.

modules/quilt/main.tf — line 104 where EnableLakeFormationGrants is unconditionally set.

Important Files Changed

Filename Overview
modules/quilt/main.tf Adds EnableLakeFormationGrants to the CFT parameters block, but always passes "Disabled" (not null) when disabled — will break existing deployments whose templates don't yet have this parameter.
modules/quilt/variables.tf Adds well-formed enable_lf_grants bool variable with nullable=false, default=false, and a clear description.
VARIABLES.md Adds a new "Lake Formation Variables" section documenting enable_lf_grants with type, default, and usage notes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[terraform apply] --> B{enable_lf_grants?}
    B -- true --> C["EnableLakeFormationGrants = 'Enabled'"]
    B -- false --> D["EnableLakeFormationGrants = 'Disabled'\n⚠️ always sent"]
    C --> E[merge with var.parameters]
    D --> E
    E --> F[aws_cloudformation_stack]
    F --> G{CFT template has\nEnableLakeFormationGrants\nparameter?}
    G -- yes --> H[Stack update succeeds]
    G -- no --> I[❌ CloudFormation rejects\nunknown parameter]
Loading

Reviews (1): Last reviewed commit: "Add enable_lf_grants variable for opt-in..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

… grants

Accounts with Lake Formation enforcement active need per-role TableWildcard
grants, but these require the deploying role to be an LF admin. Default to
false so installs don't break on accounts without LF admin setup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
parameters = merge(
var.parameters,
{
EnableLakeFormationGrants = var.enable_lf_grants ? "Enabled" : "Disabled"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Unconditional parameter breaks existing deployments

EnableLakeFormationGrants is always passed — as "Disabled" when the feature is off — even before the companion CFT template change adds this parameter. Any terraform apply on an existing deployment that doesn't yet have EnableLakeFormationGrants in its template will fail with CloudFormation rejecting the unknown parameter. Passing null omits the key from the parameters map (matching the existing pattern for PublicSubnets and UserSubnets), so CFT uses its own default and older templates stay unaffected.

Suggested change
EnableLakeFormationGrants = var.enable_lf_grants ? "Enabled" : "Disabled"
EnableLakeFormationGrants = var.enable_lf_grants ? "Enabled" : null

drernie added a commit to quiltdata/benchling-webhook that referenced this pull request Apr 12, 2026
LF TableWildcard grants require LF admin privileges that vary by account.
Gate them behind EnableLakeFormationGrants CFT parameter (default Disabled)
so deploys don't break on accounts without LF admin setup. Terraform
variable added in quiltdata/iac#104.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
drernie added a commit to quiltdata/benchling-webhook that referenced this pull request Apr 12, 2026
* docs: analysis of EventBridge rule breakage for integrated stack

Prefix filtering belongs in Docker (runtime secret), not the EventBridge
rule. The rule itself must be created in Quilt stack IaC for integrated
mode. Filed quiltdata/enterprise#1028 for pkgevents bus/source issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 0.16.0

* chore: bump version to 0.16.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: move EventBridge bucket/prefix filtering to Docker runtime

The EventBridge rule previously filtered on detail.bucket and
detail.handle (prefix), but both values come from Secrets Manager
and are unavailable at deploy time in integrated-mode stacks where
the Quilt IaC creates the rule independently.

Simplify the rule to match only source + detail-type, and add
runtime prefix filtering in the Docker handler alongside the
existing bucket check. This unblocks integrated-mode EventBridge
rule creation with zero dependency on secret-derived values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: bump version to 0.16.0

* fix: move EventBridge bucket/prefix filtering to Docker runtime

The EventBridge rule previously filtered on detail.bucket and
detail.handle (prefix), but both values come from Secrets Manager
and are unavailable at deploy time in integrated-mode stacks where
the Quilt IaC creates the rule independently.

Simplify the rule to match only source + detail-type, and add
runtime prefix filtering in the Docker handler alongside the
existing bucket check. This unblocks integrated-mode EventBridge
rule creation with zero dependency on secret-derived values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: trim AGENTS.md to guidance-only, add npm script warning

Remove architecture, file lists, and patterns that agents can derive
from code. Keep only policy, gotchas, and the critical rule to use
project npm scripts (not built-in npm commands) for version bumps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove pending canvas state, honest footer status

The pending canvas was a net negative: it replaced a working canvas with
a degraded one (disabled buttons, stripped links, Athena errors) just to
show "Updating...", then replaced it again with identical content. Now
the canvas stays unchanged until the EventBridge package event confirms
the update. Footer shows "Pending update" instead of the misleading
"Up to date" when no confirmed timestamp exists.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: document TableWildcard + IAM_ALLOWED_PRINCIPALS failure

AWS LF rejects TableWildcard grants for IAM_ALLOWED_PRINCIPALS.
Per-role TableWildcard grants work fine — need to swap the principal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: update TableWildcard spec with per-role grant strategy

Iceberg tables are also runtime-created. Both UserAthenaDatabase (7 roles)
and IcebergDatabase (2 roles) need per-role TableWildcard grants.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: complete LF TableWildcard investigation and resolution

- 02: updated analysis (Iceberg tables also runtime-created)
- 03: per-role grants fail without LF admin status
- 04: LF admin list is the real blocker
- 05: added GitHub-Deployment to LF admin list, deploy succeeded

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: spec opt-in LF grants with CFT parameter and iac PR

LF TableWildcard grants require LF admin privileges that vary by account.
Gate them behind EnableLakeFormationGrants CFT parameter (default Disabled)
so deploys don't break on accounts without LF admin setup. Terraform
variable added in quiltdata/iac#104.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Passing "Disabled" breaks existing deployments whose CFT templates
don't yet define this parameter. Using null omits the key from the
merge() map, matching the pattern for PublicSubnets and UserSubnets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant