You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

控制tfenv安装Terraform版本的并发执行以解决权限问题

解决tfenv并行安装Terraform版本的权限错误问题

问题背景

使用Atlantis搭配Terragrunt构建Terraform基础设施时,Terragrunt会为多个工作区并行调用tfenv install安装不同版本的Terraform,引发竞争条件导致权限错误,典型报错如下:

/home/user/.tfenv/lib/tfenv-exec.sh: line 43: /home/user/.tfenv/versions/1.6.2/terraform: Permission denied
/home/user/.tfenv/lib/tfenv-exec.sh: line 43: exec: /home/user/.tfenv/versions/1.6.2/terraform: cannot execute: Permission denied

已针对该问题向tfenv提交Issue,尝试编写Shell包装脚本实现tfenv install的串行化执行,但现有脚本未达到预期效果。脚本逻辑设想为:

  1. Atlantis调用tfenv包装器
  2. 包装器检查锁状态:无锁则获取锁并执行安装,有锁则等待释放
  3. 未获取锁的进程检查目标版本是否已安装,已安装则直接退出,否则等待锁释放后尝试安装

现有未生效脚本如下:

#!/bin/bash

LOCK_FILE="/tmp/tfenv-wrapper.lock"
PROCESS_COUNTER_FILE="/tmp/tfenv-process-counter"
MAX_CONCURRENT_PROCESSES=2

# Function to acquire a lock
function acquire_lock() {
    exec 100>"$LOCK_FILE"
    flock -x 100
}

# Function to release the lock
function release_lock() {
    flock -u 100
}

# Function to get the current process count
function get_process_count() {
    pgrep -f "tfenv install" | grep -v $$ | wc -l

}

# Function to update the process count
function update_process_count() {
    get_process_count > "$PROCESS_COUNTER_FILE"
}

# Set up the EXIT trap to release the lock and remove the lock file on script exit
trap 'release_lock' EXIT

# Infinite loop to keep the script running
while true; do
    # Acquire the lock
    acquire_lock
    echo "Lock acquired."

    # Read the number of running processes from the counter file
    num_processes=$(get_process_count)
    echo "Number of tfenv processes: $num_processes"

    # If the number of running processes exceeds the limit, wait
    while [ "$num_processes" -ge "$MAX_CONCURRENT_PROCESSES" ]; do
        echo "Maximum number of concurrent 'tfenv' processes reached. Waiting for processes to complete."
        sleep 2
        num_processes=$(get_process_count)
    done

    # Increment the process counter
    ((num_processes++))
    update_process_count

    # Release the lock
    release_lock
    echo "Released lock."

    # Wait for any 'tfenv' process launched outside this script to complete
    while [ "$(get_process_count)" -gt 0 ]; do
        sleep 2
    done

    # Acquire the lock again before decrementing the counter
    acquire_lock
    echo "Lock acquired."

    # Decrement the process counter
    ((num_processes--))
    update_process_count

    # Release the lock
    release_lock
    echo "Released lock."
done

解决方案建议

1. 简化版串行化tfenv包装脚本

原脚本逻辑过于复杂,改用基于文件排他锁的极简方案,确保同一时间仅一个进程执行tfenv install,且优先检查版本是否已安装:

#!/bin/bash
# 替换系统tfenv为该脚本,确保串行安装

TARGET_VERSION="$1"
LOCK_FILE="/tmp/tfenv-install.lock"

# 先检查目标版本是否已安装,避免重复执行
if tfenv list | grep -q "^$TARGET_VERSION$"; then
    exit 0
fi

# 使用flock获取排他锁,确保串行执行安装
# -w 300 表示最多等待5分钟,可根据实际调整
flock -x -w 300 "$LOCK_FILE" bash -c "
    # 再次检查版本(防止等待期间已被其他进程安装)
    if ! tfenv list | grep -q "^$TARGET_VERSION$"; then
        tfenv install \"$TARGET_VERSION\"
    fi
"

使用说明:

  • 将该脚本命名为tfenv,放置在$PATH优先级高于系统tfenv的目录(比如/usr/local/bin)
  • 确保脚本有可执行权限:chmod +x /usr/local/bin/tfenv
  • 脚本会优先检查版本是否存在,已存在则直接退出;未存在则通过flock确保串行安装

2. 预安装所有所需Terraform版本

从根源避免并行安装,在Atlantis启动前批量安装所有工作区需要的Terraform版本:

  1. 编写脚本遍历所有Terragrunt配置文件,提取terraform.required_version字段
  2. 批量执行tfenv install安装这些版本

示例提取脚本:

#!/bin/bash
# 遍历所有terragrunt.hcl文件,提取所需TF版本
find /path/to/your/infra -name "terragrunt.hcl" -exec grep -oP 'terraform.required_version\s*=\s*"\K[^"]+' {} \; | sort -u | while read -r version; do
    tfenv install "$version"
done

使用说明:

  • 将该脚本加入Atlantis启动脚本中,确保每次服务启动前都预安装所需版本
  • 若配置有更新,重新执行该脚本即可

3. 调整Atlantis并行执行策略

修改Atlantis配置,限制并行处理的工作区数量,或按Terraform版本分组串行执行:

  • 在Atlantis的atlantis.yaml中,通过parallelism字段限制全局并行任务数:
    parallelism: 1
    
  • 或使用项目分组,将使用相同Terraform版本的工作区归为一组,不同组串行执行:
    projects:
      - name: tf-v1.6.x
        dir: infra/v1.6
        workspace: default
      - name: tf-v1.7.x
        dir: infra/v1.7
        workspace: default
    
    配合Atlantis的串行执行配置,确保不同版本的分组不会并行触发安装

内容的提问来源于stack exchange,提问作者Saifeddine Rajhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:23:15