The easiest Ansible article in the world

Ansible is a strategic deployment tool in the IT industry. As long as a program of action is formulated, it will execute automated deployments according to the script. It has the ability to allow us to deploy projected IT combat power on any node in the world within 24 hours just like the US military.

Ansible Basics

In the Ansible world, there are so-called control nodes and managed nodes. The control node is the command center, usually the work computer in our hands. Of course, install Ansible:

 $ sudo add-apt-repository --yes --update ppa:ansible/ansible $ sudo apt install ansible

As for the managed node, there is no need to install any agent. This is also the biggest feature of Ansible. It uses SSH to log in to work, while other similar tools mostly need to work through an agent. The agent-free design allows us to Take it easy.

In general, there will be more than one managed node, which is why Ansible is valuable. These managed nodes can be organized in a file like hosts, which will look like this:

 [webservers] 192.168.122.17 ansible_user=web17 ansible_password=web17pw 192.168.122.18 ansible_user=web18 ansible_password=web18pw [dbservers] db01 .intranet.mydomain.net db02 .intranet.mydomain.net

This list is called inventory in the Ansible world. Its structure is similar to the INI format. It should be known at a glance. The following ansible_user and ansible_password naturally the account secret of that node!

And the two database nodes without special account and password will use the current account and key of the master node to log in. This is of course unrealistic. Who would set the account of the remote host to be the same as that of their own computer? .

The most basic installation and settings are completed, and you can play a wave!

Assuming the above inventory is located in ~/Projects/ansible/hosts, it can be called like this:

 $ cd ~ /Projects/ansible/ $ ansible webservers -i hosts -a " /bin/echo hello "

The successful message is as follows:

 192.168.122.17 | CHANGED | rc=0 >> hello 192.168.122.18 | CHANGED | rc=0 >> hello

In this simple example, the last webservers are naturally the nodes in the inventory [webservers] .

Another example:

 $ ansible webservers -i hosts -m ping

The successful response is as follows:

 192.168.122.17 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "ping": "pong" } 192.168.122.18 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": false, "ping": "pong" }

The ping above is not our usual ping command, but Ansible’s ping module , which is used to detect the Python location on the managed node and reply with pong .

The above are all methods used directly in the command line, which are more suitable for temporary remote invocation of some relatively simple commands. This mode of use is called ad hoc mode in Ansible. If it is a complex situation, it is necessary to arrange a clear program of action. , which is the playbook mentioned later.

In the previous two examples, -m ping and -a "/bin/echo hello" were used respectively, where -m means module, and -a means the parameter to module.

In the first example we omit -m and Ansible will call the default command module , which will execute the argument /bin/echo hello on the managed node.

Module

Below are some examples of various modules.

use root account

 $ ansible webservers -i hosts -a " /sbin/reboot " --become --ask-become-pass

where --become means sudo .

Because the command of the command module is not executed in the shell, the variables, pipes, and directions of the shell are invalid. If necessary, use the shell module instead:

 $ ansible webservers -i hosts -m ansible.builtin.shell -a ' echo $TERM '

file handling

Files can be copied from the master node to the managed node:

 $ ansible webservers -i hosts -m ansible.builtin.copy -a " src=/etc/hosts dest=/tmp/hosts "

Change file permissions:

 $ ansible webservers -i hosts -m ansible.builtin.file -a " dest=/srv/foo/b.txt mode=600 owner=mdehaan group=mdehaan "

Create a directory:

 $ ansible webservers -i hosts -m ansible.builtin.file -a " dest=/path/to/c state=directory "

Delete directory:

 $ ansible webservers -i hosts -m ansible.builtin.file -a " dest=/path/to/c state=absent "

I don’t know if there is a political correctness factor, but it’s rather unintuitive to use absent to indicate deletion.

Package management

Mounting Kit:

 $ ansible webservers -i hosts -m ansible.builtin.apt -a " name=mc " --become --ask-become-pass

Update kit:

 $ ansible webservers -i hosts -m ansible.builtin.apt -a " name=mc state=latest " --become --ask-become-pass

To remove the kit:

 $ ansible webservers -i hosts -m ansible.builtin.apt -a " name=mc state=absent " --become --ask-become-pass

Update kit list:

 $ ansible webservers -i hosts -m ansible.builtin.apt -a " update_cache=yes " --become --ask-become-pass

Upgrade all packages:

 $ ansible webservers -i hosts -m ansible.builtin.apt -a " upgrade=safe " --become --ask-become-pass

That safe is equivalent to apt upgrade , or full , which is equivalent to apt full-upgrade .

Account and group management

Create an account:

 $ ansible webservers -i hosts -m ansible.builtin.user -a " name=foo password=<crypted password here> " --become --ask-become-pass

