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

Commit 9097855

Browse files
committed
ISSUE #423: Support using EC2-generated password as the WinRM password
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
1 parent 988be1f commit 9097855

File tree

6 files changed

+100
-0
lines changed

6 files changed

+100
-0
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,23 @@ Vagrant.configure("2") do |config|
279279
end
280280
```
281281

282+
### WinRM passwords
283+
284+
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.
285+
286+
```ruby
287+
Vagrant.configure("2") do |config|
288+
# ... other stuff
289+
290+
config.vm.communicator = "winrm"
291+
config.winrm.username = "Administrator"
292+
293+
config.vm.provider "aws" do |aws, override|
294+
override.winrm.password = :aws
295+
end
296+
end
297+
```
298+
282299
## Development
283300

284301
To work on the `vagrant-aws` plugin, clone this repository out, and use

lib/vagrant-aws/action.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,14 @@ def self.action_reload
184184
end
185185
end
186186

187+
def self.action_get_winrm_password
188+
Vagrant::Action::Builder.new.tap do |b|
189+
b.use ConfigValidate
190+
b.use ConnectAWS
191+
b.use GetWinRMPassword
192+
end
193+
end
194+
187195
# The autoload farm
188196
action_root = Pathname.new(File.expand_path("../action", __FILE__))
189197
autoload :ConnectAWS, action_root.join("connect_aws")
@@ -204,6 +212,7 @@ def self.action_reload
204212
autoload :WarnNetworks, action_root.join("warn_networks")
205213
autoload :ElbRegisterInstance, action_root.join("elb_register_instance")
206214
autoload :ElbDeregisterInstance, action_root.join("elb_deregister_instance")
215+
autoload :GetWinRMPassword, action_root.join("get_winrm_password")
207216
end
208217
end
209218
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
require "fog"
2+
require "log4r"
3+
4+
module VagrantPlugins
5+
module AWS
6+
module Action
7+
# This action connects to AWS, verifies credentials work, and
8+
# puts the AWS connection object into the `:aws_compute` key
9+
# in the environment.
10+
class GetWinRMPassword
11+
def initialize(app, env)
12+
@app = app
13+
@logger = Log4r::Logger.new("vagrant_aws::action::get_winrm_password")
14+
end
15+
16+
def call(env)
17+
machine = env[:machine]
18+
19+
if machine.config.winrm.password == :aws
20+
machine.ui.info(I18n.t("vagrant_aws.getting_winrm_password"))
21+
22+
aws = env[:aws_compute]
23+
response = aws.get_password_data({ instance_id: machine.id })
24+
password_data = response.body['passwordData']
25+
password_data_bytes = Base64.decode64(password_data)
26+
27+
# Try to decrypt the password data using each one of the private key files
28+
# set by the user until we hit one that decrypts successfully
29+
machine.config.ssh.private_key_path.each do |private_key_path|
30+
private_key_path = File.expand_path private_key_path
31+
32+
@logger.info("Decrypting password data using #{private_key_path}")
33+
rsa = OpenSSL::PKey::RSA.new File.read private_key_path
34+
begin
35+
machine.config.winrm.password = rsa.private_decrypt password_data_bytes
36+
@logger.info("Successfully decrypted password data using #{private_key_path}")
37+
rescue OpenSSL::PKey::RSAError
38+
@logger.warn("Failed to decrypt password data using #{private_key_path}")
39+
next
40+
end
41+
42+
break
43+
end
44+
end
45+
46+
@app.call(env)
47+
end
48+
end
49+
end
50+
end
51+
end

lib/vagrant-aws/capability.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require "vagrant/action/builder"
2+
3+
module VagrantPlugins
4+
module AWS
5+
module Capability
6+
class WinRMInfo
7+
def self.winrm_info(machine)
8+
machine.action("get_winrm_password")
9+
return {}
10+
end
11+
end
12+
end
13+
end
14+
end

lib/vagrant-aws/plugin.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ class Plugin < Vagrant.plugin("2")
3434
Provider
3535
end
3636

37+
provider_capability(:aws, :winrm_info) do
38+
setup_logging
39+
40+
require_relative 'capability'
41+
Capability::WinRMInfo
42+
end
43+
3744
# This initializes the internationalization strings.
3845
def self.setup_i18n
3946
I18n.load_path << File.expand_path("locales/en.yml", AWS.source_root)

locales/en.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ en:
6262
will_not_destroy: |-
6363
The instance '%{name}' will not be destroyed, since the confirmation
6464
was declined.
65+
getting_winrm_password: |-
66+
Getting WinRM password from AWS...
6567
6668
config:
6769
access_key_id_required: |-

0 commit comments

Comments
 (0)