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
相关产品推荐
相关产品推荐

