Commit 6d56def1 authored by Joe Gornick's avatar Joe Gornick

Add inventory_file option to Ansible provisioner.

parent dc21bf01
...@@ -39,6 +39,9 @@ type Config struct { ...@@ -39,6 +39,9 @@ type Config struct {
// The directory where files will be uploaded. Packer requires write // The directory where files will be uploaded. Packer requires write
// permissions in this directory. // permissions in this directory.
StagingDir string `mapstructure:"staging_directory"` StagingDir string `mapstructure:"staging_directory"`
// The optional inventory file
InventoryFile string `mapstructure:"inventory_file"`
} }
type Provisioner struct { type Provisioner struct {
...@@ -72,11 +75,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { ...@@ -72,11 +75,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
// Templates // Templates
templates := map[string]*string{ templates := map[string]*string{
"command": &p.config.Command, "command": &p.config.Command,
"group_vars": &p.config.GroupVars, "group_vars": &p.config.GroupVars,
"host_vars": &p.config.HostVars, "host_vars": &p.config.HostVars,
"playbook_file": &p.config.PlaybookFile, "playbook_file": &p.config.PlaybookFile,
"staging_dir": &p.config.StagingDir, "staging_dir": &p.config.StagingDir,
"inventory_file": &p.config.InventoryFile,
} }
for n, ptr := range templates { for n, ptr := range templates {
...@@ -111,6 +115,14 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { ...@@ -111,6 +115,14 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
errs = packer.MultiErrorAppend(errs, err) errs = packer.MultiErrorAppend(errs, err)
} }
// Check that the inventory file exists, if configured
if len(p.config.InventoryFile) > 0 {
err = validateFileConfig(p.config.InventoryFile, "inventory_file", true)
if err != nil {
errs = packer.MultiErrorAppend(errs, err)
}
}
// Check that the group_vars directory exists, if configured // Check that the group_vars directory exists, if configured
if len(p.config.GroupVars) > 0 { if len(p.config.GroupVars) > 0 {
if err := validateDirConfig(p.config.GroupVars, "group_vars"); err != nil { if err := validateDirConfig(p.config.GroupVars, "group_vars"); err != nil {
...@@ -158,6 +170,15 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error { ...@@ -158,6 +170,15 @@ func (p *Provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
return fmt.Errorf("Error uploading main playbook: %s", err) return fmt.Errorf("Error uploading main playbook: %s", err)
} }
if len(p.config.InventoryFile) > 0 {
ui.Message("Uploading inventory file...")
src := p.config.InventoryFile
dst := filepath.Join(p.config.StagingDir, filepath.Base(src))
if err := p.uploadFile(ui, comm, dst, src); err != nil {
return fmt.Errorf("Error uploading inventory file: %s", err)
}
}
if len(p.config.GroupVars) > 0 { if len(p.config.GroupVars) > 0 {
ui.Message("Uploading group_vars directory...") ui.Message("Uploading group_vars directory...")
src := p.config.GroupVars src := p.config.GroupVars
...@@ -217,13 +238,18 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator) err ...@@ -217,13 +238,18 @@ func (p *Provisioner) executeAnsible(ui packer.Ui, comm packer.Communicator) err
// The inventory must be set to "127.0.0.1,". The comma is important // The inventory must be set to "127.0.0.1,". The comma is important
// as its the only way to override the ansible inventory when dealing // as its the only way to override the ansible inventory when dealing
// with a single host. // with a single host.
inventory := "\"127.0.0.1,\""
if len(p.config.InventoryFile) > 0 {
inventory = filepath.Join(p.config.StagingDir, filepath.Base(p.config.InventoryFile))
}
extraArgs := "" extraArgs := ""
if len(p.config.ExtraArguments) > 0 { if len(p.config.ExtraArguments) > 0 {
extraArgs = " " + strings.Join(p.config.ExtraArguments, " ") extraArgs = " " + strings.Join(p.config.ExtraArguments, " ")
} }
command := fmt.Sprintf("%s %s%s -c local -i \"127.0.0.1,\"", command := fmt.Sprintf("%s %s%s -c local -i %s",
p.config.Command, playbook, extraArgs) p.config.Command, playbook, extraArgs, inventory)
ui.Message(fmt.Sprintf("Executing Ansible: %s", command)) ui.Message(fmt.Sprintf("Executing Ansible: %s", command))
cmd := &packer.RemoteCmd{ cmd := &packer.RemoteCmd{
Command: command, Command: command,
......
...@@ -70,6 +70,46 @@ func TestProvisionerPrepare_PlaybookFile(t *testing.T) { ...@@ -70,6 +70,46 @@ func TestProvisionerPrepare_PlaybookFile(t *testing.T) {
} }
} }
func TestProvisionerPrepare_InventoryFile(t *testing.T) {
var p Provisioner
config := testConfig()
err := p.Prepare(config)
if err == nil {
t.Fatal("should have error")
}
config["playbook_file"] = ""
err = p.Prepare(config)
if err == nil {
t.Fatal("should have error")
}
playbook_file, err := ioutil.TempFile("", "playbook")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.Remove(playbook_file.Name())
config["playbook_file"] = playbook_file.Name()
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
inventory_file, err := ioutil.TempFile("", "inventory")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.Remove(inventory_file.Name())
config["inventory_file"] = inventory_file.Name()
err = p.Prepare(config)
if err != nil {
t.Fatalf("err: %s", err)
}
}
func TestProvisionerPrepare_Dirs(t *testing.T) { func TestProvisionerPrepare_Dirs(t *testing.T) {
var p Provisioner var p Provisioner
config := testConfig() config := testConfig()
......
...@@ -39,6 +39,35 @@ Optional: ...@@ -39,6 +39,35 @@ Optional:
* `extra_arguments` (array of strings) - An array of extra arguments to pass to the * `extra_arguments` (array of strings) - An array of extra arguments to pass to the
ansible command. By default, this is empty. ansible command. By default, this is empty.
* `inventory_file` (string) - The inventory file to be used by ansible.
This file must exist on your local system and will be uploaded to the
remote machine.
When using an inventory file, it's also required to `--limit` the hosts to
the specified host you're buiding. The `--limit` argument can be provided in
the `extra_arguments` option.
An example inventory file may look like:
<pre class="prettyprint">
[chi-dbservers]
db-01 ansible_connection=local
db-02 ansible_connection=local
[chi-appservers]
app-01 ansible_connection=local
app-02 ansible_connection=local
[chi:children]
chi-dbservers
chi-appservers
[dbservers:children]
chi-dbservers
[appservers:children]
chi-appservers
</pre>
* `playbook_paths` (array of strings) - An array of paths to playbook files on * `playbook_paths` (array of strings) - An array of paths to playbook files on
your local system. These will be uploaded to the remote machine under your local system. These will be uploaded to the remote machine under
`staging_directory`/playbooks. By default, this is empty. `staging_directory`/playbooks. By default, this is empty.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment