

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 EMR Serverless 中使用 Secrets Manager 保护数据
<a name="secrets-manager"></a>

AWS Secrets Manager 是一项秘密存储服务，用于保护数据库凭证、API 密钥和其他机密信息。然后，在您的代码中，将硬编码的凭证替换为对 Secrets Manager 的 API 调用。这有助于确保别人在检查您的代码时不会泄露密钥，因为代码中没有密钥。有关概述，请参阅 [AWS Secrets Manager 用户指南](https://docs.aws.amazon.com/secretsmanager/latest/userguide)。

Secrets Manager 使用密 AWS Key Management Service 钥对机密进行加密。有关更多信息，请参阅《AWS Secrets Manager 用户指南》**中的[密钥加密和解密](https://docs.aws.amazon.com/secretsmanager/latest/userguide/security-encryption.html)。

此外，您还可以配置 Secrets Manager 以根据指定的计划自动轮换密钥。这使您能够将长期密钥替换为短期密钥，这有助于显著减少泄露风险。有关更多信息，请参阅《AWS Secrets Manager 用户指南》**中的[轮换 AWS Secrets Manager 密钥](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html)。

Amazon EMR Serverless 与集成， AWS Secrets Manager 因此您可以将数据存储在 Secrets Manager 中，并在配置中使用密钥 ID。

## EMR Serverless 如何使用密钥
<a name="secrets-manager-how"></a>

当您将数据存储在 Secrets Manager 中并在您的 EMR Serverless 配置中使用密钥 ID 时，您不会以纯文本形式将敏感配置数据传递给 EMR Serverless，也不会将其暴露给外部。 APIs如果您指示键值对包含您存储在 Secrets Manager 中的密钥 ID，EMR Serverless 会在将配置数据发送给运行作业的工作线程时检索该密钥。

要指示配置的键值对包含对 Secrets Manager 中存储的密钥的引用，请在配置值中添加 `EMR.secret@` 注释。对于带有密钥 ID 注释的任何配置属性，EMR Serverless 会调用 Secrets Manager 并在作业执行时解析密钥。

## 如何创建密钥
<a name="secrets-manager-create"></a>

要创建密钥，请按照《*AWS Secrets Manager 用户指南》*中[创建 AWS Secrets Manager 密钥](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)中的步骤进行操作。在**步骤 3** 中，选择**明文**字段，输入敏感值。

## 在配置分类中提供密钥
<a name="secrets-manager-examples"></a>

以下示例展示了如何在 `StartJobRun` 的配置分类中提供密钥。如果要在应用程序级别配置 Secrets Manager 的分类，请参阅[EMR Serverless 的默认应用程序配置](default-configs.md)。

在示例中，将 `SecretName` 替换为要检索的密钥名称。有关更多信息，请参阅[如何创建密钥](#secrets-manager-create)。

**Topics**
+ [指定密钥引用 Spark](#secrets-manager-examples-spark)
+ [指定密钥引用 Hive](#secrets-manager-examples-hive)

### 指定密钥引用 Spark
<a name="secrets-manager-examples-spark"></a>

**Example 在 Spark 的外部 Hive 元存储配置中指定密钥引用**  

```
aws emr-serverless start-job-run \
  --application-id "application-id" \
  --execution-role-arn "job-role-arn" \
  --job-driver '{
        "sparkSubmit": {
            "entryPoint": "s3://amzn-s3-demo-bucket/scripts/spark-jdbc.py",
            "sparkSubmitParameters": "--jars s3://amzn-s3-demo-bucket/mariadb-connector-java.jar 
            --conf spark.hadoop.javax.jdo.option.ConnectionDriverName=org.mariadb.jdbc.Driver 
            --conf spark.hadoop.javax.jdo.option.ConnectionUserName=connection-user-name 
            --conf spark.hadoop.javax.jdo.option.ConnectionPassword=EMR.secret@SecretName
            --conf spark.hadoop.javax.jdo.option.ConnectionURL=jdbc:mysql://db-host:db-port/db-name 
            --conf spark.driver.cores=2
            --conf spark.executor.memory=10G 
            --conf spark.driver.memory=6G 
            --conf spark.executor.cores=4"
        }
    }' \
    --configuration-overrides '{
        "monitoringConfiguration": {
        "s3MonitoringConfiguration": {
            "logUri": "s3://amzn-s3-demo-bucket/spark/logs/"
        }
    }
}'
```

**Example 在 `spark-defaults` 分类中指定外部 Hive 元存储配置的密钥引用**  

```
{
        "classification": "spark-defaults",
        "properties": {
            "spark.hadoop.javax.jdo.option.ConnectionDriverName":"org.mariadb.jdbc.Driver"
            "spark.hadoop.javax.jdo.option.ConnectionURL":"jdbc:mysql://db-host:db-port/db-name"
            "spark.hadoop.javax.jdo.option.ConnectionUserName":"connection-user-name"  
            "spark.hadoop.javax.jdo.option.ConnectionPassword": "EMR.secret@SecretName",
        }
    }
```

### 指定密钥引用 Hive
<a name="secrets-manager-examples-hive"></a>

**Example 在 Hive 的外部 Hive 元存储配置中指定密钥引用**  

```
aws emr-serverless start-job-run \
  --application-id "application-id" \
  --execution-role-arn "job-role-arn" \
    --job-driver '{
        "hive": {
        "query": "s3://amzn-s3-demo-bucket/emr-serverless-hive/query/hive-query.ql",
        "parameters": "--hiveconf hive.exec.scratchdir=s3://amzn-s3-demo-bucket/emr-serverless-hive/hive/scratch 
                    --hiveconf hive.metastore.warehouse.dir=s3://amzn-s3-demo-bucket/emr-serverless-hive/hive/warehouse  
                    --hiveconf javax.jdo.option.ConnectionUserName=username
                    --hiveconf javax.jdo.option.ConnectionPassword=EMR.secret@SecretName 
                    --hiveconf hive.metastore.client.factory.class=org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClientFactory 
                    --hiveconf javax.jdo.option.ConnectionDriverName=org.mariadb.jdbc.Driver 
                    --hiveconf javax.jdo.option.ConnectionURL=jdbc:mysql://db-host:db-port/db-name"
        }
    }' \
    --configuration-overrides '{
        "monitoringConfiguration": {
        "s3MonitoringConfiguration": {
            "logUri": "s3://amzn-s3-demo-bucket"
        }
    }
}'
```

**Example 在 `hive-site` 分类中指定外部 Hive 元存储配置的密钥引用**  

```
{
    "classification": "hive-site",
    "properties": {
        "hive.metastore.client.factory.class": "org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClientFactory",
        "javax.jdo.option.ConnectionDriverName": "org.mariadb.jdbc.Driver",
        "javax.jdo.option.ConnectionURL": "jdbc:mysql://db-host:db-port/db-name",
        "javax.jdo.option.ConnectionUserName": "username",
        "javax.jdo.option.ConnectionPassword": "EMR.secret@SecretName"
    }
}
```

## 授予 Amazon EMR 检索密钥的访问权限
<a name="secrets-manager-permission"></a>

要允许 EMR Serverless 从 Secrets Manager 检索密钥值，请在创建密钥时将以下策略语句添加到密钥中。您必须使用客户托管的 KMS 密钥创建自己的密钥，EMR Serverless 才能读取密钥值。有关更多信息，请参阅《AWS Secrets Manager 用户指南》**中的 [KMS 密钥的权限](https://docs.aws.amazon.com/secretsmanager/latest/userguide/security-encryption.html#security-encryption-authz)。

在以下策略中，将 `applicationId` 替换为应用程序 ID。

**密钥的资源策略**

您必须在 AWS Secrets Manager 中密钥的资源策略中包含以下权限，以允许 EMR Serverless 检索密钥值。为确保只有特定应用程序才能检索此密钥，您可以选择在策略中指定 EMR Serverless 应用程序 ID 作为条件。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret"
      ],
      "Resource": [
        "*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": "arn:aws:emr-serverless:*:123456789012:/applications/*"
        }
      },
      "Sid": "AllowSECRETSMANAGERGetsecretvalue"
    }
  ]
}
```

------

使用以下客户托管 AWS Key Management Service (AWS KMS) 密钥策略创建您的密钥：

**客户管理的密钥 AWS KMS 政策**

```
{
    "Sid": "Allow EMR Serverless to use the key for decrypting secrets",
    "Effect": "Allow",
    "Principal": {
        "Service": [
            "emr-serverless.amazonaws.com"
        ]
    },
    "Action": [
        "kms:Decrypt",
        "kms:DescribeKey"
    ],
    "Resource": "*",
    "Condition": {
        "StringEquals": {
            "kms:ViaService": "secretsmanager.AWS 区域.amazonaws.com"
        }
    }
}
```

## 轮换密钥
<a name="secrets-manager-rotate"></a>

*轮换*是指定期更新密钥。您可以将 AWS Secrets Manager 配置为按照您指定的计划自动轮换密钥。这样，您可以将长期密钥替换为短期密钥。这有助于降低泄露的风险。当作业变为运行状态时，EMR Serverless 会从注释的配置中检索密钥值。如果您或某个进程更新了 Secrets Manager 中的密钥值，则必须提交新作业，这样作业才能获取更新的值。

**注意**  
已处于运行状态的作业无法获取更新的密钥值。这可能会导致作业失败。