Delete account:

 $ ansible webservers -i hosts -m ansible.builtin.user -a " name=foo state=absent " --become --ask-become-pass

Service management

Start the service:

 $ ansible webservers -i hosts -m ansible.builtin.service -a " name=ufw state=started " --become --ask-become-pass

Restart the service:

 $ ansible webservers -i hosts -m ansible.builtin.service -a " name=ufw state=restarted " --become --ask-become-pass

Out of service:

 $ ansible webservers -i hosts -m ansible.builtin.service -a " name=ufw state=stopped " --become --ask-become-pass

Get full node information

 $ ansible webservers -i hosts -m ansible.builtin.setup

Playbook

It’s impossible to rely on one line of instructions to conquer the world. Complex and periodic tasks can be written as Playbooks and Ansible can do them for us.

How is that different from writing a shell script yourself? Generally speaking, it is easy to write or even do it manually within three machines. If there are more than five machines, it is better to use special tools, which can speed up efficiency and reduce mistakes.

Of course, there is another delivery model, “fire and forget”, which is quite common, but it’s beyond the scope of this article.

Back to Playbook. Playbook is the structure of YAML, here is mytask.yaml:

 --- - name : My playbook  hosts : webservers  tasks : - name : Leaving a mark      ansible.builtin.command :        cmd : " touch /tmp/ansible_was_here "

start running:

 $ cd ~ /Projects/ansible/ $ ansible-playbook -i hosts mytask.yaml

result:

 PLAY [My playbook] **************************************************************** TASK [Gathering Facts] ************************************************************ ok: [192.168.122.17] ok: [192.168.122.18] TASK [Leaving a mark] ************************************************************* changed: [192.168.122.17] changed: [192.168.122.18] PLAY RECAP ************************************************************************ 192.168.122.17: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.122.18: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

In this playbook, a “play” named “My playbook” is formulated, which has “task”, and the only task is named “Leaving a mark”.

According to the above description, the basic structure of playbook is playbook > play > task:

  • A playbook can have multiple plays (a script has multiple plays)
  • A play can have multiple tasks (a play has multiple transactions)

In the example above, it’s equivalent to:

 $ ansible webservers -i hosts -m ansible.builtin.command -a " touch /tmp/ansible_was_here "

As mentioned earlier, the command module is the default behavior, so it can be simplified to:

 $ ansible webservers -i hosts -a " touch /tmp/ansible_was_here "

In the playbook example above, we fed the cmd parameters to the command module , each module has different parameters, and how to feed them depends on their documentation.

Execution order of tasks

If there are multiple tasks and multiple managed nodes, the order of execution is as follows:

  1. Run task 1 on node A
  2. Run task 1 on node B
  3. Run task 2 on node A
  4. Run task 2 on node B
  5. and so on

It will not go to the B node after running task 1234 on the A node.

If the task 1 of the B node fails, Ansible will drop the B node into the failed part, and the subsequent tasks of the B node will not run. Can the failed part be resurrected and return to glory? cannot.

use root account

On the command line we use --become to make Ansible perform work as root on the managed node, and similarly on the playbook:

 - name : Ensure the httpd service is running  ansible.builtin.service :    name : ufw    state : started  become : true

This task is equivalent to

 -m ansible.builtin.service -a " name=ufw state=started " --become

What about the sudo password? Just use the old trick --ask-become-pass , so to run this playbook it will look like this:

 $ cd ~ /Projects/ansible/ $ ansible-playbook -i hosts --ask-become-pass mytask.yaml

Alternatively, you can append the sudo password to the inventory file:

 [webservers] 192.168.122.17 ansible_user=web17 ansible_password=web17pw ansible_become_password=web17pw

If you don’t want root, but another account, you can use become_user to specify:

 - name : Ensure the httpd service is running  ansible.builtin.service :    name : nginx    state : started  become : true  become_user : nginx_admin

The above are the basics of playbook. As long as you master these basic usages, you should be able to meet most of the usage scenarios.

Ansible’s Rule of 28

This article is really just the basic foundation of Ansible, but even 20% of the usage can meet 80% of the needs.

Ansible has more fancy ways to play:

  • The concept of incorporating variables in the playbook
  • Invoke Jinja2 templating language and variables in playbook
  • Generate dynamic inventory
  • Encrypt the account password
  • call another playbook from the playbook

The usage of these icing on the cake depends on the needs. Personally, I think Ansible is only a configuration tool, which affects work efficiency but does not affect application performance. Unless your job really has to be an Ansible worker.

This article is reprinted from: https://editor.leonh.space/2022/how-to-make-you-having-rat-smell/
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment