Terraform本地执行器Sqlcmd多行脚本报错,求命令拆分方案
解决Terraform local-exec执行SQL脚本的错误
问题根源
原代码中,sqlcmd命令执行完毕后,后续的SQL语句(IF、BEGIN等)被/bin/sh当作shell命令解析,引发语法错误;同时未给用户名/密码变量添加引号,可能导致登录参数传递异常,引发登录失败。
解决方案
方法1:使用sqlcmd的-Q参数传递SQL语句
将整个SQL逻辑作为-Q参数的字符串值传递,让sqlcmd直接执行该SQL,避免shell解析SQL语法:
resource "null_resource" "init" { depends_on = [azurerm_mssql_firewall_rule.creator] provisioner "local-exec" { command = <<EOT sqlcmd -S tcp:someserver.database.windows.net -d master -U "${var.mssql_admin_username}" -P "${var.mssql_admin_password}" -Q "IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = 'poweruser') BEGIN CREATE USER poweruser; ALTER USER poweruser WITH PASSWORD '${var.mssql_admin_password}'; END;" EOT } }
方法2:通过管道传递SQL脚本给sqlcmd
使用shell heredoc将SQL内容作为sqlcmd的标准输入,确保SQL语句被sqlcmd而非shell处理:
resource "null_resource" "init" { depends_on = [azurerm_mssql_firewall_rule.creator] provisioner "local-exec" { command = <<EOT sqlcmd -S tcp:someserver.database.windows.net -d master -U "${var.mssql_admin_username}" -P "${var.mssql_admin_password}" <<SQL IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = 'poweruser') BEGIN CREATE USER poweruser; ALTER USER poweruser WITH PASSWORD '${var.mssql_admin_password}'; END; QUIT SQL EOT } }
关键说明
- 给
-U和-P的变量值添加双引号,防止用户名/密码包含特殊字符时被shell拆分,解决登录失败问题。 - 两种方法都确保SQL语句由
sqlcmd解析执行,而非shell,避免语法错误。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

