Because we find Ansible, just awesome, we would like to share our experience about contributing on it. We will see, step-by-step, how to contribute on Ansible and generally on a lot of open-source projects. We so will begin it by refreshing you on what is Ansible. Next we will see four steps, how to set-up your environment, how to develop on it, how to perform your first pull-request and then we will see the best process to have your request accepted.
Goals
The goal of this article is, of course, how to become an Ansible contributor, but not only, we will help you to speed up your pull-request merge ! Ansible needs help, and of course everyone is welcome ! Let’s begin!
Prerequisites
Contribute on Ansible implies some prerequisites.
Ansible is written in python so you’ll need different versions to ensure compatibility:
python 2.7
python 3.5
To improve development lifecycle we will use pipenv. Instead, you can use mainstream tools like virtualenv and pip.
Ansible project is hosted on github so you require a github account for deal with it. Github is based on the git version control system, so you’ll need it. You’ll need also docker to have a fully isolated development setup to play your playbooks against. Ansible unit and integration tests have parts also based on docker. For your information, this is a very interesting part to contribute on Ansible.
What’s Ansible?
If you are reading this article, you should probably be already familiar with Ansible… So if you’re not reading it, we’ll explain it quickly…
Ansible is a simple IT automation engine. It is designed to easily configure several servers. It’s a really good devOps partner to automate quickly and easily a CI/CD for example. Ansible have a lot of plugins which are used to manage almost everything in a server, network device, storage bay…. It is easy-to-use; all the configuration and playbooks are simple yaml files and it doesn’t need any agent on managed nodes. Ansible requires only an SSH connection and python installed on the managed server. In fact, that’s not really true since Ansibe can manage windows nodes using the powershell distant connexion. It is fair to say that we will cover only the Linux use cases in this article. Ansible force lies in the capability to easily configure a lot of devices and guaranty that the configuration is consistent in all targets regardless the initial state. How is it done? The concept behind an Ansible module is to be re-enterable!
Ansible have several competitors like, Chef, Puppet, Saltstack, Fabric or others. Why did we choose Ansible? As we said previously, it is easy to use, and don’t need agent. It is fully coded in python which is a language we appreciate and, on top of that, we are using it professionally every days and are really happy with it, of course.
OK, that sounds great, but what’s the price? Ansible is an open-source project which has a growing community and it is really easy to use, so it won’t costs many times (it will even save so much!) and it’s fully free (you can have some support on some modules for professional purposes regarding your use cases).
Let’s see main principles :
We will just define few glossary terms before: There are two kinds of machines used during an Ansible deployment :
- Ansible is executed on a server host called controller
- The servers/devices managed by Ansible are called managed nodes Complete glossary is available here if you need it.
Ansible uses an inventory which defines all managed nodes access in a simple (or multiples) YAML file. Ansible is using SSH to manage nodes. It can deal with a password or key authentication and is able to elevate privileges using su, sudo or several others. You can even use an SSH bastion by simply using ssh args variables or your ssh_config file. This can address almost cases.
To define what to perform on managed nodes you must create playbook. This is still YAML files. You can find some documentation about playbooks here. To avoid having code duplication and win some flexibility I strongly recommend you to use playbooks roles.
We recommend following the best practices to organize your Ansible directory layout. Get more information on how it worksor more generally on Ansible official site The Ansible documentation is really up-to-date, well organized and contained a lots of example. It will be a great help for you.
Why contribute?
Ansible usage has grown up rapidly and many issues are continuously opened. An issue can be a feature request, a bug reporting, or even simply a question to the maintenance team. Rather than considering, ansible need contributors to continue to improve its quality and stability every days. Ansible is an opensource project maintained by the redhat company, so he has to kind of contributors :
- The biggest parts of contributors are volunteers and works on ansible on free times.
- The rest of the contributors are considered as commiters, they are members of the core team.
You can contribute by adding parts of documentation migrate code, fix issues or even adding features. So all contributions are welcomes !
Contributing helps you to improve your skill about ansible but also improve your skills on large distributed development team all around the world. You would become more efficient with git usages, concepts, and a lot of stuffs very useful in the real life. Working on this project allowed us to discover it in depth. We discovered new uses, new modules, and a lot of nice things.
Contributing follow guidelines. These guidelines help developers to learn how to develop on ansible. The community can help you to introduce yourself inside contribution project.
Ansible project is hosted on github you can fork this project and start to work on. The contribution guidelines was describe in the contribution code. For submit your work you must deal with github pull request.
You can also read how to developing modules, and how to testing your work in the official documentation.
If you need help many communication channel are available for that :
IRC channels
IRC meetings
mailing list
You can find several issues on the github project page, select your subject and work on for starting contributing. However you can follow topics projects for summarize issues by themes. Now it’s time to start contributing !
Step 1 – Prepare environment
A. Setup your fork
First, go to the ansible github official page and click on the fork button.
Wait a few moments and now your fork appear in your github account.
Now prepare your local environment.
$ # setup your identity
$ git config –global user.name « <your name> »
$ git config –global user.email « <your-email@example.com> »
$ # setup pushing method
$ git config –global push.default current
Clone your fork localy and place yourself to the right branch:
$ git clone https://github.com/<your-github-account>/ansible
$ cd ansible
$ git checkout devel
Configure your clone for fetching upstream updates:
$ git remote add upstream https://github.com/ansible/ansible
$ # check remotes
$ git remote -v
origin https://github.com/<your-github-username>/ansible (fetch)
origin https://github.com/<your-github-username>/ansible (push)
upstream https://github.com/ansible/ansible (fetch)
upstream https://github.com/ansible/ansible (push)
Synchronize your local clone with upstream:
$ git fetch upstream
…
$ git merge upstream/devel
Update your forked repository
$ git push origin devel
B. Setup your python environment
Ansible is written in python so you need to setup a python develop environment. Setup a new python virtual environment :
$ pipenv –python 3.5 # replace python version for python 2.7
$ pipenv shell
$ # your now in your python virtual environment
Now source ansible development context:
$ source hacking/env-setup
Install base dependencies:
$ pipenv install -r requirements.txt
Ansible come with a lots of development dependencies, you can install all or just a subset in concordance with your development purpose.
If you work on documentation all development dependencies are presents in ./docsite_requirements.txt.
$ pipenv install -r ./docsite_requirements.txt
To working on bugfix, tests, or new features you need to install specific requirements:
$ # minimal subset of requirements to install
$ pipenv install -r ./test/runner/requirements/units.txt
$ pipenv install -r ./test/runner/requirements/integration.txt
$ pipenv install -r ./test/runner/requirements/coverage.txt
$ pipenv install -r ./test/runner/requirements/constraints.txt
$ pipenv install -r ./test/runner/requirements/ansible-test.txt
$ pipenv install -r ./test/runner/requirements/sanity.txt
Step 2 – Take action !
A. Find issues on ansible
Now it’s time to take actions! Now you’ll be able to see what’s going on under the hood of Ansible. First you need helps to find a subject to work on. Ansible gets an issues tracker which will helps you can find ideas or ways of work. If you are neeby with ansible or python I recommend to you to prefer bugfix because it can be more easily at start than directly start to write a new feature. You can filter issues with labels and choose an easy fix by using the easyfix label.
So! Go to the issues tracker and search jobs !
If you want to work on specific subjects or on specific kinds of issues you can apply filters on your research. Parts of filters are based on labels so you can use it to find your happiness. Example :
Consider you want to works on the docker features of ansible, for fixing a bug or implement a new feature, you research for appropriated label and find the existing label docker. So apply this filter to your research and reach only the issues in connection with docker subject.
Also you can filter for kind of issues (fix or feature) and refine your research.
B. Start to work
Well! You have your development environment, you know basically how to work on ansible, how about actually starting to work?
On the ansible project the default git branch is devel, devel correspond to the latest version of this product. Ansible ask to you to work on the devel branch by creating a new local feature branch based on this. Backports between versions of ansible as managed by the core team. Consider you want to fix a bug on docker module so the workflow looks like this :
$ git checkout devel
$ git checkout -b fix-docker-module
You are now on your new branch fix-docker-module. You can start to work on and to try to resolve your bug. Patches should always be made against the devel branch. For more information you can read the official ansible contributing guide.
Now you have start to work you must be careful about coding rules best practices.
C. Apply coding rules best practices
Ansible is maintained by lot of people so this project needs to impose some development guidelines for to ensure project quality, stability, and maintainability.
Ansible’s aesthetic encourages simple, readable code and consistent, conservatively extending, backwards-compatible improvements. When contributing code to Ansible, please observe the following guidelines :
Code developed for Ansible needs to support Python2-2.6 or higher and Python3-3.5 or higher. Use a 4-space indent, not tabs.
- Ansible team does not enforce 80 column lines; up to 160 columns are acceptable.
- Ansible team does not accept ‘style only’ pull requests unless the code is nearly unreadable.
- Ansible are not strictly compliant with PEP8.See PEP8 for more information.
- Ansible are not strictly compliant with PEP8 but we still want to encourage you to respect this standard.
More information about coding rules are available here.
D. Test your works
Ansible was battery included this mean that ansible come with a lot of included features, and offers to you many functionalities very useful during your developments. Ansible comes with a full suite of tests that avoiding to introduce bugs or breaking some functionalities. You so have to pass these tests and should write or improve existing if you find a lack on some. You do not need an issue for that, feel free to contribute on it, it will be a great improvement.
Before submit your works to the official project you must pass all these tests in your local environment. These tests are automatically launching during continuous integration (CI) steps of the upstream project. When your works was submitted to the ansible team CI execute tests automatically. If something went wrong your work it automatically rejected by the CI robot (ansibulbot) or by maintainers.
We can define 4 major kinds of tests :
- Compile: test python code against a variety of Python versions.
- Unit: tests directly against individual parts of the code base.
- Sanity: the primary purpose of these tests is to enforce Ansible coding standards and requirements.
- Integration: functional tests of modules and Ansible core functionality.
Now we want to focus only sanity and unit tests. These tests are commons tests for any ansible contributors. Others test (compile and integration) are less used for basic contributions.
Unit tests are tested functionalities to determine whether they are fit for use. If something went wrong you can rapidly determine where the problem occur and fix it immediately.
Sanity checks syntax and coding rules. With it you can ensure that you have applied all the best practices in use on this project.
Well! Now we want to explain to you how to deal with tests.
At step 1 we already have setup your development environment so you already have all tools for launch tests. All testing modules was available via the ansible-test command.
You can use them like this :
$ # sanity tests
$ ansible-test sanity # pass all sanity checks
…
$ ansible-test sanity –test pep8 # or define a specific test to run
…
$ # unit tests
$ ansible-test unit –tox apt # for testing the apt ansible module
$ ansible-test unit –tox –python 3.5 # for using unit test with specific version of python
For more general information about ansible tests you can read the official documentation.
Testing help you to prevent regression on your implementations, but the quality of the ansible project is also due to the fact that the contributors take care to maintain a proper version of control history.
E. Maintain a properly and semantic git history
Before submitting your work to the ansible team you must ensure yourself to have a proper git history.
What’s a proper git history? This is a semantical history that helps code reviewing and project maintainability.
Example, consider you have worked on new feature implementation, so you have made a lot of commits. Some commits was semantically valid, but others can be caused by mistakes in your development. For example fixing a bug introduced during previous commit on the same feature.
These commits can make code review hard and annoying.
After all, the fix commit is just a repair of your own implementation, the upstream project does not need to know your fix…
You can squash the fixing commit in the main commit where your core implementation comes to life. So consider these 2 commits, 1 for the main implementation, 1 for the fix, and squash them together :
$ git log
commit af15df42cd4af5f545952d00da5451fe75ae672f
Author: Hervé Beraud <herveberaud.pro@gmail.com>
Date: Thu Oct 26 16:32:18 2017 +0200
fix a problem on my own code
commit be49777a8b859c1c67b82fad0a0c79fa1510d5af
Author: Hervé Beraud <herveberaud.pro@gmail.com>
Date: Thu Oct 26 14:30:01 2017 +0200
implement a new feature
You can see your 2 commits on your history, now squash them together:
$ # now squash your history
$ git rebase -i HEAD~2
pick be49777a implement a new feature
pick af15df42 fix an problem on my own code
Now you can tell git what to do with each commit. Let’s keep the commit be49777a, the one where we added our feature. We’ll squash the following commit into the first one – leaving us with one clean commit with features X in it. You can rewrite the commit message or keep it intact.
pick be49777a implement a new feature
squash af15df42 fix an problem on my own code
Now you have a proper and semantic git history
$ git log
commit be49777a8b859c1c67b82fad0a0c79fa1510d5af
Author: Hervé Beraud <herveberaud.pro@gmail.com>
Date: Thu Oct 26 14:30:01 2017 +0200
implement a new feature
Other subject, you can also rewrite your commits message by using the –amend git option. This option allow to you to rewrite bad message or make it more semantic.
Ansible maintainers will appreciate that and you will be grateful.
Now you have made a really good job, let’s push your works on your fork together!
f. Push your works on your github repository
At this point, you’ve done your development, you’ve tested it and get a properly history, we think you can push your modifications to your own fork.
This is a really simple action, just one command to tip on your keyboard:
$ git push origin <your-branch-name>
If you already have pushed modifications to your fork and that you want to rewrite history before submitting your new pull request you can force to push your modifications by using the option –force to the git push command:
$ git push –force origin <your-branch-name>
Keep in mind to never delete your development branch before it is fully integrated to the upstream project.
Now you can start to submit your pull request to the official project.
Step 3 – Make a pull request
Congrats! You should be ready now to create your first pull request (PR) on ansible project.
a. Create a pull request on ansible github project.
You now have pushed your new branch into your fork. The next step is now to create the PR. to do this, let’s go to the ansible github project page: https://github.com/ansible/ansible. You should see a button ‘Compare & pull request’ on the top of the page:
You simply have to click it (of course) and you’ll be able to check if you’re not trying to PR unwanted commits or have a look to your code to visually check that everything seems ok. You have to double check at this step that you are asking a merge to devel branch.
Once it looks good for you, click « Create pull request » and, congrats, your request is proposed to ansible community! Few seconds after created it, the CI will run all the relevant tests against your new MR while a bot will take care of it and add several labels regarding your code. If the CI is correct and pass all the tests, the bot will ping some relevant maintainers to review your PR. For example, if you are trying to fix an issue on a module, the bot will ping the module’s authors and maintainers. The goal from this point is to obtain two shipit (or LGTM) to have your PR merged, we will treat this in step 4.
step 4 – What’s happens next?
Now you have submitted your pull request to the official ansible project, you may be confronted to two possible cases.
First, after a code review maintainers can ask you to apply changes in your code.
Secondly, your changes look good and you get two shipit.
Now we want to explain how to deals with these use cases.
a. How to integrate modifications to the PR
After a code review maintainers can ask you to apply some changes in your developments.
If you want your work being merged, you have to apply these review comments, it’s a sine qua non condition.
So in your local environment apply these changes on the branch related to your pull request.
When you have fix the review comments, you can push your modifications into your fork:
$ git push origin <your-branch-name>
Then, your changes are automatically integrated to the already existing pull request. You have just to notify the comments author to review your changes.
@reviewer_name changes applied!
If your changes are accepted the reviewer can approve these by sending a shipit to your pull request.
b. Obtain 2 shipit
To get your changes merged in the official project you need to obtain at least 2 shipit.
Shipit is a keyword recognized by the ansibulbot.
If your modifications are on a community module the ansibulbot can automatically merge your changes with the official repository source code, else, if your changes are on a core module, your modifications are merged by a core maintainer and can be rejected by him if something went wrong.
The community is very active, code review and shipit can happen faster than you think.
We recommend you to check periodically the status of your merge request. If your pull request doesn’t move forward you can ask module maintainers for a review.
Do not stay inactive and be proactive about your work !
Conclusion
Ansible is an indispensable tool, used by DevOps, system engineers, and a lot of teams and projects all around the world. Have deep knowledge on this technology is a great asset to your career, especially for DevOps/system jobs. In addition to that contributing to ansible helps this product to be more efficient and great !
With this article we have introduced to you on how to become contributors and make ansible more understandable.
We hope you liked our article, and do not hesitate to contact us to discuss with us.
About the authors
Sébastien Boyron (dj4ngo)
Sébastien Boyron is contributing to the ansible project and is interested by Openstack-ansible, Openstack-infra, Openstack-monitoring, docker on ARM and docker security. He is a system engineer affected by DevOps philosophy, automation and Infrastructure-as-a-Code.
He’s currently Technical leader in GNU/Linux, cloud and virtualization at Squad.
Hervé Beraud is contributing to the ansible project it was also contributor on Alpine Linux and somes others projects and stuffs. He’s a python addict, and DevOps enthusiastic. Also he’s specialized on CI/CD workflow, methods, and best practices on Openstack tripleO technologies and he use ansible every day at works.
He’s currently Lead DevOps Engineer and Python expert at Squad.