Ansible batch automation management tool (2)
1. Introduction to Tools and Environment
1.1 Introduction to ansible
- Tools for batch management servers
- Managing by ssh without deploying agent s
- Popular automation tools: https://github.com/ansible/ansible
1.2 Introduction to Jenkins
- Visual Operations and Maintenance (mainly for Visual Deployment)
- Continuous build, can be combined with git, svn
- Visual operation and maintenance can be realized with ssh
- Visual operation and maintenance can be realized with ansible
1.3 Check the Environment
[root@server ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [root@server ~]# uname -m x86_64 [root@server ~]# uname -r 3.10.0-862.el7.x86_64
2. Installation of Python 3 and ansible
2.1 Install Python 3.5 using source code
2.1.1 Installation Support Package
[root@Ansible ~]# yum -y install lrzsz gcc gcc-c++ ncurses ncurses-devel unzip zlib-devel zlib openssl-devel openssl [root@Ansible ~]# rpm -qa lrzsz gcc gcc-c++ ncurses ncurses-devel unzip zlib-devel zlib openssl-devel openssl gcc-c++-4.8.5-28.el7_5.1.x86_64 ncurses-devel-5.9-14.20130511.el7_4.x86_64 ncurses-5.9-14.20130511.el7_4.x86_64 openssl-1.0.2k-12.el7.x86_64 gcc-4.8.5-28.el7_5.1.x86_64 openssl-devel-1.0.2k-12.el7.x86_64 unzip-6.0-19.el7.x86_64 zlib-1.2.7-17.el7.x86_64 zlib-devel-1.2.7-17.el7.x86_64 lrzsz-0.12.20-36.el7.x86_64
2.1.2 Source Coding Python 3.5
[root@Ansible yang]# pwd /yang [root@Ansible yang]# ls Python-3.5.2.tgz [root@Ansible yang]# tar xf Python-3.5.2.tgz -C /usr/src/ #decompression [root@Ansible yang]# cd /usr/src/Python-3.5.2/ [root@Ansible Python-3.5.2]# ./configure --prefix=/usr/local/python/ #Source code compilation #The following is omitted... [root@Ansible Python-3.5.2]# make && make install #The following is omitted... [root@Ansible Python-3.5.2]# ln -s /usr/local/python/bin/python3 /usr/bin/python3 #Establishing Soft Connection [root@Ansible Python-3.5.2]# which python3 /usr/bin/python3 [root@Ansible Python-3.5.2]# Version number of Python 3-V Python Python 3.5.2
2.2 Install ansible using pip3
2.2.1 Install the latest version of ansible
[root@Ansible Python-3.5.2]# /usr/local/python/bin/pip3 install ansible #The following is omitted...
2.2.2 Creating Soft Connections
[root@Ansible Python-3.5.2]# ln -s /usr/local/python/bin/ansible /usr/local/bin/ [root@Ansible Python-3.5.2]# which ansible /usr/local/bin/ansible [root@Ansible Python-3.5.2]# ansible --version ansible 2.6.4 #ansible version config file = None configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/local/python/lib/python3.5/site-packages/ansible executable location = /usr/local/bin/ansible python version = 3.5.2 (default, Sep 6 2018, 22:33:20) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
2.3 Anible View Help
[root@ansible ~]# /usr/local/python/bin/ansible-doc -l #View the General Help [root@ansible ~]# /usr/local/python/bin/ansible-doc -s shell #View the Help of the shell module [root@ansible ~]# /usr/local/python/bin/ansible-doc -s raw
3. Implementing ssh passwordless login using public and private keys
- ansible is agent-free. How does agent-free manage servers in batches? It mainly borrows ssh to manage servers in batches.
- ssh default login is password-based, so it is difficult to manage. This lesson is mainly about ssh password-free login.
- After ssh passwordless login is implemented, using ansible batch management server becomes easier
Host | IP |
---|---|
ansible | 192.168.200.73 |
web01 | 192.168.200.74 |
web02 | 192.168.200.75 |
3.1 Generate Key Pairs
[root@Ansible ~]# ssh-keygen -t rsa -f ~/.ssh/id_rsa -P "" Generating public/private rsa key pair. Created directory '/root/.ssh'. Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:AyXvTyhwFx6yOSXrzVUBcmGCzjmgoLjo51Yn+XVdmbk root@Ansible The key's randomart image is: +---[RSA 2048]----+ | +.B =oo. | |. . .% B . | |o. ..+B.+ . +| |o . +=B o = | |.. +.S . . . .| |o + o = . . E | |. . + . o | | . o . | | +. | +----[SHA256]-----+
3.2 Distribution of keys to Web01
[root@Ansible ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 192.168.200.74 #IP of Web01 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@192.168.200.74's password: Web01 The login password of ____________ Number of key(s) added: 1 Now try logging into the machine, with: "ssh -o ' StrictHostKeyChecking=no' '192.168.200.74'" and check to make sure that only the key(s) you wanted were added.
3.3 Password-free login test
[root@Ansible ~]# hostname -I 192.168.200.73 [root@Ansible ~]# ssh 192.168.200.74 Last login: Thu Sep 6 22:16:49 2018 from 192.168.200.1 [root@Web01 ~]# hostname -I 192.168.200.74 [root@Web01 ~]# exit logout Connection to 192.168.200.74 closed.
4. Simple configuration and ping module of ansible
4.1 ansible configuration file
[root@Ansible ~]# mkdir -p /etc/ansible [root@Ansible ~]# cat /etc/ansible/hosts #ansible Host Management Profile [nginx] #The name of the managed host group Web01 ansible_ssh_host=192.168.200.74 ansible_ssh_port=22 ansible_ssh_user=root #First Host Web02 ansible_ssh_host=192.168.200.75 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=111111 #Second Host //Special tips: Web01 ===> host name ansible_ssh_host ===>Host IP ansible_ssh_port ===>ssh Default port ansible_ssh_user ===>ssh User name ansible_ssh_pass ===>ssh User's Connection Password
If we have set ssh key-free. Then you don't need to write a password. For example: Web01
If we don't have a key-free setting, we need to install the sshpass tool and write the host's connection password in the / etc/ansible/hosts file. For example, Web02
#Download epel source and install sshpass root@Ansibl ~]# yum -y install wget [root@ansible ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo [root@ansible ~]# yum -y install sshpass [root@ansible ~]# which sshpass /usr/bin/sshpass
#Modify ssh configuration file [root@ansible ~]# sed -n '35p' /etc/ssh/ssh_config # StrictHostKeyChecking ask [root@ansible ~]# vim /etc/ssh/ssh_config [root@ansible ~]# sed -n '35p' /etc/ssh/ssh_config StrictHostKeyChecking no #Remove the comment and change it to something like this #Restart ssh service [root@ansible ~]# systemctl reload sshd.service
4.2 Testing of Anible Remote Execution Command
#Connection test of ping module [root@Ansible ~]# ansible nginx -m ping Web01 | SUCCESS => { "changed": false, "ping": "pong" } Web02 | SUCCESS => { "changed": false, "ping": "pong" }
Simple usage of 4.3 ansible
Ansible-i/etc/ansible/hosts host or host group-m specified Module-a command
4.4 The ping module is used to check whether the server is connected properly. The ping module does not need - a to specify parameters.
ansible all -m ping
Host group, host, all represents all
4.4.1 Host and Host Group Notes:
Host group scope | explain |
---|---|
all | Represents all hosts |
Web01:Web02 | Multiple hosts can be specified |
all:!Web01 | Specify all but not Web02, note! Signs need to be changed before they are added.\ |
4.4.2 Operational Test
[root@Ansible ~]# ansible Web01 -m ping Web01 | SUCCESS => { "changed": false, "ping": "pong" } [root@Ansible ~]# ansible all -m ping Web01 | SUCCESS => { "changed": false, "ping": "pong" } Web02 | SUCCESS => { "changed": false, "ping": "pong" } [root@Ansible ~]# ansible Web01:Web02 -m ping Web01 | SUCCESS => { "changed": false, "ping": "pong" } Web02 | SUCCESS => { "changed": false, "ping": "pong" } [root@Ansible ~]# ansible all:\!Web01 -m ping Web02 | SUCCESS => { "changed": false, "ping": "pong" } [root@Ansible ~]# ansible Web01:Web02 -m command -a 'uptime' Web02 | SUCCESS | rc=0 >> 23:14:40 up 1:16, 3 users, load average: 0.05, 0.03, 0.05 Web01 | SUCCESS | rc=0 >> 23:14:40 up 1:16, 3 users, load average: 0.06, 0.03, 0.05
5. Three command modules of ansible
5.1 ansible module command (pipes are not supported and are not recommended)
#Command supports direct echo of command execution results [root@ansible ~]# ansible all -m command -a "pwd" Web01 | SUCCESS | rc=0 >> /root Web02 | SUCCESS | rc=0 >> /root #The command module does not support pipeline operator operations [root@ansible ~]# ansible all -m command -a "echo test | grep t" Web01 | SUCCESS | rc=0 >> test | grep t Web02 | SUCCESS | rc=0 >> test | grep t #The command module does not support redirection operations [root@ansible ~]# ansible all -m command -a "echo bb >> /tmp/testansible" Web01 | SUCCESS | rc=0 >> bb >> /tmp/testansible Web02 | SUCCESS | rc=0 >> bb >> /tmp/testansible
5.2 ansible module shell (pipeline support, redirection support)
#The shell module supports pipe characters [root@ansible ~]# ansible all -m shell -a "echo testansible | grep a" Web01 | SUCCESS | rc=0 >> testansible Web02 | SUCCESS | rc=0 >> testansible #shell supports redirection [root@ansible ~]# ansible all -m shell -a "echo bb >> /tmp/testansible" Web01 | SUCCESS | rc=0 >> Web02 | SUCCESS | rc=0 >> [root@Web01 tmp]# cat testansible bb [root@Web02 tmp]# cat testansible bb #If you encounter special symbols, you need to add escape so that ansible can work properly. [root@Ansible ~]# ansible all -m shell -a "cat /etc/passwd | awk -F":" '{print \$1}'" Web01 | SUCCESS | rc=0 >> root bin daemon adm lp sync shutdown halt mail operator games ftp nobody systemd-network dbus polkitd sshd postfix chrony Web02 | SUCCESS | rc=0 >> root bin daemon adm lp sync shutdown halt mail operator games ftp nobody systemd-network dbus polkitd sshd postfix chrony
5.3 The ansible module raw, which runs commands in the most primitive way (independent of python, implemented only through ssh)
5.3.1 Clear yum cache
[root@Ansible ~]# ansible all -m raw -a "yum -y clean all" Web02 | SUCCESS | rc=0 >> Loaded plugins: fastestmirror Cleaning repos: base extras updates Cleaning up everything Maybe you want: rm -rf /var/cache/yum, to also free up space taken by orphaned data from disabled or removed repos Cleaning up list of fastest mirrors Shared connection to 192.168.200.75 closed. Web01 | SUCCESS | rc=0 >> Loaded plugins: fastestmirror Cleaning repos: base extras updates Cleaning up everything Maybe you want: rm -rf /var/cache/yum, to also free up space taken by orphaned data from disabled or removed repos Cleaning up list of fastest mirrors Shared connection to 192.168.200.74 closed.
5.3.2 Establishing yum cache
[root@Ansible ~]# ansible all -m raw -a "yum makecache" Web02 | SUCCESS | rc=0 >> Loaded plugins: fastestmirror Determining fastest mirrors #The middle is omitted... Metadata Cache Created Shared connection to 192.168.200.75 closed. Web01 | SUCCESS | rc=0 >> Loaded plugins: fastestmirror Determining fastest mirrors #The middle is omitted... Metadata Cache Created Shared connection to 192.168.200.74 closed.
5.3.3 Yum nmap package
[root@Ansible ~]# ansible all -m raw -a "yum -y install nmap" #The following is omitted...
5.3.4 View installation results
[root@Web01 ~]# which nmap /usr/bin/nmap [root@Web02 ~]# which nmap /usr/bin/nmap
6. Anible's copy module distributes files or folders in batches
Overview of 6.1 copy module
6.1.1 copy module parameters, ansible host group-m Module-a command
- src: Specify the source file or directory
- dest: Specifies the file or directory of the target server
- backup: backup or not
- owner: User to which a file or directory belongs after being copied to the target server
- Group: The group to which a file or directory belongs after being copied to the target server
- mode: permissions for files or directories
6.1.2 Preparations
[root@Ansible ~]# mkdir yangwenbo [root@Ansible ~]# cd yangwenbo [root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# echo "welcome to yunjisuan161" > yunwei [root@Ansible yangwenbo]# cat yunwei welcome to yunjisuan161
6.1.3 All managed end nodes must install the libselinux-python package
[root@Web01 ~]# yum -y install libselinux-python [root@Web01 ~]# rpm -qa libselinux-python libselinux-python-2.5-12.el7.x86_64 [root@Web02 ~]# yum -y install libselinux-python [root@Web02 ~]# rpm -qa libselinux-python libselinux-python-2.5-12.el7.x86_64
6.2 copy module copies files
Special tips:
- If the target path does not exist, it will be automatically created
- Src==> source file path dest = destination path location
#Copy files [root@Ansible yangwenbo]# ansible all -m copy -a "src=/root/yangwenbo/yunwei dest=/root/yangwenbo/" Web01 | SUCCESS => { "changed": true, "checksum": "4775b9cf454d1817e252f0678c06d64bc214da1c", "dest": "/root/yangwenbo/yunwei", "gid": 0, "group": "root", "md5sum": "38b35e7d3f5c75583ce5e1ee5838a396", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:admin_home_t:s0", "size": 24, "src": "/root/.ansible/tmp/ansible-tmp-1536310826.228977-17143783285290/source", "state": "file", "uid": 0 } Web02 | SUCCESS => { "changed": true, "checksum": "4775b9cf454d1817e252f0678c06d64bc214da1c", "dest": "/root/yangwenbo/yunwei", "gid": 0, "group": "root", "md5sum": "38b35e7d3f5c75583ce5e1ee5838a396", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:admin_home_t:s0", "size": 24, "src": "/root/.ansible/tmp/ansible-tmp-1536310826.2419605-39881113399031/source", "state": "file", "uid": 0 } #Check copy results [root@Web01 ~]# cd yangwenbo/ [root@Web01 yangwenbo]# pwd /root/yangwenbo [root@Web01 yangwenbo]# cat yunwei welcome to yunjisuan161 [root@Web02 ~]# cd yangwenbo/ [root@Web02 yangwenbo]# pwd /root/yangwenbo [root@Web02 yangwenbo]# cat yunwei welcome to yunjisuan161
6.3 copy module copy folder
Special note: If there is a file with the same name as the file I copied in the target path, it will directly overwrite the file under the target path.
[root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat yunwei welcome to yunjisuan161 #Copy files [root@Ansible yangwenbo]# ansible Web01 -m copy -a "src=/root/yangwenbo/ dest=/root/yangwenbo/" Web01 | SUCCESS => { "changed": false, "checksum": "4775b9cf454d1817e252f0678c06d64bc214da1c", "dest": "/root/yangwenbo/yunwei", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "path": "/root/yangwenbo/yunwei", "secontext": "system_u:object_r:admin_home_t:s0", "size": 24, "state": "file", "uid": 0 } #Check copy results [root@Web01 yangwenbo]# pwd /root/yangwenbo [root@Web01 yangwenbo]# cat yunwei welcome to yunjisuan161
6.4 copy module automatic backup
Special note: parameter: backup = yes ==> means that if there is a file with the same name but different content under the target path, backup the target file before overwriting.
[root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat yunwei hello #Copy files [root@Ansible yangwenbo]# ansible Web01 -m copy -a "src=/root/yangwenbo/ dest=/root/yangwenbo/ backup=yes" Web01 | SUCCESS => { "backup_file": "/root/yangwenbo/yunwei.1990.2018-09-07@05:30:28~", "changed": true, "checksum": "f572d396fae9206628714fb2ce00f72e94f2258f", "dest": "/root/yangwenbo/yunwei", "gid": 0, "group": "root", "md5sum": "b1946ac92492d2347c6235b4d2611184", "mode": "0644", "owner": "root", "secontext": "system_u:object_r:admin_home_t:s0", "size": 6, "src": "/root/.ansible/tmp/ansible-tmp-1536312626.9388444-271698353874697/source", "state": "file", "uid": 0 } #Check copy results [root@Web01 yangwenbo]# pwd /root/yangwenbo [root@Web01 yangwenbo]# ls yunwei yunwei.1990.2018-09-07@05:30:28~ [root@Web01 yangwenbo]# cat yunwei hello [root@Web01 yangwenbo]# cat yunwei.1990.2018-09-07\@05\:30\:28~ welcome to yunjisuan161
6.5 copy module specifies user and owner
#Copy files [root@Ansible yangwenbo]# ansible Web02 -m copy -a "src=/root/yangwenbo/ dest=/root/yangwenbo/ owner=nobody group=nobody mode=0600" Web02 | SUCCESS => { "changed": true, "checksum": "f572d396fae9206628714fb2ce00f72e94f2258f", "dest": "/root/yangwenbo/yunwei", "gid": 99, "group": "nobody", "md5sum": "b1946ac92492d2347c6235b4d2611184", "mode": "0600", "owner": "nobody", "secontext": "system_u:object_r:admin_home_t:s0", "size": 6, "src": "/root/.ansible/tmp/ansible-tmp-1536312849.3372185-152360920901702/source", "state": "file", "uid": 99 } #Check copy results [root@Web02 yangwenbo]# pwd /root/yangwenbo [root@Web02 yangwenbo]# ls yunwei [root@Web02 yangwenbo]# cat yunwei hello [root@Web02 yangwenbo]# ll total 4 -rw-------. 1 nobody nobody 6 Sep 7 05:34 yunwei
7. Anible script module run scripts in batches
ansible's script module enables remote servers to run local shell scripts in batches.
#Operation examples - > remote batch distribution and automatic deployment of nginx #All managed clients need to mount CD-ROM and create local yum configuration files [root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# ls | xargs -n1 auto_nginx.sh #Automatic installation of nginx scripts fenfa.sh #Batch distribution scripts nginx-1.10.2.tar.gz #nginx source package [root@Ansible yangwenbo]# cat auto_nginx.sh #Automatic installation of nginx scripts #!/bin/sh #nginx install shell scripts test -d /media/cdrom || mkdir -p /media/cdrom mount /dev/sr0 /media/cdrom &>/dev/null yum -y install gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel &>/dev/null test -d /root/yangwenbo || exit 3 cd /root/yangwenbo/ tar xf nginx-1.10.2.tar.gz -C /usr/src/ cd /usr/src/nginx-1.10.2/ ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module &>/dev/null make &>/dev/null make install &>/dev/null exit 0 [root@Ansible yangwenbo]# cat fenfa.sh #Batch distribution scripts for source packages and installation scripts #!/bin/sh #Batch distribution scripts Group=$1 ansible $Group -m copy -a "src=/root/yangwenbo/ dest=/root/yangwenbo/" ansible $Group -m script -a "/root/yangwenbo/auto_nginx.sh"
#Activation script [root@Ansible yangwenbo]# sh fenfa.sh all Web02 | SUCCESS => { "changed": true, "dest": "/root/yangwenbo/", "src": "/root/yangwenbo/" } Web01 | SUCCESS => { "changed": true, "dest": "/root/yangwenbo/", "src": "/root/yangwenbo/" } Web02 | SUCCESS => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.200.75 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.200.75 closed." ], "stdout": "", "stdout_lines": [] } Web01 | SUCCESS => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.200.74 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.200.74 closed." ], "stdout": "", "stdout_lines": [] }
#Check script execution results [root@Web01 ~]# ll -d /usr/local/nginx drwxr-xr-x. 6 root root 54 Sep 7 06:00 /usr/local/nginx [root@Web02 ~]# ll -d /usr/local/nginx drwxr-xr-x. 6 root root 54 Sep 7 06:00 /usr/local/nginx
This script is just a demonstration example, which needs to be written as rigorously as possible.
8. Preliminary use of ansible-playbook
Using playbook, playbook can combine the modules of ansible
#Setting up the Soft Connection of ansible-playbook [root@Ansible /]# ln -s /usr/local/python/bin/ansible-playbook /usr/local/bin/ [root@Ansible /]# which ansible-playbook /usr/local/bin/ansible-playbook
8.1 Use of playbook's simple shell module
[root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat test_shell.yaml #playbook Execution Template --- #The first three small-start - hosts: Web01 tasks: - name: test shell: echo "welcome to yunjisaun" >> /tmp/username - name: test2 shell: echo "welcome to yunjisuan" >> /tmp/username //Template description: --- #You have to start with three small - - top case. - hosts: #The first level of the body configuration code must have two spaces (- one space) - host: Web01 #Web01 is the value of the host parameter, with a space between the value and hosts: tasks: #Tasks: Represents the specific tasks to be performed next - name: #Indent two more lattices (- occupies a space) relative to tasks, indicating that they belong to the lower level of tasks. - name: test #test is simply the name of the specific command to be executed. Name: There's still a space after that. shell: #Represents that calling the shell module to execute commands is still indented by two more spaces relative to tasks shell: echo "xxx" >> xxx #shell: There's still a space behind it, which needs to be noticed.
#Execute the playbook configuration file [root@Ansible yangwenbo]# ansible-playbook test_shell.yaml PLAY [Web01] *********************************************************************************** TASK [Gathering Facts] ************************************************************************* ok: [Web01] TASK [test] ************************************************************************************ changed: [Web01] TASK [test2] *********************************************************************************** changed: [Web01] PLAY RECAP ************************************************************************************* Web01 : ok=3 changed=2 unreachable=0 failed=0
#results of enforcement [root@Web01 tmp]# pwd /tmp [root@Web01 tmp]# ls username [root@Web01 tmp]# cat username welcome to yunjisaun welcome to yunjisuan
8.2 Use of playbook's simple copy module
[root@Ansible yangwenbo]# echo "welcom to yunjisuan" >> /root/yangwenbo/test_copy [root@Ansible yangwenbo]# cat test_copy welcom to yunjisuan [root@Ansible yangwenbo]# cat test_copy.yaml #playbook Execution Template --- - hosts: Web02 tasks: - name: test copy copy: src=/root/yangwenbo/test_copy dest=/tmp/
#Execute the playbook configuration file [root@Ansible yangwenbo]# ansible-playbook test_copy.yaml PLAY [Web02] *********************************************************************************** TASK [Gathering Facts] ************************************************************************* ok: [Web02] TASK [test copy] ******************************************************************************* changed: [Web02] PLAY RECAP ************************************************************************************* Web02 : ok=2 changed=1 unreachable=0 failed=0
#results of enforcement [root@Web02 tmp]# pwd /tmp [root@Web02 tmp]# ls test_copy [root@Web02 tmp]# cat test_copy welcom to yunjisuan
8.3 playbook uses register output command to run results
When we use playbook to operate the ansible module, there is no output of the execution result of the command, which is hidden by default.
We can output the execution result of the command most through the register module.
[root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat test_register.yaml #playbook Execution Template --- - hosts: all tasks: - name: test register shell: echo "hi Tom" >> /tmp/registers register: print_result #Save the output of the previous command in the variable print_result - debug: var=print_result #Output the value of the variable as debug
#Execute the playbook configuration file [root@Ansible yangwenbo]# ansible-playbook test_register.yaml PLAY [all] ************************************************************************************* TASK [Gathering Facts] ************************************************************************* ok: [Web01] ok: [Web02] TASK [test register] *************************************************************************** changed: [Web02] changed: [Web01] TASK [debug] *********************************************************************************** ok: [Web01] => { "print_result": { "changed": true, "cmd": "echo \"hi Tom\" >> /tmp/registers", "delta": "0:00:00.007286", "end": "2018-09-07 23:43:38.967375", "failed": false, "rc": 0, "start": "2018-09-07 23:43:38.960089", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } } ok: [Web02] => { "print_result": { "changed": true, "cmd": "echo \"hi Tom\" >> /tmp/registers", "delta": "0:00:00.006651", "end": "2018-09-07 23:43:38.957825", "failed": false, "rc": 0, "start": "2018-09-07 23:43:38.951174", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } } PLAY RECAP ************************************************************************************* Web01 : ok=3 changed=1 unreachable=0 failed=0 Web02 : ok=3 changed=1 unreachable=0 failed=0
#results of enforcement [root@Web01 tmp]# pwd /tmp [root@Web01 tmp]# ls registers [root@Web01 tmp]# cat registers hi Tom [root@Web02 tmp]# pwd /tmp [root@Web02 tmp]# ls registers [root@Web02 tmp]# cat registers hi Tom
8.4 nginx configuration download and detection
[root@Ansible tmp]# pwd /tmp [root@Ansible tmp]# ls nginx.conf [root@Ansible tmp]# cat nginx.conf #nginx configuration file worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name www.yangwenbo.com; location / { root html; index index.html index.htm; } } } [root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat test_nginx_conf.yaml #playbook Execution Template --- - hosts: all tasks: - name: copy nginx.conf copy: src=/tmp/nginx.conf dest=/usr/local/nginx/conf/ backup=yes - name: shell: /usr/local/nginx/sbin/nginx -t register: nginx_result - debug: var=nginx_result
#Execute the playbook configuration file [root@Ansible yangwenbo]# ansible-playbook test_nginx_conf.yaml PLAY [all] ************************************************************************************* TASK [Gathering Facts] ************************************************************************* ok: [Web01] ok: [Web02] TASK [copy nginx.conf] ************************************************************************* changed: [Web02] changed: [Web01] TASK [shell] *********************************************************************************** changed: [Web02] changed: [Web01] TASK [debug] *********************************************************************************** ok: [Web01] => { "nginx_result": { "changed": true, "cmd": "/usr/local/nginx/sbin/nginx -t", "delta": "0:00:00.720120", "end": "2018-09-07 23:14:53.043060", "failed": false, "rc": 0, "start": "2018-09-07 23:14:52.322940", "stderr": "nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok\nnginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful", "stderr_lines": [ "nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok", #Prompt nginx configuration file to be normal "nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful" ], "stdout": "", "stdout_lines": [] } } ok: [Web02] => { "nginx_result": { "changed": true, "cmd": "/usr/local/nginx/sbin/nginx -t", "delta": "0:00:00.628406", "end": "2018-09-07 23:14:52.966781", "failed": false, "rc": 0, "start": "2018-09-07 23:14:52.338375", "stderr": "nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok\nnginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful", "stderr_lines": [ "nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok", #Prompt nginx configuration file to be normal "nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful" ], "stdout": "", "stdout_lines": [] } } PLAY RECAP ************************************************************************************* Web01 : ok=4 changed=2 unreachable=0 failed=0 Web02 : ok=4 changed=2 unreachable=0 failed=0
#results of enforcement [root@Web01 /]# cat /usr/local/nginx/conf/nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name www.yangwenbo.com; location / { root html; index index.html index.htm; } } } [root@Web02 /]# cat /usr/local/nginx/conf/nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name www.yangwenbo.com; location / { root html; index index.html index.htm; } } }
9.playbook's custom variables and built-in variables
9.1 Use custom variables in Playbook
[root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat test_vars.yaml #playbook Execution Template --- - hosts: all vars: #Define variables - names: "yunjisuan" #The first name variable age: "3" #The second age variable tasks: - name: "{{ names }}" #{{}} Two pairs of braces refer to variables, with spaces at both ends of the variable name shell: echo "myname {{ names }},myage {{ age }}" >> /tmp/bianliang register: var_result - debug: var=var_result #Special note: Reference variables need to be referenced in double quotation marks.
#Execute the playbook configuration file [root@Ansible yangwenbo]# ansible-playbook test_vars.yaml PLAY [all] ************************************************************************************** TASK [Gathering Facts] ************************************************************************** ok: [Web01] ok: [Web02] TASK [yunjisuan] ******************************************************************************** changed: [Web01] changed: [Web02] TASK [debug] ************************************************************************************ ok: [Web01] => { "var_result": { "changed": true, "cmd": "echo \"myname yunjisuan,myage 3\" >> /tmp/bianliang", "delta": "0:00:00.007237", "end": "2018-09-07 23:37:10.839684", "failed": false, "rc": 0, "start": "2018-09-07 23:37:10.832447", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } } ok: [Web02] => { "var_result": { "changed": true, "cmd": "echo \"myname yunjisuan,myage 3\" >> /tmp/bianliang", "delta": "0:00:00.009848", "end": "2018-09-07 23:37:10.859020", "failed": false, "rc": 0, "start": "2018-09-07 23:37:10.849172", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } } PLAY RECAP ************************************************************************************** Web01 : ok=3 changed=1 unreachable=0 failed=0 Web02 : ok=3 changed=1 unreachable=0 failed=0
#results of enforcement [root@Web01 tmp]# pwd /tmp [root@Web01 tmp]# ls bianliang [root@Web01 tmp]# cat bianliang myname yunjisuan,myage 3 [root@Web02 tmp]# pwd /tmp [root@Web02 tmp]# ls bianliang [root@Web02 tmp]# cat bianliang myname yunjisuan,myage 3
9.2 Use ansible built-in variables in playbook
We can use ansible all-m setup | less to view ansible built-in variables
[root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat test_setupvars.yaml #playbook Execution Template --- - hosts: all gather_facts: True #Using ansible built-in variables tasks: - name: setup var shell: echo "ip {{ ansible_all_ipv4_addresses[0] }} cpu {{ ansible_processor_count }}" >> /tmp/test - name: setup var2 shell: echo "time {{ ansible_date_time["date"] }}" >> /tmp/test register: var_result - debug: var=var_result
#Execute the playbook configuration file [root@Ansible yangwenbo]# ansible-playbook test_setupvars.yaml PLAY [all] ************************************************************************************* TASK [Gathering Facts] ************************************************************************* ok: [Web01] ok: [Web02] TASK [setup var] ******************************************************************************* changed: [Web02] changed: [Web01] TASK [setup var2] ****************************************************************************** changed: [Web01] changed: [Web02] TASK [debug] *********************************************************************************** ok: [Web01] => { "var_result": { "changed": true, "cmd": "echo \"time 2018-09-07\" >> /tmp/test", "delta": "0:00:00.005305", "end": "2018-09-07 23:49:33.178900", "failed": false, "rc": 0, "start": "2018-09-07 23:49:33.173595", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } } ok: [Web02] => { "var_result": { "changed": true, "cmd": "echo \"time 2018-09-07\" >> /tmp/test", "delta": "0:00:00.005363", "end": "2018-09-07 23:49:33.230051", "failed": false, "rc": 0, "start": "2018-09-07 23:49:33.224688", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } } PLAY RECAP ************************************************************************************* Web01 : ok=4 changed=2 unreachable=0 failed=0 Web02 : ok=4 changed=2 unreachable=0 failed=0
#results of enforcement [root@Web01 tmp]# pwd /tmp [root@Web01 tmp]# ls test [root@Web01 tmp]# cat test ip 192.168.200.74 cpu 1 time 2018-09-07 [root@Web02 tmp]# pwd /tmp [root@Web02 tmp]# ls test [root@Web02 tmp]# cat test ip 192.168.200.75 cpu 1 time 2018-09-07
10.Playbook sends variable configuration files
If the configuration file is sent by using copy module, the configuration is the same.
If there is a variable configuration in the downloaded configuration file, you need to use the template module.
10.1 Distribution of Variable Configuration Files Using template Module
[root@Ansible tmp]# pwd /tmp [root@Ansible tmp]# ls test [root@Ansible tmp]# cat test my name is {{ myname }} #Custom variables my name is {{ ansible_all_ipv4_addresses[0] }} #System variables [root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat test_filevars.yaml #playbook Execution Template --- - hosts: all gather_facts: True #Open System Variables vars: - myname: "yunjisuan" #Custom variables tasks: - name: template test template: src=/tmp/test dest=/tmp/test #Using template to send variable configuration files
#Execute the playbook configuration file [root@Ansible yangwenbo]# ansible-playbook test_filevars.yaml PLAY [all] ************************************************************************************* TASK [Gathering Facts] ************************************************************************* ok: [Web01] ok: [Web02] TASK [template test] *************************************************************************** changed: [Web01] changed: [Web02] PLAY RECAP ************************************************************************************* Web01 : ok=2 changed=1 unreachable=0 failed=0 Web02 : ok=2 changed=1 unreachable=0 failed=0
#results of enforcement [root@Web01 tmp]# pwd /tmp [root@Web01 tmp]# ls test [root@Web01 tmp]# cat test my name is yunjisuan my name is 192.168.200.74 [root@Web02 tmp]# pwd /tmp [root@Web02 tmp]# ls test [root@Web02 tmp]# cat test my name is yunjisuan my name is 192.168.200.75
10.2 Use judgment grammar in downloading configuration files
10.2.1 PORT has value
[root@Ansible tmp]# pwd /tmp [root@Ansible tmp]# ls if.j2 [root@Ansible tmp]# cat if.j2 {% if PORT %} #if PORT exists ip=0.0.0.0:{{ PORT }} {% else %} #Otherwise ip=0.0.0.0:80 {% endif %} #Ending [root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat test_ifvars.yaml #playbook Execution Template --- - hosts: all gather_facts: True #Open system built-in variables vars: - PORT: 90 #Custom variables tasks: - name: jinja2 if test template: src=/tmp/if.j2 dest=/root/test
#Execute the playbook configuration file [root@Ansible yangwenbo]# ansible-playbook test_ifvars.yaml PLAY [all] ************************************************************************************* TASK [Gathering Facts] ************************************************************************* ok: [Web02] ok: [Web01] TASK [jinja2 if test] ************************************************************************** changed: [Web01] changed: [Web02] PLAY RECAP ************************************************************************************* Web01 : ok=2 changed=1 unreachable=0 failed=0 Web02 : ok=2 changed=1 unreachable=0 failed=0
#results of enforcement [root@Web01 tmp]# pwd /tmp [root@Web01 tmp]# ls test [root@Web01 tmp]# cat test ip=0.0.0.0:90 [root@Web02 tmp]# pwd /tmp [root@Web02 tmp]# ls test [root@Web02 tmp]# cat test ip=0.0.0.0:90
10.2.2 If the PORT value of the variable is empty, it will be another result.
[root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat test_ifvars.yaml #playbook Execution Template --- - hosts: all gather_facts: True vars: - PORT: #Empty tasks: - name: jinja2 if test template: src=/tmp/if.j2 dest=/root/test
#Execute the playbook configuration file [root@Ansible yangwenbo]# ansible-playbook test_ifvars.yaml PLAY [all] ************************************************************************************* TASK [Gathering Facts] ************************************************************************* ok: [Web01] ok: [Web02] TASK [jinja2 if test] ************************************************************************** changed: [Web01] changed: [Web02] PLAY RECAP ************************************************************************************* Web01 : ok=2 changed=1 unreachable=0 failed=0 Web02 : ok=2 changed=1 unreachable=0 failed=0
#results of enforcement [root@Web01 tmp]# pwd /tmp [root@Web01 tmp]# ls test [root@Web01 tmp]# cat test ip=0.0.0.0:80 [root@Web02 tmp]# pwd /tmp [root@Web02 tmp]# ls test [root@Web02 tmp]# cat test ip=0.0.0.0:80
11.Playbook's notify notification and download nginx configuration (introduction)
#Actual Actual Sending Variable nginx Configuration Files for Executable Actions [root@Ansible tmp]# pwd /tmp [root@Ansible tmp]# ls nginx.j2 [root@Ansible tmp]# cat nginx.j2 worker_processes {{ ansible_processor_count }}; #Variable parameters [root@Ansible yangwenbo]# pwd /root/yangwenbo [root@Ansible yangwenbo]# cat test_nginxvars.yaml #playbook Execution Template --- - hosts: all gather_facts: True #Open system built-in variables tasks: - name: nginx conf template: src=/tmp/nginx.j2 dest=/usr/local/nginx/conf/nginx.conf notify: - reload nginx #Send a notification to the handlers module to perform an action called reload nginx handlers: #Define actions - name: reload nginx #The name of the action shell: /usr/local/nginx/sbin/nginx -s reload