通过SSM执行Assume Role时遇配置文件不存在错误的技术求助
通过SSM执行AWS CLI命令提示配置文件不存在的问题
问题场景
通过Lambda调用SSM向EC2实例发送命令,因EC2实例配置文件角色权限不足,尝试在SSM命令中执行aws sts assume-role并指定--profile test,但收到错误:
"StandardErrorContent": "\nThe config profile (test) could not be found\nfailed to run commands: exit status 255"
已确认EC2实例上test配置文件确实存在,且SSH登录实例后可正常使用该配置文件切换角色。
相关代码:
def lambda_handler(event,context): ssm_client = boto3.client('ssm') response = ssm_client.send_command( InstanceIds=['i-xxxxxxxxx'], DocumentName="AWS-RunShellScript", Parameters={'commands': ['aws sts assume-role --role-arn arn:aws:iam::xxxxxxxxx:role/myrole --role-session-name "RoleSession1" --profile test> assume-role-output.txt' ]} ) time.sleep(2) command_id = response['Command']['CommandId'] output = ssm_client.get_command_invocation( CommandId=command_id, InstanceId='i-xxxxxxxxxx', ) return output
问题原因
SSM Run Command执行命令的环境与SSH登录后的用户环境不同:
- SSM默认以
ssm-user或系统用户身份执行命令,不会加载普通用户(如ec2-user)的AWS配置文件(通常存放在~/.aws/config或~/.aws/credentials) - 即使配置文件存在,SSM执行上下文的环境变量未指向配置文件路径,导致AWS CLI找不到指定的
test配置文件
解决方案
方案1:指定配置文件路径(适用于必须使用EC2本地配置文件的场景)
在SSM命令中显式指定配置文件的绝对路径,或者先设置环境变量指向配置文件:
# 方式1:直接指定配置文件路径 aws s3 ls --profile test --config-file /home/ec2-user/.aws/config --credentials-file /home/ec2-user/.aws/credentials # 方式2:先设置环境变量再执行命令 export AWS_CONFIG_FILE=/home/ec2-user/.aws/config && export AWS_SHARED_CREDENTIALS_FILE=/home/ec2-user/.aws/credentials && aws s3 ls --profile test
方案2:Lambda中先获取临时凭证再传给SSM(更优)
避免依赖EC2本地配置文件,直接在Lambda中调用sts:AssumeRole获取临时凭证,再将凭证通过环境变量传入SSM命令:
import boto3 import time def lambda_handler(event, context): # Lambda中切换角色获取临时凭证 sts_client = boto3.client('sts') assumed_role_resp = sts_client.assume_role( RoleArn='arn:aws:iam::xxxxxxxxx:role/myrole', RoleSessionName='RoleSession1' ) temp_creds = assumed_role_resp['Credentials'] # 构造包含临时凭证的命令列表 commands = [ f"export AWS_ACCESS_KEY_ID={temp_creds['AccessKeyId']}", f"export AWS_SECRET_ACCESS_KEY={temp_creds['SecretAccessKey']}", f"export AWS_SESSION_TOKEN={temp_creds['SessionToken']}", "aws s3 ls" # 替换为实际需要执行的AWS命令 ] ssm_client = boto3.client('ssm') response = ssm_client.send_command( InstanceIds=['i-xxxxxxxxx'], DocumentName="AWS-RunShellScript", Parameters={'commands': commands} ) time.sleep(2) command_id = response['Command']['CommandId'] output = ssm_client.get_command_invocation( CommandId=command_id, InstanceId='i-xxxxxxxxx', ) return output
注意事项
- 不要在SSM命令中直接执行
aws sts assume-role,建议直接在需要权限的AWS命令中通过--profile指定配置文件,或使用临时凭证方式 - 若使用方案2,需确保Lambda的执行角色拥有
sts:AssumeRole权限,目标角色(myrole)的信任策略允许Lambda角色进行assume操作
内容的提问来源于stack exchange,提问作者south153
相关产品推荐
相关产品推荐

