AWS Glue与IAM条件访问:如何配置IAM策略仅允许指定Glue作业执行EC2实例启动操作
你提到的这个问题确实戳中了AWS Glue当前的一个权限控制痛点——目前Glue确实没有提供类似Lambda的lambda:SourceFunctionArn这样的原生IAM条件键,用来直接识别触发API请求的具体Glue作业。不过不用担心,我们有几个可行的 workaround 可以实现你的需求,而且不需要修改Glue作业的执行角色本身:
方案1:通过临时会话标签实现细粒度控制
这个方法的核心思路是让目标Glue作业在调用EC2 API前,给自己的执行会话打上专属标签,然后在IAM策略中校验这个标签:
给Glue执行角色添加打标签权限
首先需要给现有Glue执行角色添加允许给自己的会话打标签的权限,策略示例如下:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:TagSession", "Resource": "*" } ] }修改Glue作业代码添加会话标签
在Glue作业的代码中,调用EC2StartInstancesAPI之前,先通过AWS SDK给自己的会话打上标识作业的标签。以Python为例:import boto3 # 初始化IAM客户端并添加会话标签 iam_client = boto3.client('iam') iam_client.tag_session( Tags=[ { "Key": "glue-job-identifier", "Value": "some_glue_job_name" } ] ) # 随后执行EC2实例启动操作 ec2_client = boto3.client('ec2') ec2_client.start_instances(InstanceIds=["some_instance_id"])更新EC2启动权限的IAM策略
现在可以在允许ec2:StartInstances的策略中,添加会话标签的校验条件:{ "Version": "2012-10-17", "Statement": [ { "Action": "ec2:StartInstances", "Condition": { "StringEquals": { "aws:PrincipalTag/glue-job-identifier": "some_glue_job_name" } }, "Effect": "Allow", "Resource": "arn:aws:ec2:your-region:your-account-id:instance/some_instance_id" } ] }
方案2:通过中间Lambda封装权限验证
如果修改Glue作业代码不太方便,你可以把EC2启动操作封装到Lambda函数中,通过Lambda来校验请求是否来自指定的Glue作业:
创建处理EC2启动的Lambda函数
Lambda代码会先校验请求中携带的作业名称,确认无误后再执行启动操作。示例Python代码:import boto3 ec2_client = boto3.client('ec2') TARGET_JOB_NAME = "some_glue_job_name" TARGET_INSTANCE_ID = "some_instance_id" def lambda_handler(event, context): # 从请求参数中获取Glue作业名称 incoming_job_name = event.get("glue_job_name") if incoming_job_name != TARGET_JOB_NAME: return {"statusCode": 403, "body": "仅允许指定Glue作业调用此接口"} # 执行EC2实例启动 ec2_client.start_instances(InstanceIds=[TARGET_INSTANCE_ID]) return {"statusCode": 200, "body": "实例启动成功"}配置Lambda的IAM权限
给Lambda的执行角色添加启动指定EC2实例的权限:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ec2:StartInstances", "Resource": "arn:aws:ec2:your-region:your-account-id:instance/some_instance_id" } ] }允许Glue执行角色调用该Lambda
给现有Glue执行角色添加调用目标Lambda的权限:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:your-region:your-account-id:function:your-lambda-function-name" } ] }修改Glue作业代码调用Lambda
在Glue作业中调用Lambda时,传递自身的作业名称作为参数:import boto3 lambda_client = boto3.client('lambda') lambda_client.invoke( FunctionName="your-lambda-function-name", Payload='{"glue_job_name": "some_glue_job_name"}' )
补充说明
目前AWS Glue确实没有在IAM请求上下文中注入触发请求的作业ARN,所以无法直接通过原生条件键实现你的需求。这些 workaround 都是基于现有AWS服务能力的变通方案,如果你希望AWS官方支持类似的条件键,可以通过AWS控制台的反馈渠道提交功能请求。
内容来源于stack exchange

