

# 将 AWS Glue 与 AWS Lake Formation 结合使用实现全表访问
<a name="security-access-control-fta"></a>

## 全表访问简介
<a name="security-access-control-fta-intro"></a>

AWS Glue 5.0 及更高版本支持 Apache Spark 中的全表访问（FTA）控制，具体取决于您在 AWS Lake Formation 中定义的策略。当作业角色具有全表访问权限时，您可以借助此功能从 AWS Glue Spark 作业在注册到 AWS Lake Formation 的表上执行读写操作。FTA 非常适合需要在表级别遵守安全法规的使用案例，并支持将各种 Spark 功能用于 AWS Lake Formation 表，包括弹性分布式数据集（RDD）、自定义库和用户定义函数（UDF）。

当 AWS Glue Spark 作业配置为全表访问（FTA）模式时，AWS Lake Formation 凭证将用于为注册到 AWS Lake Formation 的表读取/写入 Amazon S3 数据，而作业的运行时角色凭证将用于读取/写入未注册到 AWS Lake Formation 的表。此功能支持数据操作语言（DML）操作，包括 Apache Hive 和 Iceberg 表上的 CREATE、ALTER、DELETE、UPDATE 和 MERGE INTO 语句。

**注意**  
检查您的需求并确定是精细访问控制（FGAC）模式还是全表访问（FTA）适合您的需求。对于给定 AWS Glue 作业，只能启用一种 AWS Lake Formation 权限方法。同一个作业不能同时运行全表访问（FTA）和精细访问控制（FGAC）。

## AWS Glue 上的全表访问（FTA）工作原理
<a name="security-access-control-fta-how-it-works"></a>

 AWS Lake Formation 提供了精细访问控制（FGAC）和全表访问（FTA）这两种数据访问控制方法。FGAC 可按列、行和单元格级别进行筛选，从而增强安全性，非常适合需要精细权限的场景。FTA 非常适合需要表级别权限的简单访问控制场景。由于无需启用精细访问模式，因此简化了实施；同时由于无需系统驱动程序和系统执行程序，因此提高了性能并降低了成本；此外还支持读取和写入操作（包括 CREATE、ALTER、DELETE、UPDATE 和 MERGE INTO 命令）。

 在 AWS Glue 4.0 中，基于 AWS Lake Formation 的数据访问通过 GlueContext 类（AWS Glue 提供的实用程序类）实现。在 AWS Glue 5.0 中，基于 AWS Lake Formation 的数据访问可通过原生 Spark SQL、Spark DataFrames 实现，并且继续支持通过 GlueContext 类访问。

## 全表访问模式的实施
<a name="security-access-control-fta-implementation"></a>

### 第 1 步：在 AWS Lake Formation 中启用全表访问
<a name="security-access-control-fta-step-1"></a>

