在不使用Terraform文件供应器的情况下将本地文件部署到实例

时间:2019-10-30 17:42:13

标签: terraform terraform-provider-aws

就像其他几个发布到StackOverflow的用户一样,我遇到了文件供应商的问题,Terraform文档说我们不应该依赖它们。

解决文件供应商的最佳方法是什么-专门针对本地配置文件和脚本?

1 个答案:

答案 0 :(得分:0)

一种有效且不需要直接连接到实例的解决方案是将userdata用作钩子,以从文件的base64版本“安装”文件。

我们实际上可以将这些文件作为base64字符串嵌入到userdata初始化脚本中。这适用于AWS中的Windows和Linux实例,并且与在启动时运行userdata脚本兼容。

解决方案说明:

  1. terraform plan期间,使用terraform函数base64encode(file("path/to/file"))将所需的任何本地文件编码为base64字符串。
  2. (可选)在用户数据执行开始时保存标记文件(_INIT_STARTED_);该文件将具有开始执行userdata的创建时间戳记。
  3. 在运行 actual userdata脚本之前,将base64字符串写入文本文件。 (实际命令在Windows和Linux之间有所不同,请参见下面的示例。)
  4. 运行userdata脚本本身(userdata_win.batuserdata_lin.sh
  5. (可选)最后,保存第二个标记文件(_INIT_COMPLETE_),该文件具有userdata脚本完成时的创建时间戳。 (缺少此文件也有助于在登录实例后检测脚本故障和/或仍在运行的脚本。)

对于AWS Linux实例:

data "template_file" "userdata_lin" {
  template = <<EOF
#!/bin/bash
mkdir -p /home/ubuntu/setup-scripts
cd /home/ubuntu/setup-scripts
touch _INIT_STARTED_
echo ${base64encode(file("${path.module}/userdata_lin.sh"))} | base64 --decode > userdata.sh
echo ${base64encode(file("${path.module}/config.json"))} | base64 --decode > config.json
${file("${path.module}/userdata_lin.sh")}
sudo chmod 777 *
touch _INIT_COMPLETE_
EOF
}

# ...

resource "aws_instance" "my_linux_instance" {
  # ...
  user_data = data.template_file.userdata_lin.rendered
}

对于AWS Windows实例:

data "template_file" "userdata_win" {
  template = <<EOF
<script>
mkdir C:\Users\Administrator\setup-scripts
cd C:\Users\Administrator\setup-scripts
echo "" > _INIT_STARTED_
echo ${base64encode(file("${path.module}/userdata_win.bat"))} > tmp1.b64 && certutil -decode tmp1.b64 userdata.bat
echo ${base64encode(file("${path.module}/config.json"))} > tmp2.b64 && certutil -decode tmp2.b64 config.json
${file("${path.module}/userdata_win.bat")}
echo "" > _INIT_COMPLETE_
</script>
<persist>false</persist>
EOF
}

# ...

resource "aws_instance" "my_windows_instance" {
  # ...
  user_data = data.template_file.userdata_win.rendered
}