- OpenTofu 语言
- 资源
- 供应器
- 文件供应器
文件供应器
file
供应器将文件或目录从运行 OpenTofu 的机器复制到新创建的资源。file
供应器支持 ssh
和 winrm
类型的 连接。
将供应器作为最后的手段。对于大多数情况,有更好的替代方案。请参阅 声明供应器 以获取更多详细信息。
示例用法
resource "aws_instance" "web" {
# ...
# Copies the myapp.conf file to /etc/myapp.conf
provisioner "file" {
source = "conf/myapp.conf"
destination = "/etc/myapp.conf"
}
# Copies the string in content into /tmp/file.log
provisioner "file" {
content = "ami used: ${self.ami}"
destination = "/tmp/file.log"
}
# Copies the configs.d folder to /etc/configs.d
provisioner "file" {
source = "conf/configs.d"
destination = "/etc"
}
# Copies all files and folders in apps/app1 to D:/IIS/webapp1
provisioner "file" {
source = "apps/app1/"
destination = "D:/IIS/webapp1"
}
}
当 file
供应器通过 SSH 与 Windows 系统通信时,必须配置 OpenSSH 以使用 cmd.exe
而不是 PowerShell 运行命令。PowerShell 会导致文件解析错误,因为它与 Unix shell 和 Windows 命令解释器都不兼容。
参数参考
支持以下参数
-
source
- 源文件或目录。将其指定为相对于当前工作目录或作为绝对路径。此参数不能与content
结合使用。 -
content
- 要复制到目标的直接内容。如果目标是文件,则内容将写入该文件。如果目标是目录,则在该目录中创建名为tf-file-content
的文件。建议在使用content
时使用文件作为目标。此参数不能与source
结合使用。 -
destination
- (必需)远程系统上要写入的目标路径。有关更多信息,请参见下面的 目标路径。
目标路径
您在 destination
参数中提供的路径将由远程系统而不是 OpenTofu 本身进行评估。因此,该参数的有效值可能因目标上运行的操作系统和远程访问软件而异。
通过 SSH 连接时,file
供应器会将给定的目标路径逐字传递给远程主机上的 scp
程序。默认情况下,OpenSSH 的 scp
实现将在远程用户的 home 目录中运行,因此您可以指定一个相对路径以上传到该 home 目录,或指定一个绝对路径以上传到其他位置。远程 scp
进程将以 connection
块中指定的用户的访问级别运行,因此权限可能会阻止直接写入 home 目录之外的位置。
由于 WinRM 没有相应的 FTP 协议,因此对于 WinRM 连接,file
供应器使用更复杂的过程
- 在远程系统
TEMP
环境变量中给定的目录中生成一个临时文件名,使用伪随机 UUID 保证唯一性。 - 使用通过 WinRM 顺序生成的
echo
命令,将源文件的 base64 编码块逐渐追加到选定的临时文件。 - 使用上传的 PowerShell 脚本读取临时文件,进行 base64 解码,并将原始结果写入目标文件。
在 WinRM 的情况下,目标路径因此由 PowerShell 解释,因此必须注意不要使用 PowerShell 可能会解释的任何元字符。特别是,在使用 WinRM 时,避免在 destination
参数中包含任何不受信任的外部输入,因为它可能成为在远程系统上执行任意 PowerShell 代码的媒介。
现代 Windows 系统支持运行 OpenSSH 服务器,因此我们强烈建议尽可能选择 SSH 而不是 WinRM,并且仅在处理过时的 Windows 版本时才将 WinRM 作为最后的手段。
目录上传
file
供应器可以将完整目录上传到远程机器。上传目录时,需要考虑一些其他事项。
使用 ssh
连接类型时,目标目录必须已存在。如果需要创建它,请在文件供应器之前使用 remote-exec 供应器来创建目录
使用 winrm
连接类型时,如果目标目录不存在,则将为您创建。
源路径上尾部斜杠的存在将决定目录名称是否将嵌入到目标中,或者目标是否将被创建。例如
-
如果源是
/foo
(没有尾部斜杠),目标是/tmp
,则本地机器上的/foo
内容将上传到远程机器上的/tmp/foo
。远程机器上的foo
目录将由 OpenTofu 创建。 -
但是,如果源路径是
/foo/
(末尾带斜杠),目标路径是/tmp
,则/foo
的内容将直接上传到/tmp
中。