要使用全表访问（FTA）模式，您需要允许第三方查询引擎无需在 AWS Lake Formation 中验证 IAM 会话标签即可访问数据。要启用此模式，请按照 [Application integration for full table access](https://docs.aws.amazon.com/lake-formation/latest/dg/full-table-credential-vending.html) 中的步骤操作。

### 第 2 步：设置作业运行时角色的 IAM 权限
<a name="security-access-control-fta-step-2"></a>

要获得基础数据的读取或写入权限，除 AWS Lake Formation 权限外，作业运行时角色还需要具有 `lakeformation:GetDataAccess` IAM 权限。获得此权限后，AWS Lake Formation 将授权访问数据的临时凭证请求。

以下示例策略展示了如何提供 IAM 权限以访问 Amazon S3 中的脚本、将日志上传到 Amazon S3、AWS Glue API 权限以及访问 AWS Lake Formation 的权限。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "ScriptAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::{{amzn-s3-demo-bucket}}/scripts/*"
      ]
    },
    {
      "Sid": "LoggingAccess",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::{{amzn-s3-demo-bucket}}/logs/*"
      ]
    },
    {
      "Sid": "GlueCatalogAccess",
      "Effect": "Allow",
      "Action": [
        "glue:GetDatabase",
        "glue:GetDatabases",
        "glue:GetTable",
        "glue:GetTables",
        "glue:GetPartition",
        "glue:GetPartitions",
        "glue:CreateTable",
        "glue:UpdateTable"
      ],
      "Resource": [
        "arn:aws:glue:{{us-east-1}}:{{111122223333}}:catalog",
        "arn:aws:glue:{{us-east-1}}:{{111122223333}}:database/default",
        "arn:aws:glue:{{us-east-1}}:{{111122223333}}:table/default/*"
      ]
    },
    {
      "Sid": "LakeFormationAccess",
      "Effect": "Allow",
      "Action": [
        "lakeformation:GetDataAccess"
      ],
      "Resource": "*"
    }
  ]
}
```

------

#### 第 2.1 步：配置 AWS Lake Formation 权限
<a name="security-access-control-fta-step-2-1"></a>

从 Amazon S3 读取数据的 AWS Glue Spark 作业需要具有 AWS Lake Formation SELECT 权限。

在 Amazon S3 中写入/删除数据的 AWS Glue Spark 作业需要具有 AWS Lake Formation ALL 权限。

与 AWS Glue 数据目录交互的 AWS Glue Spark 作业需要视情况具有 DESCRIBE、ALTER、DROP 权限。

### 第 3 步：使用 AWS Lake Formation 初始化 Spark 会话以实现全表访问
<a name="security-access-control-fta-step-3"></a>

要访问注册到 AWS Lake Formation 的表，需要在 Spark 初始化期间设置以下配置，以便将 Spark 配置为使用 AWS Lake Formation 凭证。

 要访问注册到 AWS Lake Formation 的表，您需要将 Spark 会话显式配置为使用 AWS Lake Formation 凭证。在初始化 Spark 会话时添加以下配置：

```
from pyspark.sql import SparkSession
        
# Initialize Spark session with Lake Formation configurations
spark = SparkSession.builder \
    .appName("Lake Formation Full Table Access") \
    .config("spark.sql.catalog.glue_catalog", "org.apache.spark.sql.catalog.hive.GlueCatalog") \
    .config("spark.sql.catalog.glue_catalog.glue.lakeformation-enabled", "true") \
    .config("spark.sql.defaultCatalog", "glue_catalog") \
    .getOrCreate()
```

 关键配置：
+  `spark.sql.catalog.glue_catalog`：注册一个名为“glue\_catalog”的目录，该目录使用 GlueCatalog 实现 
+  `spark.sql.catalog.glue_catalog.glue.lakeformation-enabled`：为此目录显式启用 AWS Lake Formation 集成 
+  目录名称（在此例中为“glue\_catalog”）可以自定义，但在两个配置设置中必须一致 

#### Hive
<a name="security-access-control-fta-hive"></a>

```
‐‐conf spark.hadoop.fs.s3.credentialsResolverClass=com.amazonaws.AWS Glue.accesscontrol.AWSLakeFormationCredentialResolver
--conf spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true 
--conf spark.hadoop.fs.s3.folderObject.autoAction.disabled=true
--conf spark.sql.catalog.skipLocationValidationOnCreateTable.enabled=true
--conf spark.sql.catalog.createDirectoryAfterTable.enabled=true
--conf spark.sql.catalog.dropDirectoryBeforeTable.enabled=true
```

#### Iceberg
<a name="security-access-control-fta-iceberg"></a>

```
--conf spark.hadoop.fs.s3.credentialsResolverClass=com.amazonaws.AWS Glue.accesscontrol.AWSLakeFormationCredentialResolver
--conf spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true 
--conf spark.hadoop.fs.s3.folderObject.autoAction.disabled=true
--conf spark.sql.catalog.skipLocationValidationOnCreateTable.enabled=true
--conf spark.sql.catalog.createDirectoryAfterTable.enabled=true
--conf spark.sql.catalog.dropDirectoryBeforeTable.enabled=true
--conf spark.sql.catalog.<catalog>.AWS Glue.lakeformation-enabled=true
```
+  `spark.hadoop.fs.s3.credentialsResolverClass=com.amazonaws.AWS Glue.accesscontrol.AWSLakeFormationCredentialResolver`：配置 EMR 文件系统（EMRFS）以将 AWS Lake Formation S3 凭证用于注册到 AWS Lake Formation 的表。如果表未注册，请使用作业的运行时角色凭证。
+ `spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true` 和 `spark.hadoop.fs.s3.folderObject.autoAction.disabled=true`：在创建 S3 文件夹时，将 EMRFS 配置为使用内容类型标头应用程序/x 目录，而不是 $folder$ 后缀。这在读取 AWS Lake Formation 表时为必需，因为 AWS Lake Formation 凭证不允许读取带有 $folder$ 后缀的表文件夹。
+  `spark.sql.catalog.skipLocationValidationOnCreateTable.enabled=true`：将 Spark 配置为在创建表之前跳过空表位置验证。这对于注册到 AWS Lake Formation 的表是必需的，因为只有在创建 AWS Glue Data Catalog 表之后，用于验证空位置的 AWS Lake Formation 凭证才会可用。如果未启用此配置，则作业的运行时角色凭证将会验证空表位置。
+  `spark.sql.catalog.createDirectoryAfterTable.enabled=true`：将 Spark 配置为在 Hive 元数据存储中创建表后再创建 Amazon S3 文件夹。这对于注册到 AWS Lake Formation 的表为必需，因为只有在创建 AWS Glue Data Catalog 表之后，用于创建 Amazon S3 文件夹的 AWS Lake Formation 凭证才会可用。
+  `spark.sql.catalog.dropDirectoryBeforeTable.enabled=true`：将 Spark 配置为在 Hive 元数据存储中删除表之前删除 Amazon S3 文件夹。这对于注册到 AWS Lake Formation 的表是必需的，因为在从 AWS Glue Data Catalog 删除表之后，用于删除 S3 文件夹的 AWS Lake Formation 凭证将不可用。
+  `spark.sql.catalog.<catalog>.AWS Glue.lakeformation-enabled=true`：将 Iceberg 目录配置为将 AWS Lake Formation Amazon S3 凭证用于注册到 AWS Lake Formation 的表。如果表未注册，则会使用默认环境凭证。

## 使用模式
<a name="security-access-control-fta-usage"></a>

### 将 FTA 与 DataFrames 结合使用
<a name="using-fta-with-dataframes"></a>

熟悉 Spark 的用户可以将 DataFrames 与 AWS Lake Formation 全表访问模式结合使用。

AWS Glue 5.0 增加了对 Lake Formation 全表访问模式的原生 Spark 支持，从而简化了处理受保护表的方式。借助此功能，AWS Glue 5.0 AWS Glue Spark 作业可在获得全表访问权限后直接读取和写入数据，从而消除了以前会限制某些提取、转换、加载（ETL）操作的限制。现在，您可以将各种高级 Spark 功能用于 AWS Lake Formation 表，包括弹性分布式数据集（RDD）、自定义库和用户定义函数（UDF）等。

#### AWS Glue 5.0 中的原生 Spark FTA
<a name="native-spark-fta"></a>

AWS Glue 5.0 支持 Apache Spark 中的全表访问（FTA）控制模式，具体取决于您在 AWS Lake Formation 中定义的策略。这种控制级别非常适合需要在表级别遵守安全法规的使用案例。

#### Apache Iceberg 表示例
<a name="implementation"></a>

```
from pyspark.sql import SparkSession

catalog_name = "spark_catalog"
aws_region = "us-east-1"
aws_account_id = "123456789012"
warehouse_path = "s3://amzn-s3-demo-bucket/warehouse/"

spark = SparkSession.builder \
    .config("spark.sql.extensions","org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") \
    .config(f"spark.sql.catalog.{catalog_name}", "org.apache.iceberg.spark.SparkSessionCatalog") \
    .config(f"spark.sql.catalog.{catalog_name}.warehouse", f"{warehouse_path}") \
    .config(f"spark.sql.catalog.{catalog_name}.client.region",f"{aws_region}") \
    .config(f"spark.sql.catalog.{catalog_name}.glue.account-id",f"{aws_account_id}") \
    .config(f"spark.sql.catalog.{catalog_name}.glue.lakeformation-enabled","true") \
    .config(f"spark.sql.catalog.dropDirectoryBeforeTable.enabled", "true") \
    .config(f"spark.sql.catalog.{catalog_name}.catalog-impl", "org.apache.iceberg.aws.glue.GlueCatalog") \
    .config(f"spark.sql.catalog.{catalog_name}.io-impl", "org.apache.iceberg.aws.s3.S3FileIO") \
    .config("spark.sql.defaultCatalog", catalog_name) \  # Add this line
    .getOrCreate()

database_name = "your_database"
table_name = "your_table"

df = spark.sql(f"select * from {database_name}.{table_name}")
df.show()
```

#### 必需的 IAM 权限
<a name="required-iam-permissions"></a>

您的 AWS Glue 作业执行角色必须具有以下权限：

```
{
    "Action": "lakeformation:GetDataAccess",
    "Resource": "*",
    "Effect": "Allow"
}
```

以及您的数据位置相应的 S3 访问权限。

#### Lake Formation 配置
<a name="lake-formation-configuration"></a>

使用 AWS Glue 5.0 中的原生 Spark FTA 之前：

1. 允许第三方查询引擎无需在 AWS Lake Formation 中验证 IAM 会话标签即可访问数据

1. 通过 AWS Lake Formation 控制台向 AWS Glue 作业执行角色授予相应的表权限

1. 使用上例中所示的必需参数配置 Spark 会话

### 将 FTA 与 DynamicFrames 结合使用
<a name="using-fta-with-dynamicframes-section"></a>

 AWS Glue 的原生 DynamicFrames 可以与 AWS Lake Formation 全表访问结合使用，从而优化 ETL 操作。全表访问（FTA）是一种在表级别授予权限的安全模式，由于没有行级和列级权限检查的开销，因此数据处理速度比精细访问控制（FGAC）模式更快。需要处理完整的表并且表级权限能够满足安全要求时，这种方法将非常实用。

 在 AWS Glue 4.0 中将 DynamicFrames 与 FTA 结合使用时，将需要特定的 GlueContext 配置。虽然现有用于 FTA 的 AWS Glue 4.0 DynamicFrame 代码在 AWS Glue 5.0 中继续有效，不过新版本还提供了更灵活的原生 Spark FTA 支持。对于新的开发，建议考虑使用 DataFrames 部分中描述的原生 Spark 方法，尤其是在需要将额外的功能用于 AWS Lake Formation 表时，例如弹性分布式数据集（RDD）、自定义库和用户定义函数（UDF）等。

#### 所需权限
<a name="required-permissions"></a>

执行 Glue 作业的 IAM 角色必须具有下列权限：
+ `lakeformation:GetDataAccess` 许可
+ 通过 Lake Formation 控制台授予相应的 Lake Formation 表权限

#### AWS Glue 5.0 中的 DynamicFrame 实现示例
<a name="example-dynamicframe-implementation"></a>

```
from awsglue.context import GlueContext
from pyspark.context import SparkContext

# Initialize Glue context
sc = SparkContext()
glueContext = GlueContext(sc)

# Configure catalog for Iceberg tables
catalog_name = "glue_catalog"
aws_region = "us-east-1"
aws_account_id = "123456789012"
warehouse_path = "s3://amzn-s3-demo-bucket/warehouse/"

spark = glueContext.spark_session
spark.conf.set(f"spark.sql.catalog.{catalog_name}", "org.apache.iceberg.spark.SparkCatalog")
spark.conf.set(f"spark.sql.catalog.{catalog_name}.warehouse", f"{warehouse_path}")
spark.conf.set(f"spark.sql.catalog.{catalog_name}.catalog-impl", "org.apache.iceberg.aws.glue.GlueCatalog")
spark.conf.set(f"spark.sql.catalog.{catalog_name}.io-impl", "org.apache.iceberg.aws.s3.S3FileIO")
spark.conf.set(f"spark.sql.catalog.{catalog_name}.glue.lakeformation-enabled","true")
spark.conf.set(f"spark.sql.catalog.{catalog_name}.client.region",f"{aws_region}")
spark.conf.set(f"spark.sql.catalog.{catalog_name}.glue.id", f"{aws_account_id}")

# Read Lake Formation-protected table with DynamicFrame
df = glueContext.create_data_frame.from_catalog(
    database="your_database",
    table_name="your_table"
)
```

## 其他配置
<a name="security-access-control-fta-additional-config"></a>

### 在 AWS Glue Studio 笔记本中配置全表访问模式
<a name="security-access-control-fta-notebooks"></a>

要在 AWS Glue Studio 笔记本中通过交互式 Spark 会话访问注册到 AWS Lake Formation 的表，必须使用兼容性权限模式。在启动交互式会话之前，使用 `%%configure` magic 命令设置 Spark 配置。此配置必须是笔记本中的第一个命令，因为该命令无法在会话启动后应用。根据表类型选择配置：

#### 对于 Hive 表
<a name="w2aac88c20b7c21b3b5"></a>

```
%%configure
--conf spark.hadoop.fs.s3.credentialsResolverClass=com.amazonaws.glue.accesscontrol.AWSLakeFormationCredentialResolver
--conf spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true
--conf spark.hadoop.fs.s3.folderObject.autoAction.disabled=true
--conf spark.sql.catalog.skipLocationValidationOnCreateTable.enabled=true
--conf spark.sql.catalog.createDirectoryAfterTable.enabled=true
--conf spark.sql.catalog.dropDirectoryBeforeTable.enabled=true
```

#### 对于 Iceberg 表
<a name="w2aac88c20b7c21b3b7"></a>

```
%%configure
--conf spark.hadoop.fs.s3.credentialsResolverClass=com.amazonaws.glue.accesscontrol.AWSLakeFormationCredentialResolver
--conf spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true
--conf spark.hadoop.fs.s3.folderObject.autoAction.disabled=true
--conf spark.sql.catalog.skipLocationValidationOnCreateTable.enabled=true
--conf spark.sql.catalog.createDirectoryAfterTable.enabled=true
--conf spark.sql.catalog.dropDirectoryBeforeTable.enabled=true
--conf spark.sql.catalog.glue_catalog.glue.lakeformation-enabled=true
--conf spark.sql.catalog.glue_catalog.warehouse=s3://example-s3-bucket_DATA_LOCATION
--conf spark.sql.catalog.glue_catalog.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog
--conf spark.sql.catalog.glue_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO
--conf spark.sql.catalog.glue_catalog.glue.account-id=ACCOUNT_ID
--conf spark.sql.catalog.glue_catalog.glue.region=REGION
```

替换占位符：
+  S3\_DATA\_LOCATION：{{s3://amzn-s3-demo-bucket}} 
+  REGION：{{AWS 区域（例如 us-east-1）}} 
+  ACCOUNT\_ID：{{您的 AWS 账户 ID}} 

**注意**  
必须在笔记本中执行任何 Spark 操作之前设置这些配置。

### 支持的操作
<a name="security-access-control-fta-supported-operations"></a>

这些操作将使用 AWS Lake Formation 凭证来访问表数据。

**注意**  
 启用 AWS Lake Formation 时：  
 对于 FTA：启用 Spark 配置 `spark.sql.catalog.{catalog_name}.glue.lakeformation-enabled` 
+ CREATE TABLE
+ ALTER TABLE
+ INSERT INTO
+  INSERT OVERWRITE 
+ SELECT
+ UPDATE
+ MERGE INTO
+ DELETE FROM
+ ANALYZE TABLE
+ REPAIR TABLE
+ DROP TABLE
+ Spark Datasource 查询
+ Spark Datasource 写入

**注意**  
上面未列出的操作将继续使用 IAM 权限来访问表数据。

## 从 AWS Glue 4.0 迁移到 AWS Glue 5.0 FTA
<a name="security-access-control-fta-migration"></a>

从 AWS Glue 4.0 GlueContext FTA 迁移到 AWS Glue 5.0 原生 Spark FTA 时：

1. 允许第三方查询引擎无需在 AWS Lake Formation 中验证 IAM 会话标签即可访问数据。按照[第 1 步：在 AWS Lake Formation 中启用全表访问](#security-access-control-fta-step-1)中的说明操作。

1. 不需要更改作业运行时角色。但需要验证 AWS Glue 作业执行角色是否具有 lakeformation:GetDataAccess IAM 权限。

1. 修改脚本中的 Spark 会话配置。确保存在以下 Spark 配置：

   ```
   --conf spark.sql.catalog.spark_catalog=org.apache.iceberg.spark.SparkSessionCatalog
   --conf spark.sql.catalog.spark_catalog.warehouse=s3://<bucket-name>/warehouse/
   --conf spark.sql.catalog.spark_catalog.client.region=<REGION>
   --conf spark.sql.catalog.spark_catalog.glue.account-id=ACCOUNT_ID
   --conf spark.sql.catalog.spark_catalog.glue.lakeformation-enabled=true
   --conf spark.sql.catalog.dropDirectoryBeforeTable.enabled=true
   ```

1. 更新脚本，确保将 GlueContext DataFrames 更改为原生 Spark DataFrames。

1. 将 AWS Glue 作业更新为使用 AWS Glue 5.0

## 注意事项和限制
<a name="security-access-control-fta-considerations-limitations"></a>
+ 如果使用未启用全表访问的作业创建 Hive 表，并且未插入任何记录，则后续从启用全表访问的作业进行的读取或写入操作都将失败。这是因为未启用全表访问的 AWS Glue Spark 会将 $folder$ 后缀添加到表文件夹名称。要解决此问题，您可以使用以下任一方法：
  +  从未启用 FTA 的作业在表中至少插入一行。
  +  配置未启用 FTA 的作业，从而确保不在 S3 文件夹名称中使用 $folder$ 后缀。可以通过设置 Spark 配置 `spark.hadoop.fs.s3.useDirectoryHeaderAsFolderObject=true` 来实现此目的。
  +  使用 Amazon S3 控制台或 Amazon S3 CLI 在表位置 `s3://path/to/table/table_name` 创建一个 Amazon S3 文件夹。
+ 全表访问模式仅适用于 EMR 文件系统（EMRFS），不兼容 S3A 文件系统。
+  全表访问模式支持 Hive 和 Iceberg 表。尚未增加对 Hudi 和 Delta 表的支持。
+ 使用 AWS Lake Formation 精细访问控制（FGAC）规则或 AWS Glue Data Catalog 视图引用表的作业将会失败。要使用 FGAC 规则或 AWS Glue Data Catalog 视图查询表，需要使用 FGAC 模式。您可以按照以下 AWS 文档中介绍的步骤启用 FGAC 模式：将 AWS Glue 与 AWS Lake Formation 结合使用实现精细访问控制。
+  全表访问模式不支持 Spark Streaming。
+ 不能与 FGAC 同时使用。