> 技术文档 > linux系统----Ansible中的playbook简单应用

linux系统----Ansible中的playbook简单应用

目录

Playbooks中tasks语法使用

1、file

创建文件:touch

创建目录:directory

2、lineinfile

修改文件某一行文本

3、replace

根据正则表达式替换文件内容(指定换字符串)

5、template/copy

模板作用类似于copy,可将文件分发到不同节点上,可以在模板文件中引入变量

 8、wait_for

等待某些操作完成以后再进行后续操作

9、when

条件判断,满足后再执行任务


环境准备:

        下载ansible

        配置两台web主机,一台ansible服务器

        ansible主机ip:192.168.158.150

        web1主机IP:192.168.158.158

        web2主机IP:192.168.158.161

        修改好配置文件

        关闭防火墙和安全上下文

[root@bogon ~]# hostnamectl set-hostname ansible[root@bogon ~]# setenforce 0

ansible主机

创建playbook,编辑yml文件

[root@bogon ~]# mkdir playbook[root@bogon ~]# cd playbook/[root@bogon playbook]# vim test.yml

操作如下

Playbooks中tasks语法使用

1、file

操作文件,比如创建文件或目录、删除文件或目录、修改文件权限等

常用参数:

  • path:指定要操作的文件或目录

  • state:参数非常灵活,可以包含的值及含义如下

    • directory - 与path结合说明我们要操作的是一个目录

    • touch - 与path结合说明我们要操作的是一个文件

    • link - 创建软连接

    • hard - 创建硬链接

    • absent - 删除目标

  • src:当state设置为link或hard创建链接时,用于说明链接哪个文件,指定链接源

  • force:值为yes表示强制创建

  • owner:指定被操作文件的属主

  • group:指定被操作文件的属组

  • mode:指定被操作文件的权限

示例:

- name: 创建一个testfile文件       file: path=/tmp/testfile state=touch- name: 创建一个目录,并指定目录权限       file: path=/tmp/data state=directory mode=0755- name: 删除一个目录       file: path=/tmp/data state=absent  - name: recurse默认为no,指定为yes代表以递归方式指定文件权限       file: dest=/user/bin mode=0755 recurse=yes

示例:

创建文件:touch

vim test.yml

 测试成功

[root@bogon playbook]# ansible-playbook -C test.yml PLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.161]ok: [192.168.158.158]TASK [在/opt/目录下创建文件f1.txt文件] *******************************************changed: [192.168.158.161]changed: [192.168.158.158]PLAY RECAP ***********************************************************************192.168.158.158 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

翻译:

执行结果汇总 ***********************************************************************192.168.158.158 : 成功=2 已变更=1 不可达=0 失败=0 跳过=0 救援=0 忽略=0各字段含义详解:​ok=2​ (成功=2)该主机上成功完成了2个任务(无论是否产生变更)​changed=1​ (已变更=1)其中有1个任务实际修改了系统状态(例如:创建了文件/安装了软件)​unreachable=0​ (不可达=0)主机连接正常(SSH/WinRM等连接成功)​failed=0​ (失败=0)没有任务执行失败​skipped=0​ (跳过=0)没有任务因条件不满足而被跳过​rescued=0​ (救援=0)没有触发任何错误恢复机制(block-rescue结构)​ignored=0​ (忽略=0)没有主动忽略任何错误

执行成功:

[root@bogon playbook]# ansible-playbook test.yml PLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.161]ok: [192.168.158.158]TASK [在/opt/目录下创建文件f1.txt文件] *******************************************changed: [192.168.158.158]changed: [192.168.158.161]PLAY RECAP ***********************************************************************192.168.158.158 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

查验:已成功创建

        web主机

[root@web1 ~]# cd /opt/[root@web1 opt]# lsf1.txt
创建目录:directory
[root@bogon playbook]# vim test.yml---- name: adda hosts: all tasks: - name: 在/opt/目录下创建文件f1.txt文件 file: path: /opt/f1.txt state: touch - name: 在/opt/目录下创建dir目录 file: path: /opt/dir/ state: directory

 测试:

[root@bogon playbook]# ansible-playbook -C test.yml PLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.161]ok: [192.168.158.158]TASK [在/opt/目录下创建文件f1.txt文件] *******************************************changed: [192.168.158.161]changed: [192.168.158.158]TASK [在/opt/目录下创建dir目录] **************************************************changed: [192.168.158.158]changed: [192.168.158.161]PLAY RECAP ***********************************************************************192.168.158.158 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

执行

[root@bogon playbook]# ansible-playbook test.yml PLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.161]ok: [192.168.158.158]TASK [在/opt/目录下创建文件f1.txt文件] *******************************************changed: [192.168.158.161]changed: [192.168.158.158]TASK [在/opt/目录下创建dir目录] **************************************************changed: [192.168.158.158]changed: [192.168.158.161]PLAY RECAP ***********************************************************************192.168.158.158 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

 查验:

