This entry is part 2 of 4 in the series Best Practices

Synopsis

This technical guide provides a detailed overview of best practices for working with Ansible in a busy DevOps team. It covers important concepts such as idempotency and how to secure sensitive information using Ansible Vault. The guide also includes information on how to organize Ansible code in a git repository and best practices for committing changes to a repository.

Summary

This technical guide provides best practices for working with Ansible in a busy DevOps team. It covers important concepts such as idempotency and how to use Ansible Vault to secure sensitive information. The guide also includes information on how to organize Ansible code in a git repository and best practices for committing changes to a repository.

Introduction

Ansible is a popular tool for automating the configuration and management of systems. In a busy DevOps team, it is important to follow best practices when working with Ansible to ensure that the codebase is maintainable and easy to work with.

One key concept to keep in mind when working with Ansible is idempotency. An idempotent operation is one that has the same result whether it is performed once or multiple times. In other words, if an operation is idempotent, it will not change the system
state if it is run multiple times with the same parameters. This is important in Ansible because it allows you to run plays multiple times without causing unintended changes to the system.

To ensure idempotency in ansible, it is important to use the state parameter in tasks. The state the parameter allows you to specify the desired state of a resource, such as whether a package should be installed or uninstalled. Using the state parameter ensures that ansible will only make changes to the system if the specified state is not already met.

Another important aspect of working with ansible is securing sensitive information. It is important to not store sensitive information such as passwords and access keys in plaintext in the ansible codebase. Instead, you can use ansible vault to encrypt sensitive information and store it securely. To use ansible vault, you can create a vault file and use the ansible-vault command to encrypt and decrypt the file as needed.

It is also important to consider how to organize ansible code in a git repository. One way to do this is to create a separate directory for each environment, such as production, staging, and development. This can make it easier to manage and track changes to the ansible codebase.

When committing changes to a git repository, it is important to follow best practices for commit messages and branch names. Commit messages should be concise and describe the changes made in the commit. Branch names should be descriptive and follow a consistent naming convention.

In addition to following best practices for commit messages and branch names, it is also important to use tickets to track development updates. Tickets should include a clear description of the work to be done and any relevant details such as links to relevant resources or dependencies.

Conclusion

By following best practices such as ensuring idempotency and securing sensitive information using ansible vault, and organizing ansible code in a git repository in a structured way, DevOps teams can effectively work with ansible to automate the configuration and management of systems. By following these guidelines, teams can ensure that their codebase is maintainable and easy to work with, enabling them to deliver new features and updates more efficiently.

This entry is part 5 of 5 in the series Learning Ansible

Synopsis

The following guide covers the steps for setting up and configuring an Ansible project using git for source control. It covers the creation of a new git repository, installing and configuring a Python virtual environment, adding requirements to the repository, adding and committing changes to the repository, and configuring pre-commit for automated testing. It also covers basic git workflow principles and best practices, including the use of feature branches, pull requests, and automated testing.

Introduction

Ansible is a powerful tool for automating and managing IT infrastructure. When working with ansible, it is important to follow best practices, including using source control to manage your projects. Git is a popular choice for source control, and in this guide, we will cover how to set up a new ansible project using git.

In this exercise, we will create a new git repository for an ansible project, create a Python virtual environment (venv) to manage dependencies, and configure pre-commit to enforce best practices. We will also cover how to create a requirements.txt file for the repository, and how to exclude the virtual environment from the repository.

Exercise

Create a new git repository, this will be used for an Ansible project

cd $HOME
mkdir projects
cd projects
mkdir ansible-project
cd ansible-project
git init
echo "# ansible Project" > Readme.md
git add Readme.md
git commit -m "Initial commit"
git branch -M main
# Create a new repo in github
git remote add origin git@github.com:{username}/{repo}.git
# Substitute the real values for {username} and {repo} in the command above
git push -u origin main

Create a Python3 virtual environment (venv)

# Create a new virtual environment
virtualenv venv

# Activate the virtual environment
source venv/bin/activate

# Install Ansible
pip install ansible==2.9.7

# Install Pre Commit
pip install pre-commit

# Install Jinja2
pip install jinja2

The Python virtual environment allows us to create an isolated environment for our Python project. This enables us to have a consistent set of packages and versions that are required for the project, regardless of what other packages may be installed on the local machine.

Create a requirements.txt file for the repository

# Run pip freeze to list all the packages that are installed at the moment and their versions
pip freeze

# We want to take note of the main packages and their versions
pip freeze | egrep -i "ansible|pre-commit|jinja2" > requirements.txt

These commands assume that the terminal session that is in use is in an active Python virtual environment. The requirements.txt file will contain a list of the packages and their specific versions that are required for the project. This file is useful for keeping track of the packages that are required for the project, and for reproducing the same environment on other machines.

Add the requirements.txt file to the repository, commit, and push to GitHub

