Ansible编排EC2 Worker凭证失效及本地凭据未更新问题求助
我来帮你拆解这个问题,从凭证来源、实例角色使用逻辑两个角度来解释:
一、为什么Worker节点的~/.aws/credentials还留着旧凭证?
你在Master节点用STS临时凭证(assumed_role.sts_creds)通过Ansible创建Worker实例,但Master的凭证不会自动同步到Worker节点。你的Worker实例是基于指定镜像(image_instance)创建的,如果这个自定义镜像里预先打包了旧的~/.aws/credentials文件,那新实例启动后自然会继承这个旧文件。
另外,虽然你给Worker关联了ML-Ansible实例IAM角色,但AWS CLI的凭证优先级是:环境变量 > ~/.aws/credentials文件 > EC2实例角色元数据。所以只要Worker节点上存在旧的credentials文件,CLI就会优先用里面的过期凭证,而不会去用实例角色提供的有效临时凭证,这就是你遇到InvalidClientTokenId错误的核心原因。
二、IAM实例配置文件需要修改吗?
不需要动ML-Ansible角色本身——只要这个角色已经包含cloudwatch:PutMetricData的权限(你之前能正常运行的话应该是有的),问题不在角色权限,而在Worker节点的凭证使用逻辑上。
三、具体解决步骤
1. 清理自定义镜像里的旧凭证(治本方案)
如果你的Worker是用自定义AMI创建的,最好重新制作镜像:
- 启动一个临时实例,删除
~/.aws/credentials和~/.aws/config这两个文件 - 基于这个清理后的实例重新创建AMI,替换playbook里的
image_instance参数
2. 在Ansible playbook中添加清理步骤(临时/快速修复)
在创建完Worker实例后,通过Ansible远程删除每个Worker节点上的旧凭证文件:
- name: Clean up old AWS credentials on Worker nodes file: path: "/home/{{ ansible_user }}/.aws/credentials" state: absent delegate_to: "{{ item.private_ip }}" loop: "{{ ec2.instances }}" when: ec2.instances is defined
这样处理后,Worker节点的AWS CLI会自动通过EC2元数据服务获取ML-Ansible角色的临时凭证,不会再用旧文件里的无效凭证。
3. 验证实例角色的有效性
可以在任意一个Worker节点上手动执行以下命令,确认实例角色能正常工作:
# 获取实例角色的临时凭证(验证元数据服务是否正常返回) curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ML-Ansible # 测试CloudWatch调用(验证权限) aws cloudwatch put-metric-data --namespace "ML-Worker" --metric-name "TestMetric" --value 1
如果这两个命令都能正常执行(返回有效凭证+没有权限错误),就说明实例角色没问题。
4. 避免错误传递凭证
注意:不要在Ansible playbook里把Master节点的凭证复制到Worker节点——Worker的凭证应该完全依赖实例角色,这样既安全又能避免凭证过期的问题。
内容的提问来源于stack exchange,提问作者Dawny33

