This repository belongs in a family of repository templates:
- ansible-project-template
- ansible-inventory-template
- ansible-role-template
- TODO: Collection?
This repository is part of a set of template repositories. Ansible best practice suggests an Ansible Project repository and separate repositories for your Ansible Roles. The purpose of having an Ansible Project repo is to maintain a single source of truth with regards to the following elements:
- Inventory (environments, hosts, groups, platforms)
- Configuration Management (variables)
- Plugins for custom behavior
- Linting rules for Continuous Integration tests
- Playbooks to run each various use cases
- Vagrantfile definitions for testing
- and more
Ansible Playbooks
should ...
- be very short and simple and readable
- answer the questions of WHERE and WHAT
- contain one or more Plays
- be a high level workflow
Ansible Roles
should ...
- be environment-agnostic
- answer the question of HOW
- be built independently from the Ansible Project repository which allows any Ansible Playbook to use the Ansible Role and run the tasks against any environment
- be a reusable, encapsulated, and environment-agnostic object
- Multi-OS-Family To determine if your target node is a Linux or Windows system, you could use the following trick to check the open port. This makes the assumption that the Windows servers do not support SSH on port 22.
Do the following steps to enable linting and code syntax highlighting and immediate testing and module help.
- Enable Ansible Lint
# Configure Ansible Lint in your repository
mkdir -p .config && wget https://raw.githubusercontent.com/ansiblejunky/ansible-project-template/master/.config/ansible-lint.yml -O .config/ansible-lint.yml
# Configure GitHub Actions to trigger Ansible Lint for every push/pull-request
mkdir -p .github/workflows && wget https://raw.githubusercontent.com/ansiblejunky/ansible-project-template/master/.github/workflows/ansible-lint.yml -O .github/workflows/ansible-lint.yml
# TODO: add info for bit bucket
-
Install the VSCode Ansible Extension
-
Configure Ansible extension
- Configure the settings for the extension to use your custom execution environment image you built using
ansible-builder
- Configure the settings for the extension to use your custom execution environment image you built using
-
Using Ansible extension
- You can show module options as you edit your playbook by enabling VSCode IntelliSense: Ctrl+Space
- When issues arrise or odd behavior from the Ansible extension, view the VSCode
Output
window (View -> Output menu item) and selectAnsible Support
in the drop down on the right side to see what is happening inside the extension - To log issues with the extension use vscode-ansible GitHub repository
-
Generate latest
ansible.cfg
using the ansible-config tool -
Extensions
- TODO Highlight
- Python auto formatters
- [Docker]
- [Dev Containers]
- [Jinja]
- [Remote Development]
- [Vagrant]
- [CloudFormation Linter]
- [AsciiDoc]
-
TODO: Add
content/plugins
folder and explain in README (or insist plugins are created in separate repo as ansible role or collection?) -
TODO: how to use makefile or something to run ansible-navigator commands to run a playbook in VSCode
-
TODO: Add python lint config file in this repo too, since ansible has python modules, etc; consider flake8 or pylint and using VSCode python linting methods here
This repository has customized the Ansible Configuration file to set the opinionated path for all Ansible content (Roles, Collections, Plugins) to the content folder.
content/roles/requirements.yml
defines the Ansible Role dependencies that are used by our Ansible Playbookscontent/collections/requirements.yml
defines the Ansible Collection dependencies that are used by our Ansible Playbooks
# download ansible roles
ansible-galaxy role install -r content/roles/requirements.yml
It is recommended to change the default setting in ansible.cfg
from using implicit
gathering to explicit
. This forces developers to explicitly state that facts need to be gathered for particular hosts, otherwise it can result in unwanted fact gathering tasks that consume time.
This is set in the ansible.cfg
file:
gathering = explicit
Variables can be defined in many different places in this repo.
This repo implements linting
as part of the CI pipeline to ensure we fail early and fail fast
. This is accomlished with custom configuration files for both ansible-lint and yamllint.
Run local linting tests manually by performing the following command:
ansible-lint playbooks/myplaybook.yml
In today's world of hybrid cloud, you have multiple stages (dev, test, and prod) as well as when you have multiple platforms (AWX, Google Cloud, Azure, VmWare, etc) that have their own multiple stages (dev, test, prod). To address the challenge of managing these multi-stage environments
with Ansible, it is recommended to read through the following resources. No matter the situation, it is important to establish a good inventory structure so you can manage your configuration (vars) appropriately.
- How to Manage Multistage Environments with Ansible.
- Managing multiple environments with Ansible - best practices
- Ansible Playbook Structure
- Ansible: Directory Layout
Also consider the following good practices:
- Setting a default inventory in the Ansible Configuration File using the
inventory
setting. This allows you to leave off explicit inventory flag (-i) and improve development turnaround time. - Leverage the power of the
group_vars
folder to implicitly load your configuration - Test your inventory using the
ansible-inventory
command:ansible-inventory -i inventory --list
. Ensure you do not see any warning messages and you see the desired output. Variables should be assigned to hosts and group names should be listed appropriately under the right parent groups and so on.
More inventory information can be found here.
Ansible can be extended using custom plugins and modules, which are written in Python code. As a general rule of thumb, only develop plugins and modules on an as-needed basis - do not directly write a module just because you want to integrate with a new system. It is not always necessary. Automation is not about writing code - it should be focused on writing meta-language (YAML) that describes "desired state".
- Filter Plugins
Place your custom filter plugins inside the
plugins/filter
folder. Reference the following filter plugin examples from Ansible core filters.
It is recommended to get familiar with the common filter functions such as default
, mandatory
, etc. Filter functions stem from Jinja and help transform data.
- For Jinja core filter functions see the list of builtin filters.
- For Ansible core filter functions see this page.
Some common filter functions:
TODO: add info to create job template too Now that you have established an inventory structure and infra-as-code, it's time to move your inventory into Ansible Automation Platform (AAP).
- Create a new Project pointing to the Ansible Project version control repo
- Create a new Inventory
- Create a new Inventory Source in the new Inventory object you created
- Select "Source from a Project"
- Select the Project you created
- Select the inventory file as the source
- Synchronize the Inventory Source to make sure it succeeds
- Notice now that your Inventory object contains the vars and hosts and groups from the inventory structure
- Notice it loaded the variables from within the
group_vars
folder as well!
TODO: Add info
- The Inside Playbook - USING ANSIBLE AND ANSIBLE TOWER WITH SHARED ROLES
- Rolling Updates, Performance, Strategies
BSD
John Wadleigh
Ansible Framework:
Playbook:
- hosts: localhost #connection: local
TODO: get the framework from HCSC that checks for Windows or Linux machine using port check!
(payload provided from external system)
tasks:
-
include_role: name: provision vars: os_string: "{{ item.os_string }}" ... with_items: "{{ buildlist }}" when: ansible_os_family == windows
-
include_role: name: provision vars: os_string: "{{ item.os_string }}" ... with_items: "{{ buildlist }}" when: ansible_os_family == linux
-
hosts: windows gather_facts: true
tasks:
- do things
-
hosts: linux gather_facts: true
tasks:
- do things
Ansible Role:
defaults/ main.yml tasks/ main.yml linux_do_something.yml windows_do_something.yml vars/ main.yml (platform agnostic vars) port: 80 linux.yml install_path: /opt/app windows.yml install_path: c:\sdjfk
main.yml:
- include_tasks: "{{ ansible_os_family }}_do_something.yml"
update role before do below
$ ansible-galaxy role install -r content/roles/requirements.yml
Need private key to access to environment on Azure
$ export PRIVATE_KEY=~/.ssh/id_rsa
Check your config before deploy it to node
$ ansible-playbook -vvv --private-key $PRIVATE_KEY --check playbooks/rtpengine_prepare_env.yaml
$ ansible-playbook -vvv --private-key $PRIVATE_KEY --check playbooks/rtpengine_install.yml
with vault password
- want to run without cache add
--flush-cache \
- want to apply without check , remove
--check
ansible-playbook -vvv --private-key $PRIVATE_KEY --check \
--ask-vault-password \
--extra-vars @encrypted_pass.yml \
playbooks/rtpengine_prepare_env.yaml
build and install rtpengine
- add
an-archive.trafficmanager.net/debian bullseye-backports main
to /etc/apt/sources.list
before run if lack of packages - install
sudo apt install linux-headers-$(uname -r)
ansible-playbook -vvv --private-key $PRIVATE_KEY --check \
--ask-vault-password \
--extra-vars @encrypted_pass.yml \
playbooks/rtpengine_install.yml
Install needed resources before apply playbook for rtpengine on new Env
$ ansible-playbook -vvv --private-key $PRIVATE_KEY playbooks/rtpengine_prepare_env.yaml
Provision RTP engine to target Env
$ ansible-playbook -vvv --private-key $PRIVATE_KEY check playbooks/rtpengine_install.yml
Sometimes you need more perl module to check and run with rtpengine, if you need it please add `cpan Socket6 Bencode
Need private key to access to environment
$ export PRIVATE_KEY=~/.ssh/id_rsa
to use the 'ssh' connection type with passwords or pkcs11_provider, you must install the sshpass program"
check sshpass
is available in remote server
$ sshpass -V
if sshpass
is not exist, we have to install it
$ sudo apt install sshpass
Create encrypted key:value used to used to run playbook
$ ansible-vault encrypt_string 'your_sudo_password' --name 'ansible_sudo_pass' > encrypted_sudo_pass.yml
or you want another version using vault $ ansible-vault encrypt_string 'your_sudo_password' --name 'ansible_sudo_pass' --ask-vault-password > encrypted_sudo_pass.yml
$ ansible-vault encrypt_string 'your_sudo_password' --name 'ansible_ssh_pass' --ask-vault-password > encrypted_ssh_pass.yml
or in situation we need both ssh_pass and sudo_pass we have to build a yml file like this
---
- ansible_ssh_pass: 'your_ssh_password'
- ansible_sudo_pass: 'your_sudo_password'
then encrypt it with ansible-vault
$ ansible-vault encrypt --ask-vault-password encrypted_pass.yml
validate again by
$ ansible-inventory --extra-vars @encrypted_pass.yml --ask-vault-password --list
add key to your ssh-agent
eval $(ssh-agent)
ssh-add /home/abugher/.ssh/id_rsa
<TYPE IN YOUR PASSPHRASE>
ssh-add -l
Check config before deploy to node with extra vars
there only sudo pass is required
$ ansible-playbook -vvv \
--private-key $PRIVATE_KEY \
--ask-vault-password \
--extra-vars @encrypted_sudo_pass.yml \
--check playbooks/opensips_debian12_pkg.yml
there both of sudo ans ssh pass is required
$ ansible-playbook -vvv \
--private-key $PRIVATE_KEY \
--ask-vault-password \
--extra-vars @encrypted_pass.yml \
--check playbooks/opensips_debian12_pkg.yml
$ ansible-playbook -vvv \
--private-key $PRIVATE_KEY \
--ask-vault-password \
--extra-vars @encrypted_pass.yml \
--check playbooks/opensips_debian12_install.yml