如何在AWS Lambda中获取调用该函数的IAM角色的标签?
是否可以在Lambda函数内获取调用它的IAM角色的标签信息?
可行,具体实现分两种场景,根据是否能修改调用方的代码来选择:
场景1:可以修改调用方的代码(最简单直接)
这种方法不需要额外的日志或追踪服务,直接让调用角色在调用Lambda时传递自身的ARN:
给Lambda执行角色添加权限
创建一个自定义IAM策略,允许Lambda调用iam:GetRoleTags操作,资源指定为那10个调用角色的ARN(限制范围更安全,避免过度授权):{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:GetRoleTags", "Resource": [ "arn:aws:iam::123456789012:role/CallerRole1", "arn:aws:iam::123456789012:role/CallerRole2", // 剩下8个角色的ARN ] } ] }将这个策略附加到Lambda绑定的IAM角色上。
调用方传递角色ARN
每个调用角色在调用Lambda时,将自身的ARN作为事件参数传入,比如使用AWS CLI调用:aws lambda invoke --function-name MyLambda --payload '{"caller_role_arn": "arn:aws:iam::123456789012:role/CallerRole1"}' output.json如果用Python的boto3 SDK:
import boto3 import os lambda_client = boto3.client('lambda') caller_role_arn = os.environ['AWS_ROLE_ARN'] # 获取当前角色的ARN response = lambda_client.invoke( FunctionName='MyLambda', Payload=b'{"caller_role_arn": "' + caller_role_arn.encode() + b'"}' )Lambda内部获取标签
在Lambda代码中(以Python为例),解析事件中的角色ARN,调用IAM API获取标签:import boto3 iam_client = boto3.client('iam') def lambda_handler(event, context): caller_role_arn = event.get('caller_role_arn') if not caller_role_arn: return {'statusCode': 400, 'body': 'Missing caller_role_arn parameter'} # 获取角色标签 response = iam_client.get_role_tags(RoleName=caller_role_arn.split('/')[-1]) tags = response['Tags'] return {'statusCode': 200, 'body': {'caller_role_tags': tags}}
场景2:无法修改调用方代码(无需调用方配合)
如果不能要求调用方传递参数,可以通过CloudWatch Logs获取调用者的ARN,再查询标签:
给Lambda执行角色添加权限
除了iam:GetRoleTags权限,还需要添加CloudWatch Logs的读取权限,允许获取Lambda日志组的事件:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:GetRoleTags", "Resource": [ "arn:aws:iam::123456789012:role/CallerRole1", // 其他9个角色ARN ] }, { "Effect": "Allow", "Action": [ "logs:GetLogEvents", "logs:DescribeLogStreams" ], "Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/MyLambda:*" } ] }Lambda内部获取调用者ARN并查询标签
以Python为例,Lambda代码先根据当前请求ID查询CloudWatch Logs,提取调用者ARN,再获取标签:import boto3 import re iam_client = boto3.client('iam') logs_client = boto3.client('logs') def get_caller_role_arn(context): log_group_name = f'/aws/lambda/{context.function_name}' # 获取最新的日志流 streams_response = logs_client.describe_log_streams( logGroupName=log_group_name, orderBy='LastEventTime', descending=True, limit=1 ) log_stream_name = streams_response['logStreams'][0]['logStreamName'] # 查询日志事件,查找包含InvokedBy的记录 events_response = logs_client.get_log_events( logGroupName=log_group_name, logStreamName=log_stream_name, startFromHead=False, limit=50 ) # 匹配调用者ARN的正则 pattern = r'InvokedBy: (arn:aws:iam::\d+:role/[\w-]+)' for event in events_response['events']: match = re.search(pattern, event['message']) if match and context.request_id in event['message']: return match.group(1) return None def lambda_handler(event, context): caller_role_arn = get_caller_role_arn(context) if not caller_role_arn: return {'statusCode': 404, 'body': 'Failed to retrieve caller role ARN'} # 获取标签 role_name = caller_role_arn.split('/')[-1] tags_response = iam_client.get_role_tags(RoleName=role_name) tags = tags_response['Tags'] return {'statusCode': 200, 'body': {'caller_role_tags': tags}}注意:这种方法依赖CloudWatch Logs的写入延迟,可能存在短时间内无法获取日志的情况,适合对实时性要求不高的场景。
内容的提问来源于stack exchange,提问作者Jimmy Chen
相关产品推荐
相关产品推荐

