Skip to content

Commit 93fea21

Browse files
Hannah14295hrehard
andauthored
fix(examples): correct cross-account access in LF Feature Store notebook (#6048)
* fix: correct cross-account access in LF Feature Store notebook Two fixes so v3-feature-store-lake-formation-cross-account.ipynb runs end-to-end across the three accounts: 1. Online-store PutRecord/GetRecord run as the Feature Group owner (central account), not the producer. SageMaker Feature Store has no cross-account resource policy for the online store, so the producer session gets AccessDenied ('no resource-based policy allows sagemaker:PutRecord'). Cross-account sharing is via the offline store. 2. Grant the producer account cross-account Glue Data Catalog access before the PyIceberg write. GetTemporaryGlueTableCredentials requires it; without it the write fails with 'Insufficient Glue permissions to access table'. The notebook previously only granted the consumer (and only after this write). * fix: make producer Glue-access cell self-contained (import time) * docs: shorten PutRecord owner comment to match notebook style * docs: remove comments from producer Glue-access cell --------- Co-authored-by: hrehard <hrehard@amazon.com>
1 parent 6659b11 commit 93fea21

1 file changed

Lines changed: 39 additions & 2 deletions

File tree

‎v3-examples/ml-ops-examples/v3-feature-store-examples/lake-formation/v3-feature-store-lake-formation-cross-account.ipynb‎

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,8 @@
348348
"source": [
349349
"from datetime import datetime, timezone\n",
350350
"\n",
351-
"# Use the producer session to call PutRecord on the shared Feature Group\n",
352-
"sm_runtime = producer_acc_boto_session.client('sagemaker-featurestore-runtime')\n",
351+
"# Online store is single-account: PutRecord/GetRecord run as the FG owner (central)\n",
352+
"sm_runtime = central_acc_boto_session.client('sagemaker-featurestore-runtime')\n",
353353
"\n",
354354
"sm_runtime.put_record(\n",
355355
" FeatureGroupName=feature_group_arn,\n",
@@ -512,6 +512,43 @@
512512
"**Hybrid access mode must be disabled on Glue Table and Database in order for cross-account credential vending to work**"
513513
]
514514
},
515+
{
516+
"cell_type": "code",
517+
"id": "nte-producer-glue-access",
518+
"execution_count": null,
519+
"metadata": {},
520+
"outputs": [],
521+
"source": [
522+
"import json, time\n",
523+
"_db_lower = database_name.lower()\n",
524+
"_region = central_acc_boto_session.region_name\n",
525+
"_producer_stmt = {\n",
526+
" 'Sid': 'AllowProducerGlueAccess',\n",
527+
" 'Effect': 'Allow',\n",
528+
" 'Principal': {'AWS': f'arn:aws:iam::{producer_account}:root'},\n",
529+
" 'Action': 'glue:*',\n",
530+
" 'Resource': [\n",
531+
" f'arn:aws:glue:{_region}:{central_account}:catalog',\n",
532+
" f'arn:aws:glue:{_region}:{central_account}:database/{_db_lower}',\n",
533+
" f'arn:aws:glue:{_region}:{central_account}:table/{_db_lower}/*',\n",
534+
" ],\n",
535+
"}\n",
536+
"try:\n",
537+
" _cur = central_glue_client.get_resource_policy()\n",
538+
" _existing = json.loads(_cur['PolicyInJson'])\n",
539+
" _stmts = [s for s in _existing.get('Statement', []) if s.get('Sid') != 'AllowProducerGlueAccess']\n",
540+
" _stmts.append(_producer_stmt)\n",
541+
" central_glue_client.put_resource_policy(\n",
542+
" PolicyInJson=json.dumps({'Version': '2012-10-17', 'Statement': _stmts}),\n",
543+
" PolicyHashCondition=_cur['PolicyHash'], EnableHybrid='TRUE')\n",
544+
"except central_glue_client.exceptions.EntityNotFoundException:\n",
545+
" central_glue_client.put_resource_policy(\n",
546+
" PolicyInJson=json.dumps({'Version': '2012-10-17', 'Statement': [_producer_stmt]}),\n",
547+
" EnableHybrid='TRUE')\n",
548+
"print('Granted producer account cross-account Glue access')\n",
549+
"time.sleep(8)\n"
550+
]
551+
},
515552
{
516553
"cell_type": "code",
517554
"execution_count": null,

0 commit comments

Comments
 (0)