[root@web1 opt]# lsdir f1.txt

2、lineinfile

修改文件某一行文本

常用参数:

*   path:操作的文件路径
*   regexp:正则表达式,要替换的内容
*   line:指定修改后的文本内容
*   state:当设置为absent代表删除匹配的行
*   backrefs:默认为no,当未匹配到时line对应的内容会被插入到文本的末尾,为yes表示不插入
*   insertafter:借助insertafter参数可以将文本插入到“指定的行”之后
*   insertbefore:借助insertbefore参数可以将文本插入到“指定的行”之前
*   backup:是否进行备份
*   create:操作的文件不存在时是否创建

示例:

 - name: 替换文件中包含line123的行为testline   lineinfile: path=/tmp/test regexp=\"^line\" line=\"testline\"

 vim  test.yml         (注意缩进)

---- name: adda gather_facts: no hosts: all tasks: - name: 在/opt/目录下创建文件f1.txt文件 file: path: /opt/f1.txt state: touch - name: 在/opt/目录下创建dir目录 file: path: /opt/dir/ state: directory - name: 精确替换包含line123的行 lineinfile: path: /opt/f1.txt regexp: \"^line\" line: \"test\" tags: t1

[root@web1 opt]# cat f1.txt line1231lineoqoweiqweopoiline

 

测试:     只在web1上f1.txt有内容

[root@ansible playbook]# ansible-playbook -C -t t1 test.ymlPLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.158]ok: [192.168.158.161]TASK [精确替换包含line123的行] ***************************************************changed: [192.168.158.158]ok: [192.168.158.161]PLAY RECAP ***********************************************************************192.168.158.158 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

 

执行成功

[root@ansible playbook]# ansible-playbook -t t1 test.ymlPLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.158]ok: [192.168.158.161]TASK [精确替换包含line123的行] ***************************************************ok: [192.168.158.161]changed: [192.168.158.158]PLAY RECAP ***********************************************************************192.168.158.158 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

查验: 

        因为没有循环,一次只能执行一个

[root@web1 opt]# cat f1.txt line1231testopoiline[root@web1 opt]# cat f1.txt testtestopoiline

 第二次

 

  

3、replace

根据正则表达式替换文件内容(指定换字符串)

常用参数:

  • path:操作文件的路径

  • regexp:正则表达式

  • replace:指定最终要替换的字符串

  • backup:是否在修改文件之前对文件进行备份,yes是进行备份

 vim test.yml 

 - name: 将/opt/f1.txt文件中的test替换为line replace: path: /opt/f1.txt regexp: \"test\" replace: line tags: t2

 测试:

[root@ansible playbook]# ansible-playbook -C -t t2 test.ymlPLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.158]ok: [192.168.158.161]TASK [将/opt/f1.txt文件中的test替换为line] ***************************************changed: [192.168.158.161]changed: [192.168.158.158]PLAY RECAP ***********************************************************************192.168.158.158 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

执行

[root@ansible playbook]# ansible-playbook -t t2 test.ymlPLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.161]ok: [192.168.158.158]TASK [将/opt/f1.txt文件中的test替换为line] ***************************************changed: [192.168.158.158]changed: [192.168.158.161]PLAY RECAP ***********************************************************************192.168.158.158 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

查验

 

 

5、template/copy

模板作用类似于copy,可将文件分发到不同节点上,可以在模板文件中引入变量

常用参数:

  • src: 源文件路径

  • dest:目标文件路径

  • group:目标文件属组

  • mode:目标文件权限

  • backup:如果目标文件存在,则先备份目标文件

  • force:是否强制覆盖,默认为yes

  • validate:在复制之前通过命令验证目标文件,如果验证通过则复制

示例:

- template: src=/mytemplates/tt.j2 dest=/etc/file.conf- template: src=/mytemplates/tt.j2 dest=/etc/file.conf group=wheel mode=0644- template: src=/mytemplates/suzuka.j2 dest=/etc/suzuka validate=\'visudo -cf %s\'

示例:

第一步:先从远程主机拷贝一份nginx配置文件

[root@ansible playbook]# scp 192.168.158.158:/etc/nginx/nginx.conf ./nginx.conf 100% 2334 1.0MB/s 00:00 

第二步:编辑yml文件

 mag(输出文本)

vim  test.yml        

 - name: print facts variable debug: msg: \"The {{ ansible_default_ipv4.interface }} IPV4 address is {{ ansible_default_ipv4.address }}\"

 第三步:执行

[root@ansible playbook]# ansible-playbook -t t3 test.ymlPLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.158]ok: [192.168.158.161]TASK [print facts variable] ******************************************************ok: [192.168.158.158] => { \"msg\": \"The default IPV4 address is 192.168.158.158\"}ok: [192.168.158.161] => { \"msg\": \"The default IPV4 address is 192.168.158.161\"}PLAY RECAP ***********************************************************************192.168.158.158 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

 我们可以将default改为变量

