Terraform Apply超时:AWS IAM角色链1小时限制问题求助
问题
通过Jenkins流水线使用Terraform管理EKS集群时,大型集群的terraform apply步骤耗时超过1小时,会触发以下报错:
Error saving state: failed to upload state: ExpiredToken: The provided token has expired.
核心原因是当前采用IAM角色链模式:Jenkins先假定角色A,再通过角色A假定角色B执行Terraform配置,而AWS对角色链存在1小时会话时长的硬性限制。
已尝试的无效方案:
- 在Terraform AWS provider配置中添加
assume_role {}块,期望自动刷新凭证,但Terraform仅能刷新自身直接请求的凭证,无法适配角色链场景 - 设置
assume_role_duration参数,触发报错:
AWS Error: operation error STS: AssumeRole, https response error StatusCode: 400, RequestID: XXXX, api error ValidationError: The requested DurationSeconds exceeds the 1 hour session limit for roles assumed by role chaining.
可行的Workaround
1. 移除角色链,让Jenkins直接假定目标角色B
修改Jenkins执行环境的IAM权限配置,允许Jenkins所在的实体(EC2实例、EKS Pod、Jenkins服务器绑定的IAM用户等)直接假定角色B,跳过角色A的中转。这种情况下角色会话时长可配置为最长12小时(需匹配角色B的信任策略),完全覆盖长时间的terraform apply操作。
2. 拆分Terraform执行阶段
将大型集群的Terraform配置拆分为多个独立步骤,确保每个步骤的执行时间控制在1小时内:
- 先创建网络基础设施(VPC、子网、安全组)
- 再部署EKS控制平面
- 最后添加节点组、集群附加组件等
每个阶段单独执行terraform apply,执行前让Jenkins重新走角色链流程获取新的1小时有效凭证。
3. Jenkins流水线脚本化刷新凭证
在Terraform执行过程中,通过shell脚本定期刷新角色B的凭证,并更新Terraform的执行环境变量:
- 后台用AWS CLI定期执行
aws sts assume-role(基于角色A的权限),获取新的临时凭证 - 将新的
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN注入Terraform运行环境
注意:这种方式需确保Terraform能实时读取更新后的环境变量,更适合配合步骤拆分使用,避免中断当前执行进程。
4. 基于AWS Secrets Manager实现凭证自动轮换
让Jenkins先获取角色B的临时凭证,存入Secrets Manager并配置每45分钟自动轮换。轮换逻辑通过自定义Lambda函数实现,确保每次轮换时都通过角色A重新假定角色B获取新会话,Terraform则直接从Secrets Manager读取最新凭证。
内容的提问来源于stack exchange,提问作者Richard P
相关产品推荐
相关产品推荐

