2.0 Ansible Ad-Hoc Command

Overview

What are ad-hoc commands? The following is

ansible all -a "free -h"

That is to execute Ansible commands directly on the command line. It’s not my pretense. I didn’t find a good translation. Official documents and some foreign books are called this.

Running Ansible commands directly on the command line basically only exists in the test link, and sometimes the test is not used. After all, the production environment is written in playbook management, otherwise everyone will rush to the machine to execute an Ansible remote command. What records, it will not become a mess after a long time, and when written as a playbook, especially in cooperation with git for management, you can clearly see the ins and outs of service modification

When we are looking at the official documentation, how to use a certain module, the examples given by the official documentation are basically in playbook form

Why do we need ad-hoc commands?

However, in some special cases, executing Ansible commands directly on the command line has an advantage, that is, it is fast. For example, a new online service severely drags down the machine resources. At this time, it is too late to write a complete playbook, and directly command batches in one line. Stop this service first.

Ansible ad-hoc command is suitable for novices to learn and simple test. It can help us quickly understand the powerful functions of Ansible. All operations that can be directly implemented using the Ansible command line can be achieved by writing a playbook.

Environmental preparation

Same as the previous environment

[root@192-168-31-106 ~]# cat /etc/ansible/hosts 
[allservers]
192.168.31.106
192.168.31.100
192.168.31.101
192.168.31.102
[webservers]
192.168.31.100
192.168.31.101
192.168.31.102

basis

ansible group-or-host [-m MODULE_NAME] [-a MODULE_ARGS]

View help ansible -h OR man ansible

Above we view the memory command, if it is written in full, it is like this

ansible all -m shell -a "free -h"

That is, the default execution module is a shell command

The order of the parameters does not matter, the above command is also correct

ansible -m shell -a "free -h" all

Output detailed information

-v    输出详细信息
-vvv  输出更详细信息
-vvvv 调试(debug)模式

Insert picture description here

Concurrent execution

By default, Ansible uses concurrent execution to manage multiple machines and execute the following commands repeatedly to observe the order of results

ansible all -a "hostname"

Insert picture description here

It can be seen that the output order of each time is unreasonable, and the number of concurrency can be controlled by parameters

ansible all -a "hostname" -f 1
ansible all -a "hostname" --forks 10 #参数的长写法,同-f功能一致

Ansible defaults to 5 concurrent executions

Get all the environmental information of the target machine

ansible 192.168.31.100 -m setup

This command will output a large number of detailed information of the target machine, such as operating system, IP address, memory, disk, etc., and return a JSON format data. For the detailed output, we can even use this method to collect machine information in the production environment. Of course, it is best to filter this information with a program such as python for JSON formatting and parsing

Insert picture description here

Note that our IP 192.168.31.100 is already written in the host list. If you fill in an IP address that is not in the host list, an error will be reported:

[root@192-168-31-106 ~]# ansible 192.168.31.120 -m setup
[WARNING]: Could not match supplied host pattern, ignoring: 192.168.31.120
[WARNING]: No hosts matched, nothing to do

When we learn about variables later, we will talk about using this information to do some specific operations, such as judging that the target machine is CentOS6 to install a package, if it is CentOS7, install another package, etc.

Use native commands

We have used this method before, such as viewing the memory of a remote machine:

ansible all -a "free -h"  OR 
ansible all -m shell -a "free -h"

The use of -m shellfunctions is more powerful. For example, the ordinary way of executing remote commands does not support pipes, but the ordinary way of executing commands is relatively safe because of its few functions.

Insert picture description here

https://docs.ansible.com/ansible/2.9/modules/shell_module.html
https://docs.ansible.com/ansible/2.9/modules/command_module.html

Idempotence

Idempotence means that if the system is already in the desired state, nothing is done to the system.

Let's take a look below, use Ansible's YUM module to install nginx on the machine, and take this example to focus on the idempotence of Ansible

ansible webservers -m ping
ansible webservers -m yum -a "name=nginx state=present"

Insert picture description here

The command is executed for the second time, you can see that all are green, indicating that the machine status has not changed

Insert picture description here

