Skip to content
This repository has been archived by the owner on Feb 11, 2022. It is now read-only.

Commit

Permalink
ISSUE #423: Support using EC2-generated password as the WinRM password
Browse files Browse the repository at this point in the history
Adds a winrm_info provider capability to support using the EC2 GetPasswordData API as a means of getting the WinRM password.

If the winrm.password is set to :aws, go fetch the AWS password data for the machine, decrypt the user-specified private key, and set it as the winrm.password
  • Loading branch information
rafd123 committed Dec 19, 2015
1 parent 988be1f commit 9097855
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 0 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,23 @@ Vagrant.configure("2") do |config|
end
```

### WinRM passwords

Want to use the EC2-generated Administrator password as the WinRM password for your Windows images? Use `:aws` as the WinRM password, and it will be fetched and decrypted using your private key.

```ruby
Vagrant.configure("2") do |config|
# ... other stuff

config.vm.communicator = "winrm"
config.winrm.username = "Administrator"

config.vm.provider "aws" do |aws, override|
override.winrm.password = :aws
end
end
```

## Development

To work on the `vagrant-aws` plugin, clone this repository out, and use
Expand Down
9 changes: 9 additions & 0 deletions lib/vagrant-aws/action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ def self.action_reload
end
end

def self.action_get_winrm_password
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use ConnectAWS
b.use GetWinRMPassword
end
end

# The autoload farm
action_root = Pathname.new(File.expand_path("../action", __FILE__))
autoload :ConnectAWS, action_root.join("connect_aws")
Expand All @@ -204,6 +212,7 @@ def self.action_reload
autoload :WarnNetworks, action_root.join("warn_networks")
autoload :ElbRegisterInstance, action_root.join("elb_register_instance")
autoload :ElbDeregisterInstance, action_root.join("elb_deregister_instance")
autoload :GetWinRMPassword, action_root.join("get_winrm_password")
end
end
end
51 changes: 51 additions & 0 deletions lib/vagrant-aws/action/get_winrm_password.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require "fog"
require "log4r"

module VagrantPlugins
module AWS
module Action
# This action connects to AWS, verifies credentials work, and
# puts the AWS connection object into the `:aws_compute` key
# in the environment.
class GetWinRMPassword
def initialize(app, env)
@app = app
@logger = Log4r::Logger.new("vagrant_aws::action::get_winrm_password")
end

def call(env)
machine = env[:machine]

if machine.config.winrm.password == :aws
machine.ui.info(I18n.t("vagrant_aws.getting_winrm_password"))

aws = env[:aws_compute]
response = aws.get_password_data({ instance_id: machine.id })
password_data = response.body['passwordData']
password_data_bytes = Base64.decode64(password_data)

# Try to decrypt the password data using each one of the private key files
# set by the user until we hit one that decrypts successfully
machine.config.ssh.private_key_path.each do |private_key_path|
private_key_path = File.expand_path private_key_path

@logger.info("Decrypting password data using #{private_key_path}")
rsa = OpenSSL::PKey::RSA.new File.read private_key_path
begin
machine.config.winrm.password = rsa.private_decrypt password_data_bytes
@logger.info("Successfully decrypted password data using #{private_key_path}")
rescue OpenSSL::PKey::RSAError
@logger.warn("Failed to decrypt password data using #{private_key_path}")
next
end

break
end
end

@app.call(env)
end
end
end
end
end
14 changes: 14 additions & 0 deletions lib/vagrant-aws/capability.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require "vagrant/action/builder"

module VagrantPlugins
module AWS
module Capability
class WinRMInfo
def self.winrm_info(machine)
machine.action("get_winrm_password")
return {}
end
end
end
end
end
7 changes: 7 additions & 0 deletions lib/vagrant-aws/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ class Plugin < Vagrant.plugin("2")
Provider
end

provider_capability(:aws, :winrm_info) do
setup_logging

require_relative 'capability'
Capability::WinRMInfo
end

# This initializes the internationalization strings.
def self.setup_i18n
I18n.load_path << File.expand_path("locales/en.yml", AWS.source_root)
Expand Down
2 changes: 2 additions & 0 deletions locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ en:
will_not_destroy: |-
The instance '%{name}' will not be destroyed, since the confirmation
was declined.
getting_winrm_password: |-
Getting WinRM password from AWS...
config:
access_key_id_required: |-
Expand Down

0 comments on commit 9097855

Please sign in to comment.