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

如何在AWS Lambda中运行Terraform?权限报错排查与修复

问题描述

我找到一个旧的GitHub仓库,原本完全匹配我的使用场景,但因为Lambda和Python版本更新,原有代码已无法运行。现在在本地和AWS Lambda环境中执行terraform --version时,都持续遇到PermissionError: [Errno 13] Permission denied: '/tmp/tmpg4l5twh9/terraform'错误。

以下是我编写的用于更新Lambda函数的沙盒代码:

import os
import subprocess
import urllib.request
import tarfile
import json
import tempfile

# Fetch the latest version of Terraform
URL = 'https://api.github.com/repos/hashicorp/terraform/releases/latest'
with urllib.request.urlopen(URL) as response:
    data = response.read()
    encoding = response.info().get_content_charset('utf-8')
    TERRAFORM_DOWNLOAD_URL = json.loads(data.decode(encoding))['tarball_url']

# Download and extract the latest version of Terraform
with tempfile.TemporaryDirectory() as tmpdir:
    TERRAFORM_TAR_PATH = os.path.join(tmpdir, 'terraform.tar.gz')
    TERRAFORM_PATH = os.path.join(tmpdir, 'terraform')
    urllib.request.urlretrieve(TERRAFORM_DOWNLOAD_URL, TERRAFORM_TAR_PATH)
    with tarfile.open(TERRAFORM_TAR_PATH, "r:gz") as tf:
        print(f"Extracting {TERRAFORM_TAR_PATH} to {TERRAFORM_PATH}")
        tf.extractall(path=tmpdir)

    # Remove the tar file after it's extracted
    os.remove(TERRAFORM_TAR_PATH)
    print(f"All files extracted to {TERRAFORM_PATH}")
    print(f"{TERRAFORM_PATH} contents: {os.listdir(tmpdir)}")

    # Add Terraform to PATH
    os.rename(f'{tmpdir}/{os.listdir(tmpdir)[0]}', TERRAFORM_PATH)
    os.environ["PATH"] += os.pathsep + TERRAFORM_PATH
    os.chmod(TERRAFORM_PATH, 0o777)
    # os.system(f'chmod -R 777 {TERRAFORM_PATH}')
    print(os.listdir(TERRAFORM_PATH))
    subprocess.check_output([TERRAFORM_PATH, "--version"])

我认为这不是重复问题,因为我是基于一个曾正常运行的方案进行改造。

解决方案

你的代码存在几个核心问题导致权限错误,逐一修正如下:

1. 下载源错误

你当前拉取的是GitHub仓库的源码压缩包(tarball_url),而非Terraform官方预编译的可执行二进制包。源码包中没有直接可用的terraform执行文件,这是权限错误的根源之一。

2. 权限设置对象错误

你给重命名后的目录设置了777权限,但真正需要执行权限的是目录内的terraform二进制文件,而非目录本身。

修正后的完整代码

import os
import subprocess
import urllib.request
import tarfile
import json
import tempfile

# 获取Terraform最新版本的二进制包地址
URL = 'https://api.github.com/repos/hashicorp/terraform/releases/latest'
with urllib.request.urlopen(URL) as response:
    data = response.read()
    encoding = response.info().get_content_charset('utf-8')
    release_data = json.loads(data.decode(encoding))
    
    # 匹配Lambda运行环境(Linux x86_64)的二进制包
    for asset in release_data['assets']:
        if asset['name'].endswith('linux_amd64.zip'):
            TERRAFORM_DOWNLOAD_URL = asset['browser_download_url']
            break

# 下载并解压Terraform二进制文件
with tempfile.TemporaryDirectory() as tmpdir:
    TERRAFORM_ZIP_PATH = os.path.join(tmpdir, 'terraform.zip')
    TERRAFORM_BIN_PATH = os.path.join(tmpdir, 'terraform')
    
    urllib.request.urlretrieve(TERRAFORM_DOWNLOAD_URL, TERRAFORM_ZIP_PATH)
    
    # Terraform官方二进制包为zip格式,切换解压模式
    with tarfile.open(TERRAFORM_ZIP_PATH, "r:zip") as tf:
        tf.extract('terraform', path=tmpdir)
    
    os.remove(TERRAFORM_ZIP_PATH)
    
    # 给二进制文件添加执行权限(0o755足够,无需过度开放777)
    os.chmod(TERRAFORM_BIN_PATH, 0o755)
    
    # 直接调用二进制文件验证版本
    result = subprocess.check_output([TERRAFORM_BIN_PATH, "--version"])
    print(result.decode('utf-8'))

关键修正说明

  • 替换下载源:从源码包改为匹配Lambda运行环境的预编译二进制zip包,确保获取到可执行文件。
  • 修正解压格式:Terraform官方发布的二进制包为zip格式,而非tar.gz,因此调整解压模式为r:zip。
  • 精准设置权限:仅给terraform二进制文件添加执行权限,避免不必要的权限开放。
  • 直接调用执行:不再依赖PATH环境变量,直接指定二进制文件路径执行,规避路径配置问题。

Lambda的/tmp目录本身具备读写权限,只要确保解压后的二进制文件拥有执行权限,即可解决权限错误问题。

内容的提问来源于stack exchange,提问作者John R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:23:34