Can you just use the Shell command without using the YUM module? Yes, as follows

ansible webservers -m shell -a "yum install nginx -y"

Insert picture description here

We can see that the output content has blue warning content, reminding us that it is recommended to use the YUM module instead of the Shell YUM command, and more importantly, the output content of the next three machines are all yellow, indicating that the machine status has been modified, even We have executed it many times ansible webservers -m shell -a "yum install nginx -y", and the output is still in the state of yellow CHANGED

It can be seen that if you want Ansible to perfectly support idempotence, you need to not use direct Shell commands as much as possible, but use Ansible's own modules. We will learn about other Ansible modules later.

There are two advantages to using Ansible's own modules instead of native shell commands:

  1. Easy to maintain, the syntax of Ansible modules is unified, and if the shell script is written complex, it is difficult to maintain
  2. Support idempotency

Why do we have to emphasize the importance of idempotence? For example, in a common scenario, the boss said to initialize a new machine and install nginx to provide seven-layer load balancing services. The team has written the corresponding playbook before, ideally it is An Ansible command directly completes the initialization, but no one can guarantee that an error will never be reported. Once there is any error or new requirements are added, this set of Ansible services is required to support repeated execution, and the state is always the expected state. In other words, we The playbook file that I want to write is a description of the state, similar to "keep nginx installed and started" instead of "install nginx"

Although the ideal is good, in actual work, I want to ensure that there is no way to run shell commands directly in the Ansible script. All modules are built in Ansible, which is difficult, very difficult, but we must at least make sure not to dig big holes and avoid them. The first time the script is executed is normal, but the state of the system when a script is executed multiple times is completely unpredictable.

Similarly, we use the copy module to test the effect of idempotence

ansible all  -m copy -a "src=/root/node_exporter-1.0.0.linux-amd64.tar.gz  dest=/tmp"
ansible all  -m copy -a "src=/root/node_exporter-1.0.0.linux-amd64.tar.gz  dest=/tmp"
上面的命令连续执行两次,可以发现第1次输出为黄色,表明系统已经做了修改,第2次输出为绿色表明无任何修改,具有一定的幂等性

Restrict execution to a certain machine

Suppose our previous host list is like this

[root@192-168-31-106 ~]# cat /etc/ansible/hosts 
[webservers]
192.168.31.100
192.168.31.101

That is, there are already 2 webserver servers, but the current scenario is that the amount is too large and the machine cannot withstand it. It is necessary to initialize a new webserver machine to join the cluster, so we modify the host list and add a line of IP as follows

[root@192-168-31-106 ~]# cat /etc/ansible/hosts 
[webservers]
192.168.31.100
192.168.31.101
192.168.31.102

At this time, when we perform related deployment operations, we hope to limit the operations to the 102 machines. Others do not move, we can use --limit ${ip}parameters

ansible webservers -m yum -a "name=nginx state=present" --limit "192.168.31.102"

Management system users and groups

In the shell command, we use useradd、usermod、userdelto manage users and use groupadd、groupdel、groupmodto manage groups

Use userand groupmanage separately in Ansible

Management group group

ansible 192.168.31.100 -m group -a "name=test1 state=present" #增加test1组
ansible 192.168.31.100 -m group -a "name=test1 state=absent"  #删除test1组
ansible 192.168.31.100 -m group -a "name=test1 state=present gid=2000"  #指定组的gid

Insert picture description here

Management user user

ansible 192.168.31.100 -m user -a "name=test2 state=present"   #增加用户
ansible 192.168.31.100 -m user -a "name=test2 state=absent"    #删除用户
ansible 192.168.31.100 -m user -a "name=test3 password={
   
   { '123456' | password_hash('sha512', 'mysecretsalt') }} state=present" #创建用户并指定密码

Insert picture description here
Insert picture description here

For more parameters, refer to the official document

https://docs.ansible.com/ansible/2.9/modules/user_module.html
https://docs.ansible.com/ansible/2.9/modules/group_module.html

Management Pack

As we have seen above, Ansible's yum module manages packages, and Ansible also has a general package management module that can support different operating systems across platforms

