Thinking about new modules: test module

Hi all,

I have a new module idea but no implementation at all. This email is
just a problem presentation.

Recently, DevOps people in Japan begin to use serverspec[1] to test
target host environment.

The serverspec is written in RSpec. Below is an example about httpd is
installed and working correctly.

    describe package('httpd') do
      it { should be_installed }
    describe service('httpd') do
      it { should be_enabled }
      it { should be_running }
    end
    describe port(80) do
      it { should be_listening }
    end
    describe file('/etc/httpd/conf/httpd.conf') do
      it { should be_file }
      it { should contain "ServerName www.example.jp" }
    end

You may think "This is same as PlayBooks. I don't need it". But this
is "Test for Playbook(or Recipe)". Many people accept "Test for source
code", why not this?

serverspec is written in Ruby, and many people are using with Chef.
But if it with Ansible, we can

- check current environment before play
- or, check the environment is correct after play
- or, if the environment is different from the assumption, send a notification
  by using notification modules.

So, I want to ask you who are interested in the Configuration Management,

1. What do you think about this kind of test tool (in general)?
2. How about to add this type of tool as ansible module?
3. If this idea is good, how to implement and write test configuration?
   (we should re-implement by Python)

I have written a similar tool on top of the fabric, called envassert[2].
But I think this implementation is not so good because of lack of test
suite and less functionality.

Currently I have no time to design and implement. If someone thinks
this is good and try to implement, I appreciate.

Any thought?

Regards,
WAKAYAMA Shirou

[1] http://serverspec.org/
[2] https://bitbucket.org/r_rudi/envassert

Hi,

This reminds me a little of what I have done in a few roles. Eg. the last tasks in a network configuration role are:

  • name: read short hostname
    command: /bin/hostname -s
    register: read_hostname_short
    ignore_errors: yes

  • name: test short hostname
    fail: msg=“Incorrect short hostname set (got {{ read_hostname_short.stdout }}, but should be {{ node_name }}).”
    when: read_hostname_short.stdout != node_name

  • name: test ping www.google.com
    command: /bin/ping -c 1 -w 3 www.google.com

They shouldn’t fail and if they do there is something seriously wrong.

For your given example in serverspec maybe the most useful test would be if you get the correct web page when accessing port 80, this can be done with the uri module. There is no need to check each detail, because Ansible should do them correctly, just the end result that depends on all the previous details.

Greetings,
gw

Folks are definitely embedding tests in playbooks by tasks, like the above.

My question about serverspec is just that it looks very much like another syntax (Cucumber or RSpec) which clashes a lot with the aesthethics of Ansible being a simple data format.

Having a “test/” namespace of modules in Ansible core though, could be VERY interesting, like “is_port_open: port=80 [host=XYZ]”, etc.

That way you could embed the tests in your Ansible playbook directly (as some are doing) but still have some higher level checks.

As for the idea of checking file permissions, I don’t know – it seems that’s the job of the module to get right, so you are also writing more tests than you need to, which Ansible believes you shouldn’t have to do. In enforcing the state of the module, the module makes it so, so the check would be redundant.

But something like:

post_tasks:

  • is_port_open: port=80
  • is_process_running: httpd

etc, I could kind of see liking, provided it did not duplicate too much with other modules.

post_tasks is already an Ansible 1.2 feature and is just a list of tasks that run after any handlers in the main block. They are useful (pre_tasks/post_tasks) in dealing with load balancers and monitoring outage windows, for instance.

Hi gw and Micheal,

This reminds me a little of what I have done in a few roles.

I feel easy when I read this. Maybe many other people also have.

My question about serverspec is just that it looks very much like *another* syntax (Cucumber or RSpec) which clashes a lot with the aesthethics of Ansible being a simple data format.

Sorry to write too little. That serverspec is just an example.
serverspec is written in Ruby so RSpec is quite natural.
But in Python, syntax should be changed. perhaps yaml for Ansible.

As for the idea of checking file permissions, I don't know -- it seems that's the job of the module to get right, so you are also writing more tests than you need to, which Ansible believes you shouldn't have to do. In enforcing the state of the module, the module makes it so, so the check would be redundant.

Right. Ansible modules have test in themselves. Instead, I think a
test is written for desired final state on target system wide.

So,

post_tasks:
   - is_port_open: port=80
   - is_process_running: httpd

is Lovely. pre_task is also useful. But this may becomes so long. How
about separates to other files like this? (in test directory you
wrote)

post_tasks:
  - check: src=test/finalstate.yml

This also means that is implemented in a module, not core. I think
check module should have many check points,
it's better to separate from core, I think.
(And if a test file is separated, the other processes can use that easily.)

Thank you,
WAKAYAMA Shirou

post_tasks:

  • check: src=test/finalstate.yml

That syntax doesn’t make sense. Simplify it down to:

post_tasks:

  • tasks/tests/apache.yml
  • tasks/tests/mysql.yml

and you’re golden.

post_tasks:

  • include: path/to/other.yml

should allow keeping things in another file.

I like the idea of this being a lot of modules in a “test/” namespace rather than making it just one main “check” module.

Ah yeah. I meant to include the “include” definition in there.

Hi Michael,

I like the idea of this being a lot of modules in a "test/" namespace rather
than making it just one main "check" module.

hmm. Agree. I have changed my mind.
If there are under "test/" namespace, its easy to add more tests like
    riak_has_key: name="blah"

But I think it may grow shortly so it should be different web pages
from current module page.

Thank you for discussion,
WAKAYAMA Shirou