How to create a simple CI/CD Pipeline with Ansible Tower
CI/CD (Continuous Integration/Continuous Deployment) Pipeline implementation is the backbone of the modern Development environment. It is set of operating principles, and collection of practices that enables application development teams to deliver code changes more frequently and reliably. CI/CD is an agile methodology best practice, it enables software development teams to focus on fulfilling business requirements, maintaining code quality and security. And development of building fully automated workflow goes DevOps team to create create CI/CD pipeline as per business requirements.
Continuous Integration (CI)
It is a DevOps practice of placing automation to integrate individual developer contributions into a shared code repository. This practice encourages committing changes more often, versus committing large changes frequently.
Continuous Delivery (CD)
Continuous Delivery is software development approach which helps developers to automate beyond just unit tests so that they can validate software/application updates across multiple dimensions before deploying code to production environment.
Automated workflows are grouped together in jobs, which are placed in a pipeline. The pipeline defines the order in which the jobs to be executed.
There are no defined rules for the contents of your pipeline, but the basic premise is that pipelines facilitate automated quality control. This automation eliminates the need for human intervention in a reliably repeatable way.
There are few basic jobs which your pipeline may includes.
- It checks syntax to ensure that code does not contain any syntax errors that prevents code compilation.
- “Linting” (running a program to analyze the code) to detect behaviors and practices that could be potentially improved.
- Calling necessary steps to build code to produce a deployable artifact.
- Deploying and installing code on to a server.
- Unit testing: to validate that an individual unit of code (function) works as expected.
- Smoke testing: in the form of cursory, limited tests to ensure that the most important functions work.
- Integration testing: to validate that the individual units of code (functions) work together as expected.
- Regression testing: to verify that new, or recently modified code does not adversely affect existing features (functions).
Above practice helps to rectify most of the issues before deploying code in production and it has many benefits.
- Fast feedback about operational status of code, once it is committed
- End-to-end testing of code is automated when code is checked in, resulting in a faster feedback loop between developers working on the code.
- Facilitates integrating code from committed from different developers.
- It helps to get visibility for developers collaborating on code.
- Developers and testers are able to fail faster, within the same sprint, further reducing the feedback loop.
- Reduced debugging sessions at the end of long sprints.
Basic requirements to start with CI/CD Pipeline:
- Access to Distributed Version Control System
- Test for your code
- Access of CI/CD service to run the tests
Building CI/CD Pipelines with Ansible Tower
Use a CI/CD pipeline, integrated with Ansible Tower, to perform automated routines with each commit to an Ansible Playbook project. Generally a pipeline performs the following steps:
- Pulls the latest version of the playbook from dev branch.
- Performs syntax checking to ensure the sanity of the code.
- Linting to ensure that it adheres to a set of rules.
- Synchronizes the playbook from the dev branch to a Project in Ansible Tower.
- Executes the Job Template against the Inventory defined in Ansible Tower, using the code in the dev branch.
- It verifies the functionality of a critical component in the form of a unit test for the hosts in the Inventory.
- Merging the dev branch to the master branch.
- Synchronizing the playbook from the master branch to a Project in Ansible Tower.
- Executing the Job Template against the Prod Inventory in Ansible Tower, using code from the master branch.
- Validating the functionality of a critical component in the form of a unit test for hosts in the Prod Inventory.
- Also sends a notification to inform the developers of the status of the job.
Automation allows developers to create or edit playbook using their choice of tools or module. Developers can simply commit their code and don’t bother about anything else because after committing, automation CI pipeline integrated with Ansible Tower will take care of everything. Pipeline automates processes that would otherwise have to be performed manually.
Ansible Lint
Ansible Lint is a command line tool used to linting the playbooks. It detect errors, bugs, suspicious code constructs, and stylistic errors that could potentially be improved.
Ansible Lint is basically used by the Ansible Galaxy project to lint and calculate quality scores for content contributed to the Galaxy Hub but in Ansible tower it is coming with lint as a inbuilt feature.
Ansible Lint uses rules from ${PYTHON_PATH}/site-packages/ansiblelint/rules/ in the form of Python modules which may be used as it is or we can also modify according to requirement. Additional user-defined rules may be created and used with the default rules.
Consider below example badly written playbook
[user1@onionlinux ]$ cat playbook.yml --- - name: bad playbook hosts: demo1.onionlinux.com tasks: - command: systemctl mask iptables.service ...
Syntactically, the playbook has no errors, and the ansible-playbook playbook.yml –syntax-check command will state the same.
[user1@onionlinux ]$ ansible-playbook playbook.yml --syntax-check playbook: playbook.yml
Ansible Lint reveals that this is not well written playbook.
[user1@onionlinux ]$ ansible-lint playbook.yml [301] Commands should not change things if nothing needs doing 1 playbook.yml:6 2 Task/Handler: command systemctl mask iptables.service 3 [303] systemctl used in place of systemd module playbook.yml:6 Task/Handler: command systemctl mask iptables.service [502] All tasks should be named playbook.yml:6 Task/Handler: command systemctl mask iptables.service
- Numbers in square brackets will tell us which linting rules (tags) were matched, along with a short description of the issue.
- The filename and the line numbers where the issues were found.
- The names of the problematic tasks.
Rules inside ansible-lint are implemented as Python modules, and are stored in ${PYTHON_PATH}/site-packages/ansiblelint/rules/.
Solving these issues is simplified with help of of ansible-lint.
[user1@onionlinux ]$ cat playbook.yml --- - name: better playbook hosts: demo1.onionlinux.com tasks: - name: Mask iptables.service systemd: name: iptables.service masked: true ... [user1@onionlinux ]$ ansible-lint playbook.yml [user1@onionlinux ]$ echo $? 0
The ansible-lint command is having much better capability to verifying the sanity of a playbook as compared to the ansible-playbook –syntax-check command. Thus, there is no need to use ansible-playbook –syntax-check while using the ansible-lint command.
ansible-lint command implements rules as Python modules, and we can also use our own rule in addition to the default ones.
[user1@onionlinux1 ~]$ ansible-lint -R ~/ansible-lint/custom_rules/ playbook.yml
To override the default rules in ${PYTHON_PATH}/site-packages/ansiblelint/rules/, and instead use only your custom rules, use the ansible-lint command as follows:
[user1@onionlinux1 ~]$ ansible-lint -r ~/ansible-lint/custom_rules/ playbook.yml
To know more about ansible lint, please refer here.
You can read more basic about Ansible in my another post Ansible Deployment .
I hope you like this post “How to create a simple CI/CD Pipeline with Ansible Tower”, if you have any questions? please leave comment below!
Thanks for reading. If you like this post probably you might like my next ones, so please support me by subscribing my blog.
Thanks to provide material on CI/CD ….
Thanks Ashutosh, Please subscribe my website to get all updates.