第四步:过滤之后拷贝到一个文件里

[root@ansible playbook]# ansible 192.168.158.158 -m setup | grep -n ansible_default_ipv457: \"ansible_default_ipv4\": {

 

[root@ansible playbook]# ansible 192.168.158.158 -m setup > facts.txt

 interface是ens33

 第五步:将变量引用到文本里

 - name: print facts variable debug: msg: \"The {{ ansible_default_ipv4.interface }} IPV4 address is {{ ansible_default_ipv4.address }}\" tags: t3 - name: 拷贝nginx配置文件 template: src=./nginx.j2 dest=/etc/nginx/nginx.conf tags: t4

 执行看一下

        变量引用了

[root@ansible playbook]# ansible-playbook -t t3 test.ymlPLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.158]ok: [192.168.158.161]TASK [print facts variable] ******************************************************ok: [192.168.158.158] => { \"msg\": \"The ens33 IPV4 address is 192.168.158.158\"}ok: [192.168.158.161] => { \"msg\": \"The ens33 IPV4 address is 192.168.158.161\"}PLAY RECAP ***********************************************************************192.168.158.158 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

 将变量引用到nginx配置文件里

[root@ansible playbook]# lsfacts.txt nginx.conf test.yml[root@ansible playbook]# vim nginx.conf ---------------------- server { listen {{ ansible_default_ipv4.address }}:80; listen [::]:80; server_name _; root /usr/share/nginx/html;-------------------------

 修改文件后缀

[root@ansible playbook]# mv nginx.conf nginx.j2[root@ansible playbook]# lsfacts.txt nginx.j2 test.yml

 执行成功

[root@ansible playbook]# ansible-playbook -t t4 test.ymlPLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.158]ok: [192.168.158.161]TASK [拷贝nginx配置文件] *********************************************************changed: [192.168.158.161]changed: [192.168.158.158]PLAY RECAP ***********************************************************************192.168.158.158 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

去web主机上查验nginx配置文件

成功引用

 

 8、wait_for

等待某些操作完成以后再进行后续操作

**常用参数:**

*   connect\\_timeout:在下一个任务执行之前等待连接的超时时间
*   delay:指在等待过程中轮询的时间间隔
*   host:等待的主机地址,默认是127.0.0.1
*   port:等待的主机端口
*   path:文件路径,只有当这个文件存在时才开始执行下一个任务
*   state:等待的状态,值可以为started/stoped/absent/present
*   timeout:等待的超时时间,默认300秒

**示例:**

- name: 每隔10s检查一次,等待8080端口正常监听,才开始下一个任务,直到超时
  wait_for: port=8080 state=started delay=10
- name: 等待文件创建
  wait_for: path=/tmp/tt
 

 示例

此时web两台主机都是启用nginx了的,此时80号端口已被监听

vim test.yml

 - name: 每隔10s检查一次,等待80端口正常监听,才开始下一个任务,直到超时 wait_for: port=80 state=started delay=10 - name: 如果上个任务为真执行下一个,创建文件 file: path: /opt/1.txt state: touch

 当80号端口被监听后,才执行下一个任务创建文件

 执行

[root@ansible playbook]# ansible-playbook test.yml PLAY [adda] **********************************************************************TASK [Gathering Facts] ***********************************************************ok: [192.168.158.158]ok: [192.168.158.161]TASK [每隔10s检查一次,等待80端口正常监听,才开始下一个任务,直到超时] ***********ok: [192.168.158.158]ok: [192.168.158.161]TASK [如果上个任务为真执行下一个,创建文件] ***************************************changed: [192.168.158.161]changed: [192.168.158.158]PLAY RECAP ***********************************************************************192.168.158.158 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 

 查验:成功执行

9、when

条件判断,满足后再执行任务

示例: when是条件

- name: 判断变量tt是否定义  shell: echo \"I\'ve got {{ tt }}\"  when: tt is defined

 当主机名是web1时,下载httpd软件包 (此时只有一台web1,另一台web2)

vim test.yml

 - name: output debug: msg: \"{{ ansible_hostname }}\" - name: 条件任务 yum: name: httpd state: present when: ansible_hostname == \"web1\"

 

执行成功

[root@ansible playbook]# ansible-playbook test.yml PLAY [adda] *************************************************************************************************TASK [Gathering Facts] **************************************************************************************ok: [192.168.158.158]ok: [192.168.158.161]TASK [output] ***********************************************************************************************ok: [192.168.158.158] => { \"msg\": \"web1\"}ok: [192.168.158.161] => { \"msg\": \"agent2\"}TASK [条件任务] *********************************************************************************************skipping: [192.168.158.161]changed: [192.168.158.158]PLAY RECAP **************************************************************************************************192.168.158.158 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.158.161 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 

 

 去web主机查验

hostname为web1的主机安装了httpd软件包