Original link: https://editor.leonh.space/2022/ansible/
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 '
set the clock
$ ansible webservers -i hosts -m community.general.timezone -a ' name=Asia/Taipei ' --become --ask-become-pass
After setting the time zone, it is best to restart the cron service:
$ ansible webservers -i hosts -m ansible.builtin.service -a " name=cron state=restarted " --become --ask-become-pass
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 is 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, “shoot and forget” that is quite common, but that’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 above playbook example, we feed the cmd
parameters to the command module , each module has different parameters, and how to feed it depends on their documentation.
Execution order of tasks
If there are multiple tasks and multiple managed nodes, the order of execution is as follows:
- Run task 1 on node A
- Run task 1 on node B
- Run task 2 on node A
- Run task 2 on node B
- 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 UFW 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 Nginx 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 guy, so wait for the rest when I get into Red Hat :p.
This article is reprinted from: https://editor.leonh.space/2022/ansible/
This site is for inclusion only, and the copyright belongs to the original author.