代码之家  ›  专栏  ›  技术社区  ›  Akshay Tilekar

如何通过terraform执行powershell命令

  •  1
  • Akshay Tilekar  · 技术社区  · 6 年前

    我正试图从am i创建一个windows ec2实例,并对其执行powershell命令:

    data "aws_ami" "ec2-worker-initial-encrypted-ami" {
        filter {
            name   = "tag:Name"
            values = ["ec2-worker-initial-encrypted-ami"]
        }  
    }
    
    resource "aws_instance" "my-test-instance" {
      ami             = "${data.aws_ami.ec2-worker-initial-encrypted-ami.id}"
      instance_type   = "t2.micro"
    
      tags {
        Name = "my-test-instance"
      }
    
      provisioner "local-exec" {
        command = "C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Scripts\\InitializeInstance.ps1 -Schedule",
        interpreter = ["PowerShell"]
      }
    
    }
    

    我面临以下错误:

    • aws_instance.my-test-instance:运行命令“c:\programdata\amazon\ec2 windows\launch\scripts\initializeinstance.ps1时出错 -日程表:退出状态1。输出:术语“C:\ProgramData\Amazon\EC2 Windows\Launch\scripts\InitializeInstance.ps1” 无法识别为cmdlet、函数、脚本文件或 可操作程序。检查名称的拼写,或者路径是否 包括,请验证路径是否正确,然后重试。在第1行 字符:72
    • C:\ProgramData\Amazon\EC2 Windows\Launch\scripts\InitializeInstance.ps1 <<<<-日程安排
      • categoryinfo:objectnotfound:(C:\程序数据…izeInstance.ps1:string)[], CommandNotFoundException异常
      • fullyQualifiederRorID:CommandNotFoundException
    3 回复  |  直到 6 年前
        1
  •  6
  •   Brandon Miller    6 年前

    你正在使用 local-exec 在运行terraform的工作站上运行请求powershell代码的provisioner:

    本地exec provisioner在资源之后调用本地可执行文件 是创建的。这会在运行terraform的机器上调用一个进程, 不在资源上。

    听起来你想在结果实例上执行powershell脚本,在这种情况下,你需要使用 remote-exec 将在目标资源上运行PowerShell的设置程序:

    远程exec provisioner调用远程资源上的脚本 在它被创造之后。这可用于运行配置 管理工具,引导到集群中,等等。

    你还需要包括 connection 详细信息,例如:

      provisioner "remote-exec" {
        command = "C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Scripts\\InitializeInstance.ps1 -Schedule",
        interpreter = ["PowerShell"]
        connection {
          type     = "winrm"
          user     = "Administrator"
          password = "${var.admin_password}"
        }
      }
    

    这意味着此实例还必须准备好接受winrm连接。

    不过,完成这项任务还有其他选择。例如使用 userdata , which Terraform also supports . 这可能类似于以下示例:

    在terraform中使用userdata文件的示例

    文件名 userdata.txt :

    <powershell>
    C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Scripts\\InitializeInstance.ps1 -Schedule
    </powershell>
    

    使用userdata文件启动实例:

    resource "aws_instance" "my-test-instance" {
      ami             = "${data.aws_ami.ec2-worker-initial-encrypted-ami.id}"
      instance_type   = "t2.micro"
    
      tags {
        Name = "my-test-instance"
      }
    
      user_data = "${file(userdata.txt)}"
    }
    

    这个 file interpolation 将以字符串形式读取userdata文件的内容,以传递给userdata以进行实例启动。一旦实例启动,它就应该按预期运行脚本。

        2
  •  1
  •   Brian Warsing    6 年前

    ftr:brandon的答案是正确的,除了为 remote-exec 包括设置程序不支持的密钥。

    也不是 command 也不 interpreter 是受支持的密钥。

    https://www.terraform.io/docs/provisioners/remote-exec.html

        3
  •  1
  •   Pixel    5 年前

    布赖恩所说的是正确的,你会得到“无效或未知的密钥:解释器”错误。

    要正确运行powershell,您需要根据brandon的答案按如下方式运行它:

    provisioner "remote-exec" {
        connection {
          type     = "winrm"
          user     = "Administrator"
          password = "${var.admin_password}"
        }
    
    inline = [
             "powershell -ExecutionPolicy Unrestricted -File C:\\ProgramData\\Amazon\\EC2-Windows\\Launch\\Scripts\\InitializeInstance.ps1 -Schedule"
            ]
          }