Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't use ansible inventory file because it is executable

I am trying to run an Ansible inventory file ansible -i hosts-prod all -u root -m ping and it is failing with this message:

ERROR: The file hosts-prod is marked as executable, 
but failed to execute correctly. If this is not supposed 
to be an executable script, correct this with 
`chmod -x hosts-prod`.

I believe this is because I am using Virtual Box and shared folders which is forcing all my files to ug+rwx. And vbox does not permit changing permissions on shared folders (at least shared folders coming from Windows which is my situation)

Is there a way to allow Ansible to run this file? I can see several options:

  1. Edit hosts-prod to become an executable file. I don't know what's involved in this (being new to Ansible, obviously).
  2. Set a configuration option in Ansible to tell it not to run this file as executable - just treat it as the static configuration file it is. I can't find an option to do this, so I suspect it's not possible.
  3. Move the file outside of shared-folders: not an option in my case.
  4. Your better idea..

All assistance/ideas appreciated!

The actual hosts-prod config file looks as follows, so any tips on making it internally executable would be welcome:

web01 ansible_ssh_host=web01.example.com
db01 ansible_ssh_host=db01.example.com

[webservers]
web01

[dbservers]
db01

[all:vars]
ansible_ssh_user=root
like image 761
Steve Midgley Avatar asked Nov 11 '14 07:11

Steve Midgley


People also ask

How do I specify Ansible inventory file?

The default location for inventory is a file called /etc/ansible/hosts . You can specify a different inventory file at the command line using the -i <path> option.

Which is the default Ansible inventory file?

The default location for the inventory file is /etc/ansible/hosts. You can also create project-specific inventory files in alternate locations. The inventory file can list individual hosts or user-defined groups of hosts.

What format are Ansible inventory files formatted it?

yaml inventory – Uses a specific YAML file as an inventory source. — Ansible Documentation.

Which argument is used while executing an inventory file?

The inventory file path can either be specified with “-i” argument or by defining the same in the config file. Inventories can be static or dynamic, or even a combination of both, and Ansible is able to use multiple inventories as well.


2 Answers

@hkariti's answer is first and closest to the original question. I ended up re-writing the config file entirely into a Ruby script and that is working fine. I thought I'd share that code here since finding complete examples for Ansible dynamic inventory files wasn't super easy for me. The file is different from a static file in how you associate variables with machine listings in the inventory (using the _meta tag)..

#!/usr/bin/env ruby
# this file must be executable (chmod +x) in order for ansible to use it
require 'json'
module LT
  module Ansible
    def self.staging_inventory
      {
        local: {
          hosts:["127.0.0.1"],
          vars: { 
            ansible_connection: "local"
          }
        },
        common: {
          hosts: [],
          children: ["web", "db"],
          vars: {
            ansible_connection: "ssh",
          }
        },
        web: {
          hosts: [],
          children: ["web_staging"]
        },
        db: {
          hosts: [],
          children: ["db_staging"]
        },
        web_staging: {
          hosts: ["webdb01-ci"],
          vars: {
            # server specific vars here
          }
        },
        db_staging: {
          hosts: ["webdb01-ci"]
        }
      }
    end
  end
end
# ansible will pass "--list" to this file when run from command line
# testing for --list should let us require this file in code libraries as well
if ARGV.find_index("--list") then
  puts LT::Ansible::staging_inventory.to_json
end
like image 29
Steve Midgley Avatar answered Sep 27 '22 22:09

Steve Midgley


Executable inventories are parsed as JSON instead of ini files, so you can convert it to a script that outputs JSON. On top of that, Ansible passes some arguments to them to a simple 'cat' isn't enough:

#!/bin/bash
cat <<EOF
{
 "_meta": {
   "hostvars": {
     "host1": { "some_var": "value" }
   }
 },
 "hostgroup1": [
   "host1",
   "host2"
 ]
 ...
}
EOF

Not as elegant as a simple 'cat', but should work.

like image 123
hkariti Avatar answered Sep 27 '22 23:09

hkariti