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

如何从Terraform向cloud-init调用的bash脚本传递参数

解决方案

问题根因

原有写法存在两个核心错误:

  • base64encode(file(var.bootstrap_file) "123456") 仅做简单字符串拼接,将脚本内容和密码拼成了一段连续文本,并不会给脚本传入位置参数,cloud-init执行user-data中的shell脚本时,无法识别拼接在尾部的字符串为$1参数。
  • 直接拼接明文密码存在泄露风险,且Jupyter要求服务配置中传入哈希后的密码值,直接传明文无法正常认证。

不需要使用remote-exec,全程通过cloud-init的user-data通道即可实现,无需向Terraform配置传入SSH私钥,无额外安全风险。


第一步:调整Terraform配置

放弃file+字符串拼接的写法,使用Terraform内置的templatefile函数完成脚本参数渲染,将密码定义为敏感变量避免日志泄露。

  1. 先在variables.tf中新增密码变量:
variable "jupyter_password" {
  type        = string
  description = "Jupyter Notebook访问密码"
  sensitive   = true # 标记为敏感值,Terraform执行时不会在输出日志中打印明文
}
  1. 修改实例资源中的metadata配置:
resource "oci_core_instance" "jupyterlab_instance" {
  # 保留原有其他实例配置(可用性域、镜像、规格、子网等)
  metadata = {
    ssh_authorized_keys = var.ssh_public_key_file
    user_data           = base64encode(templatefile("${path.module}/bootstrap.sh", {
      jupyter_plain_password = var.jupyter_password
    }))
  }
}

执行部署时通过-var="jupyter_password=你的实际密码"或者.tfvars文件传入密码值即可。


第二步:修改bootstrap.sh脚本

脚本头部增加shebang声明,将原位置参数$1替换为模板占位符,在脚本内部完成Jupyter密码哈希生成,避免明文写入systemd配置。修改后完整内容如下:

#!/bin/bash
function systemd_jupyter_instance() {
  echo "setting up systemd for jupyter at 0.0.0.0:8888"

  # 脚本内生成Jupyter要求的哈希密码,根据安装的Jupyter版本选择对应导入路径
  # 新版Jupyter使用jupyter_server.auth模块,老版本Notebook可替换为from IPython.lib.security import passwd
  password_hash=$(python3 -c "from jupyter_server.auth import passwd; print(passwd('${jupyter_plain_password}'))")

  mkdir -p /etc/jupyter /home/opc
  cat <<EOF > /etc/systemd/system/jupyterInst.service
[Unit]
Description=Jupyter instance
After=network.target

[Service]
User=opc
Group=opc
WorkingDirectory=/home/opc
ExecStart=/usr/local/bin/jupyter-notebook --ip=0.0.0.0 --port=8888 --NotebookApp.password=${password_hash}
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

  systemctl daemon-reload
  systemctl is-active --quiet jupyterInst && systemctl stop jupyterInst
  systemctl enable --now jupyterInst
  systemctl status jupyterInst --no-pager
}

function main() {
  # 如果镜像未预装Jupyter,可在此处补充安装命令,例如:
  # pip3 install jupyter
  systemd_jupyter_instance
}

main

注意事项

  • bootstrap.sh第一行必须保留#!/bin/bash声明,否则cloud-init可能无法正确识别脚本执行器。
  • templatefile渲染时会自动将${jupyter_plain_password}占位符替换为传入的实际密码值,渲染完成后生成完整可执行脚本,无需额外传参。
  • 整个配置流程不需要建立SSH连接到实例,完全通过云实例元数据通道传递配置,不存在私钥泄露风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:57:21