git add requirements.txt
git commit -m "Added python requirements.txt file to repository"
git push origin main

Deactivate the virtualenv

deactivate

The terminal session has now been returned to its previous state, and running a Python command at this point will not use the virtual environment to access modules.

Omit the virtual environment from the git repository

touch .gitignore 
echo "venv" >> .gitignore

Add the .gitignore file to the repository, commit and push to GitHub

git add .gitignore
git commit -m "Added git ignore file"
git push origin main

Note, using two right angle brackets >> will append the entry “venv” to the file .gitignore, if you run the command twice, you will get two entries in your ,gitignore file. If you would like to create and overwrite the file you can use a single right angle bracket e.g. >

Prepare the .pre-commit-config.yaml file

echo -e "repos:\n - repo: https://github.com/ansible/ansible-lint\n rev: stable\n hooks:\n - id: ansible-lint" >> .pre-commit-config.yaml 
echo -e "repos:\n - repo: https://github.com/pre-commit/mirrors-yamllint\n rev: v1.23.0\n hooks:\n - id: yamllint" >> .pre-commit-config.yaml 
echo -e "repos:\n - repo: https://github.com/pre-commit/mirrors-flake8\n rev: v3.8.4\n hooks:\n - id: flake8" >> .pre-commit-config.yaml

The .pre-commit-config.yaml file is used to configure pre-commit

Add the .pre-commit-config.yaml file to the repository, commit and push to GitHub

git add .pre-commit-config.yaml
git commit -m "Added .pre-commit-config.yaml file"
git push origin main

Configure pre-commit to run in the git repository

pre-commit install

Add the pre-commit hooks to the repository, commit and push to GitHub

git add .git/hooks/pre-commit
git commit -m "Added pre-commit hooks to repository"
git push origin main

Verify pre-commit has been installed correctly

Run the following command to confirm that pre-commit is installed correctly:

pre-commit run --all-files

If the installation was successful, you should see output similar to the following:

Checking for added files... 
[INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Initializing environment for https://github.com/pre-commit/mirrors-ansible-lint.
[INFO] Initializing environment for https://github.com/pre-commit/mirrors-flake8. 
[INFO] Initializing environment for https://github.com/pre-commit/mirrors-yamllint.
[INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Installing environment for https://github.com/pre-commit/mirrors-ansible-lint.
[INFO] Installing environment for https://github.com/pre-commit/mirrors-flake8.
[INFO] Installing environment for https://github.com/pre-commit/mirrors-yamllint. ...

If you receive an error, it may be because pre-commit is not installed correctly. In this case, try uninstalling and reinstalling pre-commit:

pip uninstall
pre-commit
pip install pre-commit

Once pre-commit is installed correctly, you can begin using it to enforce your chosen coding standards and practices.

Conclusion

By following the steps in this guide, you should now have a fully configured ansible project that is ready for development. You should have installed ansible and other required python modules into a virtual environment created a requirements.txt file and set up pre-commit to enforce your chosen coding standards. You should now be able to start developing your ansible project with confidence, knowing that your code will be automatically checked and validated before it is committed to your git repository.

This entry is part 2 of 4 in the series DevOps

Ansible is an open-source automation platform that allows you to automate the configuration and management of systems and applications. It uses a simple, human-readable language called YAML to describe the tasks that need to be performed, and it can be used to automate a wide variety of tasks including provisioning and configuration of infrastructure, deploying applications, and managing software and system updates.

One of the key benefits of Ansible is that it is agentless, meaning that it does not require any software to be installed on the target systems in order to manage them. This makes it easy to get started with ansible, as there is no need to install and configure agents or other software on your servers. Instead, ansible relies on the use of SSH to connect to the target systems and execute tasks.

Ansible uses a concept called “playbooks” to describe the tasks that need to be performed. Playbooks are written in YAML and are made up of a series of “plays” that define the tasks to be executed and the systems on which they should be executed. Playbooks can be used to define the desired state of a system or application, and ansible will ensure that the system is configured accordingly.

Ansible also uses the concept of an “inventory” to define the systems that it should manage. The inventory is a list of the systems in your environment and can be defined in a variety of formats including INI and YAML. The inventory can be used to group systems together, making it easy to target specific subsets of systems when running ansible playbooks.

Here is an example ansible playbook that installs and starts the Apache web server on a group of systems:

---
- hosts: webservers
  tasks:
  - name: Install Apache
    yum:
      name: httpd
      state: present
  - name: Start Apache
    service:
      name: httpd
      state: started

This playbook consists of a single play that targets the “webservers” group in the inventory. The play consists of two tasks: the first task installs the Apache web server package using the yum package manager, and the second task starts the Apache service. When this playbook is run, ansible will connect to each of the systems in the “webservers” group and execute these tasks, ensuring that the Apache web server is installed and running on all of the systems.