Ansible project primarily consists of
Main component of playbooks. Least degree of separation of actions. Get compiled into python code and ran on remote. Offer alternatives to many common commands.
Use ansible-galaxy to install or package them. Can be organized in collections. Many vendors like Grafana and Prometheus provide official collections for their products.
Multiple hosts organized by groups. Has the following syntax:
[my_group]
1.2.3.5
1.2.3.4 ansible_user=root ansible_port=2201Or a yaml version:
all:
hosts:
1.2.3.5:
1.2.3.4:
ansible_user: root
ansible_port: 2201Alongside host defenitions inventory contains host and group
variables, stored in host_vars and group_vars
dirs in yaml files with names corresponding to hosts or groups. These
vars will be expanded in modules, templates and roles.
Alternatively inventory can be dynamically generated - via a
python/shell/shebanged script or an executable, returning a json object.
Format of that object is similar to what
ansible-inventory --list spits out.
Essentially inventory is a collection of contexts to run a playbook
for, with ssh connection build in - though nothing is stopping you from
not using that ssh connection with connection: local and
passing whatever as the inventory.
In fact ansible inventory isn't limited to hosts, you can put
arbitrary data there and benefit from filtering, sequence,
run_once, facts and other ansible features for parallel
processing of data.
For example, this inventory contains a list of kubernetes objects with each one's associated facts:
observer:
hosts:
availability-orchestration:
type: deployment
market:
hosts:
cart:
type: statefulset
cart-orchestration:
type: deploymentYou can use a playbook like this to run batch operations on it quite easily (of course you should use kubernetes module in this particular example but I'm too lazy to look it up):
- name: Rollout market
gather_facts: false
connection: local
hosts: market
serial: 4
tasks:
- cmd: "kubectl rollout restart {{ type }}/{{ ansible_host }}"A builtin solution for keeping and distributing secrets. In the
simplest mode of operation functions just like git-crypt
encrypted with a password. Has a whole ton of configurations. Example
setup:
ansible-vault create secrets.yml
echo "pass" > ./.vault-passAfter that add vault_password_file=.vault_pass to
defaults in your config.
Variables related to remote systems are called
facts, while variables related to ansible itself are
called magic variables. You can access facts in the
ansible_facts var and some in top-level
ansible_ variables.
Default facts include info about:
Ansible uses jinja2 for templating, you can read about
it (in the context of flask) here.
Most acions require root access. Easiest way to achieve this is to
login as root using public keys. Alternatively you can
become with predefined password. Passwords can be stored in
ansible-vault or provided at runtime with
--ask-pass for ssh and
--ask-become-pass for become.
--check --diff for dry runsansible-playbook --list-tasks to enumerate tasks
for --start-at-taskimport_role) if you want to be
able to use --start-at-task on tasks inside a roleRealisticly you should use vagrant with ansible provisioner or molecule, since they configure everything for you. But what they do is mostly equivalent to this.
To test a playbook on a docker container you can use the following command:
See below for a systemd enabled version!
docker run --rm -it \
-l "ansible_playground" \
ubuntu:jammy \
sh -c "while true; do sleep 999; done"With this inventory file (you need community.docker
playbook):
plugin: community.docker.docker_containers
docker_host: unix:///var/run/docker.sock
filters:
- include: >-
"ansible_playground" in docker_config.Labels
- exclude: true(Or just use container's name and
ansible_connection=docker)
Most ansible roles rely on systemd for starting stuff, so for a
complete test you most often would need it working. Since docker doesn't
play nice with cgroups v2 (or so I've heard), simplest (or only)
solution is to switch to podman (which runs systemd by default). Notice
/usr/sbin/init being PID 1, this is required. Docker can
run systemd, but needs some tweaks and specific images to do this.
podman run --rm -it \
-l "ansible_playground" \
--name ansible_playground \
hlabs/ssh-python \
/usr/sbin/initIf /usr/sbin/init doesn't exist, try
/lib/systemd/systemd. If that doesn't exist either, you
need to install systemd first.
With something similar to this in your inventory:
localhost ansible_user=root ansible_port=2022 ansible_connection=podman