Merge pull request #6450 from shadycuz/ansible_winrm

Feature: Add randomly generated win_rm password to the ansible provisioner
This commit is contained in:
Megan Marsh 2018-07-18 09:49:48 -07:00 committed by GitHub
commit fe15bc53a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 5 deletions

View File

@ -26,6 +26,7 @@ import (
"golang.org/x/crypto/ssh"
"github.com/hashicorp/packer/common"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
@ -67,9 +68,19 @@ type Provisioner struct {
ansibleMajVersion uint
}
type PassthroughTemplate struct {
WinRMPassword string
}
func (p *Provisioner) Prepare(raws ...interface{}) error {
p.done = make(chan struct{})
// Create passthrough for winrm password so we can fill it in once we know
// it
p.config.ctx.Data = &PassthroughTemplate{
WinRMPassword: `{{.WinRMPassword}}`,
}
err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &p.config.ctx,
@ -188,6 +199,25 @@ func (p *Provisioner) getVersion() error {
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
ui.Say("Provisioning with Ansible...")
// Interpolate env vars to check for .WinRMPassword
p.config.ctx.Data = &PassthroughTemplate{
WinRMPassword: getWinRMPassword(p.config.PackerBuildName),
}
for i, envVar := range p.config.AnsibleEnvVars {
envVar, err := interpolate.Render(envVar, &p.config.ctx)
if err != nil {
return fmt.Errorf("Could not interpolate ansible env vars: %s", err)
}
p.config.AnsibleEnvVars[i] = envVar
}
// Interpolate extra vars to check for .WinRMPassword
for i, arg := range p.config.ExtraArguments {
arg, err := interpolate.Render(arg, &p.config.ctx)
if err != nil {
return fmt.Errorf("Could not interpolate ansible env vars: %s", err)
}
p.config.ExtraArguments[i] = arg
}
k, err := newUserKey(p.config.SSHAuthorizedKeyFile)
if err != nil {
@ -381,7 +411,15 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, pri
go repeat(stdout)
go repeat(stderr)
ui.Say(fmt.Sprintf("Executing Ansible: %s", strings.Join(cmd.Args, " ")))
// remove winrm password from command, if it's been added
flattenedCmd := strings.Join(cmd.Args, " ")
sanitized := flattenedCmd
if len(getWinRMPassword(p.config.PackerBuildName)) > 0 {
sanitized = strings.Replace(sanitized,
getWinRMPassword(p.config.PackerBuildName), "*****", -1)
}
ui.Say(fmt.Sprintf("Executing Ansible: %s", sanitized))
if err := cmd.Start(); err != nil {
return err
}
@ -508,6 +546,11 @@ func newSigner(privKeyFile string) (*signer, error) {
return signer, nil
}
func getWinRMPassword(buildName string) string {
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
return winRMPass
}
// Ui provides concurrency-safe access to packer.Ui.
type Ui struct {
sem chan int

View File

@ -61,6 +61,15 @@ Optional Parameters:
"ansible_env_vars": [ "ANSIBLE_HOST_KEY_CHECKING=False", "ANSIBLE_SSH_ARGS='-o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s'", "ANSIBLE_NOCOLOR=True" ]
}
```
If you are running a Windows build on AWS, Azure or Google Compute and would
like to access the auto-generated password that Packer uses to connect to a
Windows instance via WinRM, you can use the template variable
{{.WinRMPassword}} in this option.
For example:
```json
"ansible_env_vars": [ "WINRM_PASSWORD={{.WinRMPassword}}" ],
```
- `command` (string) - The command to invoke ansible.
Defaults to `ansible-playbook`.
@ -78,6 +87,18 @@ Optional Parameters:
}
```
If you are running a Windows build on AWS, Azure or Google Compute and would
like to access the auto-generated password that Packer uses to connect to a
Windows instance via WinRM, you can use the template variable
{{.WinRMPassword}} in this option.
For example:
```json
"extra_arguments": [
"--extra-vars", "winrm_password={{ .WinRMPassword }}"
]
```
- `groups` (array of strings) - The groups into which the Ansible host
should be placed. When unspecified, the host is not associated with any
groups.