在Ansible系列的第5部分中,我们将说明如何使用Ansible模块创建Ansible Plays和Playbooks。
Create-Ansible-Plays-and-Playbooks
Ansible附带称为模块的独立脚本,这些模块在playbooks中用于在远程节点上执行特定任务。
模块对于自动化任务(如包管理、存档和复制文件)非常有用。它们允许你对配置文件进行调整,并管理诸如路由器、交换机、负载均衡器、防火墙和其他设备主机等设备。
本次主题的目的是向你概述Ansible模块可以完成的各种任务:
Linux中的软件包管理
软件包管理是系统管理员最基本、最频繁的任务之一。Ansible附带的模块可以帮助你在基于RedHat和Debian的系统中执行包管理任务。
它们相对容易猜测。有用于基于Debian的APT软件包管理的apt模块,用于YUM软件包管理的旧yum模块以及与较新的RHEL发行版关联的dnf模块。
以下是在剧本中如何使用模块的一些示例:
示例1:在RHEL 8上安装Apache Web服务器
---- name: install Apache webserver hosts: webservers tasks: - name: install httpd dnf: name: httpd State: latest
示例2:在Debian 10上安装Apache Web服务器
---- name: install Apache webserver host: databases tasks: - name: install Apache webserver apt: name: apache2 State: latest
服务模块
该服务模块允许系统管理员在系统上启动,停止,更新,升级和重新加载服务。
示例1:启动Apache Webserver
---- name: Start service httpd, if not started server: name: httpd state: started
示例2:停止Apache Web服务器
---- name: stop service httpd service: name: httpd state: stopped
示例3:重新启动网络接口enp2s0
---- name: Restart network service for interface eth0 service: name: network state: restarted args: enp2s0
复制模块
顾名思义,复制模块将文件从远程计算机上的一个位置复制到同一计算机上的另一个位置。
示例1:将文件从本地复制到远程Linux
---- name: Copy file with owner and permissions copy: src: /etc/files/tecmint.conf dest: /srv/tecmint.conf owner: tecmint group: tecmint mode: '0644'
该剧本复制配置文件tecmint.conf从/etc/files/目录到/srv目录下,同时修改属主属组及文件权限为644。
还可以使用符号表示来表示权限,如最后一行所示。
示例2:将文件从本地复制到远程Linux
---- name: Copy file with owner and permissions copy: src: /etc/files/tecmint.conf dest: /srv/tecmint.conf owner: tecmint group: tecmint mode: u=rw, g=r, o=r
上一个示例中的权限可以表示为最后一行中所示:为用户分配了读和写入权限,为组分配了读权限,为其他用户分配了读权限。
文件模块
文件模块用于执行许多文件操作,包括创建文件和目录、分配文件权限和设置符号链接。
示例1:执行Linux文件权限
---- name: Change file ownership, group and permissions file: path: /etc/tecmint.conf owner: tecmint group: tecmint mode: '0644'
上面的play在/etc目录中创建了一个名为tecmint.conf的文件,将权限设置为0644。
示例2:删除Linux文件
---- name: Remove file(delete file) file: path: /etc/tecmint.conf state: absent
这将删除文件tecmint.conf。
示例3:创建目录
---- name: create a Directory file: path: /etc/mydirectory State: directory mode: '0777'
这将在/etc目录中创建一个目录,将权限设置为0777。
示例4:递归删除目录
---- name: Recursively deleting a directory file: path: /etc/te
这里仅仅是删除tecmint.conf文件,同时还可以删除目录。
Lineinfile模块
当你需要更改文件中的一行时,lineinfile模块非常有用。它可以替换存在行的内容。
示例1:在Linux中处理文件
---- name: Ensure SElinux is set to enforcing mode lineinfile: path: /etc/selinux/config regexp: '^SELINUX=' line: SELINUX=disabled
上面的play将SELINUX值设置为Disabled。
示例2:在Linux中更改文件
--- name: Add a line to a file if does not exist, without passing regexp lineinfie: line: 10.200.50.51 tecmint.com create: yes
这会将条目10.200.50.51 tecmint.com添加到/etc/hosts文件中。
存档模块
一个归档模块,用于创建的单个或多个文件压缩存档。假设压缩源存在于目标目的地。存档后,可以使用remove=True 语句删除或删除源文件。
示例1:创建一个存档文件
---- name: Compress directory /path/to/tecmint_dir/ into /path/to/tecmint.tgz archive: path: /path/to/tecmint_dir dest: /path/to/tecmint.tgzThis compresses the /path/to/tecmint_dir directory to /path/to/tecmint.tgz
示例2:创建存档文件并删除
- name: Compress regular file /path/to/tecmint into /path/to/foo.gz and remove it archive: patch: /path/to/tecmint dest: /path/to/tecmint.tgz remove: yes
在以上play中,归档完成后,源文件/path/to/tecmint将被删除。
示例3:创建一个存档文件
---- name: Create a bz2 archive of /path/to/tecmint archive: path: /path/to/tecmint format: bz2
这将从/path/to/tecmint文件创建一个bz2格式的压缩文件。
Git模块
该模块管理软件存储库的git checkout。
示例1:检查Git存储库
- git: repo: 'https://foosball.example.org/path/to/repo.git' dest: /srv/checkout version: release-0.22
命令模块
命令模块是最常用的模块之一,它使用命令名,后面跟着一个参数列表。该命令的传递方式与在Linux shell中键入的方式相同。
示例1:运行命令
- name: Executing a command using the command module command: cat helloworld.txt
示例2:检查远程Linux的正常运行时间
--- - name: Check the remote host uptime host: servers tasks: - name: Execute the Uptime command over Command module register: uptimeoutput command: "uptime"- debug: var: uptimeoutput.stdout_lines
命令模块检索远程服务器的正常运行时间。
检索运行命令结果的变量
通常,Ansible playbooks用于在托管主机上执行任务,而不在命令行上显示输出。但是,有些实例可能要求你捕获输出或结果。在本节中,我们将向你介绍如何在变量中捕获playbook的输出并稍后显示它。
ansible寄存器用于捕获任务的输出并将其保存为变量。此后,变量将包含任务的标准输出。
例如,假设你想使用df-Th / 命令检查各个根目录中受管节点的磁盘使用情况。你将使用'command' 模块定义命令,并使用'register' 将std输出保存在变量中。
要显示该命令,你将在stdout返回值旁边使用“debug” 模块。
--- - hosts: all become: yes tasks: - name: Execute /boot usage on Hosts command: 'df -Th /' register: df - debug: var=df.stdout
现在,让我们运行playbook。在这种情况下,我们将playbook命名为check_disk_space.yml。
ansible-playbook check_disk_space.yml
检查Ansible受管节点的磁盘使用情况
如你所见,输出全都杂乱无章,难以跟进。
要对齐输出并使其更易于阅读,请将stdout返回值替换为stdout_lines。
--- - hosts: all become: yes tasks: - name: Execute /boot usage on Hosts command: 'df -Th /' register: df - debug: var=df.stdout_lines
使用条件控制play执行
就像在编程语言中一样,当可能有多个结果时,将使用条件语句。让我们看一下Ansible剧本中一些常用的条件语句。
何时声明
有时,你可能希望在特定节点上执行任务,而不是在其他节点上执行任务。"when" 条件语句很容易在剧本中使用和实现。使用"When" 子句时,只需声明该子句旁边的条件,如下所示:
when: condition
当条件满足时,则在远程系统上执行任务。
让我们看看一些例子:
示例1:使用When运算符
---- hosts: all tasks: - name: Install Nginx on Debian apt: name=nginx state=present when: ansibel_os_family == "Debian"
上面的play在运行Debian发行版系列的主机上安装了Nginx Web服务器。
你还可以在条件语句的旁边使用OR 和AND 运算符。
示例2:将AND运算符与When一起使用
---- hosts: all tasks: - name: Install Nginx on Debian apt: name=nginx state=present when: ansible_os_family == “Debian” and ansible_distribution_version == “18.04”
使用AND 运算符时,必须满足两个语句才能执行任务。
上面的play将Nginx安装在运行Debian OS版本18.04的Nodes上。显然,这将是Ubuntu 18.04。
示例3:将OR运算符与When一起使用
使用OR 运算符,如果满足任一条件,则执行任务。
---- hosts: all tasks: - name: Install Nginx on Debian apt: name=nginx state=present when: ansible_os_family == “Debian” or Ansible_os_family == “SUSE”
上面的play将Nginx Web服务器安装在Debian或SUSE系列操作系统或两者之上。
注意:== 在测试条件时,请务必使用双等号。
循环条件
条件语句也可以循环使用。假设你有一个需要在远程节点上安装的多个软件包的列表。
在下面的手册中,我们有一个名为package的数组,其中包含需要安装的软件包的列表。如果required子句设置为True,则将一个接一个地执行这些任务。
--- - name: Install Software packages hosts: all vers: packages: • name: nginxrequired: True • name: mysqlrequired: True • name: apacherequired: False tasks: • name: Install “{{ item.name }}”on Debianapt: name: “{{ item.name }}” state: present When: item.required == Trueloop: “{{ packages }}”
配置错误处理
有时,运行剧本时任务失败。假设你正在3台服务器上运行5个任务,如下面的剧本所示。如果服务器2上的任务3(启动MySQL)发生错误,Ansible将停止执行服务器2上的其余任务,并尝试完成其余服务器上的其余任务。
--- - name: Install Software packages hosts: server1, server2, server3 tasks:- name: Install dependencies<< some code >>- name: Install MySQL database<< some code >>- name: Start MySQL<< some code >>- name: Install Nginx<< some code >>- name: Start Nginx<< some code >>
例如,如果要在执行剧本时保持一致,请停止执行剧本,如果其中一台服务器发生故障,请添加该选项。
--- - name: Install Software packages hosts: server1, server2, server3 any_errors_fatal: true tasks:
这样,如果一个任务在一个服务器上失败,Ansible将停止在所有服务器上执行整个剧本并退出。
如果你希望剧本忽略错误并继续执行其余任务,请使用ignore_errors:True选项。
--- - name: Install Software packages hosts: server1, server2, server3 tasks:- name: Install dependencies<< some code >> ignore_errors: True
创建剧本以将系统配置为指定状态
在本节中,我们介绍了运行剧本时可用的一些其他选项。
让我们从Check 模式或Dry run选项开始。运行playbook时,使用dry run或check mode选项检查是否会遇到任何错误,以及是否会在托管主机上进行任何更改。但是,它不会对远程节点进行任何更改。
例如,要尝试运行名为httpd.yml的playbook来安装并启动Apache webserver运行:
ansible-playbook httpd.yml --check
试运行Ansible剧本
我们需要考虑的另一个选项是--start at task 选项。当指定剧本应该开始或开始的任务的名称时,使用此选项。
让我们举个例子:下面的剧本阐明了两个任务:第一个剧本安装Apache Web服务器,第二个剧本安装htop实用程序。
--- - name: Install httpd hosts: all tasks: yum: name: httpd state: Installed- name: Install htop yum: name: htop state: started
如果要跳过安装Apache Web服务器,而是安装htop实用程序,请运行:
ansible-playbook playbook.yml --start-at-task “Install htop”
使用Ansible Playbook安装软件包
最后,你可以通过将tags选项添加到playbook中来标记任务或play,如下所示。当你有一个相当大的playbook,并且你想从整个playbook中运行特定的任务时,这个方法很有用。
--- - name: Install httpd tags: Install and start hosts: all![Create-Ansible-Plays-and-Playbooks.png](https://upload-images.jianshu.io/upload_images/3275724-02643522809647da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) tasks: yum: name: httpd state: Installed tags: Install • service: name: httpdstate: started
ansible-playbook playbook.yml -tags "Install
要省略标记,请使用--skip tags选项,如图所示。
ansible-playbook playbook.yml --skip-tags "Install"
结论
在本主题中,我们介绍了Ansible中常用的模块,如何从分析剧本的执行中检索stdout,如何使用剧本中的条件,以及如何管理运行任务时可能出现的错误。最后,我们回顾了playbook的配置,以及如果不打算运行整个playbook,如何使用其他选项来决定要运行哪些任务。