Suitable - A wrapper to simplify the Ansible API

Hi!

I wrote a thing which makes the Ansible API easier to use:
https://github.com/seantis/suitable

We mostly use Puppet for provisioning in our company, but we maintain a number of scripts which do migrations or glue certain things together. For those we use Ansible.

Since using the Ansible API got repetitive quickly I wrote this little wrapper. Michael got wind of it and encouraged me to announce it here.
I’m happy to get feedback on the project and would love to see this or something like this make it into the core.

Though I’d imagine it might need some more nooks and crannies to be useful as an API.

Cheers,

Denis

Hi Denis,

Spoke with you on twitter.

Thanks for posting here – I really do like the idea of higher level API abstractions available in core.

I’m not entirely positive what we’d want a module API to look like but may have some preferences on tweaks:

This part

hosts = Api(['web.seantis.dev', 'db.seantis.dev'])
hosts.user(name='denis')

I think I’d like to see something like AnsibleCaller(authentication=AnsibleAuthentication())

And the auth object could take things like sudo_user/sudo, etc.

Obviously would also want to make sure it worked well with inventory files, etc.

Ultimately I think what we’d want is for this API to be a bit higher level than Runner, and then get AnsiblePlaybook to use it directly.

If all the tests pass, it’s a win!

FYI:

(A) I’m also not sure all the callback stuff is needed in that case.

(B) Getting /usr/bin/ansible to use the same would also be desirable.

I definitely see the case for the authentication abstraction. That would take the runner out of the picture, simplifying the documentation.

For the inventory, the Inventory class would probably do as an alternative to a host list:

hosts=AnsibleCaller(inventory.get_hosts(pattern=‘webserver’), auth)

The problem is that the inventory has all these concepts I don’t use, like host-specific ssh parameters, group variables and so on. Personally I would leave these things out of the API, because I have no use for them. But if this is to be a more general part of the core this sure is a requirement.

So a more complex version would look like this:

hosts=AnsibleCaller(inventory, auth, pattern=‘webservers’)

Like that I could pass the inventory to the runner, so it could do what it needs to do with it. But I don’t know if this makes a lot of sense, because I’m really not that experienced with Ansible. I only picked some parts that helped me do my job :slight_smile:

Maybe we should move this discussion to a Github ticket in the Ansible project to define the api with some example code? I don’t think I’ll implement these things in Suitable as it stands, because it really does what I need it to do at this point.

Aside – I generally don’t like discussions in GitHub tickets, not only are they not threaded, it’s among a much smaller group of people and is easily lost in the issue tracker. Plus, when they get closed, people tend to still comment on them – where no one will reply, and then quickly it becomes a discussion of why someone didn’t reply.

It sounds like we’re not ready for this yet, regardless.

Ultimately I think my question with it is this – it’s nice that folks are interested in the Ansible API and making it easier, though I thought it was premature to cloud PyPi search results. Wait until we have that, and then get it into core. Then it becomes clear that that’s the endorsed way to go.

Otherwise, I’m likely to break you, and I’m definitely not going to keep up with it, so it being in PyPi becomes confusing to people wanting to interface with Ansible.

I recognize that some things – particularly Runner’s “stats” callbacks, are not always the easiest, and I do want to see this made better, but I also want it to be comprehensive.

I don’t mind putting in a warning that it’s probably not the way to go and that people should use Ansible directly if they want something sustainable, if that’s what you’re concerned about. It can obviously break at any point if Ansible changes.

I’m not really after users anyway, I just like my stuff on Github/PyPI because it makes things easy.

Though I think the benefit of a separate library is the fact that allows for experiments that don’t break anything in the core. If this is implemented in Ansible now the interface needs to be stable and it needs to be maintained for a long time.

Most of my concern is PyPi is problematic because it shows up in results when people are trying to install things, where as core has a very large contributor pool, thus we’re likely to have something around that is not well maintained confusing folks trying to use the Ansible API, so it’s better to evolve something in core that we want people using.

“Though I think the benefit of a separate library is the fact that allows for experiments that don’t break anything in the core”

Branches in version control describe this pretty well.

IMHO, PyPi should be for released software people want to maintain for a long time as well – and I can’t entirely guarantee the contact of Runner for what you are doing either.

GitHub’s great, It and GitHub are quite different things, lest PyPi start to turn into CPAN, which it is starting to do.

Ultimately I think the question is do we want to try to make the Runner API easier over time, etc, and should arrive an established way to do that if it’s a need we have.

I understand your point. Of course I cannot promise to support suitable for 10 years (but then few packages released on PyPI come with such a promise). We do however use it internally in a number of projects already, so its not exactly a weekend project either.

Anyway, to make sure that nobody gets confused I added a stern warning to the readme. If someone visits the PyPI page it can’t really be missed. Users ignoring that warning and the fact that there’s next to no docs can’t probably be kept from danger anyhow.

I’ll keep an eye on how this works for us and on the changes in Ansible. I’ll do what’s easier in the long run - keep a separate lib or start an api branch.