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

Terraform AutoScaling组模块UserData无法传递带变量Shell脚本问题问询

报错原因

你遇到的错误是两个问题共同导致的:

  • HCL插值语法和Shell变量语法冲突:Terraform的HCL语言默认会将${}格式的内容识别为自身的插值表达式,需要调用对应Terraform变量。你直接将包含Shell变量${CURL_FILEPATH}的脚本放在变量的heredoc块中,Terraform会尝试解析这些Shell变量为Terraform变量,找不到就抛出"Variables not allowed"错误。
  • 函数使用错误:filebase64()函数的入参是本地文件的路径,作用是读取文件内容后做base64编码,你传入的是已经存储在变量中的脚本字符串,不符合函数要求。

解决方案

步骤1:修改变量定义,关闭heredoc内部插值解析

将heredoc的起始标记从<<EOF改为<<'EOF',给EOF加单引号后,整个heredoc块的内容会被当作纯字面量处理,Terraform不会解析内部的${}内容,Shell变量语法会被原样保留。
修改后的变量定义如下:

variable "s1_aws_userdata" {
  type = string
  default = <<'EOF'
#!/usr/bin/env bash

function download_and_run_scripts {
    echo
    # dependency check
    if [ ! -x /usr/bin/curl ]; then
        echo -e "Error, curl is not installed."
        exit 1
    fi
    # s1g_install scripts
    local DOWNLOAD_SCRIPTS="toolkit.sh ${AMI_SCRIPTS}"
    local CURL_FILEPATH=""
    for CURL_FILEPATH in ${DOWNLOAD_SCRIPTS}; do
        echo -e "\nGoing to download: ${CURL_FILEPATH}\n"

        case ${CURL_FILEPATH} in
            toolkit.sh)
                local CURL_REPO="s1_tools"
                ;;
            *)
                local CURL_REPO="s1g_install"
                ;;
        esac

        local CURL_TOKEN="xxxx"
        local CURL_OWNER="xxx"
        local CURL_URL="xxxxx"

        /usr/bin/curl --header "Authorization: token ${CURL_TOKEN}" --header "Accept: application/vnd.github.v3.raw" \
          --location ${CURL_URL} -o /tmp/${CURL_FILEPATH} --silent
        if [ ! -f /tmp/${CURL_FILEPATH} ]; then
            echo -e "Error, unable to download ${CURL_FILEPATH} file."
            exit 1
        fi
        chmod +x /tmp/${CURL_FILEPATH}
        source /tmp/${CURL_FILEPATH}
    done
}

#------------------------------------------------------------------------------------------
# Define here scripts (separated with 1 space) that will be executed on first run:
AMI_SCRIPTS="s1_ami_base_lynis.sh"
#------------------------------------------------------------------------------------------
download_and_run_scripts
EOF
}

步骤2:修改user_data_base64赋值逻辑

将filebase64替换为base64encode,直接对变量中的字符串内容做base64编码即可:

user_data_base64 = base64encode(var.s1_aws_userdata)

拓展说明

如果你需要将Terraform变量注入到Shell脚本中,不需要给EOF加单引号,只需要将Shell变量的$转义为\$即可,Terraform的变量直接用${var.xxx}格式引用即可,示例如下:

variable "github_token" {
  type = string
  sensitive = true
}

variable "s1_aws_userdata" {
  type = string
  default = <<EOF
#!/usr/bin/env bash
local CURL_TOKEN="${var.github_token}" # 这里是Terraform注入的变量
local CURL_FILEPATH=""
for CURL_FILEPATH in \${DOWNLOAD_SCRIPTS}; do # 这里是Shell变量,加反斜杠转义
  ...
done
EOF
}

内容的提问来源于stack exchange,提问作者Maury Diaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:45:04