在 EMR Serverless 中使用 Secrets Manager 保护数据 - Amazon EMR

在 EMR Serverless 中使用 Secrets Manager 保护数据

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 用户指南》中的密钥加密和解密

此外,您还可以配置 Secrets Manager 以根据指定的计划自动轮换密钥。这使您能够将长期密钥替换为短期密钥,这有助于显著减少泄露风险。有关更多信息,请参阅 AWS Secrets Manager用户指南中的轮换 AWS Secrets Manager 密钥

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

EMR Serverless 如何使用密钥

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

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

如何创建密钥

要创建密钥,请遵循《AWS Secrets Manager 用户指南》创建 AWS Secrets Manager 密钥的说明。在步骤 3 中,选择明文字段,输入敏感值。

在配置分类中提供密钥

以下示例展示了如何在 StartJobRun 的配置分类中提供密钥。如果要在应用程序级别配置 Secrets Manager 的分类,请参阅 EMR Serverless 的默认应用程序配置

在示例中,将 SecretName 替换为要检索的密钥名称。包括连字符,后跟 Secrets Manager 添加到密钥 ARN 末尾的 6 个字符。有关更多信息,请参阅 如何创建密钥

指定密钥引用 Spark

例 在 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/" } } }'
例 在 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

例 在 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" } } }'
例 在 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 检索密钥的访问权限

要允许 EMR Serverless 从 Secrets Manager 检索密钥值,请在创建密钥时将以下策略语句添加到密钥中。您必须使用客户托管的 KMS 密钥创建自己的密钥,EMR Serverless 才能读取密钥值。有关更多信息,请参阅《AWS Secrets Manager 用户指南》中的 KMS 密钥的权限

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

密钥的资源策略

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

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret" ], "Principal": { "Service": [ "emr-serverless.amazonaws.com" ] }, "Resource": [ "*" ], "Condition": { "StringEquals": { "aws:SourceArn": "arn:aws:emr-serverless:AWS 区域:aws_account_id:/applications/applicationId" } } } ] }

使用以下策略为客户管理型 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" } } }

轮换密钥

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

注意

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