diff --git a/v3-examples/ml-ops-examples/v3-feature-store-examples/lake-formation/v3-feature-store-lake-formation-cross-account.ipynb b/v3-examples/ml-ops-examples/v3-feature-store-examples/lake-formation/v3-feature-store-lake-formation-cross-account.ipynb index 14253509a6..97a7eb7612 100644 --- a/v3-examples/ml-ops-examples/v3-feature-store-examples/lake-formation/v3-feature-store-lake-formation-cross-account.ipynb +++ b/v3-examples/ml-ops-examples/v3-feature-store-examples/lake-formation/v3-feature-store-lake-formation-cross-account.ipynb @@ -348,8 +348,8 @@ "source": [ "from datetime import datetime, timezone\n", "\n", - "# Use the producer session to call PutRecord on the shared Feature Group\n", - "sm_runtime = producer_acc_boto_session.client('sagemaker-featurestore-runtime')\n", + "# Online store is single-account: PutRecord/GetRecord run as the FG owner (central)\n", + "sm_runtime = central_acc_boto_session.client('sagemaker-featurestore-runtime')\n", "\n", "sm_runtime.put_record(\n", " FeatureGroupName=feature_group_arn,\n", @@ -512,6 +512,43 @@ "**Hybrid access mode must be disabled on Glue Table and Database in order for cross-account credential vending to work**" ] }, + { + "cell_type": "code", + "id": "nte-producer-glue-access", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import json, time\n", + "_db_lower = database_name.lower()\n", + "_region = central_acc_boto_session.region_name\n", + "_producer_stmt = {\n", + " 'Sid': 'AllowProducerGlueAccess',\n", + " 'Effect': 'Allow',\n", + " 'Principal': {'AWS': f'arn:aws:iam::{producer_account}:root'},\n", + " 'Action': 'glue:*',\n", + " 'Resource': [\n", + " f'arn:aws:glue:{_region}:{central_account}:catalog',\n", + " f'arn:aws:glue:{_region}:{central_account}:database/{_db_lower}',\n", + " f'arn:aws:glue:{_region}:{central_account}:table/{_db_lower}/*',\n", + " ],\n", + "}\n", + "try:\n", + " _cur = central_glue_client.get_resource_policy()\n", + " _existing = json.loads(_cur['PolicyInJson'])\n", + " _stmts = [s for s in _existing.get('Statement', []) if s.get('Sid') != 'AllowProducerGlueAccess']\n", + " _stmts.append(_producer_stmt)\n", + " central_glue_client.put_resource_policy(\n", + " PolicyInJson=json.dumps({'Version': '2012-10-17', 'Statement': _stmts}),\n", + " PolicyHashCondition=_cur['PolicyHash'], EnableHybrid='TRUE')\n", + "except central_glue_client.exceptions.EntityNotFoundException:\n", + " central_glue_client.put_resource_policy(\n", + " PolicyInJson=json.dumps({'Version': '2012-10-17', 'Statement': [_producer_stmt]}),\n", + " EnableHybrid='TRUE')\n", + "print('Granted producer account cross-account Glue access')\n", + "time.sleep(8)\n" + ] + }, { "cell_type": "code", "execution_count": null,