diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index 0577c58f3..64ad08f9c 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -53,6 +53,7 @@ type Config struct { SSHAuthorizedKeyFile string `mapstructure:"ssh_authorized_key_file"` SFTPCmd string `mapstructure:"sftp_command"` UseSFTP bool `mapstructure:"use_sftp"` + InventoryDirectory string `mapstructure:"inventory_directory"` inventoryFile string } @@ -249,7 +250,7 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { go p.adapter.Serve() if len(p.config.inventoryFile) == 0 { - tf, err := ioutil.TempFile("", "packer-provisioner-ansible") + tf, err := ioutil.TempFile(p.config.InventoryDirectory, "packer-provisioner-ansible") if err != nil { return fmt.Errorf("Error preparing inventory file: %s", err) } @@ -300,9 +301,16 @@ func (p *Provisioner) Cancel() { os.Exit(0) } +func (p *Provisioner) getInventoryArg() string { + if len(p.config.InventoryDirectory) != 0 { + return p.config.InventoryDirectory + } + return p.config.inventoryFile +} + func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator, privKeyFile string) error { playbook, _ := filepath.Abs(p.config.PlaybookFile) - inventory := p.config.inventoryFile + inventory := p.getInventoryArg() var envvars []string args := []string{playbook, "-i", inventory} diff --git a/provisioner/ansible/provisioner_test.go b/provisioner/ansible/provisioner_test.go index 13042c5e1..60098ac32 100644 --- a/provisioner/ansible/provisioner_test.go +++ b/provisioner/ansible/provisioner_test.go @@ -76,6 +76,12 @@ func TestProvisionerPrepare_Defaults(t *testing.T) { if err != nil { t.Fatalf("err: %s", err) } + + config["inventory_directory"] = "some_directory" + err = p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } } func TestProvisionerPrepare_PlaybookFile(t *testing.T) { @@ -246,6 +252,55 @@ func TestProvisionerPrepare_LocalPort(t *testing.T) { } } +func TestProvisioner_getInventoryArg(t *testing.T) { + var p Provisioner + config := testConfig(t) + defer os.Remove(config["command"].(string)) + + hostkey_file, err := ioutil.TempFile("", "hostkey") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.Remove(hostkey_file.Name()) + + publickey_file, err := ioutil.TempFile("", "publickey") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.Remove(publickey_file.Name()) + + playbook_file, err := ioutil.TempFile("", "playbook") + if err != nil { + t.Fatalf("err: %s", err) + } + defer os.Remove(playbook_file.Name()) + + config["ssh_host_key_file"] = hostkey_file.Name() + config["ssh_authorized_key_file"] = publickey_file.Name() + config["playbook_file"] = playbook_file.Name() + + err = p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } + + p.config.inventoryFile = "somefile" + if p.getInventoryArg() != "somefile" { + t.Fatal("getInventoryArg should return inventoryFile if InventoryDirectory is not set.") + } + + // Uses InventoryDirectory if set + config["inventory_directory"] = "somedirectory" + err = p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } + + if p.getInventoryArg() != "somedirectory" { + t.Fatal("getInventoryArg should return InventoryDirectory if InventoryDirectory is set.") + } +} + func TestAnsibleGetVersion(t *testing.T) { if os.Getenv("PACKER_ACC") == "" { t.Skip("This test is only run with PACKER_ACC=1 and it requires Ansible to be installed") diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 316263538..61f263fc5 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -113,6 +113,15 @@ Optional Parameters: - `user` (string) - The `ansible_user` to use. Defaults to the user running packer. +- `inventory_directory` (string) - The directory in which to place the + generated ansible inventory file. If this is specified, then this directory + is what will get passed to the `-i` argument of the `ansible` command when + this provisioner runs Ansible. By default, the generated ansible inventory + will be placed in a temporary file in the system-specific temporary file + location, and the fully-qualified name of this temporary file will be passed + to the `-i` argument of the `ansible` command when this provisioner runs + ansible. + ## Limitations ### Redhat / CentOS