如何以编程方式/远程执行EC2 Windows实例中的程序

我想启动一个EC2 Windows实例,上传一个EXEecutable并执行它(全部以自动方式 ,这很重要)

到目前为止,我能够以编程方式启动EC2 Windows实例并获取其参数(密码/ IP),现在我想find一种方法来上传这个可执行文件( 从我的Windows机器或从我的其他EC2 linux实例 )并运行它。

我曾经想过启动一个RDP连接并使用一个macros软件来上传和执行这个文件,但是根据以前的经验,这是一个糟糕/脆弱的方法。

我也想过把这个EXE上传到服务器,然后在Windows上做这样的事情:

wget http://www.domain.com/my-file.exe 

除了Windows 没有 wget!

所以我的问题是: 有没有办法在EC2 Windows实例中以编程方式上传和执行EXEcutable?

命令ec2-run-instances有两个附加参数,可以在运行该命令时使用。 user-data命令和user-data-file这两者执行相同的任务,只是他们从不同的输入读取。 当你使用这个参数的时候,用户数据的内容将被上传到一个只有已经启动的实例可用的amazon托管的URI http://169.254.169.254/1.0/user-data

在linux环境下这样做的正常方法是上传一个shell脚本到实例来下载exe,你的用户数据文件可能看起来像这样…

 #! /bin/bash wget http://www.domain.com/my-file.exe 

在Windows中,当启动实例时没有安装用于执行用户数据文件的默认服务,但是有一个开源项目CloudInit.NET ,它可以模拟相同的进程,但使用PowerShell脚本。 唯一的要求是.NET 4.0和CloudInit.NET。 一旦安装,它将在实例启动时执行用户数据文件。 下载文件并使用powershell脚本执行它非常简单。

 !# /powershell/ $wc = New-Object System.Net.WebClient $wc.DownloadFile("http://www.domain.com/my-file.exe", "C:\my-file.exe"); & 'C:\my-file.exe' 

另一种方法是使用Windows powershell和WinRM – 它允许远程执行,有点像Linux上的ssh。

以下是您可以在客户端上运行的一个powershell脚本示例,用于远程执行脚本(摘自https://github.com/CloudifySource/cloudify/blob/master/esc/src/main/resources/clouds/ec2 -win / upload / bootstrap-client.ps1 ):

 param ([string]$target, [string]$username, [string]$password, [string]$command) $ErrorActionPreference="Stop" # Set up the password $securePassword = ConvertTo-SecureString -AsPlainText -Force $password $cred = New-Object System.Management.Automation.PSCredential $username, $securePassword Write-Host "Connecting to management service of $target" Connect-WSMan -Credential $cred $target set-item WSMan:\$target\Client\TrustedHosts -Value * -Force set-item WSMan:\$target\Shell\MaxMemoryPerShellMB -Value 0 -Force Write-Host Invoking command on Remote host $target Invoke-Command -ComputerName $target -Credential $cred -ScriptBlock { Invoke-Expression $args[0] } -ArgumentList $command Write-Host "Command finished" 

您可以使用以下命令从您自己的脚本运行此命令:

 powershell.exe -inputformat none -File PATH_TO_SCRIPT -target TARGET_IP -password PASSWORD -username USERNAME -command COMMAND_TO_EXECUTE 

你可能应该引用你的字符串,特别是密码和命令,因为这些字符通常会有特殊的字符,powershell可以解释为别的东西。

WinRM服务在EC2 Amazon Windows AMI上默认打开。 您只需要在安全组中打开端口5985(WinRM端口)。

最后,如果你之前从未在你的客户端机器上使用过powershell remoting,那么你应该执行一些命令来设置它(你只需要做一次):

 set-item WSMan:\localhost\Client\TrustedHosts -Value * -Force set-item WSMan:\localhost\Shell\MaxMemoryPerShellMB -Value 0 -Force Enable-PSRemoting Set-ExecutionPolicy unrestricted 

确保以管理员身份运行。

你可以用两种方法处理这个问题,

  • 在Windows SFTP程序中使用winscp。

    要在Windows上使用SFTP访问您的Amazon服务器,请下载Windows SFTP应用程序。 使用WinSCP,您将与您的服务器建立一个SFTP会话。 WinSCP提供了一些很好的功能,使您可以轻松地使用EC2服务器。 例如,按钮栏中的命令将使用您用于SFTP会话的相同凭据打开PuTTY SSH终端会话。 (您也可以通过单击CTRL + P启动PuTTY会话)。

  • 获取一个S3存储桶并挂载到所有的Windows和Linux EC2实例上。 您应该能够从工作站将文件上载并下载到S3存储桶,这些存储可供您的实例访问。

这听起来像是一个完美的CloudFormation用例。 我创建了一个演示的模板。 要使用,请将您的可执行文件放在S3存储桶中,并使用以下模板创建一个新的CloudFormation堆栈。 它会从S3下载你的可执行文件并运行它。 注意:该模板使用内置CloudFormationScripts的特殊AMI 。

 { "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "Spot Autoscaling for installing and running Windows Services.", "Parameters" : { "InstanceType" : { "Description" : "Webserver EC2 instance type", "Type" : "String", "Default" : "m1.small", "AllowedValues" : ["t1.micro", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge", "cc2.8xlarge", "cg1.4xlarge"], "ConstraintDescription" : "must be a valid EC2 instance type." }, "KeyName" : { "Description" : "The EC2 Key Pair to get Admin password to Instance.", "Type" : "String" }, "DeployS3Bucket" : { "Description" : "The S3 Bucket where deploy files are stored", "Type" : "String" }, "DeployS3Key" : { "Description" : "The exe file that runs on startup", "Type" : "String" } }, "Mappings" : { "RegionToAMIMap" : { "us-east-1" : { "AMI" : "ami-60b90609" }, "us-west-1" : { "AMI" : "ami-5bd6f11e" }, "eu-west-1" : { "AMI" : "ami-07151573" }, "ap-southeast-1" : { "AMI" : "ami-6ab5f538" }, "ap-northeast-1" : { "AMI" : "ami-424ff043" } } }, "Resources" : { "IAMUser" : { "Type" : "AWS::IAM::User", "Properties" : { "Path" : "/", "Policies" : [{ "PolicyName" : "root", "PolicyDocument" : { "Statement" : [{ "Effect" : "Allow", "Action" : "*", "Resource" : "*" }] } }] } }, "IAMUserAccessKey" : { "Type" : "AWS::IAM::AccessKey", "Properties" : { "UserName" : { "Ref" : "IAMUser" } } }, "SecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable RDP", "SecurityGroupIngress" : [{ "IpProtocol" : "tcp", "FromPort" : "3389", "ToPort" : "3389", "CidrIp" : "0.0.0.0/0" }] } }, "RunExecutable" : { "Type" : "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "files" : { "c:\\ToRun\\executable.exe" : { "source" : { "Fn::Join" : ["/", ["http://s3.amazonaws.com", { "Ref" : "DeployS3Bucket" }, { "Ref" : "DeployS3Key" }]] }, "authentication" : "S3AccessCreds" } }, "commands" : { "1-run-executable" : { "command" : "c:\\ToRun\\executable.exe" } } } }, "AWS::CloudFormation::Authentication" : { "S3AccessCreds" : { "type" : "S3", "accessKeyId" : { "Ref" : "IAMUserAccessKey" }, "secretKey" : { "Fn::GetAtt" : ["IAMUserAccessKey", "SecretAccessKey"] }, "buckets" : [{ "Ref" : "DeployS3Bucket" }] } } }, "Properties" : { "KeyName" : { "Ref" : "KeyName" }, "ImageId" : { "Fn::FindInMap" : ["RegionToAMIMap", { "Ref" : "AWS::Region" }, "AMI"] }, "SecurityGroups" : [{ "Ref" : "SecurityGroup" }], "InstanceType" : { "Ref" : "InstanceType" }, "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", ["<script>\n", "cfn-init.exe -v -s ", { "Ref" : "AWS::StackName" }, " -r RunExecutable ", " --access-key ", { "Ref" : "IAMUserAccessKey" }, " --secret-key ", { "Fn::GetAtt" : ["IAMUserAccessKey", "SecretAccessKey"] }, "\n", "</script>"]] } } } } }, "Outputs" : {} } 

我已经在2011年为企业部署做了类似的AWS自动化工作。亚马逊的云计算和opsworks仍然在建设当中。然而,我们已经成功地完成了使用dotnet的linux和windows平台的部署自动化。排除了powershell和ftp模式因为这是一个企业环境,有港口限制。 以下是我使用的方法。

注意:这是asp.net的web应用程序

对于linux部署。

我们使用了一个名为sharpshell(sharpSSH)的开源项目,这是c#应用程序,它简化了windows和linux之间的shell通信。只需提供目标aws地址和安全密钥即可进行连接。 我们根据我们的要求定制应用程序

对于窗户

虽然说云形成的API仍然没有可用的AWS文档。 我们使用了一种解决方法,即web服务方法。 创建一个基本上传文件到服务器和部署的web服务。 用这个网站服务器托管在amazaon的Windows服务器上。创建一个基本的图像和证书。 最后,从这个映像中创建的新实例将拥有托管的web服务,可以调用这些服务来上传部署包并安装在该系统上。

虽然上述的起动器不是傻子,控制力也不大。 我们实现了从Windows到Linux跨平台直接部署的功能,而无需使用S3存储桶或PowerShell。

如果您需要澄清,请告诉我。

干杯! 查尔斯