跳至主要内容

文件供应器

file 供应器将文件或目录从运行 OpenTofu 的机器复制到新创建的资源。file 供应器支持 sshwinrm 类型的 连接

示例用法

代码块
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"
}
}

参数参考

支持以下参数

  • 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 供应器使用更复杂的过程

  1. 在远程系统 TEMP 环境变量中给定的目录中生成一个临时文件名,使用伪随机 UUID 保证唯一性。
  2. 使用通过 WinRM 顺序生成的 echo 命令,将源文件的 base64 编码块逐渐追加到选定的临时文件。
  3. 使用上传的 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中。