ansible 192.168.31.100 -m package -a "name=git state=present"

Insert picture description here

Manage files and directories

1 View the status information of the file

#该功能类似 stat
ansible all -m stat -a "path=/etc/profile"

Insert picture description here

2 Copy local files or directories (on the management machine) to the remote machine

#该功能类似 scp 、 rsync
ansible 192.168.31.100 -m copy -a "src=/etc/hosts dest=/tmp/hosts"

Insert picture description here

Which srccan be a file, it can be a directory, if it is a directory, pay attention to whether there is a slash at the end, the behavior is different

  • There is a slash, copy the contents of the directory, excluding the directory itself

  • No slash, copy together with the directory itself and the contents of the directory

    ansible 192.168.31.100 -m copy -a “src=/etc/sysconfig/network-scripts dest=/tmp”
    ansible 192.168.31.100 -m copy -a “src=/etc/sysconfig/network-scripts/ dest=/tmp”

Insert picture description here

rsync also has a similar logic. You can test it in actual use.
Unlike the cp command, it is similar to cp /etc/* and this logic with asterisks is not supported.

3 Pull the files of the remote machine to the local

#这种场景应用的比较少,我们演示一种情况,备份所有机器的/etc/hosts到管理机器上
ansible all -m fetch -a "src=/etc/hosts dest=/tmp/xtmp"
#可以看到,还贴心的自动生成了IP文件夹以区分

Insert picture description here

4 Create directories and files

#类似 touch mkdir
ansible 192.168.31.100 -m file -a "path=/tmp/test10 mode=644 state=directory"   #创建目录
ansible 192.168.31.100 -m file -a "path=/tmp/test6.txt mode=0644 state=touch"   #创建文件

Insert picture description here

5 delete directories and files

ansible 192.168.31.100 -m file -a "path=/tmp/test10 state=absent"

Insert picture description here

For more detailed functions of file operations, refer to official documents

https://docs.ansible.com/ansible/2.9/modules/file_module.html
https://docs.ansible.com/ansible/2.9/modules/copy_module.html

Manage scheduled tasks

Not much to say, let’s just look at a simple effect

ansible  192.168.31.100 -m cron -a "name='cron_test' minute='*/2' job='date >> /tmp/tmp.txt' state='present'"
ansible  192.168.31.100 -m cron -a "name='cron_test' minute='*/2' job='date >> /tmp/tmp.txt' state='absent'"

Insert picture description here

Reference link

https://docs.ansible.com/ansible/2.9/modules/cron_module.html

Elevated privileges

The user who executes Ansible is the current user by default. If the management machine is executed as root, the target machine is also the root user, and the user can be changed by parameters

ansible all -a "whoami" -u nginx

SSH password-free configuration is for users. If we use other users to execute Ansible commands, then this user also needs to configure password-free

If this ordinary user has configured sudo to avoid being close to root, you can add parameters -b OR ----become, so that operations that need to be elevated to perform operations can be performed normally

ansible all -a "whoami" -u nginx -b

Possible errors

1 No hosts matched

When encountering this kind of error, it is usually because the host list is not configured correctly. If you confirm that it has been configured correctly, you can also specify the host list file by setting environment variables, such as

ANSIBLE_INVENTORY=/etc/ansible/hosts ansible all -a "hostname"

The above command is executed directly, clearly telling Ansible the path, or you can write the relevant environment variables into the script, or/etc/profile

2 The authenticity of host ‘192.168.31.100’ can’t be established

This kind of error is reported because, by default, SSH remote has a process of entering yes to confirm. We can use a remote command to test and enter yes, or use the following environment variables

ANSIBLE_HOST_KEY_CHECKING=False ansible all -a "hostname"

to sum up

In this article, we mainly focus on Ansible Ad-Hoc commands, taking some key modules as examples, to expand on some of the main functions of Ansible, the main purpose is to let everyone have an intuitive understanding of what Ansible can do, and also briefly Discussed the important concept of idempotence. With these basic understandings, we have laid a good foundation for us to learn the playbook.

Guess you like

Origin blog.csdn.net/xys2015/article/details/113822144