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

在不使用Terraform文件供应器的情况下将本地文件部署到实例,terraform,terraform-provider-aws,Terraform,Terraform Provider Aws,和其他几个发布到StackOverflow的用户一样,我遇到了文件供应器的问题,Terraform文档说我们不应该依赖它们 解决文件供应器(特别是本地配置文件和脚本)的最佳方法是什么?一种非常有效且不需要直接连接到实例的解决方案是使用userdata作为钩子,从base64版本的文件“安装”文件 我们实际上可以将这些文件作为base64字符串嵌入到userdata初始化脚本中。这适用于AWS中的Windows和Linux实例,也与启动时运行userdata脚本兼容 解决方案说明: 在terraf

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


解决文件供应器(特别是本地配置文件和脚本)的最佳方法是什么?

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

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

解决方案说明:
  • terraform plan
    期间,使用terraform函数
    base64encode(file(“path/to/file”))
    将您需要的任何本地文件编码为base64字符串
  • (可选)在开始执行userdata时保存标记文件(
    \u INIT\u STARTED\u
    );此文件将具有
    userdata
    执行开始时的创建时间戳
  • 在运行实际的userdata脚本之前,将base64字符串写入文本文件。(实际命令在windows和linux之间有所不同,请参见下面的示例。)
  • 运行
    userdata
    脚本本身(
    userdata\u win.bat
    userdata\u lin.sh
  • (可选)最后,保存第二个标记文件(_INIT_COMPLETE),该文件将具有
    userdata
    脚本完成时的创建时间戳。(缺少此文件也有助于检测脚本失败和/或在登录到实例后仍在运行脚本。)
  • 对于AWS Linux实例:
    data“模板文件”userdata\u lin{
    template=config.json
    ${file(${path.module}/userdata\u lin.sh”)}
    sudo chmod 777*
    触摸初始完成_
    EOF
    }
    # ...
    资源“aws\u实例”“我的linux\u实例”{
    # ...
    user\u data=data.template\u file.userdata\u lin.rendered
    }
    
    对于AWS Windows实例:
    data“模板文件”userdata\u win{
    template=tmp1.b64&&certutil-解码tmp1.b64 userdata.bat
    echo${base64encode(文件(“${path.module}/config.json”)}>tmp2.b64&&certutil-解码tmp2.b64 config.json
    ${file(“${path.module}/userdata\u win.bat”)}
    回显“”>\u初始\u完成_
    假的
    EOF
    }
    # ...
    资源“aws\U实例”“我的windows\U实例”{
    # ...
    user\u data=data.template\u file.userdata\u win.rendered
    }
    
    谢谢你的建议!如果可用,您可以使用
    b64
    编码。
    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
    }