-1

I'm presently writing some documentation (specifically on how to set up Ansible with a local Vagrant machine) and I like to list commentary in the form of commands to issue. For example:

  1. Set up the SSH agent:

    ssh-agent bash
    ssh-add .vagrant/machines/default/virtualbox/private_key
    

However, sometimes I find I want to document a change in a config file, which is not so easy to describe. I presently do this:

  1. Configure Ansible to use port 2222 for Vagrant

    Modify /etc/ansible/ansible.cfg to use remote_port = 2222
    

I'd rather do something like this (a theoretical command) as it could be issued quickly and in a more automated fashion than reaching for a text editor:

  1. Configure Ansible to use port 2222 for Vagrant

    ansible-config remote_port 2222
    

This appears to be an ini file, so if the ansible binary doesn't support this (and I can't see that it does), is there a general Linux/Unix way to do this? Failing the above, how about:

iniwrite /etc/ansible/ansible.cfg defaults.remote_port 2222

Of course I could write a script of some kind, but it'd be better not to reinvent the wheel!

I am using Ubuntu 14.04 LTS.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • I think you have write that feature yourself. Would be easy with Python ConfigParser: https://docs.python.org/2/library/configparser.html. – totoro Apr 09 '16 at 16:31

4 Answers4

2

That's precisely one of the problems Ansible is supposed to solve - so you can use it to write its own configuration file. Just create a bootstrap playbook that does all the necessary things on localhost (aside from installing Ansible, of course).

A predecessor to these tools is Augeas. It comes with a default IniFile "lens" that you could use to write various ini entries easily.

Xiong Chiamiov
  • 13,076
  • 9
  • 63
  • 101
  • That's a great idea! Would you recommend the [ini config module](http://docs.ansible.com/ansible/ini_file_module.html)? – halfer Apr 12 '16 at 11:05
  • That module is a nice option if you only want to modify a bit of the file from whatever the user has as a default; if you want to control the entire thing, you can just use [copy](https://docs.ansible.com/ansible/copy_module.html) or [template](https://docs.ansible.com/ansible/template_module.html). – Xiong Chiamiov Apr 12 '16 at 18:48
  • Yeah, in this case it would be editing an existing ini file - the Ansible config itself. – halfer Apr 12 '16 at 19:30
1

I don't know about such a tool and it is definitely not part of the default toolchain you can expect to be installed on your user's systems.

You can use sed:

sed -i 's/^remote_port=.*/remote_port=2222/' ansible.cfg

All GNU/Linux users will understand that especially since you describe what it is doing.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • what about if the config file doesn't have a `remote_port=` line in the first place ? :) – isedev Apr 09 '16 at 16:18
  • That's not really the question here, imo. Am I missing something? – hek2mgl Apr 09 '16 at 16:21
  • I am saying that "modify ... to use ..." doesn't necessarily exclude adding the line if it is not present (rather than just modifying an existing one)... just semantics. – isedev Apr 09 '16 at 16:23
  • Sure, but since it is just documentation, either you assume it is there (imo this is standard for ansible) or you need to describe in the documentation that it need to be present. Of course one could also elaborate on the script, but then it is not so easy to understand anymore imo. – hek2mgl Apr 09 '16 at 16:25
  • This is a good solution (for which many thanks) though isedev's point is a good one - it so happens that the default `ansible.cfg` defines this variable, but a general ini writer should add a key if it does not exist already. However, if it turns out standard Linux does not include a binary to do that, I'll run with this. – halfer Apr 09 '16 at 16:43
  • Yep. `sed` is what you'll find in most such documentations. If that should not work, I would simply tell the user to open a text editor and change the file. – hek2mgl Apr 09 '16 at 17:01
  • @halfer That's probably too hackish :) http://stackoverflow.com/a/27531122/171318 – hek2mgl Apr 09 '16 at 17:11
  • Ah good find @hek2mgl! Since Ansible uses ini groups I guess that would work, although using `git` for it is probably even less clear... `:-)` – halfer Apr 09 '16 at 17:18
1

The ansible-config script could be as simple as:

#!/bin/sh
CFG=/etc/ansible/ansible.cfg
awk '{BEGIN {found=0} END {if(!found){print keyword" = "value}} if($0~"^ *"keyword" *="){print keyword" = "value; found=1}else{print $0}}' \
    keyword="$1" value="$2" $CFG > $CFG.new \
    && mv $CFG.new $CFG \
    || rm -f $CFG.new

Some error checking would be required, etc..., but it gives you the idea.

isedev
  • 18,848
  • 3
  • 60
  • 59
  • Thanks, and upvoted. I am sure this would work, but from a documentation perspective, I'm looking for something that is _easier_ than asking someone to edit a particular line of a file. I'd say the above is even harder, especially if it could use some error checking as well. – halfer Apr 09 '16 at 16:40
  • 1
    Updated answer to cope with the case where the keyword is not already present in the config file. – isedev Apr 09 '16 at 16:45
  • Thanks for this - I am not much of an Awker, but I'll give it a try! – halfer Apr 10 '16 at 12:28
0

Whilst the main point of my question was "how to automate the writing of ini files in general", I have found out how to avoid it for Ansible. The SSH port can be added into the /etc/ansible/hosts file, thus:

127.0.0.1:2222

This overrides the remote_port in the /etc/ansible/ansible.cfg configuration ini file.

halfer
  • 19,824
  • 17
  • 99
  • 186