如何在Lambda函数中获取EC2实例IAM角色凭证?
Lambda获取EC2实例关联IAM角色临时凭证的解决方案
为什么你在Lambda里拿不到EC2的元数据?
Lambda环境里的http://169.254.169.254是Lambda自身的元数据端点,返回的是Lambda执行角色的凭证,并非目标EC2实例的关联角色凭证——这就是你调用失败的核心原因。
正确实现步骤
1. 配置Lambda执行角色权限
Lambda要获取EC2角色的临时凭证,需要两个关键权限:
ec2:DescribeInstances:用于查询目标EC2实例绑定的IAM角色信息sts:AssumeRole:用于扮演该EC2角色,获取临时访问凭证
给Lambda的执行角色添加以下IAM策略片段:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ec2:DescribeInstances", "Resource": "*" }, { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::你的AWS账号ID:role/EC2实例绑定的IAM角色名称" } ] }
2. 用boto3编写Lambda代码
分两步实现凭证获取:先查询EC2实例的关联角色,再通过STS服务扮演该角色拿到临时凭证。示例Python代码如下:
import boto3 def lambda_handler(event, context): # 初始化AWS客户端 ec2_client = boto3.client('ec2') sts_client = boto3.client('sts') # 替换为你的目标EC2实例ID target_instance_id = "i-0abc123def456ghi" # 步骤1:获取EC2实例绑定的IAM角色ARN ec2_response = ec2_client.describe_instances(InstanceIds=[target_instance_id]) instance_profile_arn = ec2_response['Reservations'][0]['Instances'][0]['IamInstanceProfile']['Arn'] # 从实例配置文件ARN转换为角色ARN(实例配置文件与角色名称一致,仅路径不同) role_arn = instance_profile_arn.replace('/instance-profile/', '/role/') # 步骤2:扮演角色获取临时凭证 sts_response = sts_client.assume_role( RoleArn=role_arn, RoleSessionName="Lambda-Fetch-EC2-Role-Creds", DurationSeconds=3600 # 最长可设为角色允许的最大会话时长,默认1小时 ) # 提取凭证信息 credentials = sts_response['Credentials'] access_key_id = credentials['AccessKeyId'] secret_access_key = credentials['SecretAccessKey'] session_token = credentials['SessionToken'] expiration_time = credentials['Expiration'] # 这里添加更新ServiceNow密钥管理器的逻辑 update_servicenow_credentials(access_key_id, secret_access_key, session_token, expiration_time) return { 'statusCode': 200, 'body': f"凭证已更新,过期时间:{expiration_time}" } def update_servicenow_credentials(access_key, secret_key, session_token, expiration): # 替换为你实际的ServiceNow密钥更新API调用逻辑 pass
3. 优化自动刷新逻辑
给Lambda配置CloudWatch定时触发(比如每天执行一次,或在凭证过期前1小时执行),实现凭证的自动更新,完全替代手动轮换操作。
简化方案:直接让Lambda扮演目标角色
如果无需依赖EC2实例的存在,可跳过查询EC2的步骤,直接让Lambda扮演供外部应用使用的IAM角色——只要Lambda执行角色拥有sts:AssumeRole权限访问该角色即可,代码会更简洁。
内容的提问来源于stack exchange,提问作者K P
相关产品推荐
相关产品推荐

