Merge pull request #6450 from shadycuz/ansible_winrm
Feature: Add randomly generated win_rm password to the ansible provisioner
This commit is contained in:
commit
fe15bc53a8
|
@ -26,6 +26,7 @@ import (
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
|
|
||||||
"github.com/hashicorp/packer/common"
|
"github.com/hashicorp/packer/common"
|
||||||
|
commonhelper "github.com/hashicorp/packer/helper/common"
|
||||||
"github.com/hashicorp/packer/helper/config"
|
"github.com/hashicorp/packer/helper/config"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
|
@ -67,9 +68,19 @@ type Provisioner struct {
|
||||||
ansibleMajVersion uint
|
ansibleMajVersion uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PassthroughTemplate struct {
|
||||||
|
WinRMPassword string
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provisioner) Prepare(raws ...interface{}) error {
|
func (p *Provisioner) Prepare(raws ...interface{}) error {
|
||||||
p.done = make(chan struct{})
|
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{
|
err := config.Decode(&p.config, &config.DecodeOpts{
|
||||||
Interpolate: true,
|
Interpolate: true,
|
||||||
InterpolateContext: &p.config.ctx,
|
InterpolateContext: &p.config.ctx,
|
||||||
|
@ -188,6 +199,25 @@ func (p *Provisioner) getVersion() error {
|
||||||
|
|
||||||
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
|
||||||
ui.Say("Provisioning with Ansible...")
|
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)
|
k, err := newUserKey(p.config.SSHAuthorizedKeyFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -381,7 +411,15 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, pri
|
||||||
go repeat(stdout)
|
go repeat(stdout)
|
||||||
go repeat(stderr)
|
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 {
|
if err := cmd.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -508,6 +546,11 @@ func newSigner(privKeyFile string) (*signer, error) {
|
||||||
return signer, nil
|
return signer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getWinRMPassword(buildName string) string {
|
||||||
|
winRMPass, _ := commonhelper.RetrieveSharedState("winrm_password", buildName)
|
||||||
|
return winRMPass
|
||||||
|
}
|
||||||
|
|
||||||
// Ui provides concurrency-safe access to packer.Ui.
|
// Ui provides concurrency-safe access to packer.Ui.
|
||||||
type Ui struct {
|
type Ui struct {
|
||||||
sem chan int
|
sem chan int
|
||||||
|
|
|
@ -14,7 +14,7 @@ Type: `ansible`
|
||||||
The `ansible` Packer provisioner runs Ansible playbooks. It dynamically creates
|
The `ansible` Packer provisioner runs Ansible playbooks. It dynamically creates
|
||||||
an Ansible inventory file configured to use SSH, runs an SSH server, executes
|
an Ansible inventory file configured to use SSH, runs an SSH server, executes
|
||||||
`ansible-playbook`, and marshals Ansible plays through the SSH server to the
|
`ansible-playbook`, and marshals Ansible plays through the SSH server to the
|
||||||
machine being provisioned by Packer.
|
machine being provisioned by Packer.
|
||||||
|
|
||||||
-> **Note:**: Any `remote_user` defined in tasks will be ignored. Packer will
|
-> **Note:**: Any `remote_user` defined in tasks will be ignored. Packer will
|
||||||
always connect with the user given in the json config for this provisioner.
|
always connect with the user given in the json config for this provisioner.
|
||||||
|
@ -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" ]
|
"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.
|
- `command` (string) - The command to invoke ansible.
|
||||||
Defaults to `ansible-playbook`.
|
Defaults to `ansible-playbook`.
|
||||||
|
@ -72,12 +81,24 @@ Optional Parameters:
|
||||||
These arguments *will not* be passed through a shell and arguments should
|
These arguments *will not* be passed through a shell and arguments should
|
||||||
not be quoted. Usage example:
|
not be quoted. Usage example:
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"extra_arguments": [ "--extra-vars", "Region={{user `Region`}} Stage={{user `Stage`}}" ]
|
"extra_arguments": [ "--extra-vars", "Region={{user `Region`}} Stage={{user `Stage`}}" ]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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
|
- `groups` (array of strings) - The groups into which the Ansible host
|
||||||
should be placed. When unspecified, the host is not associated with any
|
should be placed. When unspecified, the host is not associated with any
|
||||||
groups.
|
groups.
|
||||||
|
@ -146,7 +167,7 @@ commonly useful Ansible variables:
|
||||||
|
|
||||||
To debug underlying issues with Ansible, add `"-vvvv"` to `"extra_arguments"` to enable verbose logging.
|
To debug underlying issues with Ansible, add `"-vvvv"` to `"extra_arguments"` to enable verbose logging.
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"extra_arguments": [ "-vvvv" ]
|
"extra_arguments": [ "-vvvv" ]
|
||||||
}
|
}
|
||||||
|
@ -167,7 +188,7 @@ Redhat / CentOS builds have been known to fail with the following error due to `
|
||||||
|
|
||||||
Building within a chroot (e.g. `amazon-chroot`) requires changing the Ansible connection to chroot.
|
Building within a chroot (e.g. `amazon-chroot`) requires changing the Ansible connection to chroot.
|
||||||
|
|
||||||
``` json
|
```json
|
||||||
{
|
{
|
||||||
"builders": [
|
"builders": [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue