当前位置:土豆新闻网 > 科技 >

Ansible playbook 编程

时间:2020-06-14 09:22:46观看次数:99
"\u003Cp\u003E主机规划\u003C\u002Fp\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002F0481d56b3a1949c596345a94b3d00257\" img_width=\"836\" img_height=\"327\" alt=\"Ansible playbook 编程\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch2 class=\"pgc-h-arrow-right\"\u003E添加用户账号\u003C\u002Fh2\u003E\u003Cp\u003E\u003Cstrong\u003E说明:\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E1、 运维人员使用的登录账号;\u003C\u002Fp\u003E\u003Cp\u003E2、 所有的业务都放在 \u002Fapp\u002F 下「yun用户的家目录」,避免业务数据乱放;\u003C\u002Fp\u003E\u003Cp\u003E3、 该用户也被 ansible 使用,因为几乎所有的生产环境都是禁止 root 远程登录的(因此该 yun 用户也进行了 sudo 提权)。\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E1 # 使用一个专门的用户,避免直接使用root用户\u003Cbr\u003E2 # 添加用户、指定家目录并指定用户密码\u003Cbr\u003E3 # sudo提权\u003Cbr\u003E4 # 让其它普通用户可以进入该目录查看信息\u003Cbr\u003E5 useradd -u 1050 -d \u002Fapp yun && echo '123456' | \u002Fusr\u002Fbin\u002Fpasswd --stdin yun\u003Cbr\u003E6 echo "yun ALL=(ALL) NOPASSWD: ALL" >> \u002Fetc\u002Fsudoers\u003Cbr\u003E7 chmod 755 \u002Fapp\u002F\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch2 class=\"pgc-h-arrow-right\"\u003EAnsible 配置清单Inventory\u003C\u002Fh2\u003E\u003Cp\u003E之后文章都是如下主机配置清单\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager ansible_info]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u003Cbr\u003E 3 [yun@ansi-manager ansible_info]$ cat hosts_key \u003Cbr\u003E 4 # 方式1、主机 + 端口 + 密钥\u003Cbr\u003E 5 [manageservers]\u003Cbr\u003E 6 172.16.1.180:22\u003Cbr\u003E 7 \u003Cbr\u003E 8 [proxyservers]\u003Cbr\u003E 9 172.16.1.18[1:2]:22\u003Cbr\u003E10 \u003Cbr\u003E11 # 方式2:别名 + 主机 + 端口 + 密码\u003Cbr\u003E12 [webservers]\u003Cbr\u003E13 web01 ansible_ssh_host=172.16.1.183 ansible_ssh_port=22\u003Cbr\u003E14 web02 ansible_ssh_host=172.16.1.184 ansible_ssh_port=22\u003Cbr\u003E15 web03 ansible_ssh_host=172.16.1.185 ansible_ssh_port=22\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E条件判断-when\u003C\u002Fh1\u003E\u003Cp\u003Ewhen 判断在 ansible 任务中的使用频率非常高。\u003C\u002Fp\u003E\u003Cp\u003E例如判断主机是否已经安装指定的软件包;对机器的操作系统进行判断然后再根据不同的方法「yum或apt等」进行软件包安装;根据操作系统的版本判断进行软件包的安装「是安装MySQL还是Mariadb」等。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E示例:根据主机名的不同,下载不同的文件\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object04]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject04\u003Cbr\u003E 3 [yun@ansi-manager object04]$ ll\u003Cbr\u003E 4 total 4\u003Cbr\u003E 5 -rw-rw-r-- 1 yun yun 950 Oct 26 10:22 test_when.yml\u003Cbr\u003E 6 [yun@ansi-manager object04]$ cat test_when.yml \u003Cbr\u003E 7 ---\u003Cbr\u003E 8 # 根据 hostname 的不同下载不同的图片\u003Cbr\u003E 9 # 特殊组 all,对所有机器有效\u003Cbr\u003E10 - hosts: all\u003Cbr\u003E11 \u003Cbr\u003E12 tasks:\u003Cbr\u003E13 - name: "download picture jvm-01-01.png"\u003Cbr\u003E14 get_url:\u003Cbr\u003E15 url: http:\u002F\u002Fwww.zhangblog.com\u002Fuploads\u002Fjvm\u002Fjvm-01-01.png\u003Cbr\u003E16 dest: \u002Ftmp\u002F\u003Cbr\u003E17 when: ansible_hostname == "ansi-haproxy01"\u003Cbr\u003E18 \u003Cbr\u003E19 - name: "download picture jvm-01-02.png"\u003Cbr\u003E20 get_url:\u003Cbr\u003E21 url: http:\u002F\u002Fwww.zhangblog.com\u002Fuploads\u002Fjvm\u002Fjvm-01-02.png\u003Cbr\u003E22 dest: \u002Ftmp\u002F\u003Cbr\u003E23 when: ansible_hostname == "ansi-haproxy02"\u003Cbr\u003E24 \u003Cbr\u003E25 - name: "other download picture jvm-01-03.png"\u003Cbr\u003E26 get_url:\u003Cbr\u003E27 url: http:\u002F\u002Fwww.zhangblog.com\u002Fuploads\u002Fjvm\u002Fjvm-01-03.png\u003Cbr\u003E28 dest: \u002Ftmp\u002F\u003Cbr\u003E29 # 从 facts 中获取的变量,ansible_facts['ansible_hostname'] != "ansi-haproxy01" 错误写法;ansible_hostname != "ansi-haproxy01" 正确写法\u003Cbr\u003E30 #when: (ansible_hostname != "ansi-haproxy01") and (ansible_hostname != "ansi-haproxy02") # 写法一\u003Cbr\u003E31 #或者如下3行 列表之间关系是 (and 与) 等同于上一行\u003Cbr\u003E32 #when:\u003Cbr\u003E33 # - ansible_hostname != "ansi-haproxy01"\u003Cbr\u003E34 # - ansible_hostname != "ansi-haproxy02"\u003Cbr\u003E35 #when: ansible_hostname is not match "ansi-haproxy0*" # 写法二\u003Cbr\u003E36 when: (ansible_hostname is match "ansi-manager") or (ansible_hostname is match "ansi-web*") # 写法三\u003Cbr\u003E37 \u003Cbr\u003E38 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_when.yml # 语法检测\u003Cbr\u003E39 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_when.yml # 预执行,测试执行\u003Cbr\u003E40 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key test_when.yml # 执行\u003Cbr\u003E41 \u003Cbr\u003E42 PLAY [all] *******************************************************************************************************\u003Cbr\u003E43 \u003Cbr\u003E44 TASK [Gathering Facts] *******************************************************************************************\u003Cbr\u003E45 ok: [web01]\u003Cbr\u003E46 ok: [web02]\u003Cbr\u003E47 ok: [web03]\u003Cbr\u003E48 ok: [172.16.1.180]\u003Cbr\u003E49 ok: [172.16.1.181]\u003Cbr\u003E50 ok: [172.16.1.182]\u003Cbr\u003E51 \u003Cbr\u003E52 TASK [download picture jvm-01-01.png] ****************************************************************************\u003Cbr\u003E53 skipping: [172.16.1.180]\u003Cbr\u003E54 skipping: [web01]\u003Cbr\u003E55 skipping: [web02]\u003Cbr\u003E56 skipping: [web03]\u003Cbr\u003E57 skipping: [172.16.1.182]\u003Cbr\u003E58 changed: [172.16.1.181]\u003Cbr\u003E59 \u003Cbr\u003E60 TASK [download picture jvm-01-02.png] ****************************************************************************\u003Cbr\u003E61 skipping: [172.16.1.180]\u003Cbr\u003E62 skipping: [web01]\u003Cbr\u003E63 skipping: [web02]\u003Cbr\u003E64 skipping: [web03]\u003Cbr\u003E65 skipping: [172.16.1.181]\u003Cbr\u003E66 changed: [172.16.1.182]\u003Cbr\u003E67 \u003Cbr\u003E68 TASK [other download picture jvm-01-03.png] **********************************************************************\u003Cbr\u003E69 skipping: [172.16.1.181]\u003Cbr\u003E70 skipping: [172.16.1.182]\u003Cbr\u003E71 changed: [web02]\u003Cbr\u003E72 changed: [web01]\u003Cbr\u003E73 changed: [172.16.1.180]\u003Cbr\u003E74 changed: [web03]\u003Cbr\u003E75 \u003Cbr\u003E76 PLAY RECAP *******************************************************************************************************\u003Cbr\u003E77 172.16.1.180 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0\u003Cbr\u003E78 172.16.1.181 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0\u003Cbr\u003E79 172.16.1.182 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0\u003Cbr\u003E80 web01 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0\u003Cbr\u003E81 web02 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0\u003Cbr\u003E82 web03 : ok=2 changed=1 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E标准循环\u003C\u002Fh1\u003E\u003Cp\u003E\u003Cstrong\u003E注意:\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E1、循环语法有两种:loop 和 with_。\u003C\u002Fp\u003E\u003Cp\u003E2、loop 是在ansible 2.5 添加的,with_ 是一直存在的,推荐使用 loop。在未来 with_ 可能被弃用。\u003C\u002Fp\u003E\u003Ch2 class=\"pgc-h-arrow-right\"\u003E简单列表循环\u003C\u002Fh2\u003E\u003Cp\u003E如果我们需要在 playbook 中启动多个服务,或者下载多个文件;按照之前所学的,那么我们需要写多个 task。但这样会使得 playbook 变得臃肿,因此这时我们就需要引进循环了。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E示例:一次启动多个服务,下载多个文件\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E使用 loop 方式【推荐】\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object04]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject04\u003Cbr\u003E 3 [yun@ansi-manager object04]$ ll\u003Cbr\u003E 4 total 20\u003Cbr\u003E 5 -rw-rw-r-- 1 yun yun 594 Aug 23 22:10 test_loop.yml\u003Cbr\u003E 6 [yun@ansi-manager object04]$ cat test_loop.yml \u003Cbr\u003E 7 ---\u003Cbr\u003E 8 # 启动多个服务 和下载多个文件\u003Cbr\u003E 9 - hosts: proxyservers\u003Cbr\u003E10 \u003Cbr\u003E11 tasks:\u003Cbr\u003E12 - name: "start httpd, rpcbind, network server"\u003Cbr\u003E13 service:\u003Cbr\u003E14 name: "{{ item }}" # 需要用引号引起来\u003Cbr\u003E15 state: started\u003Cbr\u003E16 loop:\u003Cbr\u003E17 - httpd\u003Cbr\u003E18 - rpcbind\u003Cbr\u003E19 - network\u003Cbr\u003E20 \u003Cbr\u003E21 - name: "download multiple file"\u003Cbr\u003E22 get_url:\u003Cbr\u003E23 url: "{{ item }}" # 需要用引号引起来\u003Cbr\u003E24 dest: \u002Ftmp\u002F\u003Cbr\u003E25 loop:\u003Cbr\u003E26 - http:\u002F\u002Fwww.zhangblog.com\u002Fuploads\u002Fjvm\u002Fjvm-01-01.png\u003Cbr\u003E27 - http:\u002F\u002Fwww.zhangblog.com\u002Fuploads\u002Fjvm\u002Fjvm-01-02.png\u003Cbr\u003E28 - http:\u002F\u002Fwww.zhangblog.com\u002Fuploads\u002Fjvm\u002Fjvm-01-03.png\u003Cbr\u003E29 \u003Cbr\u003E30 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_loop.yml # 语法检测\u003Cbr\u003E31 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_loop.yml # 预执行,测试执行\u003Cbr\u003E32 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key test_loop.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cp\u003E备注:以上方法可用在 yum 模块中。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E使用 with_items 方式\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E其中 playbook 文件中仅把 loop 变为了 with_items。\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object04]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject04\u003Cbr\u003E 3 [yun@ansi-manager object04]$ ll\u003Cbr\u003E 4 total 20\u003Cbr\u003E 5 -rw-rw-r-- 1 yun yun 594 Aug 23 22:10 test_with_items.yml\u003Cbr\u003E 6 [yun@ansi-manager object04]$ cat test_with_items.yml \u003Cbr\u003E 7 ---\u003Cbr\u003E 8 # 启动多个服务 和下载多个文件\u003Cbr\u003E 9 - hosts: proxyservers\u003Cbr\u003E10 \u003Cbr\u003E11 tasks:\u003Cbr\u003E12 - name: "start httpd, rpcbind, network server"\u003Cbr\u003E13 service:\u003Cbr\u003E14 name: "{{ item }}" # 需要用引号引起来\u003Cbr\u003E15 state: started\u003Cbr\u003E16 with_items:\u003Cbr\u003E17 - httpd\u003Cbr\u003E18 - rpcbind\u003Cbr\u003E19 - network\u003Cbr\u003E20 \u003Cbr\u003E21 - name: "download multiple file"\u003Cbr\u003E22 get_url:\u003Cbr\u003E23 url: "{{ item }}" # 需要用引号引起来\u003Cbr\u003E24 dest: \u002Ftmp\u002F\u003Cbr\u003E25 with_items:\u003Cbr\u003E26 - http:\u002F\u002Fwww.zhangblog.com\u002Fuploads\u002Fjvm\u002Fjvm-01-01.png\u003Cbr\u003E27 - http:\u002F\u002Fwww.zhangblog.com\u002Fuploads\u002Fjvm\u002Fjvm-01-02.png\u003Cbr\u003E28 - http:\u002F\u002Fwww.zhangblog.com\u002Fuploads\u002Fjvm\u002Fjvm-01-03.png\u003Cbr\u003E29 \u003Cbr\u003E30 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_with_items.yml # 语法检测\u003Cbr\u003E31 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_with_items.yml # 预执行,测试执行\u003Cbr\u003E32 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key test_with_items.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cp\u003E如果用在 yum 模块中则会报如下弃用告警,因此该方法不适用于 yum 模块。\u003C\u002Fp\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp9.pstatp.com\u002Flarge\u002Fpgc-image\u002F8e5f88eb56684acab29e7dca182c1b01\" img_width=\"933\" img_height=\"178\" alt=\"Ansible playbook 编程\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch2 class=\"pgc-h-arrow-right\"\u003E遍历哈希列表\u003C\u002Fh2\u003E\u003Cp\u003E如果我们需要创建多个用户并且每个用户都有指定的附加组;或者要创建多个文件,每个文件属主、属组、权限不一样;或者需要拷贝文件,但是每个文件的位置不一样,且属主、属组、权限不一样等等;那之前所学的简单循环就不能满足我们的需求了。这时「哈希列表循环」就闪亮登场了。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E示例:\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E使用 loop 方式【推荐】\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object04]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject04\u003Cbr\u003E 3 [yun@ansi-manager object04]$ ll\u003Cbr\u003E 4 total 16\u003Cbr\u003E 5 drwxrwxr-x 2 yun yun 56 Oct 26 16:03 file\u003Cbr\u003E 6 -rw-rw-r-- 1 yun yun 1205 Oct 26 16:02 test_loop_hash.yml\u003Cbr\u003E 7 [yun@ansi-manager object04]$ cat file\u002Fconfig_test.conf.j2 \u003Cbr\u003E 8 111\u003Cbr\u003E 9 [yun@ansi-manager object04]$ cat file\u002Fyml_test_j2.yml \u003Cbr\u003E10 222\u003Cbr\u003E11 [yun@ansi-manager object04]$ cat test_loop_hash.yml \u003Cbr\u003E12 ---\u003Cbr\u003E13 # 使用循环字典创建多个用户,创建多个文件,拷贝多个文件\u003Cbr\u003E14 - hosts: proxyservers\u003Cbr\u003E15 \u003Cbr\u003E16 tasks:\u003Cbr\u003E17 - name: "Create multiple user"\u003Cbr\u003E18 user:\u003Cbr\u003E19 name: "{{ item.user }}"\u003Cbr\u003E20 groups: "{{ item.groups }}"\u003Cbr\u003E21 loop:\u003Cbr\u003E22 - { user: "testuser1", groups: "root" }\u003Cbr\u003E23 - { user: "testuser2", groups: "root,yun" }\u003Cbr\u003E24 \u003Cbr\u003E25 - name: "Create multiple file or dir"\u003Cbr\u003E26 file:\u003Cbr\u003E27 path: "{{ item.path }}"\u003Cbr\u003E28 owner: "{{ item.owner }}"\u003Cbr\u003E29 group: "{{ item.group }}"\u003Cbr\u003E30 mode: "{{ item.mode }}"\u003Cbr\u003E31 state: "{{ item.state }}"\u003Cbr\u003E32 loop:\u003Cbr\u003E33 - { path: "\u002Ftmp\u002Fwith_items_testdir", owner: "yun", group: "root", mode: "755", state: "directory" }\u003Cbr\u003E34 - { path: "\u002Ftmp\u002Fwith_items_testfile", owner: "bin", group: "bin", mode: "644", state: "touch" }\u003Cbr\u003E35 \u003Cbr\u003E36 - name: "copy multiple file"\u003Cbr\u003E37 copy:\u003Cbr\u003E38 src: "{{ item.src }}"\u003Cbr\u003E39 dest: "{{ item.dest }}"\u003Cbr\u003E40 owner: "{{ item.owner }}"\u003Cbr\u003E41 group: "{{ item.group }}"\u003Cbr\u003E42 loop:\u003Cbr\u003E43 - { src: ".\u002Ffile\u002Fconfig_test.conf.j2", dest: "\u002Ftmp\u002Fwith_items_testdir\u002F", owner: "yun", group: "root" }\u003Cbr\u003E44 - { src: ".\u002Ffile\u002Fyml_test_j2.yml", dest: "\u002Ftmp\u002Fyml_test.yml", owner: "yun", group: "yun" }\u003Cbr\u003E45 \u003Cbr\u003E46 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_loop_hash.yml # 语法检测\u003Cbr\u003E47 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_loop_hash.yml # 预执行,测试执行\u003Cbr\u003E48 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key test_loop_hash.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E使用 with_items 方式\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E其中 playbook 文件中仅把 loop 变为了 with_items。\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object04]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject04\u003Cbr\u003E 3 [yun@ansi-manager object04]$ ll\u003Cbr\u003E 4 total 16\u003Cbr\u003E 5 drwxrwxr-x 2 yun yun 56 Oct 26 16:03 file\u003Cbr\u003E 6 -rw-rw-r-- 1 yun yun 1205 Oct 26 16:02 test_with_items_hash.yml\u003Cbr\u003E 7 [yun@ansi-manager object04]$ cat file\u002Fconfig_test.conf.j2 \u003Cbr\u003E 8 111\u003Cbr\u003E 9 [yun@ansi-manager object04]$ cat file\u002Fyml_test_j2.yml \u003Cbr\u003E10 222\u003Cbr\u003E11 [yun@ansi-manager object04]$ cat test_with_items_hash.yml \u003Cbr\u003E12 ---\u003Cbr\u003E13 # 使用循环字典创建多个用户,创建多个文件,拷贝多个文件\u003Cbr\u003E14 - hosts: proxyservers\u003Cbr\u003E15 \u003Cbr\u003E16 tasks:\u003Cbr\u003E17 - name: "Create multiple user"\u003Cbr\u003E18 user:\u003Cbr\u003E19 name: "{{ item.user }}"\u003Cbr\u003E20 groups: "{{ item.groups }}"\u003Cbr\u003E21 with_items:\u003Cbr\u003E22 - { user: "testuser1", groups: "root" }\u003Cbr\u003E23 - { user: "testuser2", groups: "root,yun" }\u003Cbr\u003E24 \u003Cbr\u003E25 - name: "Create multiple file or dir"\u003Cbr\u003E26 file:\u003Cbr\u003E27 path: "{{ item.path }}"\u003Cbr\u003E28 owner: "{{ item.owner }}"\u003Cbr\u003E29 group: "{{ item.group }}"\u003Cbr\u003E30 mode: "{{ item.mode }}"\u003Cbr\u003E31 state: "{{ item.state }}"\u003Cbr\u003E32 with_items:\u003Cbr\u003E33 - { path: "\u002Ftmp\u002Fwith_items_testdir", owner: "yun", group: "root", mode: "755", state: "directory" }\u003Cbr\u003E34 - { path: "\u002Ftmp\u002Fwith_items_testfile", owner: "bin", group: "bin", mode: "644", state: "touch" }\u003Cbr\u003E35 \u003Cbr\u003E36 - name: "copy multiple file"\u003Cbr\u003E37 copy:\u003Cbr\u003E38 src: "{{ item.src }}"\u003Cbr\u003E39 dest: "{{ item.dest }}"\u003Cbr\u003E40 owner: "{{ item.owner }}"\u003Cbr\u003E41 group: "{{ item.group }}"\u003Cbr\u003E42 with_items:\u003Cbr\u003E43 - { src: ".\u002Ffile\u002Fconfig_test.conf.j2", dest: "\u002Ftmp\u002Fwith_items_testdir\u002F", owner: "yun", group: "root" }\u003Cbr\u003E44 - { src: ".\u002Ffile\u002Fyml_test_j2.yml", dest: "\u002Ftmp\u002Fyml_test.yml", owner: "yun", group: "yun" }\u003Cbr\u003E45 \u003Cbr\u003E46 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_with_items_hash.yml # 语法检测\u003Cbr\u003E47 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_with_items_hash.yml # 预执行,测试执行\u003Cbr\u003E48 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key test_with_items_hash.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch2 class=\"pgc-h-arrow-right\"\u003E遍历字典\u003C\u002Fh2\u003E\u003Cp\u003E\u003Cstrong\u003E示例:\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E使用 loop 方式【推荐】\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object04]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject04\u003Cbr\u003E 3 [yun@ansi-manager object04]$ ll\u003Cbr\u003E 4 total 28\u003Cbr\u003E 5 -rw-rw-r-- 1 yun yun 452 Oct 26 16:46 test_loop_dict.yml\u003Cbr\u003E 6 [yun@ansi-manager object04]$ cat test_loop_dict.yml \u003Cbr\u003E 7 ---\u003Cbr\u003E 8 # 打印信息\u003Cbr\u003E 9 - hosts: manageservers\u003Cbr\u003E10 vars:\u003Cbr\u003E11 users:\u003Cbr\u003E12 alice:\u003Cbr\u003E13 name: Alice Appleworth\u003Cbr\u003E14 telephone: 123-456-7890\u003Cbr\u003E15 bob:\u003Cbr\u003E16 name: Bob Bananarama\u003Cbr\u003E17 telephone: 987-654-3210\u003Cbr\u003E18 \u003Cbr\u003E19 tasks:\u003Cbr\u003E20 - name: "print user info"\u003Cbr\u003E21 debug:\u003Cbr\u003E22 msg: "User {{ item.key }}, userfullname: {{ item.value.name }} ({{ item.value.telephone }})"\u003Cbr\u003E23 # 将字典转换为适合循环的项表 第一种方式推荐\u003Cbr\u003E24 loop: "{{ users|dict2items }}"\u003Cbr\u003E25 #loop: "{{ lookup('dict', users) }}"\u003Cbr\u003E26 \u003Cbr\u003E27 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_loop_dict.yml # 语法检测\u003Cbr\u003E28 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_loop_dict.yml # 预执行,测试执行\u003Cbr\u003E29 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key test_loop_dict.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E使用 with_items 方式\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object04]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject04\u003Cbr\u003E 3 [yun@ansi-manager object04]$ ll\u003Cbr\u003E 4 total 28\u003Cbr\u003E 5 -rw-rw-r-- 1 yun yun 458 Oct 26 16:47 test_with_items_dict.yml\u003Cbr\u003E 6 [yun@ansi-manager object04]$ cat test_with_items_dict.yml \u003Cbr\u003E 7 ---\u003Cbr\u003E 8 # 打印信息\u003Cbr\u003E 9 - hosts: manageservers\u003Cbr\u003E10 vars:\u003Cbr\u003E11 users:\u003Cbr\u003E12 alice:\u003Cbr\u003E13 name: Alice Appleworth\u003Cbr\u003E14 telephone: 123-456-7890\u003Cbr\u003E15 bob:\u003Cbr\u003E16 name: Bob Bananarama\u003Cbr\u003E17 telephone: 987-654-3210\u003Cbr\u003E18 \u003Cbr\u003E19 tasks:\u003Cbr\u003E20 - name: "print user info"\u003Cbr\u003E21 debug:\u003Cbr\u003E22 msg: "User {{ item.key }}, userfullname: {{ item.value.name }} ({{ item.value.telephone }})"\u003Cbr\u003E23 # with_dict 会直接解析字典\u003Cbr\u003E24 with_dict: "{{ users }}"\u003Cbr\u003E25 \u003Cbr\u003E26 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_with_items_dict.yml # 语法检测\u003Cbr\u003E27 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_with_items_dict.yml # 预执行,测试执行\u003Cbr\u003E28 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key test_with_items_dict.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E变量循环-vars\u003C\u002Fh1\u003E\u003Cp\u003E针对yum 安装多个包很有用,其他则会报出警告。\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object04]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject04\u003Cbr\u003E 3 [yun@ansi-manager object04]$ ll\u003Cbr\u003E 4 total 36\u003Cbr\u003E 5 -rw-rw-r-- 1 yun yun 252 Oct 26 17:46 test_cycle_vars.yml\u003Cbr\u003E 6 [yun@ansi-manager object04]$ cat test_cycle_vars.yml \u003Cbr\u003E 7 ---\u003Cbr\u003E 8 # 批量包安装\u003Cbr\u003E 9 - hosts: proxyservers\u003Cbr\u003E10 \u003Cbr\u003E11 tasks:\u003Cbr\u003E12 - name: "Install multiple packages"\u003Cbr\u003E13 yum:\u003Cbr\u003E14 name: "{{ multi_package }}"\u003Cbr\u003E15 state: present\u003Cbr\u003E16 vars:\u003Cbr\u003E17 multi_package:\u003Cbr\u003E18 - tree\u003Cbr\u003E19 - nc\u003Cbr\u003E20 - tcpdump\u003Cbr\u003E21 \u003Cbr\u003E22 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_cycle_vars.yml # 语法检测\u003Cbr\u003E23 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_cycle_vars.yml # 预执行,测试执行\u003Cbr\u003E24 [yun@ansi-manager object04]$ ansible-playbook -b -i ..\u002Fhosts_key test_cycle_vars.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cp\u003E该方法不一定适用于其他模块\u003C\u002Fp\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002Ffe8a5e17c49047f58603ff1f2330d8d6\" img_width=\"937\" img_height=\"73\" alt=\"Ansible playbook 编程\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E触发器-handlers\u003C\u002Fh1\u003E\u003Cp\u003E当我们修改了服务的配置文件时,这时我们需要去重启服务,那么 handlers 就可以派上用场了。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E注意事项:\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E1、无论多少个 task 通知了相同的 handlers,handlers 仅会在所有 tasks 结束后运行一次。\u003C\u002Fp\u003E\u003Cp\u003E2、只有 task 发生改变了才会通知 handlers,没有改变则不会通知和触发 handlers。\u003C\u002Fp\u003E\u003Cp\u003E3、不能用 handlers 替代 task 。\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object05]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject05\u003Cbr\u003E 3 [yun@ansi-manager object05]$ ll\u003Cbr\u003E 4 total 24\u003Cbr\u003E 5 drwxrwxr-x 2 yun yun 129 Aug 24 11:41 file\u003Cbr\u003E 6 -rw-rw-r-- 1 yun yun 1029 Aug 24 11:57 test_handlers.yml\u003Cbr\u003E 7 [yun@ansi-manager object05]$ ll file\u002F # 涉及配置文件\u003Cbr\u003E 8 total 20\u003Cbr\u003E 9 -rw-r--r-- 1 yun yun 11767 Aug 24 11:41 httpd.conf.j2\u003Cbr\u003E10 [yun@ansi-manager object05]$ vim file\u002Fhttpd.conf.j2 # 配置文件修改的地方\u003Cbr\u003E11 …………\u003Cbr\u003E12 # Change this to Listen on specific IP addresses as shown below to \u003Cbr\u003E13 # prevent Apache from glomming onto all bound IP addresses.\u003Cbr\u003E14 #\u003Cbr\u003E15 #Listen 12.34.56.78:80\u003Cbr\u003E16 ###### 端口改为变量\u003Cbr\u003E17 Listen {{ httpd_port }}\u003Cbr\u003E18 \u003Cbr\u003E19 …………\u003Cbr\u003E20 [yun@ansi-manager object05]$ cat test_handlers.yml # yml 文件\u003Cbr\u003E21 ---\u003Cbr\u003E22 # 比如安装配置启动 httpd。当我们修改配置文件,重启 httpd 服务\u003Cbr\u003E23 # 要求:修改配置,重启一个或多个服务\u003Cbr\u003E24 - hosts: proxyservers\u003Cbr\u003E25 # 这里为了演示方便,因此变量直接就写在了该文件中\u003Cbr\u003E26 vars:\u003Cbr\u003E27 - httpd_port: 8081\u003Cbr\u003E28 \u003Cbr\u003E29 tasks:\u003Cbr\u003E30 - name: "Install httpd"\u003Cbr\u003E31 yum:\u003Cbr\u003E32 name: "{{ packages }}"\u003Cbr\u003E33 state: present\u003Cbr\u003E34 vars:\u003Cbr\u003E35 packages:\u003Cbr\u003E36 - httpd\u003Cbr\u003E37 - httpd-tools\u003Cbr\u003E38 \u003Cbr\u003E39 - name: "Httpd config"\u003Cbr\u003E40 template:\u003Cbr\u003E41 src: .\u002Ffile\u002Fhttpd.conf.j2\u003Cbr\u003E42 dest: \u002Fetc\u002Fhttpd\u002Fconf\u002Fhttpd.conf\u003Cbr\u003E43 # 一个通知\u003Cbr\u003E44 # notify: "Restart httpd server"\u003Cbr\u003E45 # 多个通知\u003Cbr\u003E46 notify:\u003Cbr\u003E47 - "Restart httpd server"\u003Cbr\u003E48 - "Restart crond server"\u003Cbr\u003E49 \u003Cbr\u003E50 - name: "Start httpd server"\u003Cbr\u003E51 systemd:\u003Cbr\u003E52 name: httpd\u003Cbr\u003E53 state: started\u003Cbr\u003E54 enabled: yes\u003Cbr\u003E55 \u003Cbr\u003E56 handlers:\u003Cbr\u003E57 - name: "Restart httpd server"\u003Cbr\u003E58 systemd:\u003Cbr\u003E59 name: httpd\u003Cbr\u003E60 state: restarted\u003Cbr\u003E61 \u003Cbr\u003E62 - name: "Restart crond server"\u003Cbr\u003E63 systemd:\u003Cbr\u003E64 name: crond\u003Cbr\u003E65 state: restarted\u003Cbr\u003E66 \u003Cbr\u003E67 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_handlers.yml # 语法检测\u003Cbr\u003E68 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_handlers.yml # 预执行,测试执行\u003Cbr\u003E69 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_handlers.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E任务标签-tags\u003C\u002Fh1\u003E\u003Cp\u003E默认情况下,当我们执行一个 playbook 时,会执行该 playbook 中所有的任务。如果只想执行一个 task 或者部分 task 用于调试或者需求就是执行部分 task。那么可以使用 ansible 的标签(tags)功能给单独 task 或者全部 task 打上标签。之后利用这些标签来指定要运行哪些 playbook 任务,或不运行哪些 playbook 任务。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E打标签方式\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E对一个 task 打一个标签;\u003C\u002Fp\u003E\u003Cp\u003E对一个 task 打多个标签;\u003C\u002Fp\u003E\u003Cp\u003E对多个 task 打一个标签\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E标签如何运用\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E-t TAGS, --tags=TAGS:执行指定的 tag 标签任务;多个标签使用逗号分开\u003C\u002Fp\u003E\u003Cp\u003E--skip-tags=SKIP_TAGS:跳过指定标签不执行,执行指定外的 task「标签作用于 task 上,即使该task还有其他标签,这个 task 也不会被执行」;多个标签使用逗号分开\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object05]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject05\u003Cbr\u003E 3 [yun@ansi-manager object05]$ ll\u003Cbr\u003E 4 total 8\u003Cbr\u003E 5 drwxrwxr-x 2 yun yun 27 Oct 26 18:07 file\u003Cbr\u003E 6 -rw-rw-r-- 1 yun yun 1004 Oct 26 19:21 test_tags.yml\u003Cbr\u003E 7 [yun@ansi-manager object05]$ cat test_tags.yml \u003Cbr\u003E 8 ---\u003Cbr\u003E 9 # tags 标签测试\u003Cbr\u003E10 - hosts: proxyservers\u003Cbr\u003E11 # 这里为了演示方便,因此变量直接就写在了该文件中\u003Cbr\u003E12 vars:\u003Cbr\u003E13 - httpd_port: 8081\u003Cbr\u003E14 \u003Cbr\u003E15 tasks:\u003Cbr\u003E16 - name: "Install httpd"\u003Cbr\u003E17 yum:\u003Cbr\u003E18 name: "{{ packages }}"\u003Cbr\u003E19 state: present\u003Cbr\u003E20 vars:\u003Cbr\u003E21 packages:\u003Cbr\u003E22 - httpd\u003Cbr\u003E23 - httpd-tools\u003Cbr\u003E24 tags: \u003Cbr\u003E25 - httpd_server\u003Cbr\u003E26 - httpd_install\u003Cbr\u003E27 \u003Cbr\u003E28 - name: "Httpd config"\u003Cbr\u003E29 template:\u003Cbr\u003E30 src: .\u002Ffile\u002Fhttpd.conf.j2\u003Cbr\u003E31 dest: \u002Fetc\u002Fhttpd\u002Fconf\u002Fhttpd.conf\u003Cbr\u003E32 notify: "Restart httpd server"\u003Cbr\u003E33 tags:\u003Cbr\u003E34 - httpd_server\u003Cbr\u003E35 - httpd_config\u003Cbr\u003E36 \u003Cbr\u003E37 - name: "Start httpd server"\u003Cbr\u003E38 systemd:\u003Cbr\u003E39 name: httpd\u003Cbr\u003E40 state: started\u003Cbr\u003E41 enabled: yes\u003Cbr\u003E42 tags: \u003Cbr\u003E43 - httpd_server\u003Cbr\u003E44 - httpd_start\u003Cbr\u003E45 \u003Cbr\u003E46 - name: "Create dir"\u003Cbr\u003E47 file:\u003Cbr\u003E48 path: \u002Ftmp\u002Fwith_items_testdir\u003Cbr\u003E49 state: directory\u003Cbr\u003E50 tags: create_dir\u003Cbr\u003E51 \u003Cbr\u003E52 handlers:\u003Cbr\u003E53 - name: "Restart httpd server"\u003Cbr\u003E54 systemd:\u003Cbr\u003E55 name: httpd\u003Cbr\u003E56 state: restarted\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003Eplaybook 标签查看\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_tags.yml # 语法检测\u003Cbr\u003E 2 ## 查看 playbook 中的任务和标签\u003Cbr\u003E 3 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_tags.yml --list-tasks \u003Cbr\u003E 4 \u003Cbr\u003E 5 playbook: test_tags.yml\u003Cbr\u003E 6 \u003Cbr\u003E 7 play #1 (proxyservers): proxyservers TAGS: []\u003Cbr\u003E 8 tasks:\u003Cbr\u003E 9 Install httpd TAGS: [httpd_install, httpd_server]\u003Cbr\u003E10 Httpd config TAGS: [httpd_config, httpd_server]\u003Cbr\u003E11 Start httpd server TAGS: [httpd_server, httpd_start]\u003Cbr\u003E12 Create dir TAGS: [create_dir]\u003Cbr\u003E13 ## 查看 playbook 中的标签\u003Cbr\u003E14 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_tags.yml --list-tags\u003Cbr\u003E15 \u003Cbr\u003E16 playbook: test_tags.yml\u003Cbr\u003E17 \u003Cbr\u003E18 play #1 (proxyservers): proxyservers TAGS: []\u003Cbr\u003E19 TASK TAGS: [create_dir, httpd_config, httpd_install, httpd_server, httpd_start]\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003Eplaybook 执行\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 ## 单个标签执行\u003Cbr\u003E 2 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_tags.yml -t httpd_install \u003Cbr\u003E 3 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_tags.yml -t httpd_server\u003Cbr\u003E 4 ## 多个标签执行\u003Cbr\u003E 5 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_tags.yml -t httpd_install,httpd_config,httpd_start\u003Cbr\u003E 6 ## 跳过哪些标签不执行「标签作用于 task 上,即使该 task 还有其他标签,这个 task 也不会被执行」\u003Cbr\u003E 7 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_tags.yml --skip-tags httpd_server\u003Cbr\u003E 8 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_tags.yml --skip-tags httpd_install,create_dir\u003Cbr\u003E 9 ## 执行整个 playbook \u003Cbr\u003E10 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_tags.yml\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E文件引用\u002F复用-include与import\u003C\u002Fh1\u003E\u003Cp\u003E在实际应用中,是不可能将所有 task 写在一个 playbook 中的,需要进行拆分,方便后期重复使用。这样后面写其他 playbook 的时候,如果有重复的,那么直接引用之前写的即可。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003EIncludes 与 Imports\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E1、include 和 import 虽然功能相近,但是 ansible 执行引擎对他们的处理却截然不同。\u003C\u002Fp\u003E\u003Cp\u003E2、所有 import* 语句都会在解析 playbook 时进行预处理。「提前准备好工具」\u003C\u002Fp\u003E\u003Cp\u003E3、所有 include* 语句都是在执行 playbook 时遇到再处理。「需要什么工具,再拿什么工具」\u003C\u002Fp\u003E\u003Cp\u003EPS:include 模块:这个模块还将支持一段时间,但在不久的将来可能会弃用「最好不要使用这个模块」。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E示例\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object05]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject05\u003Cbr\u003E 3 [yun@ansi-manager object05]$ ll\u003Cbr\u003E 4 total 32\u003Cbr\u003E 5 drwxrwxr-x 2 yun yun 103 Aug 24 19:51 file_yml\u003Cbr\u003E 6 -rw-rw-r-- 1 yun yun 518 Aug 24 19:56 test_include.yml\u003Cbr\u003E 7 [yun@ansi-manager object05]$ ll file_yml\u002F\u003Cbr\u003E 8 total 16\u003Cbr\u003E 9 -rw-rw-r-- 1 yun yun 136 Aug 24 19:51 httpd_config.yml\u003Cbr\u003E10 -rw-rw-r-- 1 yun yun 133 Aug 24 19:41 httpd_install.yml\u003Cbr\u003E11 -rw-rw-r-- 1 yun yun 80 Aug 24 19:42 httpd_restart.yml\u003Cbr\u003E12 -rw-rw-r-- 1 yun yun 93 Aug 24 19:41 httpd_start.yml\u003Cbr\u003E13 ## 每个小 yml 文件的具体内容\u003Cbr\u003E14 [yun@ansi-manager object05]$ cat file_yml\u002Fhttpd_install.yml \u003Cbr\u003E15 - name: "Install httpd"\u003Cbr\u003E16 yum:\u003Cbr\u003E17 name: "{{ packages }}"\u003Cbr\u003E18 state: present\u003Cbr\u003E19 vars:\u003Cbr\u003E20 packages:\u003Cbr\u003E21 - httpd\u003Cbr\u003E22 - httpd-tools\u003Cbr\u003E23 \u003Cbr\u003E24 [yun@ansi-manager object05]$ cat file_yml\u002Fhttpd_config.yml \u003Cbr\u003E25 - name: "Httpd config"\u003Cbr\u003E26 template:\u003Cbr\u003E27 src: .\u002Ffile\u002Fhttpd.conf.j2\u003Cbr\u003E28 dest: \u002Fetc\u002Fhttpd\u002Fconf\u002Fhttpd.conf\u003Cbr\u003E29 notify: "Restart httpd server"\u003Cbr\u003E30 \u003Cbr\u003E31 [yun@ansi-manager object05]$ cat file_yml\u002Fhttpd_start.yml \u003Cbr\u003E32 - name: "Start httpd server"\u003Cbr\u003E33 systemd:\u003Cbr\u003E34 name: httpd\u003Cbr\u003E35 state: started\u003Cbr\u003E36 enabled: yes\u003Cbr\u003E37 \u003Cbr\u003E38 [yun@ansi-manager object05]$ cat file_yml\u002Fhttpd_restart.yml \u003Cbr\u003E39 - name: "Restart httpd server"\u003Cbr\u003E40 systemd:\u003Cbr\u003E41 name: httpd\u003Cbr\u003E42 state: restarted\u003Cbr\u003E43 \u003Cbr\u003E44 ###### 主调用 yml 文件内容 ######\u003Cbr\u003E45 [yun@ansi-manager object05]$ cat test_include.yml \u003Cbr\u003E46 ---\u003Cbr\u003E47 # 调用其他 yml 文件\u003Cbr\u003E48 - hosts: proxyservers\u003Cbr\u003E49 # 这里为了演示方便,因此变量直接就写在了该文件中\u003Cbr\u003E50 vars:\u003Cbr\u003E51 - httpd_port: 8083\u003Cbr\u003E52 \u003Cbr\u003E53 tasks:\u003Cbr\u003E54 - include_tasks: .\u002Ffile_yml\u002Fhttpd_install.yml\u003Cbr\u003E55 - include_tasks: .\u002Ffile_yml\u002Fhttpd_config.yml\u003Cbr\u003E56 - include_tasks: .\u002Ffile_yml\u002Fhttpd_start.yml\u003Cbr\u003E57 \u003Cbr\u003E58 handlers:\u003Cbr\u003E59 # 使用 import 进行预处理,这样防止 notify 时,在 handlers 找不到对应的信息\u003Cbr\u003E60 - import_tasks: .\u002Ffile_yml\u002Fhttpd_restart.yml\u003Cbr\u003E61 \u003Cbr\u003E62 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_include.yml # 语法检测\u003Cbr\u003E63 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_include.yml # 预执行,测试执行\u003Cbr\u003E64 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_include.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E忽略错误-ignore_errors\u003C\u002Fh1\u003E\u003Cp\u003E在 playbook 执行过程中,默认情况下如果有错误发生,那么后面的 task 就不执行,并且退出当前的 playbook。\u003C\u002Fp\u003E\u003Cp\u003E如果我们对某些 task 执行结果不关心,不管执行是否成功,后面的 task 也要继续执行。那就需要通过 ignore_errors 来忽略当前 task 的错误结果,让后面的 task 继续往下执行。\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object05]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject05\u003Cbr\u003E 3 [yun@ansi-manager object05]$ ll\u003Cbr\u003E 4 total 36\u003Cbr\u003E 5 -rw-rw-r-- 1 yun yun 479 Aug 26 09:24 test_ignore_errors.yml\u003Cbr\u003E 6 [yun@ansi-manager object05]$ cat test_ignore_errors.yml \u003Cbr\u003E 7 ---\u003Cbr\u003E 8 # ignore_errors 测试\u003Cbr\u003E 9 - hosts: proxyservers\u003Cbr\u003E10 \u003Cbr\u003E11 tasks:\u003Cbr\u003E12 - name: "Install httpd"\u003Cbr\u003E13 yum:\u003Cbr\u003E14 name: "{{ packages }}"\u003Cbr\u003E15 state: present\u003Cbr\u003E16 vars:\u003Cbr\u003E17 packages:\u003Cbr\u003E18 - httpd\u003Cbr\u003E19 - httpd-tools\u003Cbr\u003E20 \u003Cbr\u003E21 - name: "Shell false"\u003Cbr\u003E22 shell: \u002Fbin\u002Ffalse\u003Cbr\u003E23 # 是否忽略该 task 的错误 「打开或关闭注释,对比」\u003Cbr\u003E24 ignore_errors: True\u003Cbr\u003E25 \u003Cbr\u003E26 - name: "Create dir"\u003Cbr\u003E27 file:\u003Cbr\u003E28 path: \u002Ftmp\u002Fwith_items_testdir\u003Cbr\u003E29 state: directory\u003Cbr\u003E30 \u003Cbr\u003E31 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_ignore_errors.yml # 语法检测\u003Cbr\u003E32 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_ignore_errors.yml # 预执行,测试执行\u003Cbr\u003E33 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_ignore_errors.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E默认情况\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002Fff9229b13adb4e3cbcef8b25979f4090\" img_width=\"939\" img_height=\"367\" alt=\"Ansible playbook 编程\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E使用了 ignore_errors 的情况\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002F089cfc627aa84018b2d948132c1ea80a\" img_width=\"835\" img_height=\"460\" alt=\"Ansible playbook 编程\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E自定义错误判定条件-failed_when\u003C\u002Fh1\u003E\u003Cp\u003E命令不依赖返回状态码来判定是否执行失败,而是要查看命令返回内容来决定,比如返回内容中包括 command not found 字符串,则判定为失败。\u003C\u002Fp\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object05]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject05\u003Cbr\u003E 3 [yun@ansi-manager object05]$ ll\u003Cbr\u003E 4 total 48\u003Cbr\u003E 5 -rw-rw-r-- 1 yun yun 369 Aug 29 16:12 test_custom_error.yml\u003Cbr\u003E 6 [yun@ansi-manager object05]$ cat test_custom_error.yml \u003Cbr\u003E 7 ---\u003Cbr\u003E 8 # 自定义错误条件\u003Cbr\u003E 9 - hosts: proxyservers\u003Cbr\u003E10 \u003Cbr\u003E11 tasks:\u003Cbr\u003E12 - name: "this command prints 'command not found' if not find"\u003Cbr\u003E13 shell: "kkk -x" # 测试一\u003Cbr\u003E14 #shell: "\u002Fbin\u002Fkkk -x" # 测试二\u003Cbr\u003E15 register: shell_result\u003Cbr\u003E16 failed_when: "'command not found' in shell_result['stderr']"\u003Cbr\u003E17 \u003Cbr\u003E18 - name: "print shell_result info"\u003Cbr\u003E19 debug:\u003Cbr\u003E20 msg: "{{ shell_result['stderr'] }}"\u003Cbr\u003E21 \u003Cbr\u003E22 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_custom_error.yml # 语法检测\u003Cbr\u003E23 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_custom_error.yml # 预执行,测试执行\u003Cbr\u003E24 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_custom_error.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E强制调用触发器-force_handlers\u003C\u002Fh1\u003E\u003Cp\u003E通常情况下,当 task 执行失败后,playbook 会终止。任何在此之前已经被 task notify 的 handlers 都不会被执行。\u003C\u002Fp\u003E\u003Cp\u003E此时,如果你在 playbook 中设置了 force_handlers: yes 参数,则被通知的 handlers 就会被强制执行(有些特殊场景可能会使用到)。\u003C\u002Fp\u003E\u003Cp\u003E如示例,在一个 playbook 中,如果配置文件的 task 已经被执行成功,并且 notify 了 handlers,之后必须重启服务。那么我们会强制要求:即使后续的 task 执行失败,之前被通知的 handlers 也必须执行。\u003C\u002Fp\u003E\u003Cp\u003E如果不强制执行就变成了,第一次执行时:配置文件修改成功,但由于之后有 task 执行失败,导致 playbook 终止,后续 handlers 没有被调用,对应服务没有重启;第二次执行时:配置文件没发生改变「因此第一次已经更新了配置文件」,因此不会通知 handlers。最终结果就是配置改变了,但是就是没有重启服务。显然不符合我们的初衷。\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object05]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject05\u003Cbr\u003E 3 [yun@ansi-manager object05]$ ll\u003Cbr\u003E 4 total 40\u003Cbr\u003E 5 drwxrwxr-x 2 yun yun 129 Aug 24 14:28 file\u003Cbr\u003E 6 -rw-rw-r-- 1 yun yun 909 Aug 29 12:23 test_error_deal.yml\u003Cbr\u003E 7 [yun@ansi-manager object05]$ cat test_error_deal.yml \u003Cbr\u003E 8 ---\u003Cbr\u003E 9 # 即使 task 执行错误,之前已 notify 的 handlers 必须被执行\u003Cbr\u003E10 - hosts: proxyservers\u003Cbr\u003E11 # 这里为了演示方便,因此变量直接就写在了该文件中\u003Cbr\u003E12 vars:\u003Cbr\u003E13 - httpd_port: 8087\u003Cbr\u003E14 # 即使 task 执行错误,之前已 notify 的 handlers 必须被执行\u003Cbr\u003E15 force_handlers: yes\u003Cbr\u003E16 \u003Cbr\u003E17 tasks:\u003Cbr\u003E18 - name: "Install httpd"\u003Cbr\u003E19 yum:\u003Cbr\u003E20 name: "{{ packages }}"\u003Cbr\u003E21 state: present\u003Cbr\u003E22 vars:\u003Cbr\u003E23 packages:\u003Cbr\u003E24 - httpd\u003Cbr\u003E25 - httpd-tools\u003Cbr\u003E26 \u003Cbr\u003E27 - name: "Httpd config"\u003Cbr\u003E28 template:\u003Cbr\u003E29 src: .\u002Ffile\u002Fhttpd.conf.j2\u003Cbr\u003E30 dest: \u002Fetc\u002Fhttpd\u002Fconf\u002Fhttpd.conf\u003Cbr\u003E31 notify: "Restart httpd server"\u003Cbr\u003E32 \u003Cbr\u003E33 - name: "Start httpd server"\u003Cbr\u003E34 systemd:\u003Cbr\u003E35 name: httpd\u003Cbr\u003E36 state: started\u003Cbr\u003E37 enabled: yes\u003Cbr\u003E38 \u003Cbr\u003E39 # \u002Fbin\u002Ffalse 返回状态码为1,不为0\u003Cbr\u003E40 - name: "Shell task"\u003Cbr\u003E41 shell: \u002Fbin\u002Ffalse\u003Cbr\u003E42 \u003Cbr\u003E43 - name: "Create dir"\u003Cbr\u003E44 file:\u003Cbr\u003E45 path: \u002Ftmp\u002Fwith_items_testdir\u003Cbr\u003E46 state: directory\u003Cbr\u003E47 \u003Cbr\u003E48 handlers:\u003Cbr\u003E49 - name: "Restart httpd server"\u003Cbr\u003E50 systemd:\u003Cbr\u003E51 name: httpd\u003Cbr\u003E52 state: restarted\u003Cbr\u003E53 \u003Cbr\u003E54 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_error_deal.yml # 语法检测\u003Cbr\u003E55 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_error_deal.yml # 预执行,测试执行\u003Cbr\u003E56 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_error_deal.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E \u003C\u002Fp\u003E\u003Ch1 class=\"pgc-h-arrow-right\"\u003E抑制changed状态-changed_when\u003C\u002Fh1\u003E\u003Cp\u003Eansible 会自动判断模块执行状态,command、shell 及其它模块如果修改了远程主机状态则被判定为 changed 状态,不过也可以自己决定达到 changed 状态的条件。\u003C\u002Fp\u003E\u003Cp\u003E当我们在 playbook 中使用 shell 或者 command 模块时,每次 task 执行状态都是 changed。原因是因为每次我们都去执行获取当前数据,而不是一个固化的状态。\u003C\u002Fp\u003E\u003Cp\u003E但在实际应用中,我们可能不需要 shell 或者 command 模块执行后的 changed 状态,这时我们就需要通过 changed_when: false 来抑制这个改变。\u003C\u002Fp\u003E\u003Cp\u003E当然上述的 changed_when: false 可以在任何模块中使用,不局限于 shell 和 command 模块,只是我们常用于这两个模块而已。\u003C\u002Fp\u003E\u003Cpre\u003E\u003Ccode\u003E 1 [yun@ansi-manager object05]$ pwd\u003Cbr\u003E 2 \u002Fapp\u002Fansible_info\u002Fobject05\u003Cbr\u003E 3 [yun@ansi-manager object05]$ ll\u003Cbr\u003E 4 total 44\u003Cbr\u003E 5 -rw-rw-r-- 1 yun yun 299 Aug 29 14:47 test_changed_when.yml\u003Cbr\u003E 6 [yun@ansi-manager object05]$ cat test_changed_when.yml \u003Cbr\u003E 7 ---\u003Cbr\u003E 8 # 使用 changed_when: false 抑制 changed 状态\u003Cbr\u003E 9 - hosts: proxyservers\u003Cbr\u003E10 \u003Cbr\u003E11 tasks:\u003Cbr\u003E12 - name: "Shell task"\u003Cbr\u003E13 shell: netstat -lntp | grep 'httpd'\u003Cbr\u003E14 register: check_httpd\u003Cbr\u003E15 # changed_when: false # 任何时候,都不为 changed 状态\u003Cbr\u003E16 #### check_httpd['stdout'] 不包含 httpd 为 true,否则 false\u003Cbr\u003E17 changed_when: "'httpd' not in check_httpd['stdout']" # 结果为 false \u003Cbr\u003E18 \u003Cbr\u003E19 - name: "Debug output"\u003Cbr\u003E20 debug:\u003Cbr\u003E21 msg: "{{ check_httpd.stdout }}"\u003Cbr\u003E22 \u003Cbr\u003E23 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key --syntax-check test_changed_when.yml # 语法检测\u003Cbr\u003E24 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key -C test_changed_when.yml # 预执行,测试执行\u003Cbr\u003E25 [yun@ansi-manager object05]$ ansible-playbook -b -i ..\u002Fhosts_key test_changed_when.yml # 执行\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp3.pstatp.com\u002Flarge\u002Fpgc-image\u002Fa02a20ffea2c41968d01d0dfa938e457\" img_width=\"494\" img_height=\"640\" alt=\"Ansible playbook 编程\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E"'.slice(6, -6), groupId: '6826326959442625038
Copyright © 2018-2020 www.tdftex.cn Inc. All Rights Reserved. 土豆新闻网 版权所有