playbook应用和roles自动化批量安装示例,playbook方式及语法

By admin in 美高梅手机版4858 on 2019年4月8日

一、什么是playbook及其构成

Ansible连串(5):playbook应用和roles自动化批量装置示例,ansibleplaybook

正文目录:
一.一 yaml语法和演示
一.2 ansible-playbook命令表明及playbook书写不难示例
1.3 playbook基础
  1.3.1 hosts和remote_user
  1.3.2 task list
  1.3.3 notify和handler
  1.3.4 标签tags
1.4 include和roles
  1.4.1 include
  1.4.2 roles
1.五 roles示例:批量自动化安装

playbook是ansible达成批量自动化最要害的手段。在里边能够采纳变量、引用、循环等功效,比较ad-hoc而言,其功用要强大的多。

正文目录:
1.一yaml语法和演示
一.二ansible-playbook命令表达及playbook书写简单示例
1.3
playbook基础
  1.3.1
hosts和remote_user
  1.3.2
task
list
playbook应用和roles自动化批量安装示例,playbook方式及语法。  1.3.3
notify和handler
  1.3.4
标签tags
1.4
include和roles
  1.4.1
include
  1.4.2
roles
一.5roles示例:批量自动化安装

Ansible连串小说:http://www.cnblogs.com/f-ck-need-u/p/7576137.html**

什么是playbook

playbook 翻译过来就是"剧本"

壹.壹 yaml简单示例

ansible的playbook选取yaml语法。以下是一个yaml格式的文本:

---
# Members in Bob's family
    name: Bob
    age: 30
    gender: Male
    wife: 
        name: Alice
        age: 27
        gender: Female
    children: 
      - name: Jim
        age: 6
        gender: Male
      - name: Lucy
        age: 3
        gender: Female

playbook是ansible达成批量自动化最要紧的手段。在内部能够利用变量、引用、循环等成效,相比较ad-hoc而言,其成效要强有力的多。


playbook的组成

play:定义的是主机的角色
task:定义的是具体执行的任务
playbook:由一个或多个play组成,一个play可以包含多个task

美高梅手机版4858 1

 

一.二 ansible-playbook命令表达及playbook书写不难示例

以下是二个简单的playbook示例。该示例执行三个职务,第贰个职务是举行三个/bin/date命令,第四个职务是复制/etc/fstab文件到指标主机上的/tmp下,它们分别接纳了ansible的command模块和copy模块。

cat /tmp/test.yaml 
---
    - hosts: centos7
      tasks: 
        - name: execute date cmd
          command: /bin/date
        - name: copy fstab to /tmp
          copy: src=/etc/fstab dest=/tmp

挥洒好playbook后,使用ansible-playbook命令来进行。ansible-playbook命令的抉择和ansible命令选项绝大部分都同壹。但也有其有意的选项。以下是截取出来的支援消息。

ansible-playbook --help
Usage: ansible-playbook playbook.yml

Options:
  -e EXTRA_VARS,--extra-vars=EXTRA_VARS # 设置额外的变量,格式为key/value。-e "key=KEY",
                                        # 如果是文件方式传入变量,则-e "@param_file"
  --flush-cache          # 清空收集到的fact信息缓存
  --force-handlers       # 即使task执行失败,也强制执行handlers
  --list-tags            # 列出所有可获取到的tags
  --list-tasks           # 列出所有将要被执行的tasks
  -t TAGS,--tags=TAGS    # 以tag的方式显式匹配要执行哪些tag中的任务
  --skip-tags=SKIP_TAGS  # 以tag的方式忽略某些要执行的任务。被此处匹配的tag中的任务都不会执行
  --start-at-task=START_AT_TASK # 从此task开始执行playbook
  --step                 # one-step-at-a-time:在每一个任务执行前都进行交互式确认
  --syntax-check         # 检查playbook语法

未来实施上面的test.yaml。

ansible-playbook /tmp/test.yaml 

PLAY [centos7] **********************************************************************

TASK [Gathering Facts] **************************************************************
ok: [192.168.100.64]
ok: [192.168.100.65]
ok: [192.168.100.63]

TASK [execute date cmd] *************************************************************
changed: [192.168.100.63]
changed: [192.168.100.64]
changed: [192.168.100.65]

TASK [copy fstab to /tmp] ***********************************************************
changed: [192.168.100.64]
changed: [192.168.100.63]
changed: [192.168.100.65]

PLAY RECAP **************************************************************************
192.168.100.63             : ok=3    changed=2    unreachable=0    failed=0
192.168.100.64             : ok=3    changed=2    unreachable=0    failed=0
192.168.100.65             : ok=3    changed=2    unreachable=0    failed=0

从上述结果中,能够看看:(一)暗中同意情况下,ansible-playbook和ansible是一致的,都以二头阻塞情势,须要先在拥有主机上实施完叁个职务,才会继续下三个职分;(二)在执行前会自动收集fact音讯;(三)从显示结果中可以断定出任务是不是真的进行了,抑只怕是因为幂等性而从未进行。(四)每2个play都包涵数个task,且都有响应音信play
recap。

一.一 yaml不难示例

ansible的playbook选择yaml语法。以下是1个yaml格式的文本:

---
# Members in Bob's family
    name: Bob
    age: 30
    gender: Male
    wife: 
        name: Alice
        age: 27
        gender: Female
    children: 
      - name: Jim
        age: 6
        gender: Male
      - name: Lucy
        age: 3
        gender: Female

playbook是ansible完成批量自动化最要害的手法。在当中能够选取变量、引用、循环等作用,相比较ad-hoc而言,其成效要强有力的多。

二、playbook的优势

1、功能比adhoc更全
2、控制好依赖
3、展现更直观
4、持久使用

1.3 playbook的内容

壹.二 ansible-playbook命令表达及playbook书写简单示例

以下是三个大约的playbook示例。该示例执行四个职务,第3个任务是执行3个/bin/date命令,第1个职责是复制/etc/fstab文件到对象主机上的/tmp下,它们各自选用了ansible的command模块和copy模块。

cat /tmp/test.yaml 
---
    - hosts: centos7
      tasks: 
        - name: execute date cmd
          command: /bin/date
        - name: copy fstab to /tmp
          copy: src=/etc/fstab dest=/tmp

挥洒好playbook后,使用ansible-playbook命令来推行。ansible-playbook命令的取舍和ansible命令选项多方都同一。但也有其有意的选项。以下是截取出来的救助消息。

ansible-playbook --help
Usage: ansible-playbook playbook.yml

Options:
  -e EXTRA_VARS,--extra-vars=EXTRA_VARS # 设置额外的变量,格式为key/value。-e "key=KEY",
                                        # 如果是文件方式传入变量,则-e "@param_file"
  --flush-cache          # 清空收集到的fact信息缓存
  --force-handlers       # 即使task执行失败,也强制执行handlers
  --list-tags            # 列出所有可获取到的tags
  --list-tasks           # 列出所有将要被执行的tasks
  -t TAGS,--tags=TAGS    # 以tag的方式显式匹配要执行哪些tag中的任务
  --skip-tags=SKIP_TAGS  # 以tag的方式忽略某些要执行的任务。被此处匹配的tag中的任务都不会执行
  --start-at-task=START_AT_TASK # 从此task开始执行playbook
  --step                 # one-step-at-a-time:在每一个任务执行前都进行交互式确认
  --syntax-check         # 检查playbook语法

昨日推行上边的test.yaml。

ansible-playbook /tmp/test.yaml 

PLAY [centos7] **********************************************************************

TASK [Gathering Facts] **************************************************************
ok: [192.168.100.64]
ok: [192.168.100.65]
ok: [192.168.100.63]

TASK [execute date cmd] *************************************************************
changed: [192.168.100.63]
changed: [192.168.100.64]
changed: [192.168.100.65]

TASK [copy fstab to /tmp] ***********************************************************
changed: [192.168.100.64]
changed: [192.168.100.63]
changed: [192.168.100.65]

PLAY RECAP **************************************************************************
192.168.100.63             : ok=3    changed=2    unreachable=0    failed=0
192.168.100.64             : ok=3    changed=2    unreachable=0    failed=0
192.168.100.65             : ok=3    changed=2    unreachable=0    failed=0

从以上结果中,能够见到:(一)暗许情状下,ansible-playbook和ansible是1律的,都以一路阻塞方式,须要先在具备主机上执行完3个职分,才会持续下二个职务;(二)在履行前会自动采集fact消息;(三)从出示结果中得以看清出职分是还是不是真正举行了,抑可能是因为幂等性而从不实施。(肆)每1个play都包涵数个task,且都有响应新闻play
recap。

一.一 yaml不难示例

ansible的playbook选择yaml语法。以下是3个yaml格式的文件:

---
# Members in Bob's family
    name: Bob
    age: 30
    gender: Male
    wife: 
        name: Alice
        age: 27
        gender: Female
    children: 
      - name: Jim
        age: 6
        gender: Male
      - name: Lucy
        age: 3
        gender: Female

叁、playbook的安插语法

1.3.1 hosts和remoter_user

对于playbook中的每八个play,使用hosts选项能够定义要实施那一个使命的主机或主机组,还足以应用remote_user钦定在长距离主机上进行职分的用户,实际上remote_user是ssh连接到被控主机上的用户,任其自流执行命令的地方也将是此用户。

例如:

---
    - hosts: centos6,centos7,192.168.100.59
      remote_user: root
      tasks: XXXXXX

还足以在有些task上独立定义执行该task的身价,那将掩盖全局的概念。

---
    - hosts: centos6,centos7,192.168.100.59
      remote_user: root
      tasks: 
        - name: run a command
          shell: /bin/date
        - name: copy a file to /tmp
          copy: src=/etc/fstab dest=/tmp
          remote_user: myuser

也支撑权限升级的秘诀。

---
    - hosts: centos6,centos7,192.168.100.59
      remote_user: yourname
      tasks: 
        - name: run a command
          shell: /bin/date
        - name: copy a file to /tmp
          copy: src=/etc/fstab dest=/tmp
          become: yes
          become_method: sudo
          become_user: root    # 此项默认值就是为root,所以可省

从地点的示范能够看来remote_user实际上并不是执行职责的相对身份,它只是ssh连接过去的地点,只然而未有点名become的时候,它正好就用此身份来运转职务。

1.3 playbook的内容

一.2 ansible-playbook命令表达及playbook书写简单示例

以下是三个简易的playbook示例。该示例执行三个职务,第四个职分是实践3个/bin/date命令,第一个任务是复制/etc/fstab文件到对象主机上的/tmp下,它们各自采取了ansible的command模块和copy模块。

cat /tmp/test.yaml 
---
    - hosts: centos7
      tasks: 
        - name: execute date cmd
          command: /bin/date
        - name: copy fstab to /tmp
          copy: src=/etc/fstab dest=/tmp

书写好playbook后,使用ansible-playbook命令来执行。ansible-playbook命令的精选和ansible命令选项多头都一模一样。但也有其故意的选项。以下是截取出来的扶助音讯。

ansible-playbook --help
Usage: ansible-playbook playbook.yml

Options:
  -e EXTRA_VARS,--extra-vars=EXTRA_VARS # 设置额外的变量,格式为key/value。-e "key=KEY",
                                        # 如果是文件方式传入变量,则-e "@param_file"
  --flush-cache          # 清空收集到的fact信息缓存
  --force-handlers       # 即使task执行失败,也强制执行handlers
  --list-tags            # 列出所有可获取到的tags
  --list-tasks           # 列出所有将要被执行的tasks
  -t TAGS,--tags=TAGS    # 以tag的方式显式匹配要执行哪些tag中的任务
  --skip-tags=SKIP_TAGS  # 以tag的方式忽略某些要执行的任务。被此处匹配的tag中的任务都不会执行
  --start-at-task=START_AT_TASK # 从此task开始执行playbook
  --step                 # one-step-at-a-time:在每一个任务执行前都进行交互式确认
  --syntax-check         # 检查playbook语法

方今执行上边的test.yaml。

ansible-playbook /tmp/test.yaml 

PLAY [centos7] **********************************************************************

TASK [Gathering Facts] **************************************************************
ok: [192.168.100.64]
ok: [192.168.100.65]
ok: [192.168.100.63]

TASK [execute date cmd] *************************************************************
changed: [192.168.100.63]
changed: [192.168.100.64]
changed: [192.168.100.65]

TASK [copy fstab to /tmp] ***********************************************************
changed: [192.168.100.64]
changed: [192.168.100.63]
changed: [192.168.100.65]

PLAY RECAP **************************************************************************
192.168.100.63             : ok=3    changed=2    unreachable=0    failed=0
192.168.100.64             : ok=3    changed=2    unreachable=0    failed=0
192.168.100.65             : ok=3    changed=2    unreachable=0    failed=0

从以上结果中,能够看到:(1)默许景况下,ansible-playbook和ansible是同等的,都是联合阻塞形式,需求先在全数主机上进行完二个职分,才会连续下二个职务;(2)在实施前会自动采集fact消息;(3)从出示结果中得以判断出职责是还是不是确实进行了,抑只怕是因为幂等性而从未履行。(4)每一个play都饱含数个task,且都有响应新闻play
recap。

主旨选取

1.3.2 task list

1.特性
种种play都带有1个hosts和1个tasks,hosts定义的是inventory中待控制的主机,tasks下定义的是1密密麻麻task任务列表,比如调用各样模块。那几个task按顺序2回施行一个,直到全部被筛选出来的主机都进行了那个task之后才会活动到下二个task上实行相同的操作。

急需小心的是,尽管唯有被筛选出来的主机会进行相应的task,但是富有主机(此处的富有主机表示的是,hosts选项所钦命的那一个主机)都会吸收接纳一模一样的task指令,全数主机械收割到指令后,ansible主要控制端会筛选有个别主机,并经过ssh在中远距离执行职分。也正是说,如若翻开ansible-playbook -vvvv的新闻,将会发现暂时任务文件会经过sftp发送到全部的被控主机上,然则只有一对被筛选(假如进展了筛选)的主机才会ssh过去并远程执行命令。

当某一台被控主机执行有些职责出错或破产时,它将会被移除出任务轮询列表。也正是说,对于某主机来说,某职务执行破产,后续的具备职分都不会再去实践。当然,那不会潜移默化别的的主机执行任务(除非主机的任务之间有依靠关系)。

最器重的是,ansible中的task是幂等性的,数次履行不会潜移默化那么些成功施行过的职务。此外幂等性还表现在实施破产后只要改进了playbook再一次实施,将不会影响那多少个原来已经进行成功的天职,固然是见仁见智主机也不会影响。仅那上头而言,ansible对于排错来说是最最和谐的。当然,有些特殊的模块可能尤其定义的task并不一定总是幂等的,例如最简便易行的,执行1个command恐怕shell模块的吩咐,它会再度执行。但也有艺术使其变得幂等,以command和shell模块为例,它们有多个采取:creates和removes,它们分别代表被控主机上钦定的公文存在(不存在)时就不执行命令。

2.定义task的细节

  • (一).能够为各类task加上name项,也得以七个task信赖于贰个name。

譬如说下边包车型客车八个例子。从五个示范中得以看出,五个task其实都以属于四个name的,第四个task无需再选用name命名。

示例一:

tasks: 
    - name: do something to initialize mariadb
      file: path=/mydata/data state=directory owner=mysql group=mysql mode=0755
    - shell: /usr/bin/mysql_install_db --datadir=/mydata/data --user=mysql creates=/mydata/data/ibdata1

示例二:

tasks: 
    - name: echo var passed by nginx 
      shell: echo "{{ hi_var }}"
      register: var_result
    - debug: msg="{{ var_result.stdout }}"

实在,name只是壹种描述性语句,它可以定义在别的地方。例如,定义在play的下面。

---
- name: start a play
  hosts: localhost
  tasks:
  • (二).既然是task,那么势必会有其要履行的多少个或多个任务,其本质是加载并执行ansible对应的模块。在playbook中,每调用的1个模块都称之为一个action。

诸如,定义3个确认保证服务是开行状态的task,有以下两种格局传递模块参数:

tasks: 
  - name: be sure the sshd is running
    service: name=sshd state=started     # 方法一: 定义为key=value,直接传递参数给模块

    service:                             # 方法二: 定义为key: value方式
      name: sshd
      state: started

    service:                  # 方法三: 使用args内置关键字,然后定义为key: value方式
    args: 
      name: sshd
      state: started

但要注意,ping模块、command和shell模块是不必要key=value格式的。对于ping命令,能够间接省略key=value。对于command和shell,只必要给定命令路径和要接上去的选项或参数即可,且无法利用方面包车型地铁方法二。例如上边定义的是二个ntpdate命令,只需给定它的参数即可。

tasks: 
    - name: execute command ntpdate
      shell: /usr/sbin/ntpdate ntp1.aliyun.com
    - name: ping host
      ping:

对此command或shell模块来说,有时候要思量命令的回到状态码。如若要不经意非0状态码继续执行任务,能够利用以下两种艺术:

tasks: 
    - name: ignore non_zero return code
      shell: /usr/sbin/ntpdate ntp1.aliyun.com || /bin/true

或者

tasks: 
    - name: another way to ignore the non_zero return code
      shell: /usr/sbin/ntpdate ntp1.aliyun.com
      ignore_errors: true
  • (三).如若action的key=value太多,导致内容太长,能够在上1行的缩进级别基础上继续缩进表示续行。

譬如,上面包车型客车owner比src多缩进了四个空格。

tasks:
  - name: Copy ansible inventory file to client
    copy: src=/etc/fstab dest=/tmp
              owner=root group=root mode=0644
  • (四).在action的value部分,能够引用已经定义的变量,能够是已定义好的自定义的变量,也能够是放置变量。变量相关内容见后文。

  • (5).使用include指令,能够将其余的playbook文件包蕴到此playbook文件中。include的法子见下文。

1.3.1 hosts和remoter_user

对此playbook中的种种play,使用hosts选项能够定义要执行那一个义务的主机或主机组,还是能使用remote_user钦点在中远距离主机上进行职务的用户,实际上remote_user是ssh连接到被控主机上的用户,顺其自然执行命令的地位也将是此用户。

例如:

---
    - hosts: centos6,centos7,192.168.100.59
      remote_user: root
      tasks: XXXXXX

就算在hosts处能够行使”,”分隔主机或主机组,但法定手册上并未介绍该格局。除此而外,有以下二种钦点主机和主机组的法子:

  • all*:表示inventory中的全数主机。
  • ::取并集。例如”host1:host二:group一”表示2台主机加二个主机组。
  • :&:取交集。例如”group一:&group贰”表示五个主机组中都有个别主机。
  • :!:排除。例如”group1:!host一”表示group第11中学排除host一主机的剩余主机。
  • 通配符:例如”web*.baidu.com”。
  • 数字范围:例如”web[0-5].baidu.com”。
  • 字母范围:例如”web[a-d].baidu.com”。
  • 正则表达式:以”~”开头。例如”~web\d\.baidu\.com”。

除此以外,在ansible命令行或ansible-playbook命令行中,能够选择”-l”选项来限制执行任务的主机。例如:

ansile centos -l host[1:5] -m ping

意味着centos主机组中唯有host一到host5才实施ping模块。

还能在有些task上单独定义执行该task的地方,那将掩盖全局的定义。

---
    - hosts: centos6,centos7,192.168.100.59
      remote_user: root
      tasks: 
        - name: run a command
          shell: /bin/date
        - name: copy a file to /tmp
          copy: src=/etc/fstab dest=/tmp
          remote_user: myuser

也支撑权限升级的法子。

---
    - hosts: centos6,centos7,192.168.100.59
      remote_user: yourname
      tasks: 
        - name: run a command
          shell: /bin/date
        - name: copy a file to /tmp
          copy: src=/etc/fstab dest=/tmp
          become: yes
          become_method: sudo
          become_user: root    # 此项默认值就是为root,所以可省

从地点的演示能够看到remote_user实际上并不是实践职务的断然身份,它只是ssh连接过去的地点,只可是未有点名become的时候,它正好就用此身份来运维职责。

1.3 playbook的内容

playbook基础运用

ansible-playbook playbook.yml [options]

-u REMOTE_USER, --user=REMOTE_USER 
# ssh 连接的用户名 
-k, --ask-pass 
#ssh登录认证密码 
-s, --sudo 
#sudo 到root用户,相当于Linux系统下的sudo命令
-U SUDO_USER, --sudo-user=SUDO_USER 
#sudo 到对应的用户 
-K, --ask-sudo-pass #用户的密码(—sudo时使用) 
-T TIMEOUT, --timeout=TIMEOUT 
# ssh 连接超时,默认 10 秒 
-C, --check # 指定该参数后,执行 playbook 文件不会真正去执行,而是模拟执行一遍,然后输出本次执行会对远程主机造成的修改 
-e EXTRA_VARS, --extra-vars=EXTRA_VARS 
# 设置额外的变量如:key=value 形式 或者 YAML or JSON,以空格分隔变量,或用多个-e 
-f FORKS, --forks=FORKS # 进程并发处理,默认 5 
-i INVENTORY, --inventory-file=INVENTORY 
# 指定 hosts 文件路径,默认 default=/etc/ansible/hosts 
-l SUBSET, --limit=SUBSET 
# 指定一个 pattern,对- hosts:匹配到的主机再过滤一次 
--list-hosts # 只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook 
--list-tasks # 列出该 playbook 中会被执行的 task 
--private-key=PRIVATE_KEY_FILE # 私钥路径 
--step # 同一时间只执行一个 task,每个 task 执行前都会提示确认一遍 
--syntax-check # 只检测 playbook 文件语法是否有问题,不会执行该 playbook 
-t TAGS, --tags=TAGS #当 play 和 task 的 tag 为该参数指定的值时才执行,多个 tag 以逗号分隔 
--skip-tags=SKIP_TAGS # 当 play 和 task 的 tag 不匹配该参数指定的值时,才执行 
-v, --verbose #输出更详细的执行过程信息,-vvv可得到所有执行过程信息。

原文链接:https://www.imooc.com/article/22729

1.3.3 notify和handler

ansible中差不多拥有的模块都负有幂等性,这意味被控主机的气象是或不是产生改变是能被捕捉的,即每种职务的changed=true或changed=false。ansible在捕捉到changed=true时,能够触发notify组件(假若定义了该器件)。

notify是三个组件,并非3个模块,它能够间接定义action,其主要指标是调用handler。例如:

tasks: 
    - name: copy template file to remote host
      template: src=/etc/ansible/nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: 
        - restart nginx
        - test web page
      copy: src=nginx/index.html.j2 dest=/usr/share/nginx/html/index.html
      notify: 
        - restart nginx

那意味当执行template模块的职务时,假若捕捉到changed=true,那么就会触发notify,如若分发的index.html改变了,那么也重启nginx(当然那是没需求的)。notify下定义了四个待调用的handler。handler首要用来重启服务只怕触发系统重启,除外很少使用handler。以下是那八个handler的情节:

handlers: 
    - name: restart nginx
      service: name=nginx state=restarted
    - name: test web page
      shell: curl -I http://192.168.100.10/index.html | grep 200 || /bin/false

handler的定义和tasks的定义完全等同,唯壹须要限制的是handler中task的name必须和notify中定义的称呼壹致。

只顾,notify是在实践完三个play中具备task后被触发的,在贰个play中也只会被触发一遍。意味着假若2个play中有四个task出现了changed=true,它也只会触发三回。例如地点的示范中,向nginx复制配置文件和复制index.html时要是都发生了改变,都会触发重启apache操作。然则只会在推行完play后重启二遍,以免止多余的重启。

1.3.2 task list

1.特性
各种play都带有2个hosts和三个tasks,hosts定义的是inventory中待控制的主机,tasks下定义的是一密密麻麻task任务列表,比如调用各样模块。这几个task按梯次1回施行2个,直到全体被筛选出来的主机都执行了那几个task之后才会移动到下三个task上举办同样的操作。

急需小心的是,尽管唯有被筛选出来的主机会实施相应的task,不过富有主机(此处的有着主机表示的是,hosts选项所钦点的那么些主机)都会吸收接纳壹模一样的task指令,全数主机械收割到指令后,ansible主要控制端会筛选某个主机,并经过ssh在中距离执行职责。也正是说,要是翻开ansible-playbook -vvvv的音信,将会发现近年来职务文件会通过sftp发送到全部的被控主机上,但是只有一部分被筛选(假使进展了筛选)的主机才会ssh过去并远程执行命令。

当某一台被控主机执行有些职责出错或失利时,它将会被移除出职务轮询列表。也正是说,对于某主机来说,某任务履行破产,后续的有着职分都不会再去实施。当然,那不会影响其余的主机执行任务(除非主机的义务之间有依靠关系)。

最关键的是,ansible中的task是幂等性的,数次实践不会潜移默化这么些成功实行过的职分。别的幂等性还呈以往推行破产后如果纠正了playbook再一次实施,将不会影响那个原本已经执行成功的职分,就算是见仁见智主机也不会影响。仅那上边而言,ansible对于排错来说是非常和谐的。当然,有个别特殊的模块或许新鲜定义的task并不一定总是幂等的,例如最简易的,执行二个command或许shell模块的通令,它会再也执行。但也有主意使其变得幂等,以command和shell模块为例,它们有多少个挑选:creates和removes,它们各自代表被控主机上钦命的文书存在(不存在)时就不执行命令。

2.定义task的细节

  • (一).能够为各样task加上name项,也能够多少个task注重于1个name。

比如下边包车型客车四个例子。从三个示范中得以观察,四个task其实都以属于3个name的,第1个task无需再利用name命名。

示例一:

tasks: 
    - name: do something to initialize mariadb
      file: path=/mydata/data state=directory owner=mysql group=mysql mode=0755
    - shell: /usr/bin/mysql_install_db --datadir=/mydata/data --user=mysql creates=/mydata/data/ibdata1

示例二:

tasks: 
    - name: echo var passed by nginx 
      shell: echo "{{ hi_var }}"
      register: var_result
    - debug: msg="{{ var_result.stdout }}"

其实,name只是1种描述性语句,它可以定义在其他地点。例如,定义在play的顶端。

---
- name: start a play
  hosts: localhost
  tasks:
  • (2).既然是task,那么肯定会有其要实施的三个或五个任务,其本质是加载并执行ansible对应的模块。在playbook中,每调用的贰个模块都称为1个action。

比如说,定义二个承保服务是运维状态的task,有以下二种办法传递模块参数:

tasks: 
  - name: be sure the sshd is running
    service: name=sshd state=started     # 方法一: 定义为key=value,直接传递参数给模块

    service:                             # 方法二: 定义为key: value方式
      name: sshd
      state: started

    service:                  # 方法三: 使用args内置关键字,然后定义为key: value方式
    args: 
      name: sshd
      state: started

但要注意,ping模块、command和shell模块是不供给key=value格式的。对于ping命令,能够直接省略key=value。对于command和shell,只要求给定命令路径和要接上去的选项或参数即可,且不能选择方面的方法二。例如上面定义的是一个ntpdate命令,只需给定它的参数即可。

tasks: 
    - name: execute command ntpdate
      shell: /usr/sbin/ntpdate ntp1.aliyun.com
    - name: ping host
      ping:

对此command或shell模块来说,有时候要考虑命令的回到状态码。若是要不经意非0状态码继续执行职务,能够使用以下二种方法:

tasks: 
    - name: ignore non_zero return code
      shell: /usr/sbin/ntpdate ntp1.aliyun.com || /bin/true

或者

tasks: 
    - name: another way to ignore the non_zero return code
      shell: /usr/sbin/ntpdate ntp1.aliyun.com
      ignore_errors: true
  • (三).假如action的key=value太多,导致内容太长,能够在上1行的缩进级别基础上持续缩进表示续行。

比如说,上面包车型大巴owner比src多缩进了四个空格。

tasks:
  - name: Copy ansible inventory file to client
    copy: src=/etc/fstab dest=/tmp
              owner=root group=root mode=0644
  • (四).在action的value部分,能够引用已经定义的变量,能够是已定义好的自定义的变量,也得以是放到变量。变量相关内容见后文。

  • (五).使用include指令,可以将别的的playbook文件包罗到此playbook文件中。include的点子见下文。

1.3.1 hosts和remoter_user

对于playbook中的每1个play,使用hosts选项能够定义要实施那个职分的主机或主机组,还足以行使remote_user钦赐在长距离主机上进行职分的用户,实际上remote_user是ssh连接到被控主机上的用户,任天由命执行命令的地点也将是此用户。

例如:

---
    - hosts: centos6,centos7,192.168.100.59
      remote_user: root
      tasks: XXXXXX

虽说在hosts处能够利用”,”分隔主机或主机组,但官方手册上并不曾介绍该方法。除此而外,有以下两种钦点主机和主机组的点子:

  • all*:表示inventory中的全体主机。
  • ::取并集。例如”host一:host2:group一”表示二台主机加贰个主机组。
  • :&:取交集。例如”group一:&group2″表示七个主机组中都有的主机。
  • :!:排除。例如”group1:!host1″表示group第11中学解决host一主机的剩余主机。
  • 通配符:例如”web*.baidu.com”。
  • 数字范围:例如”web[0-5].baidu.com”。
  • 字母范围:例如”web[a-d].baidu.com”。
  • 正则表达式:以”~”开头。例如”~web\d\.baidu\.com”。

其它,在ansible命令行或ansible-playbook命令行中,能够使用”-l”选项来界定执行职分的主机。例如:

ansile centos -l host[1:5] -m ping

表示centos主机组中唯有host壹到host5才实施ping模块。

还足以在有些task上独立定义执行该task的身价,那将覆盖全局的概念。

---
    - hosts: centos6,centos7,192.168.100.59
      remote_user: root
      tasks: 
        - name: run a command
          shell: /bin/date
        - name: copy a file to /tmp
          copy: src=/etc/fstab dest=/tmp
          remote_user: myuser

也帮衬权限升级的点子。

---
    - hosts: centos6,centos7,192.168.100.59
      remote_user: yourname
      tasks: 
        - name: run a command
          shell: /bin/date
        - name: copy a file to /tmp
          copy: src=/etc/fstab dest=/tmp
          become: yes
          become_method: sudo
          become_user: root    # 此项默认值就是为root,所以可省

从地点的以身作则能够旁观remote_user实际上并不是推行职责的相对身份,它只是ssh连接过去的身价,只然则未有点名become的时候,它正好就用此身份来运营职责。

选拔情形

1.3.4 标签tag

能够为playbook中的每一个职分都打上标签,标签的基本点效率是能够在ansible-playbook中装置只进行什么样被打上tag的天职或忽略被打上tag的义务。

tasks: 
   - name: make sure apache is running
     service: name=httpd state=started
     tags: apache
   - name: make sure mysql is running
     service: name=mysqld state=started
     tags: mysql

以下是ansible-playbook命令关于tag的选项。

  --list-tags           # list all available tags
  -t TAGS, --tags=TAGS  # only run plays and tasks tagged with these values
  --skip-tags=SKIP_TAGS # only run plays and tasks whose tags do not match these values

1.3.3 notify和handler

ansible中差不离全数的模块都怀有幂等性,那意味着被控主机的状态是否发生变更是能被捕捉的,即各类职责的changed=true或changed=false。ansible在捕捉到changed=true时,能够触发notify组件(假如定义了该零件)。

notify是二个零部件,并非三个模块,它能够平昔定义action,其重大指标是调用handler。例如:

tasks: 
    - name: copy template file to remote host
      template: src=/etc/ansible/nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: 
        - restart nginx
        - test web page
      copy: src=nginx/index.html.j2 dest=/usr/share/nginx/html/index.html
      notify: 
        - restart nginx

这意味当执行template模块的职务时,借使捕捉到changed=true,那么就会触发notify,假使分发的index.html改变了,那么也重启nginx(当然这是没供给的)。notify下定义了八个待调用的handler。handler首要用于重启服务依然触发系统重启,除了那么些之外很少使用handler。以下是那多个handler的始末:

handlers: 
    - name: restart nginx
      service: name=nginx state=restarted
    - name: test web page
      shell: curl -I http://192.168.100.10/index.html | grep 200 || /bin/false

handler的定义和tasks的定义完全等同,唯1需求限制的是handler中task的name必须和notify中定义的名目壹致。

留意,notify是在履行完一个play中全部task后被触发的,在一个play中也只会被触发一遍。意味着1旦三个play中有四个task出现了changed=true,它也只会接触1回。例如地方的演示中,向nginx复制配置文件和复制index.html时假若都发出了改动,都会触发重启apache操作。可是只会在实施完play后重启三遍,以幸免多余的重启。

1.3.2 task list

1.特性
各种play都包含二个hosts和1个tasks,hosts定义的是inventory中待控制的主机,tasks下定义的是壹雨后玉兰片task任务列表,比如调用各类模块。那些task按顺序1回实施叁个,直到全部被筛选出来的主机都进行了这一个task之后才会活动到下四个task上进展相同的操作。

内需小心的是,固然唯有被筛选出来的主机会举办相应的task,可是拥有主机(此处的保有主机表示的是,hosts选项所内定的那一个主机)都会接到1模壹样的task指令,全数主机收到指令后,ansible主要控制端会筛选某个主机,并经过ssh在长途执行职分。相当于说,倘若查看ansible-playbook -vvvv的新闻,将会发现目前职责文件会透过sftp发送到全部的被控主机上,但是只有局地被筛选(要是进行了筛选)的主机才会ssh过去并远程执行命令。

当某一台被控主机执行某些任务出错或退步时,它将会被移除出任务轮询列表。也便是说,对于某主机来说,某职分履行破产,后续的全数义务都不会再去实践。当然,那不会影响其他的主机执行职责(除非主机的职分之间有依靠关系)。

最重点的是,ansible中的task是幂等性的,多次实践不会影响那么些成功举办过的职务。其余幂等性还突显在推行破产后假若纠正了playbook再次实施,将不会潜移默化那叁个原本已经执行成功的天职,就算是见仁见智主机也不会潜移默化。仅这地点而言,ansible对于排错来说是极致和谐的。当然,某个特殊的模块也许尤其定义的task并不一定总是幂等的,例如最简便易行的,执行三个command也许shell模块的通令,它会再也执行。但也有主意使其变得幂等,以command和shell模块为例,它们有八个挑选:creates和removes,它们分别代表被控主机上内定的公文存在(不存在)时就不执行命令。

2.定义task的细节

  • (一).能够为各种task加上name项,也能够四个task正视于贰个name。

譬如下边包车型地铁多个例证。从多个示范中得以观望,四个task其实都以属于2个name的,第3个task无需再采用name命名。

示例一:

tasks: 
    - name: do something to initialize mariadb
      file: path=/mydata/data state=directory owner=mysql group=mysql mode=0755
    - shell: /usr/bin/mysql_install_db --datadir=/mydata/data --user=mysql creates=/mydata/data/ibdata1

示例二:

tasks: 
    - name: echo var passed by nginx 
      shell: echo "{{ hi_var }}"
      register: var_result
    - debug: msg="{{ var_result.stdout }}"

事实上,name只是壹种描述性语句,它可以定义在另各市方。例如,定义在play的上方。

---
- name: start a play
  hosts: localhost
  tasks:
  • (二).既然是task,那么早晚会有其要实践的多个或五个任务,其本质是加载并执行ansible对应的模块。在playbook中,每调用的二个模块都号称一个action。

例如,定义二个保障服务是运营状态的task,有以下两种方法传递模块参数:

tasks: 
  - name: be sure the sshd is running
    service: name=sshd state=started     # 方法一: 定义为key=value,直接传递参数给模块

    service:                             # 方法二: 定义为key: value方式
      name: sshd
      state: started

    service:                  # 方法三: 使用args内置关键字,然后定义为key: value方式
    args: 
      name: sshd
      state: started

但要注意,ping模块、command和shell模块是不必要key=value格式的。对于ping命令,能够一向省略key=value。对于command和shell,只须求给定命令路径和要接上去的选项或参数即可,且无法运用方面包车型客车方法2。例如上面定义的是贰个ntpdate命令,只需给定它的参数即可。

tasks: 
    - name: execute command ntpdate
      shell: /usr/sbin/ntpdate ntp1.aliyun.com
    - name: ping host
      ping:

对于command或shell模块来说,有时候要考虑命令的回到状态码。假设要不经意非0状态码继续执行职责,能够选拔以下三种格局:

tasks: 
    - name: ignore non_zero return code
      shell: /usr/sbin/ntpdate ntp1.aliyun.com || /bin/true

或者

tasks: 
    - name: another way to ignore the non_zero return code
      shell: /usr/sbin/ntpdate ntp1.aliyun.com
      ignore_errors: true
  • (三).借使action的key=value太多,导致内容太长,能够在上壹行的缩进级别基础上此起彼伏缩进表示续行。

譬如说,下边包车型大巴owner比src多缩进了陆个空格。

tasks:
  - name: Copy ansible inventory file to client
    copy: src=/etc/fstab dest=/tmp
              owner=root group=root mode=0644
  • (四).在action的value部分,能够引用已经定义的变量,可以是已定义好的自定义的变量,也能够是放到变量。变量相关内容见后文。

  • (伍).使用include指令,能够将此外的playbook文件蕴涵到此playbook文件中。include的法子见下文。

1、playbook的配置

示例:

---
- hosts : 192.168.56.11
  remote_user : root
  vars :
          touch_file : devops.file
  tasks :
          - name : touch file
            shell: "touch /tmp/{{touch_file}}"

 

 

1.4 include和roles

假使将有着的play都写在1个playbook中,很不难导致那些playbook文件变得臃肿庞大,且不易读。因而,能够将几个不等职务分别写在分化的playbook中,然后采纳include将其包罗进去即可。而role则是组成playbook的点子。无论是include依旧role,其目标都以分开大playbook以及复用有些细化的play甚至是task。

1.3.4 标签tag

能够为playbook中的各样义务都打上标签,标签的首要意义是能够在ansible-playbook中装置只举办怎么样被打上tag的职责或忽视被打上tag的任务。

tasks: 
   - name: make sure apache is running
     service: name=httpd state=started
     tags: apache
   - name: make sure mysql is running
     service: name=mysqld state=started
     tags: mysql

以下是ansible-playbook命令关于tag的选项。

  --list-tags           # list all available tags
  -t TAGS, --tags=TAGS  # only run plays and tasks tagged with these values
  --skip-tags=SKIP_TAGS # only run plays and tasks whose tags do not match these values

1.3.3 notify和handler

ansible中差不多拥有的模块都有着幂等性,那表示被控主机的气象是还是不是产生转移是能被捕捉的,即每一个任务的changed=true或changed=false。ansible在捕捉到changed=true时,能够触发notify组件(假若定义了该器件)。

notify是二个组件,并非1个模块,它能够一贯定义action,其主要指标是调用handler。例如:

tasks: 
    - name: copy template file to remote host
      template: src=/etc/ansible/nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: 
        - restart nginx
        - test web page
      copy: src=nginx/index.html.j2 dest=/usr/share/nginx/html/index.html
      notify: 
        - restart nginx

这表示当执行template模块的职分时,要是捕捉到changed=true,那么就会触发notify,假诺分发的index.html改变了,那么也重启nginx(当然那是没须求的)。notify下定义了八个待调用的handler。handler主要用来重启服务可能触发系统重启,除了那些之外很少使用handler。以下是这四个handler的内容:

handlers: 
    - name: restart nginx
      service: name=nginx state=restarted
    - name: test web page
      shell: curl -I http://192.168.100.10/index.html | grep 200 || /bin/false

handler的概念和tasks的概念完全平等,唯一要求限制的是handler中task的name必须和notify中定义的名目一致。

在意,notify是在执行完三个play中负有task后被触发的,在2个play中也只会被触发2回。意味着1旦叁个play中有多少个task出现了changed=true,它也只会接触一遍。例如地点的演示中,向nginx复制配置文件和复制index.html时即便都发出了变动,都会触发重启apache操作。可是只会在实施完play后重启叁遍,以制止多余的重启。

2、执行

devops@devops-virtual-machine:/etc/ansible$ cat /etc/ansible/hosts
[test_group1]
#192.168.56.11:22 ansible_ssh_user=root ansible_ssh_pass='1234567'
#192.168.56.11:22 ansible_ssh_user=root ansible_ssh_key_file=/home/devops/.ssh/id_rsa
192.168.56.11:22 ansible_ssh_user=root

#列出f1.yml指的的主机与/etc/ansible/hosts匹配到的主机
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook -i /etc/ansible/hosts --list-hosts ./f1.yml

playbook: ./f1.yml

  play #1 (192.168.56.11): 192.168.56.11    TAGS: []
    pattern: ['192.168.56.11']
    hosts (1):
      192.168.56.11




devops@devops-virtual-machine:/etc/ansible$ ansible-playbook -i /etc/ansible/hosts ./f1.yml

PLAY [192.168.56.11] ***********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.56.11]

TASK [touch file] **************************************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.56.11]

PLAY RECAP *********************************************************************************************************************
192.168.56.11              : ok=2    changed=1    unreachable=0    failed=0

 

3、执行结果回到

  • 庚戌革命:表示有task执行破产也许升迁的消息
  • 香艳:表示执行了且变动了长途主机状态
  • 浅蓝紫:表示执行成功

1.4.1 include

能够将task列表和handlers独立写在其余的公文中,然后在有个别playbook文件中使用include来含有它们。除此而外,还足以写独立的playbook文件,使用include来含有那一个文件。

也正是说,include能够导入二种文件:导入task、导入playbook。

一.一种是职分列表式的文件(未有tasks或handlers指令),它不得不在tasks或handlers指令的子选项处使用include包罗。那种办法能够传递变量到被含有的公文中。

若果有个别task列表文件/yaml/a.yaml内容如下:

---
    - name: execute ntpdate
      shell: /usr/sbin/ntpdate ntp1.aliyun.com

在同目录/yaml下有贰个名称叫test.yaml的playbook(除了role,playbook中具有相对路径都以依照playbook或inventory的),在此playbook中利用include来含有它,即便选择相对路径将会包蕴同目录下的文件。

---
    - hosts: centos7
      tasks:
       - include: a.yaml

能够在include的时候传递变量给相应的公文,那样在被含有的公文中就可以引用该变量的值。

---
  - hosts: centos7
    tasks:
      - include: a.yaml sayhi="hello world"

或者

---
  - hosts: centos7
    tasks:
       - include: a.yaml
         vars: 
           sayhi: "hello world"

下一场能够在被含有的文书a.yaml中应用该变量。例如:

---
    - name: execute ntpdate
      shell: /usr/sbin/ntpdate ntp1.aliyun.com
    - name: say hi to world
      debug: msg="{{ sayhi }}"

推行该test.yaml,将会输出对应的变量值。

ansible-playbook /yaml/test.yaml

PLAY [centos7] **************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [192.168.100.64]
ok: [192.168.100.63]
ok: [192.168.100.65]

TASK [execute ntpdate] *******************************************************************
changed: [192.168.100.64]
changed: [192.168.100.65]
changed: [192.168.100.63]

TASK [sayhi to world] *******************************************************************
ok: [192.168.100.63] => {
    "changed": false, 
    "msg": "hello world"
}
ok: [192.168.100.65] => {
    "changed": false, 
    "msg": "hello world"
}
ok: [192.168.100.64] => {
    "changed": false, 
    "msg": "hello world"
}

PLAY RECAP ******************************************************************************
192.168.100.63             : ok=3    changed=1    unreachable=0    failed=0   
192.168.100.64             : ok=3    changed=1    unreachable=0    failed=0   
192.168.100.65             : ok=3    changed=1    unreachable=0    failed=0

二.另壹种是include整个playbook文件,即include的动作是加载一个或三个play,所以写在第一流列表的层系。

- name: this is a play at the top level of a file
  hosts: all
  remote_user: root

  tasks:

  - name: say hi
    tags: foo
    shell: echo "hi..."

- include: load_balancers.yml  sayhi="hello world"
- include: webservers.yml
- include: dbservers.yml

    any other operations

亟待证实的是,在ansible
2.4本子中,添加了includes和imports二种导入的点子,它们对静态和动态导入援助的更加细化,而ansible
二.叁及此前的include语句已经丢掉,但仍可用。相关法定手册地址。

1.4 include和roles

壹旦将具有的play都写在3个playbook中,很简单造成这一个playbook文件变得臃肿庞大,且不易读。由此,能够将多少个不等职务分别写在差别的playbook中,然后使用include将其蕴藉进去即可。而role则是组成playbook的艺术。无论是include仍旧role,其指标都以分开大playbook以及复用有个别细化的play甚至是task。

1.3.4 标签tag

能够为playbook中的各类任务都打上标签,标签的关键功效是足以在ansible-playbook中设置只进行如何被打上tag的任务或忽视被打上tag的任务。

tasks: 
   - name: make sure apache is running
     service: name=httpd state=started
     tags: apache
   - name: make sure mysql is running
     service: name=mysqld state=started
     tags: mysql

以下是ansible-playbook命令关于tag的选项。

  --list-tags           # list all available tags
  -t TAGS, --tags=TAGS  # only run plays and tasks tagged with these values
  --skip-tags=SKIP_TAGS # only run plays and tasks whose tags do not match these values

长机相称

 

 

 

1.4.2 roles

roles意为剧中人物,主要用于封装playbook完毕复用性。在ansible中,roles通过文件的团伙结构来显示。

对此一个role,它的文件组织结构如下图所示。

              美高梅手机版4858 2

第三需求有3个roles目录。同时,在roles目录所在目录中,还要有三个playbook文件,此处为nginx.yml,nginx.yml文件是ansible-playbook需求履行的文书,在此文件中定义了剧中人物,当执行到剧中人物时,将会到roles中对应的剧中人物目录中搜索相关文件。

roles目录中的子目录是便是各种role。例如,此处唯有多少个名称叫nginx的role,在role目录中,有多少个固定名称的目录(假若未有则忽略)。在那些目录中,还要有一些永恒名称的公文,除了定位名称的文件,别的的文件能够自由命名。以下是各种目录的意思:

  • tasks目录:存放task列表。若role要卓有功用,此目录必须要有贰个主task文件main.yml,在main.yml中得以行使include包蕴同目录(即tasks)中的别的文件。
  • 美高梅手机版4858 ,handlers目录:存放handlers的目录,若要生效,则文件必须名称叫main.yml文件。
  • files目录:在task中推行copy或script模块时,假诺应用的是相对路径,则会到此目录中搜寻对应的文件。
  • templates目录:在task中进行template模块时,假诺应用的是相对路径,则会到此目录中寻觅对应的模块文件。
  • vars目录:定义专属于该role的变量,若是要有var文件,则必须为main.yml文件。
  • defaults目录:定义剧中人物私下认可变量,剧中人物暗中同意变量的优先级最低,会被私自其余层次的同名变量覆盖。如若要有var文件,则必须为main.yml文件。
  • meta目录:用于定义剧中人物注重,假诺要有剧中人物依赖关系,则文件必须为main.yml。

从而,相对完好的role的文件组织结构如下图。

              美高梅手机版4858 3

假借使五个role,则在roles同级目录下定义多少个入站(成效类似于C语言的main函数)文件(如上边的nginx.yml),并在roles目录下创办对应的role目录即可。

              美高梅手机版4858 4

当然,倘使不是应用相对路径,那么role的文书结构就无所谓了,不过roles成效开发出来,正是为着化解文件混乱和playbook臃肿难点的。所以假若能够,尽量使用推荐的role文件结构。

除此以外,假如role中冒出的task、var、handler等和独立定义的指标同名争执了,则先行实施role中的内容。

以下是nginx role的入站文件nginx.yml的始末。

---
  - hosts: centos7
    roles:
      - nginx

越来越多更详实的role用法以及共青团和少先队结构,见下边包车型地铁言传身教。

1.4.1 include

能够将task列表和handlers独立写在任何的公文中,然后在某些playbook文件中使用include来含有它们。除此而外,还足以写独立的playbook文件,使用include来含有这一个文件。

约等于说,include能够导入两种文件:导入task、导入playbook。

一.一种是职务列表式的公文(未有tasks或handlers指令),它只幸好tasks或handlers指令的子选项处使用include包蕴。那种艺术得以传递变量到被含有的文本中。

如若有些task列表文件/yaml/a.yaml内容如下:

---
    - name: execute ntpdate
      shell: /usr/sbin/ntpdate ntp1.aliyun.com

在同目录/yaml下有贰个名称为test.yaml的playbook(除了role,playbook中拥有相对路径都以依据playbook的),在此playbook中应用include来含有它,如若利用相对路径将会蕴藏同目录下的文本。

---
    - hosts: centos7
      tasks:
       - include: a.yaml

能够在include的时候传递变量给相应的文件,那样在被含有的文书中就足以引用该变量的值。

---
  - hosts: centos7
    tasks:
      - include: a.yaml sayhi="hello world"

或者

---
  - hosts: centos7
    tasks:
       - include: a.yaml
         vars: 
           sayhi: "hello world"

下一场能够在被含有的文书a.yaml中央银行使该变量。例如:

---
    - name: execute ntpdate
      shell: /usr/sbin/ntpdate ntp1.aliyun.com
    - name: say hi to world
      debug: msg="{{ sayhi }}"

履行该test.yaml,将会输出对应的变量值。

ansible-playbook /yaml/test.yaml

PLAY [centos7] **************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [192.168.100.64]
ok: [192.168.100.63]
ok: [192.168.100.65]

TASK [execute ntpdate] *******************************************************************
changed: [192.168.100.64]
changed: [192.168.100.65]
changed: [192.168.100.63]

TASK [sayhi to world] *******************************************************************
ok: [192.168.100.63] => {
    "changed": false, 
    "msg": "hello world"
}
ok: [192.168.100.65] => {
    "changed": false, 
    "msg": "hello world"
}
ok: [192.168.100.64] => {
    "changed": false, 
    "msg": "hello world"
}

PLAY RECAP ******************************************************************************
192.168.100.63             : ok=3    changed=1    unreachable=0    failed=0   
192.168.100.64             : ok=3    changed=1    unreachable=0    failed=0   
192.168.100.65             : ok=3    changed=1    unreachable=0    failed=0

二.另一种是include整个playbook文件,即include的动作是加载二个或四个play,所以写在一流列表的层次。

- name: this is a play at the top level of a file
  hosts: all
  remote_user: root

  tasks:

  - name: say hi
    tags: foo
    shell: echo "hi..."

- include: load_balancers.yml  sayhi="hello world"
- include: webservers.yml
- include: dbservers.yml

    any other operations

亟需表明的是,在ansible
二.四本子中,添加了includes和imports二种导入的措施,它们对静态和动态导入支持的更加细化,而ansible
二.3及以前的include语句已经撤废,但仍可用。相关法定手册地址。

1.4 include和roles

万壹将有所的play都写在2个playbook中,很简单导致那些playbook文件变得臃肿庞大,且不易读。由此,能够将七个不一致职务分别写在分歧的playbook中,然后利用include将其包含进去即可。而role则是结合playbook的办法。无论是include依然role,其指标都以分开大playbook以及复用有个别细化的play甚至是task。

yaml语法和变量

1.五 roles示例:批量自动化安装

上面演示的是利用role批量自动安装nginx和mysql(CentOS 6)或maridb(CentOS
七)的演示。由于被控节点有CentOS 6和CentOS
7二种发行版的操作系统,因而除了要选用对应的数据库,还要让nginx的安顿文件适应各操作系统,因为nginx在那八个本子的种类上配置内容有所分裂。在此,nginx、mysql和mariadb是三个role,且让nginx
role依赖于mysql或mariadb role。

下边包车型地铁例子中,有个别地点是不太合理或多余的行为,但是作为学习示例,能够很好的精通roles之间的团队结构和连锁的操作。

率先是文本的构造。

美高梅手机版4858 5

美高梅手机版4858 6

里面site.yml是入站文件,用于调用nginx、mysql和mariadb那三个role,这么些文件中的内容如下。它有一个效益:(一)在调用roles从前,先依据发行版配置好yum源(pre_tasks);(二)调用nginx
role,此处未有调用mysql和mariadb那三个role,因为在nginx
role的meta/main.yml文件中定义了nginx
role依赖于那三个role,所以那边能够绝不定义;(三)在实施完nginx
role之后,输出三个提醒音信(post_tasks)。

cat /yaml/site.yml
---
  - hosts: centos
    remote_user: root

 # 根据发行版配置好yum源,使用when进行条件判断   
    pre_tasks: 
        - name: config the yum repo for centos 7
          yum_repository:
              name: epel
              description: epel
              baseurl: http://mirrors.aliyun.com/epel/7/$basearch/
              gpgcheck: no
          when: ansible_distribution_major_version == "7"

        - name: config the yum repo for centos 6
          yum_repository:
              name: epel
              description: epel
              baseurl: http://mirrors.aliyun.com/epel/6/$basearch/
              gpgcheck: no
          when: ansible_distribution_major_version == "6"

    roles: 
        - nginx

# 输出over消息
    post_tasks:
      - shell: echo 'deploy nginx/mysql over'
        register: ok_var
      - debug: msg='{{ ok_var.stdout }}'

以下是nginx role中的各文件内容。个中template复制的源文件都以从centos 陆nginx和centos 七 nginx上提取的,只不过是重新命名了罢了。

/yaml/roles/nginx/tasks/main.yml 
---
   - name: make sure nginx state is installed
     yum: name=nginx state=installed

   - name: template nginx.conf
# 基于变量赋值配置文件模板,检查配置文件语法,并在必要的时候触发handler
     template: src=nginx{{ ansible_distribution_major_version }}.conf.j2
                  dest=/etc/nginx/nginx.conf
                  validate="/usr/sbin/nginx -t -c %s"  
     notify: 
        - restart nginx

# 基于jinja2渲染模板文件,且改变时也触发重启操作
   - name: copy index.html
     template: src=index.html.j2 dest=/usr/share/nginx/html/index.html
     notify: 
        - restart nginx

   - name: make sure nginx service is running
     service: name=nginx state=started

# 引用变量 nginx_port,在vars/main.yml中定义了
   - name: make sure port is open
     wait_for: port="{{ nginx_port }}"

/yaml/roles/nginx/handlers/main.yml 
---
   - name: restart nginx
     service: name=nginx state=restarted

/yaml/roles/nginx/vars/main.yml 
nginx_port: 80

# 定义nginx依赖于MySQL或mariadb,具体依赖于哪个,是通过条件进行判断的,centos 6表示依赖于mysql,centos 7表示依赖于mariadb
# 同时传递了两个值给变量hi_var,由于是在依赖的时候传递的,所以这两个变量可直接在依赖的role(mysql role或mariadb role)的playbook中引用
/yaml/roles/nginx/meta/main.yml 
---
   dependencies: 
     - { role: mysql,hi_var: "hello mysql",when: "ansible_distribution_major_version == '6'" }
     - { role: mariadb,hi_var: "hello mariadb",when: "ansible_distribution_major_version == '7'" }

地点拷贝了index.html.j二,其内容为:

shell> cat /yaml/roles/nginx/templates/index.html.j2 
<h1>hello from {{ ansible_default_ipv4.address }}<h1>

在template执行时,它会利用jinja2引擎对文本中的变量实行调换,使得在拷贝到不一致主机时,该index.html的剧情是依照远程主机ip的。此处使用的变量是采访到的facts中的变量”ansible_default_ipv4.address”。

以下是mysql
role中各文件的始末。注意,MySQL的my.cnf和mariadb的my.cnf私下认可景况下并不1致(mariadb的my.cnf默许多了一项配置”!includedir
/etc/my.cnf.d”,MySQL需求废除该项),所以要求各自提供。

/yaml/roles/mysql/tasks/main.yml 
---
    - name: make sure mysql is installed
      yum: name=mysql-server state=installed

# 特别需要注意下面的初始化命令,由于执行的是shell模块,所以要考虑其幂等性,显然初始化动作是一定要实现幂等性的
    - name: do something to initialize mysql
      file: path=/mydata/data state=directory owner=mysql group=mysql mode=0755
    - shell: /usr/bin/mysql_install_db --datadir=/mydata/data --user=mysql creates=/mydata/data/ibdata1

    - name: copy my.cnf
      copy: src=my.cnf dest=/etc/my.cnf
      notify: 
         - restart mysql

    - name: make sure mysql is running
      service: name=mysqld state=started

    - name: make sure mysql port is open
      wait_for: 
         port: "{{ mysql_port }}"
         timeout: 10

# 这里输出了nginx/meta/main.yml中传递的变量
    - name: echo var passed by nginx 
      shell: echo "{{ hi_var }}"
      register: var_result
    - debug: msg="{{ var_result.stdout }}"

/yaml/roles/mysql/handlers/main.yml 
---
   - name: restart mysql
     service: name=mysqld state=restarted

/yaml/roles/mysql/vars/main.yml 
---
    mysql_port: 3306

以下是mariadb
role中各文件的剧情,和mysql大体上是同样的。注意,MySQL的my.cnf和mariadb的my.cnf默许意况下并不均等,所以必要各自提供。

/yaml/roles/mariadb/tasks/main.yml 
---
    - name: make sure mariadb is installed
      yum: name=mariadb-server state=installed

    - name: do something to initialize mariadb
      file: path=/mydata/data state=directory owner=mysql group=mysql mode=0755
    - shell: /usr/bin/mysql_install_db --datadir=/mydata/data --user=mysql creates=/mydata/data/ibdata1

    - name: copy my.cnf
      copy: src=my.cnf dest=/etc/my.cnf
      notify: 
         - restart mariadb

    - name: make sure mariadb is running
      service: name=mariadb state=started

    - name: make sure mariadb port is open
      wait_for: 
         port: "{{ mariadb_port }}"
         timeout: 10

    - name: echo var passed by nginx 
      shell: echo "{{ hi_var }}"
      register: var_result
    - debug: msg="{{ var_result.stdout }}"

/yaml/roles/mariadb/handlers/main.yml 
---
    - name: restart mariadb
      service: name=mariadb state=restarted

/yaml/roles/mariadb/vars/main.yml 
---
    mariadb_port: 3306

以下是两台机器的测试结果,1台是centos 七(1玖2.16八.十0.54),1台是centos
6(192.16八.100.70)。

PLAY [newhosts] *************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [192.168.100.70]
ok: [192.168.100.54]

TASK [config the yum repo for centos 7] *************************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [config the yum repo for centos 6] *************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : make sure mysql is installed] *********************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : do something to initialize mysql] *****************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : command] ******************************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : copy my.cnf] **************************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : make sure mysql is running] ***********************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : make sure mysql port is open] *********************************************
skipping: [192.168.100.54]
ok: [192.168.100.70]

TASK [mysql : echo var passed by nginx] *************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : debug] ********************************************************************
skipping: [192.168.100.54]
ok: [192.168.100.70] => {
    "changed": false, 
    "msg": "hello mysql"
}

TASK [mariadb : make sure mariadb is installed] *****************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : do something to initialize mariadb] *************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : command] ****************************************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : copy my.cnf] ************************************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : make sure mariadb is running] *******************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : make sure mariadb port is open] *****************************************
skipping: [192.168.100.70]
ok: [192.168.100.54]

TASK [mariadb : echo var passed by nginx] ***********************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : debug] ******************************************************************
skipping: [192.168.100.70]
ok: [192.168.100.54] => {
    "changed": false, 
    "msg": "hello mysql"
}

TASK [nginx : make sure nginx state is installed] ***************************************
changed: [192.168.100.54]
changed: [192.168.100.70]

TASK [nginx : template nginx.conf] ******************************************************
ok: [192.168.100.70]
changed: [192.168.100.54]

TASK [nginx : copy index.html] **********************************************************
changed: [192.168.100.70]
changed: [192.168.100.54]

TASK [nginx : make sure nginx service is running] ***************************************
changed: [192.168.100.54]
changed: [192.168.100.70]

TASK [nginx : make sure port is open] ***************************************************
ok: [192.168.100.70]
ok: [192.168.100.54]

RUNNING HANDLER [mysql : restart mysql] *************************************************
changed: [192.168.100.70]

RUNNING HANDLER [mariadb : restart mariadb] *********************************************
changed: [192.168.100.54]

RUNNING HANDLER [nginx : restart nginx] *************************************************
changed: [192.168.100.54]

TASK [command] **************************************************************************
changed: [192.168.100.54]
changed: [192.168.100.70]

TASK [debug] ****************************************************************************
ok: [192.168.100.54] => {
    "changed": false, 
    "msg": "deploy nginx/mysql over"
}
ok: [192.168.100.70] => {
    "changed": false, 
    "msg": "deploy nginx/mysql over"
}

PLAY RECAP ******************************************************************************
192.168.100.54             : ok=19   changed=14   unreachable=0    failed=0   
192.168.100.70             : ok=18   changed=12   unreachable=0    failed=0

深信看过地点的roles组织示例,对roles的用法和playbook就有了较深的认识。其实,ansible有3个网址专门存放了一大堆的playbook,算是playbook仓库吧。能够下载下来稍作修改就能动用,尽管不选拔,借鉴他们的写法也是很值得的。地址:ansible
galaxy

除此以外,依照不一致专业协会role大概会让playbook写起来更易于,例如地点的演示中,遵照发行版来划分role比上边遵照设置软件项目划分只怕会更简便些。当然,假使在inventory中就分开好centos
陆和centos 7也是足以的。哪一类更利于、复用性越来越好就须求活动思虑了。

归来种类小说大纲:

1.4.2 roles

roles意为角色,重要用来封装playbook完结复用性。在ansible中,roles通过文件的集体结构来显现。

对于一个role,它的文件协会结构如下图所示。

              美高梅手机版4858 7

第贰必要有贰个roles目录。同时,在roles目录所在目录中,还要有1个playbook文件,此处为nginx.yml,nginx.yml文件是ansible-playbook需求执行的文书,在此文件中定义了角色,当执行到角色时,将会到roles中对应的剧中人物目录中搜寻有关文书。

roles目录中的子目录是就是各类role。例如,此处唯有贰个名叫nginx的role,在role目录中,有多少个固定名称的目录(假设未有则忽略)。在那一个目录中,还要有部分定位名称的文本,除了固定名称的公文,其余的公文可以任意命名。以下是逐一目录的意义:

  • tasks目录:存放task列表。若role要一蹴而就,此目录须要求有3个主task文件main.yml,在main.yml中得以采纳include包括同目录(即tasks)中的其余文件。
  • handlers目录:存放handlers的目录,若要生效,则文件必须名称叫main.yml文件。
  • files目录:在task中执行copy或script模块时,假使采用的是相对路径,则会到此目录中追寻对应的公文。
  • templates目录:在task中履行template模块时,倘若接纳的是相对路径,则会到此目录中寻觅对应的模块文件。
  • vars目录:定义专属于该role的变量,若是要有var文件,则必须为main.yml文件。
  • defaults目录:定义剧中人物暗中同意变量,剧中人物暗中同意变量的优先级最低,会被任意其余层次的同名变量覆盖。假设要有var文件,则必须为main.yml文件。
  • meta目录:用于定义剧中人物注重,要是要有剧中人物正视关系,则文件必须为main.yml。

据此,相对完整的role的文件组织结构如下图。

              美高梅手机版4858 8

假如是七个role,则在roles同级目录下定义四个入站(成效类似于C语言的main函数)文件(如上边包车型客车nginx.yml),并在roles目录下创办对应的role目录即可。

              美高梅手机版4858 9

自然,若是否利用相对路径,那么role的文本结构就无所谓了,可是roles功效开发出来,正是为着消除文件混乱和playbook臃肿难点的。所以假诺得以,尽量选用推荐的role文件结构。

此外,假如role中冒出的task、var、handler等和单独定义的靶子同名争持了,则优先实施role中的内容。

以下是nginx role的入站文件nginx.yml的始末。

---
  - hosts: centos7
    roles:
      - nginx

越多更详尽的role用法以及共青团和少先队结构,见下边包车型客车以身作则。

1.4.1 include

能够将task列表和handlers独立写在别的的文本中,然后在有个别playbook文件中采取include来含有它们。除外,还是能写独立的playbook文件,使用include来含有那一个文件。

也正是说,include能够导入二种文件:导入task、导入playbook。

一.一种是职务列表式的文件(未有tasks或handlers指令),它不得不在tasks或handlers指令的子选项处使用include包罗。那种办法得以传递变量到被含有的文件中。

假使有个别task列表文件/yaml/a.yaml内容如下:

---
    - name: execute ntpdate
      shell: /usr/sbin/ntpdate ntp1.aliyun.com

在同目录/yaml下有1个名叫test.yaml的playbook(除了role,playbook中享有相对路径都以依照playbook的),在此playbook中利用include来含有它,假设利用相对路径将会包括同目录下的公文。

---
    - hosts: centos7
      tasks:
       - include: a.yaml

能够在include的时候传递变量给相应的文件,那样在被含有的文书中就足以引用该变量的值。

---
  - hosts: centos7
    tasks:
      - include: a.yaml sayhi="hello world"

或者

---
  - hosts: centos7
    tasks:
       - include: a.yaml
         vars: 
           sayhi: "hello world"

接下来能够在被含有的文书a.yaml中动用该变量。例如:

---
    - name: execute ntpdate
      shell: /usr/sbin/ntpdate ntp1.aliyun.com
    - name: say hi to world
      debug: msg="{{ sayhi }}"

进行该test.yaml,将会输出对应的变量值。

ansible-playbook /yaml/test.yaml

PLAY [centos7] **************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [192.168.100.64]
ok: [192.168.100.63]
ok: [192.168.100.65]

TASK [execute ntpdate] *******************************************************************
changed: [192.168.100.64]
changed: [192.168.100.65]
changed: [192.168.100.63]

TASK [sayhi to world] *******************************************************************
ok: [192.168.100.63] => {
    "changed": false, 
    "msg": "hello world"
}
ok: [192.168.100.65] => {
    "changed": false, 
    "msg": "hello world"
}
ok: [192.168.100.64] => {
    "changed": false, 
    "msg": "hello world"
}

PLAY RECAP ******************************************************************************
192.168.100.63             : ok=3    changed=1    unreachable=0    failed=0   
192.168.100.64             : ok=3    changed=1    unreachable=0    failed=0   
192.168.100.65             : ok=3    changed=1    unreachable=0    failed=0

贰.另1种是include整个playbook文件,即include的动作是加载1个或多少个play,所以写在5星级列表的层系。

- name: this is a play at the top level of a file
  hosts: all
  remote_user: root

  tasks:

  - name: say hi
    tags: foo
    shell: echo "hi..."

- include: load_balancers.yml  sayhi="hello world"
- include: webservers.yml
- include: dbservers.yml

    any other operations

亟待注解的是,在ansible
二.4版本中,添加了includes和imports三种导入的法子,它们对静态和动态导入补助的越来越细化,而ansible
2.三及从前的include语句已经撤除,但仍可用。相关官方手册地址。

yaml语法

  • 大大小小写敏感
  • 利用缩进表示层级关系(只好空格无法选择tab)
  • yaml文件”—“作为文书档案的起来

yaml协助的数据结构

美高梅手机版4858 10

 

yaml变量的运用

美高梅手机版4858 11

 

转发请注脚出处:

一.五 roles示例:批量自动化安装

上面演示的是运用role批量自动安装nginx和mysql(CentOS 6)或maridb(CentOS
七)的示范。由于被控节点有CentOS 六和CentOS
7两种发行版的操作系统,由此除了要挑选对应的数据库,还要让nginx的布局文件适应各操作系统,因为nginx在那三个版本的系统上安插内容有所区别。在此,nginx、mysql和mariadb是1个role,且让nginx
role依赖于mysql或mariadb role。

下边包车型地铁例子中,某些地点是不太合理或多余的一言一动,然而作为读书示例,能够很好的明亮roles之间的公司结构和血脉相通的操作。

第壹是文件的布局。

美高梅手机版4858 12

美高梅手机版4858 13

个中site.yml是入站文件,用于调用nginx、mysql和mariadb那三个role,那个文件中的内容如下。它有二个作用:(一)在调用roles在此之前,先依据发行版配置好yum源(pre_tasks);(二)调用nginx
role,此处未有调用mysql和mariadb那多少个role,因为在nginx
role的meta/main.yml文件中定义了nginx
role注重于那多个role,所以那边能够不用定义;(3)在实施完nginx
role之后,输出3个提示消息(post_tasks)。

cat /yaml/site.yml
---
  - hosts: centos
    remote_user: root

 # 根据发行版配置好yum源,使用when进行条件判断   
    pre_tasks: 
        - name: config the yum repo for centos 7
          yum_repository:
              name: epel
              description: epel
              baseurl: http://mirrors.aliyun.com/epel/7/$basearch/
              gpgcheck: no
          when: ansible_distribution_major_version == "7"

        - name: config the yum repo for centos 6
          yum_repository:
              name: epel
              description: epel
              baseurl: http://mirrors.aliyun.com/epel/6/$basearch/
              gpgcheck: no
          when: ansible_distribution_major_version == "6"

    roles: 
        - nginx

# 输出over消息
    post_tasks:
      - shell: echo 'deploy nginx/mysql over'
        register: ok_var
      - debug: msg='{{ ok_var.stdout }}'

以下是nginx role中的各文件内容。当中template复制的源文件都以从centos 6nginx和centos 7 nginx上领取的,只不过是重新命名了罢了。

/yaml/roles/nginx/tasks/main.yml 
---
   - name: make sure nginx state is installed
     yum: name=nginx state=installed

   - name: template nginx.conf
# 基于变量赋值配置文件模板,检查配置文件语法,并在必要的时候触发handler
     template: src=nginx{{ ansible_distribution_major_version }}.conf.j2
                  dest=/etc/nginx/nginx.conf
                  validate="/usr/sbin/nginx -t -c %s"  
     notify: 
        - restart nginx

# 基于jinja2渲染模板文件,且改变时也触发重启操作
   - name: copy index.html
     template: src=index.html.j2 dest=/usr/share/nginx/html/index.html
     notify: 
        - restart nginx

   - name: make sure nginx service is running
     service: name=nginx state=started

# 引用变量 nginx_port,在vars/main.yml中定义了
   - name: make sure port is open
     wait_for: port="{{ nginx_port }}"

/yaml/roles/nginx/handlers/main.yml 
---
   - name: restart nginx
     service: name=nginx state=restarted

/yaml/roles/nginx/vars/main.yml 
nginx_port: 80

# 定义nginx依赖于MySQL或mariadb,具体依赖于哪个,是通过条件进行判断的,centos 6表示依赖于mysql,centos 7表示依赖于mariadb
# 同时传递了两个值给变量hi_var,由于是在依赖的时候传递的,所以这两个变量可直接在依赖的role(mysql role或mariadb role)的playbook中引用
/yaml/roles/nginx/meta/main.yml 
---
   dependencies: 
     - { role: mysql,hi_var: "hello mysql",when: "ansible_distribution_major_version == '6'" }
     - { role: mariadb,hi_var: "hello mariadb",when: "ansible_distribution_major_version == '7'" }

上边拷贝了index.html.j贰,其剧情为:

shell> cat /yaml/roles/nginx/templates/index.html.j2 
<h1>hello from {{ ansible_default_ipv4.address }}<h1>

在template执行时,它会动用jinja二引擎对文件中的变量进行替换,使得在拷贝到区别主机时,该index.html的始末是依据远程主机ip的。此处使用的变量是收集到的facts中的变量”ansible_default_ipv4.address”。

以下是mysql
role中各文件的剧情。注意,MySQL的my.cnf和mariadb的my.cnf暗中同意境况下并分化(mariadb的my.cnf暗许多了一项配置”!includedir
/etc/my.cnf.d”,MySQL要求撤销该项),所以必要各自提供。

/yaml/roles/mysql/tasks/main.yml 
---
    - name: make sure mysql is installed
      yum: name=mysql-server state=installed

# 特别需要注意下面的初始化命令,由于执行的是shell模块,所以要考虑其幂等性,显然初始化动作是一定要实现幂等性的
    - name: do something to initialize mysql
      file: path=/mydata/data state=directory owner=mysql group=mysql mode=0755
    - shell: /usr/bin/mysql_install_db --datadir=/mydata/data --user=mysql creates=/mydata/data/ibdata1

    - name: copy my.cnf
      copy: src=my.cnf dest=/etc/my.cnf
      notify: 
         - restart mysql

    - name: make sure mysql is running
      service: name=mysqld state=started

    - name: make sure mysql port is open
      wait_for: 
         port: "{{ mysql_port }}"
         timeout: 10

# 这里输出了nginx/meta/main.yml中传递的变量
    - name: echo var passed by nginx 
      shell: echo "{{ hi_var }}"
      register: var_result
    - debug: msg="{{ var_result.stdout }}"

/yaml/roles/mysql/handlers/main.yml 
---
   - name: restart mysql
     service: name=mysqld state=restarted

/yaml/roles/mysql/vars/main.yml 
---
    mysql_port: 3306

以下是mariadb
role中各文件的始末,和mysql大体上是同等的。注意,MySQL的my.cnf和mariadb的my.cnf暗许意况下并不1致,所以供给各自提供。

/yaml/roles/mariadb/tasks/main.yml 
---
    - name: make sure mariadb is installed
      yum: name=mariadb-server state=installed

    - name: do something to initialize mariadb
      file: path=/mydata/data state=directory owner=mysql group=mysql mode=0755
    - shell: /usr/bin/mysql_install_db --datadir=/mydata/data --user=mysql creates=/mydata/data/ibdata1

    - name: copy my.cnf
      copy: src=my.cnf dest=/etc/my.cnf
      notify: 
         - restart mariadb

    - name: make sure mariadb is running
      service: name=mariadb state=started

    - name: make sure mariadb port is open
      wait_for: 
         port: "{{ mariadb_port }}"
         timeout: 10

    - name: echo var passed by nginx 
      shell: echo "{{ hi_var }}"
      register: var_result
    - debug: msg="{{ var_result.stdout }}"

/yaml/roles/mariadb/handlers/main.yml 
---
    - name: restart mariadb
      service: name=mariadb state=restarted

/yaml/roles/mariadb/vars/main.yml 
---
    mariadb_port: 3306

以下是两台机器的测试结果,壹台是centos 七(1九2.16八.十0.54),一台是centos
陆(1玖二.16八.十0.70)。

PLAY [newhosts] *************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [192.168.100.70]
ok: [192.168.100.54]

TASK [config the yum repo for centos 7] *************************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [config the yum repo for centos 6] *************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : make sure mysql is installed] *********************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : do something to initialize mysql] *****************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : command] ******************************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : copy my.cnf] **************************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : make sure mysql is running] ***********************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : make sure mysql port is open] *********************************************
skipping: [192.168.100.54]
ok: [192.168.100.70]

TASK [mysql : echo var passed by nginx] *************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : debug] ********************************************************************
skipping: [192.168.100.54]
ok: [192.168.100.70] => {
    "changed": false, 
    "msg": "hello mysql"
}

TASK [mariadb : make sure mariadb is installed] *****************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : do something to initialize mariadb] *************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : command] ****************************************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : copy my.cnf] ************************************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : make sure mariadb is running] *******************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : make sure mariadb port is open] *****************************************
skipping: [192.168.100.70]
ok: [192.168.100.54]

TASK [mariadb : echo var passed by nginx] ***********************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : debug] ******************************************************************
skipping: [192.168.100.70]
ok: [192.168.100.54] => {
    "changed": false, 
    "msg": "hello mysql"
}

TASK [nginx : make sure nginx state is installed] ***************************************
changed: [192.168.100.54]
changed: [192.168.100.70]

TASK [nginx : template nginx.conf] ******************************************************
ok: [192.168.100.70]
changed: [192.168.100.54]

TASK [nginx : copy index.html] **********************************************************
changed: [192.168.100.70]
changed: [192.168.100.54]

TASK [nginx : make sure nginx service is running] ***************************************
changed: [192.168.100.54]
changed: [192.168.100.70]

TASK [nginx : make sure port is open] ***************************************************
ok: [192.168.100.70]
ok: [192.168.100.54]

RUNNING HANDLER [mysql : restart mysql] *************************************************
changed: [192.168.100.70]

RUNNING HANDLER [mariadb : restart mariadb] *********************************************
changed: [192.168.100.54]

RUNNING HANDLER [nginx : restart nginx] *************************************************
changed: [192.168.100.54]

TASK [command] **************************************************************************
changed: [192.168.100.54]
changed: [192.168.100.70]

TASK [debug] ****************************************************************************
ok: [192.168.100.54] => {
    "changed": false, 
    "msg": "deploy nginx/mysql over"
}
ok: [192.168.100.70] => {
    "changed": false, 
    "msg": "deploy nginx/mysql over"
}

PLAY RECAP ******************************************************************************
192.168.100.54             : ok=19   changed=14   unreachable=0    failed=0   
192.168.100.70             : ok=18   changed=12   unreachable=0    failed=0

深信看过地点的roles组织示例,对roles的用法和playbook就有了较深的认识。其实,ansible有一个网址专门存放了一大堆的playbook,算是playbook仓库吧。能够下载下来稍作修改就能选取,尽管不应用,借鉴他们的写法也是很值得的。地址:ansible
galaxy

除此以外,依照分化专业协会role可能会让playbook写起来更易于,例如地方的演示中,依照发行版来划分role比地方根据设置软件项目划分或许会更简约些。当然,假诺在inventory中就分割好centos
陆和centos 柒也是能够的。哪一类更方便人民群众、复用性越来越好就需求活动思虑了。

归来体系小说大纲:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

1.4.2 roles

roles意为剧中人物,首要用以封装playbook完结复用性。在ansible中,roles通过文件的集体结构来展现。

对此一个role,它的文件组织结构如下图所示。

              美高梅手机版4858 14

首先必要有一个roles目录。同时,在roles目录所在目录中,还要有贰个playbook文件,此处为nginx.yml,nginx.yml文件是ansible-playbook须要执行的公文,在此文件中定义了角色,当执行到剧中人物时,将会到roles中对应的剧中人物目录中寻找相关文件。

roles目录中的子目录是正是种种role。例如,此处唯有2个名字为nginx的role,在role目录中,有多少个定点名称的目录(借使未有则忽略)。在这几个目录中,还要有部分定位名称的文书,除了定位名称的文本,其余的文本能够任意命名。以下是各种目录的意义:

  • tasks目录:存放task列表。若role要卓有成效,此目录必须求有二个主task文件main.yml,在main.yml中得以采纳include包涵同目录(即tasks)中的其余文件。
  • handlers目录:存放handlers的目录,若要生效,则文件必须名叫main.yml文件。
  • files目录:在task中实行copy或script模块时,假诺使用的是相对路径,则会到此目录中搜寻对应的文书。
  • templates目录:在task中实践template模块时,假使使用的是相对路径,则会到此目录中寻找对应的模块文件。
  • vars目录:定义专属于该role的变量,假设要有var文件,则必须为main.yml文件。
  • defaults目录:定义剧中人物暗许变量,角色默许变量的优先级最低,会被随便别的层次的同名变量覆盖。假使要有var文件,则必须为main.yml文件。
  • meta目录:用于定义剧中人物注重,若是要有剧中人物重视关系,则文件必须为main.yml。

据此,相对完整的role的文件组织结构如下图。

              美高梅手机版4858 15

只若是四个role,则在roles同级目录下定义八个入站(效率类似于C语言的main函数)文件(如下面的nginx.yml),并在roles目录下开创对应的role目录即可。

              美高梅手机版4858 16

本来,倘诺不是运用绝对路径,那么role的公文结构就无所谓了,不过roles作用开发出来,正是为着消除文件混乱和playbook臃肿难题的。所以借使得以,尽量采纳推荐的role文件结构。

其余,要是role中冒出的task、var、handler等和独门定义的对象同名争辩了,则优先实施role中的内容。

以下是nginx role的入站文件nginx.yml的剧情。

---
  - hosts: centos7
    roles:
      - nginx

愈来愈多更详尽的role用法以及组织结构,见上边包车型大巴示范。

playbook变量

  1. playbook的yaml文件中的定义变量赋值
  2. –extra-vars执行参数赋给变量 

 示例:

devops@devops-virtual-machine:/etc/ansible$ cat f1.yml
---
- hosts : 192.168.56.11
  remote_user : root
  #  vars :           # 注册这两行
          #          touch_file : devops.file
  tasks :
          - name : touch file
            shell: "touch /tmp/{{touch_file}}"


# 执行
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook ./f1.yml --extra-vars "touch_file=json2"

PLAY [192.168.56.11] ***********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.56.11]

TASK [touch file] **************************************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.56.11]

PLAY RECAP *********************************************************************************************************************
192.168.56.11              : ok=2    changed=1    unreachable=0    failed=0

翻开执行结果

devops@devops-virtual-machine:/etc/ansible$ ansible  all -a 'ls /tmp'
192.168.56.11 | SUCCESS | rc=0 >>
devops.file
json2

  3、在文书中定义变量

在资金财产清单中定义变量

美高梅手机版4858 17美高梅手机版4858 18

devops@devops-virtual-machine:/etc/ansible$ cat /etc/ansible/hosts
[test_group1]
#192.168.56.11:22 ansible_ssh_user=root ansible_ssh_pass='1234567'
#192.168.56.11:22 ansible_ssh_user=root ansible_ssh_key_file=/home/devops/.ssh/id_rsa
192.168.56.11:22 ansible_ssh_user=root


# 添加两行内容如下: 当f1.yaml执行时会引用(touch_file)这个变量
[test_group1:vars]
touch_file=json3

# 执行
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook ./f1.yml

PLAY [192.168.56.11] ***********************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.56.11]

TASK [touch file] **************************************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.56.11]

PLAY RECAP *********************************************************************************************************************
192.168.56.11              : ok=2    changed=1    unreachable=0    failed=0


# 查看执行服务器(192.168.56.11 )上是否有json3文件
devops@devops-virtual-machine:/etc/ansible$ ansible  all -a 'ls /tmp'
192.168.56.11 | SUCCESS | rc=0 >>
json2
json3

示例

  四、注册变量

register关键字能够储存钦定的指令的输出结果到2个自定义的变量中

– name: get time

  command:date

  register:date_output

美高梅手机版4858 19美高梅手机版4858 20

devops@devops-virtual-machine:/etc/ansible$ cat f4.yml
---
- hosts : 192.168.56.11
  remote_user : root
  vars :
      touch_file : devops.file
  tasks :
      - name : get date
        command : date              # 执行date命令
        register : date_output      # 把date的执行结果赋值给date_output
      - name : touch file
        shell : "touch /tmp/{{touch_file}}"
      - name : echo date_output
        shell : "echo {{date_output.stdout}}>/tmp/{{touch_file}}"

# 执行 加vvv显示详细信息
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook ./f4.yml -vvv
ansible-playbook 2.4.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/devops/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/dist-packages/ansible-2.4.1.0-py3.6.egg/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.6.5 (default, Apr  1 2018, 05:46:30) [GCC 7.3.0]
Using /etc/ansible/ansible.cfg as config file
Parsed /etc/ansible/hosts inventory source with ini plugin

PLAYBOOK: f4.yml ***********************************************************************************************
1 plays in ./f4.yml

PLAY [192.168.56.11] *******************************************************************************************

TASK [Gathering Facts] *****************************************************************************************
Using module file /usr/local/lib/python3.6/dist-packages/ansible-2.4.1.0-py3.6.egg/ansible/modules/system/setup.py
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<192.168.56.11> (0, b'/root\n', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1531396830.9463239-175629470926231 `" && echo ansible-tmp-1531396830.9463239-175629470926231="` echo /root/.ansible/tmp/ansible-tmp-1531396830.9463239-175629470926231 `" ) && sleep 0'"'"''
<192.168.56.11> (0, b'ansible-tmp-1531396830.9463239-175629470926231=/root/.ansible/tmp/ansible-tmp-1531396830.9463239-175629470926231\n', b'')
<192.168.56.11> PUT /tmp/tmpihpjzcgr TO /root/.ansible/tmp/ansible-tmp-1531396830.9463239-175629470926231/setup.py
<192.168.56.11> SSH: EXEC sftp -b - -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 '[192.168.56.11]'
<192.168.56.11> (0, b'sftp> put /tmp/tmpihpjzcgr /root/.ansible/tmp/ansible-tmp-1531396830.9463239-175629470926231/setup.py\n', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1531396830.9463239-175629470926231/ /root/.ansible/tmp/ansible-tmp-1531396830.9463239-175629470926231/setup.py && sleep 0'"'"''
<192.168.56.11> (0, b'', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 -tt 192.168.56.11 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1531396830.9463239-175629470926231/setup.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1531396830.9463239-175629470926231/" > /dev/null 2>&1 && sleep 0'"'"''
<192.168.56.11> (0, b'\r\n{"invocation": {"module_args": {"filter": "*", "gather_subset": ["all"], "fact_path": "/etc/ansible/facts.d", "gather_timeout": 10}}, "ansible_facts": {"ansible_product_serial": "VMware-56 4d ba ea 2a 14 bd 0e-90 3f 06 a4 d2 a0 10 ca", "ansible_form_factor": "Other", "ansible_distribution_file_parsed": true, "ansible_fips": false, "ansible_service_mgr": "systemd", "ansible_user_id": "root", "ansible_selinux_python_present": true, "ansible_userspace_bits": "64", "ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDvGRGyqSELPCWRxOyhXtCk8HvSnKH82paTv3gVgfkmD9wI7eVXXQDXOoTXYJZzKK5bDy3fsSZg7BpHDLysHff1fUh3oexfzUepT440VAonQl9cWSdUgSQUPZdJuj+o+9teIbkT4yWxh+ou+59uC1z0zwWWs99aIn4Ul/RdAjJJr0O+iTYcdHsnupAxf9T/bpsW49cTRXhhzkQW9gUpyanfVU94Y+cKb/D178V//zL4/Km/90WSFQGMW0xWTSxh1QbqZge639K3BR/wL5VUJhy8Nv6HQPgV9aTkCLNERk4sjrMWQWP4jsT0VPQ0VpS7iE7GQZrbPx3qE/49vcQNIwG3", "gather_subset": ["all"], "ansible_real_user_id": 0, "ansible_architecture": "x86_64", "ansible_local": {}, "ansible_distribution_version": "7.3.1611", "ansible_domain": "example.com", "ansible_distribution_file_path": "/etc/redhat-release", "ansible_user_shell": "/bin/bash", "ansible_date_time": {"weekday_number": "4", "iso8601_basic_short": "20180712T200057", "tz": "CST", "weeknumber": "28", "hour": "20", "year": "2018", "minute": "00", "tz_offset": "+0800", "month": "07", "epoch": "1531396857", "iso8601_micro": "2018-07-12T12:00:57.933420Z", "weekday": "\\u661f\\u671f\\u56db", "time": "20:00:57", "date": "2018-07-12", "iso8601": "2018-07-12T12:00:57Z", "day": "12", "iso8601_basic": "20180712T200057933342", "second": "57"}, "ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIDG1zxZJmUXAcaboS6in1sWqmzxiu0mqwHsr0wzF2khq", "ansible_processor_cores": 1, "ansible_virtualization_role": "guest", "ansible_distribution_file_variety": "RedHat", "ansible_env": {"LANG": "zh_CN.UTF-8", "TERM": "xterm-256color", "SHELL": "/bin/bash", "XDG_RUNTIME_DIR": "/run/user/0", "SHLVL": "2", "SSH_TTY": "/dev/pts/0", "HOME": "/root", "SSH_CLIENT": "192.168.56.133 44790 22", "LESSOPEN": "||/usr/bin/lesspipe.sh %s", "PWD": "/root", "LOGNAME": "root", "USER": "root", "MAIL": "/var/mail/root", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", "LS_COLORS": "rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:", "XDG_SESSION_ID": "5", "_": "/usr/bin/python", "SSH_CONNECTION": "192.168.56.133 44790 192.168.56.11 22"}, "ansible_effective_group_id": 0, "ansible_bios_version": "6.00", "ansible_processor": ["0", "GenuineIntel", "Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz"], "ansible_virtualization_type": "VMware", "ansible_lo": {"features": {"tx_checksum_ipv4": "off [fixed]", "generic_receive_offload": "on", "tx_checksum_ipv6": "off [fixed]", "tx_scatter_gather_fraglist": "on [fixed]", "rx_all": "off [fixed]", "highdma": "on [fixed]", "rx_fcs": "off [fixed]", "tx_lockless": "on [fixed]", "tx_tcp_ecn_segmentation": "on", "tx_tcp6_segmentation": "on", "tx_gso_robust": "off [fixed]", "tx_ipip_segmentation": "off [fixed]", "tx_checksumming": "on", "vlan_challenged": "on [fixed]", "loopback": "on [fixed]", "fcoe_mtu": "off [fixed]", "scatter_gather": "on", "tx_checksum_sctp": "on [fixed]", "tx_vlan_stag_hw_insert": "off [fixed]", "rx_vlan_stag_hw_parse": "off [fixed]", "rx_vlan_stag_filter": "off [fixed]", "large_receive_offload": "off [fixed]", "tx_scatter_gather": "on [fixed]", "rx_checksumming": "on [fixed]", "tx_tcp_segmentation": "on", "netns_local": "on [fixed]", "busy_poll": "off [fixed]", "generic_segmentation_offload": "on", "tx_udp_tnl_segmentation": "off [fixed]", "tcp_segmentation_offload": "on", "l2_fwd_offload": "off [fixed]", "rx_vlan_offload": "off [fixed]", "ntuple_filters": "off [fixed]", "tx_vlan_offload": "off [fixed]", "tx_nocache_copy": "off [fixed]", "tx_mpls_segmentation": "off [fixed]", "udp_fragmentation_offload": "on", "tx_sctp_segmentation": "on", "tx_sit_segmentation": "off [fixed]", "tx_checksum_fcoe_crc": "off [fixed]", "hw_tc_offload": "off [fixed]", "tx_checksum_ip_generic": "on [fixed]", "tx_fcoe_segmentation": "off [fixed]", "rx_vlan_filter": "off [fixed]", "receive_hashing": "off [fixed]", "tx_gre_segmentation": "off [fixed]"}, "hw_timestamp_filters": [], "mtu": 65536, "device": "lo", "promisc": false, "timestamping": ["rx_software", "software"], "ipv4": {"broadcast": "host", "netmask": "255.0.0.0", "network": "127.0.0.0", "address": "127.0.0.1"}, "ipv6": [{"scope": "host", "prefix": "128", "address": "::1"}], "active": true, "type": "loopback"}, "ansible_memtotal_mb": 976, "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPb+x6CxAv1fn1DdrTK9Gn1AetZc+7Z1fNOmHTKK5YLW9AcE1dNj7ch7XzP98BpgJjkwuqig3TzYuzSajNi7qVg=", "ansible_device_links": {"masters": {"sda2": ["dm-0", "dm-1"]}, "labels": {"sr0": ["CentOS\\\\x207\\\\x20x86_64"]}, "ids": {"sr0": ["ata-VMware_Virtual_IDE_CDROM_Drive_10000000000000000001"], "sda2": ["lvm-pv-uuid-6PpuNw-P0Sl-vgrG-eph3-vPgV-80rS-kVO4nk"], "dm-0": ["dm-name-cl-root", "dm-uuid-LVM-yZVSxca2orueczI165YImVDpRd6Uy7HQ7Qpv8yMY9esqgrnFTcf8dbPKaZ5DK7j1"], "dm-1": ["dm-name-cl-swap", "dm-uuid-LVM-yZVSxca2orueczI165YImVDpRd6Uy7HQJsBOsjYPBRT6yKFLgQcHw9IcENdrUaD0"]}, "uuids": {"sr0": ["2016-12-05-13-55-45-00"], "sda1": ["bd203c5e-8ff1-4060-bcaf-990e2ccb61c1"], "dm-0": ["8d886d43-1ef5-451a-951c-4170c89c9412"], "dm-1": ["2b2df9d8-6c15-4c0e-a4cb-9e25edbf17b8"]}}, "ansible_default_ipv4": {"macaddress": "00:0c:29:a0:10:ca", "network": "192.168.56.0", "mtu": 1500, "broadcast": "192.168.56.255", "alias": "eth0", "netmask": "255.255.255.0", "address": "192.168.56.11", "interface": "eth0", "type": "ether", "gateway": "192.168.56.2"}, "ansible_swapfree_mb": 2047, "ansible_default_ipv6": {}, "ansible_distribution_release": "Core", "ansible_system_vendor": "VMware, Inc.", "ansible_apparmor": {"status": "disabled"}, "ansible_cmdline": {"LANG": "en_US.UTF-8", "BOOT_IMAGE": "/vmlinuz-3.10.0-514.el7.x86_64", "quiet": true, "net.ifnames": "0", "rhgb": true, "biosdevname": "0", "crashkernel": "auto", "rd.lvm.lv": "cl/swap", "ro": true, "root": "/dev/mapper/cl-root"}, "ansible_effective_user_id": 0, "ansible_user_gid": 0, "ansible_selinux": {"status": "disabled"}, "ansible_product_version": "None", "ansible_os_family": "RedHat", "ansible_userspace_architecture": "x86_64", "ansible_product_uuid": "EABA4D56-142A-0EBD-903F-06A4D2A010CA", "ansible_system": "Linux", "ansible_pkg_mgr": "yum", "ansible_memfree_mb": 192, "ansible_devices": {"sr0": {"scheduler_mode": "cfq", "rotational": "1", "vendor": "NECVMWar", "sectors": "8554496", "links": {"masters": [], "labels": ["CentOS\\\\x207\\\\x20x86_64"], "ids": ["ata-VMware_Virtual_IDE_CDROM_Drive_10000000000000000001"], "uuids": ["2016-12-05-13-55-45-00"]}, "sas_device_handle": null, "sas_address": null, "virtual": 1, "host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)", "sectorsize": "2048", "removable": "1", "support_discard": "0", "model": "VMware IDE CDR10", "partitions": {}, "holders": [], "size": "16.32 GB"}, "sda": {"scheduler_mode": "deadline", "rotational": "1", "vendor": "VMware,", "sectors": "104857600", "links": {"masters": [], "labels": [], "ids": [], "uuids": []}, "sas_device_handle": null, "sas_address": null, "virtual": 1, "host": "SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)", "sectorsize": "512", "removable": "0", "support_discard": "0", "model": "VMware Virtual S", "partitions": {"sda2": {"sectorsize": 512, "uuid": null, "links": {"masters": ["dm-0", "dm-1"], "labels": [], "ids": ["lvm-pv-uuid-6PpuNw-P0Sl-vgrG-eph3-vPgV-80rS-kVO4nk"], "uuids": []}, "sectors": "102758400", "start": "2099200", "holders": ["cl-root", "cl-swap"], "size": "49.00 GB"}, "sda1": {"sectorsize": 512, "uuid": "bd203c5e-8ff1-4060-bcaf-990e2ccb61c1", "links": {"masters": [], "labels": [], "ids": [], "uuids": ["bd203c5e-8ff1-4060-bcaf-990e2ccb61c1"]}, "sectors": "2097152", "start": "2048", "holders": [], "size": "1.00 GB"}}, "holders": [], "size": "50.00 GB"}, "dm-0": {"scheduler_mode": "", "rotational": "1", "vendor": null, "sectors": "98549760", "links": {"masters": [], "labels": [], "ids": ["dm-name-cl-root", "dm-uuid-LVM-yZVSxca2orueczI165YImVDpRd6Uy7HQ7Qpv8yMY9esqgrnFTcf8dbPKaZ5DK7j1"], "uuids": ["8d886d43-1ef5-451a-951c-4170c89c9412"]}, "sas_device_handle": null, "sas_address": null, "virtual": 1, "host": "", "sectorsize": "512", "removable": "0", "support_discard": "0", "model": null, "partitions": {}, "holders": [], "size": "46.99 GB"}, "dm-1": {"scheduler_mode": "", "rotational": "1", "vendor": null, "sectors": "4194304", "links": {"masters": [], "labels": [], "ids": ["dm-name-cl-swap", "dm-uuid-LVM-yZVSxca2orueczI165YImVDpRd6Uy7HQJsBOsjYPBRT6yKFLgQcHw9IcENdrUaD0"], "uuids": ["2b2df9d8-6c15-4c0e-a4cb-9e25edbf17b8"]}, "sas_device_handle": null, "sas_address": null, "virtual": 1, "host": "", "sectorsize": "512", "removable": "0", "support_discard": "0", "model": null, "partitions": {}, "holders": [], "size": "2.00 GB"}}, "ansible_user_uid": 0, "ansible_lvm": {"pvs": {"/dev/sda2": {"free_g": "0.00", "size_g": "49.00", "vg": "cl"}}, "lvs": {"root": {"size_g": "46.99", "vg": "cl"}, "swap": {"size_g": "2.00", "vg": "cl"}}, "vgs": {"cl": {"free_g": "0.00", "size_g": "49.00", "num_lvs": "2", "num_pvs": "1"}}}, "ansible_distribution": "CentOS", "ansible_user_dir": "/root", "ansible_dns": {"nameservers": ["192.168.56.2"]}, "ansible_distribution_major_version": "7", "module_setup": true, "ansible_processor_count": 1, "ansible_hostname": "linux-node1", "ansible_processor_vcpus": 1, "ansible_swaptotal_mb": 2047, "ansible_lsb": {}, "ansible_real_group_id": 0, "ansible_bios_date": "05/19/2017", "ansible_all_ipv6_addresses": ["fe80::20c:29ff:fea0:10ca"], "ansible_interfaces": ["lo", "eth0"], "ansible_uptime_seconds": 695, "ansible_machine_id": "9460c222be194212b2efa3c8edde3c95", "ansible_kernel": "3.10.0-514.el7.x86_64", "ansible_memory_mb": {"real": {"total": 976, "used": 784, "free": 192}, "swap": {"cached": 0, "total": 2047, "free": 2047, "used": 0}, "nocache": {"used": 464, "free": 512}}, "ansible_user_gecos": "root", "ansible_system_capabilities_enforced": "True", "ansible_python": {"executable": "/usr/bin/python", "version": {"micro": 5, "major": 2, "releaselevel": "final", "serial": 0, "minor": 7}, "type": "CPython", "has_sslcontext": true, "version_info": [2, 7, 5, "final", 0]}, "ansible_processor_threads_per_core": 1, "ansible_fqdn": "linux-node1.example.com", "ansible_mounts": [{"block_used": 576476, "uuid": "8d886d43-1ef5-451a-951c-4170c89c9412", "size_total": 50432839680, "block_total": 12312705, "mount": "/", "block_available": 11736229, "size_available": 48071593984, "fstype": "xfs", "inode_total": 24637440, "options": "rw,relatime,attr2,inode64,noquota", "device": "/dev/mapper/cl-root", "inode_used": 57053, "block_size": 4096, "inode_available": 24580387}, {"block_used": 35407, "uuid": "bd203c5e-8ff1-4060-bcaf-990e2ccb61c1", "size_total": 1063256064, "block_total": 259584, "mount": "/boot", "block_available": 224177, "size_available": 918228992, "fstype": "xfs", "inode_total": 524288, "options": "rw,relatime,attr2,inode64,noquota", "device": "/dev/sda1", "inode_used": 330, "block_size": 4096, "inode_available": 523958}], "ansible_eth0": {"macaddress": "00:0c:29:a0:10:ca", "features": {"tx_checksum_ipv4": "off [fixed]", "generic_receive_offload": "on", "tx_checksum_ipv6": "off [fixed]", "tx_scatter_gather_fraglist": "off [fixed]", "rx_all": "off", "highdma": "off [fixed]", "rx_fcs": "off", "tx_lockless": "off [fixed]", "tx_tcp_ecn_segmentation": "off [fixed]", "tx_tcp6_segmentation": "off [fixed]", "tx_gso_robust": "off [fixed]", "tx_ipip_segmentation": "off [fixed]", "tx_checksumming": "on", "vlan_challenged": "off [fixed]", "loopback": "off [fixed]", "fcoe_mtu": "off [fixed]", "scatter_gather": "on", "tx_checksum_sctp": "off [fixed]", "tx_vlan_stag_hw_insert": "off [fixed]", "rx_vlan_stag_hw_parse": "off [fixed]", "rx_vlan_stag_filter": "off [fixed]", "large_receive_offload": "off [fixed]", "tx_scatter_gather": "on", "rx_checksumming": "off", "tx_tcp_segmentation": "on", "netns_local": "off [fixed]", "busy_poll": "off [fixed]", "generic_segmentation_offload": "on", "tx_udp_tnl_segmentation": "off [fixed]", "tcp_segmentation_offload": "on", "l2_fwd_offload": "off [fixed]", "rx_vlan_offload": "on", "ntuple_filters": "off [fixed]", "tx_vlan_offload": "on [fixed]", "tx_nocache_copy": "off", "tx_mpls_segmentation": "off [fixed]", "udp_fragmentation_offload": "off [fixed]", "tx_sctp_segmentation": "off [fixed]", "tx_sit_segmentation": "off [fixed]", "tx_checksum_fcoe_crc": "off [fixed]", "hw_tc_offload": "off [fixed]", "tx_checksum_ip_generic": "on", "tx_fcoe_segmentation": "off [fixed]", "rx_vlan_filter": "on [fixed]", "receive_hashing": "off [fixed]", "tx_gre_segmentation": "off [fixed]"}, "type": "ether", "pciid": "0000:02:01.0", "module": "e1000", "mtu": 1500, "device": "eth0", "promisc": false, "timestamping": ["tx_software", "rx_software", "software"], "ipv4": {"broadcast": "192.168.56.255", "netmask": "255.255.255.0", "network": "192.168.56.0", "address": "192.168.56.11"}, "ipv6": [{"scope": "link", "prefix": "64", "address": "fe80::20c:29ff:fea0:10ca"}], "active": true, "speed": 1000, "hw_timestamp_filters": []}, "ansible_nodename": "linux-node1.example.com", "ansible_product_name": "VMware Virtual Platform", "ansible_machine": "x86_64", "ansible_system_capabilities": ["cap_chown", "cap_dac_override", "cap_dac_read_search", "cap_fowner", "cap_fsetid", "cap_kill", "cap_setgid", "cap_setuid", "cap_setpcap", "cap_linux_immutable", "cap_net_bind_service", "cap_net_broadcast", "cap_net_admin", "cap_net_raw", "cap_ipc_lock", "cap_ipc_owner", "cap_sys_module", "cap_sys_rawio", "cap_sys_chroot", "cap_sys_ptrace", "cap_sys_pacct", "cap_sys_admin", "cap_sys_boot", "cap_sys_nice", "cap_sys_resource", "cap_sys_time", "cap_sys_tty_config", "cap_mknod", "cap_lease", "cap_audit_write", "cap_audit_control", "cap_setfcap", "cap_mac_override", "cap_mac_admin", "cap_syslog", "35", "36+ep"], "ansible_all_ipv4_addresses": ["192.168.56.11"], "ansible_python_version": "2.7.5"}}\r\n', b'Connection to 192.168.56.11 closed.\r\n')
ok: [192.168.56.11]
META: ran handlers

TASK [get date] ************************************************************************************************
task path: /etc/ansible/f4.yml:7
Using module file /usr/local/lib/python3.6/dist-packages/ansible-2.4.1.0-py3.6.egg/ansible/modules/commands/command.py
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<192.168.56.11> (0, b'/root\n', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1531396858.131543-153072002529949 `" && echo ansible-tmp-1531396858.131543-153072002529949="` echo /root/.ansible/tmp/ansible-tmp-1531396858.131543-153072002529949 `" ) && sleep 0'"'"''
<192.168.56.11> (0, b'ansible-tmp-1531396858.131543-153072002529949=/root/.ansible/tmp/ansible-tmp-1531396858.131543-153072002529949\n', b'')
<192.168.56.11> PUT /tmp/tmpvtmja2wo TO /root/.ansible/tmp/ansible-tmp-1531396858.131543-153072002529949/command.py
<192.168.56.11> SSH: EXEC sftp -b - -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 '[192.168.56.11]'
<192.168.56.11> (0, b'sftp> put /tmp/tmpvtmja2wo /root/.ansible/tmp/ansible-tmp-1531396858.131543-153072002529949/command.py\n', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1531396858.131543-153072002529949/ /root/.ansible/tmp/ansible-tmp-1531396858.131543-153072002529949/command.py && sleep 0'"'"''
<192.168.56.11> (0, b'', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 -tt 192.168.56.11 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1531396858.131543-153072002529949/command.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1531396858.131543-153072002529949/" > /dev/null 2>&1 && sleep 0'"'"''
<192.168.56.11> (0, b'\r\n{"changed": true, "end": "2018-07-12 20:00:58.966945", "stdout": "2018\\u5e74 07\\u6708 12\\u65e5 \\u661f\\u671f\\u56db 20:00:58 CST", "cmd": ["date"], "rc": 0, "start": "2018-07-12 20:00:58.964445", "stderr": "", "delta": "0:00:00.002500", "invocation": {"module_args": {"warn": true, "executable": null, "_uses_shell": false, "_raw_params": "date", "removes": null, "creates": null, "chdir": null, "stdin": null}}}\r\n', b'Connection to 192.168.56.11 closed.\r\n')
changed: [192.168.56.11] => {
    "changed": true,
    "cmd": [
        "date"
    ],
    "delta": "0:00:00.002500",
    "end": "2018-07-12 20:00:58.966945",
    "failed": false,
    "invocation": {
        "module_args": {
            "_raw_params": "date",
            "_uses_shell": false,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "warn": true
        }
    },
    "rc": 0,
    "start": "2018-07-12 20:00:58.964445",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "2018年 07月 12日 星期四 20:00:58 CST",
    "stdout_lines": [
        "2018年 07月 12日 星期四 20:00:58 CST"
    ]
}

TASK [touch file] **********************************************************************************************
task path: /etc/ansible/f4.yml:10
Using module file /usr/local/lib/python3.6/dist-packages/ansible-2.4.1.0-py3.6.egg/ansible/modules/commands/command.py
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<192.168.56.11> (0, b'/root\n', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1531396858.9646013-174118352784299 `" && echo ansible-tmp-1531396858.9646013-174118352784299="` echo /root/.ansible/tmp/ansible-tmp-1531396858.9646013-174118352784299 `" ) && sleep 0'"'"''
<192.168.56.11> (0, b'ansible-tmp-1531396858.9646013-174118352784299=/root/.ansible/tmp/ansible-tmp-1531396858.9646013-174118352784299\n', b'')
<192.168.56.11> PUT /tmp/tmpo3kyh0pw TO /root/.ansible/tmp/ansible-tmp-1531396858.9646013-174118352784299/command.py
<192.168.56.11> SSH: EXEC sftp -b - -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 '[192.168.56.11]'
<192.168.56.11> (0, b'sftp> put /tmp/tmpo3kyh0pw /root/.ansible/tmp/ansible-tmp-1531396858.9646013-174118352784299/command.py\n', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1531396858.9646013-174118352784299/ /root/.ansible/tmp/ansible-tmp-1531396858.9646013-174118352784299/command.py && sleep 0'"'"''
<192.168.56.11> (0, b'', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 -tt 192.168.56.11 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1531396858.9646013-174118352784299/command.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1531396858.9646013-174118352784299/" > /dev/null 2>&1 && sleep 0'"'"''
<192.168.56.11> (0, b'\r\n{"changed": true, "end": "2018-07-12 20:00:59.818106", "stdout": "", "cmd": "touch /tmp/devops.file", "rc": 0, "start": "2018-07-12 20:00:59.815108", "stderr": "", "delta": "0:00:00.002998", "invocation": {"module_args": {"warn": true, "executable": null, "_uses_shell": true, "_raw_params": "touch /tmp/devops.file", "removes": null, "creates": null, "chdir": null, "stdin": null}}, "warnings": ["Consider using file module with state=touch rather than running touch"]}\r\n', b'Connection to 192.168.56.11 closed.\r\n')
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.56.11] => {
    "changed": true,
    "cmd": "touch /tmp/devops.file",
    "delta": "0:00:00.002998",
    "end": "2018-07-12 20:00:59.818106",
    "failed": false,
    "invocation": {
        "module_args": {
            "_raw_params": "touch /tmp/devops.file",
            "_uses_shell": true,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "warn": true
        }
    },
    "rc": 0,
    "start": "2018-07-12 20:00:59.815108",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "",
    "stdout_lines": []
}

TASK [echo date_output] ****************************************************************************************
task path: /etc/ansible/f4.yml:12
Using module file /usr/local/lib/python3.6/dist-packages/ansible-2.4.1.0-py3.6.egg/ansible/modules/commands/command.py
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<192.168.56.11> (0, b'/root\n', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1531396859.8218389-268766387785393 `" && echo ansible-tmp-1531396859.8218389-268766387785393="` echo /root/.ansible/tmp/ansible-tmp-1531396859.8218389-268766387785393 `" ) && sleep 0'"'"''
<192.168.56.11> (0, b'ansible-tmp-1531396859.8218389-268766387785393=/root/.ansible/tmp/ansible-tmp-1531396859.8218389-268766387785393\n', b'')
<192.168.56.11> PUT /tmp/tmp__kyifmp TO /root/.ansible/tmp/ansible-tmp-1531396859.8218389-268766387785393/command.py
<192.168.56.11> SSH: EXEC sftp -b - -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 '[192.168.56.11]'
<192.168.56.11> (0, b'sftp> put /tmp/tmp__kyifmp /root/.ansible/tmp/ansible-tmp-1531396859.8218389-268766387785393/command.py\n', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 192.168.56.11 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1531396859.8218389-268766387785393/ /root/.ansible/tmp/ansible-tmp-1531396859.8218389-268766387785393/command.py && sleep 0'"'"''
<192.168.56.11> (0, b'', b'')
<192.168.56.11> ESTABLISH SSH CONNECTION FOR USER: root
<192.168.56.11> SSH: EXEC ssh -o StrictHostKeyChecking=no -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/devops/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=20 -tt 192.168.56.11 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1531396859.8218389-268766387785393/command.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1531396859.8218389-268766387785393/" > /dev/null 2>&1 && sleep 0'"'"''
<192.168.56.11> (0, b'\r\n{"changed": true, "end": "2018-07-12 20:01:00.692177", "stdout": "", "cmd": "echo 2018\\u5e74 07\\u6708 12\\u65e5 \\u661f\\u671f\\u56db 20:00:58 CST>/tmp/devops.file", "rc": 0, "start": "2018-07-12 20:01:00.689318", "stderr": "", "delta": "0:00:00.002859", "invocation": {"module_args": {"warn": true, "executable": null, "_uses_shell": true, "_raw_params": "echo 2018\\u5e74 07\\u6708 12\\u65e5 \\u661f\\u671f\\u56db 20:00:58 CST>/tmp/devops.file", "removes": null, "creates": null, "chdir": null, "stdin": null}}}\r\n', b'Connection to 192.168.56.11 closed.\r\n')
changed: [192.168.56.11] => {
    "changed": true,
    "cmd": "echo 2018年 07月 12日 星期四 20:00:58 CST>/tmp/devops.file",
    "delta": "0:00:00.002859",
    "end": "2018-07-12 20:01:00.692177",
    "failed": false,
    "invocation": {
        "module_args": {
            "_raw_params": "echo 2018年 07月 12日 星期四 20:00:58 CST>/tmp/devops.file",
            "_uses_shell": true,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "warn": true
        }
    },
    "rc": 0,
    "start": "2018-07-12 20:01:00.689318",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "",
    "stdout_lines": []
}
META: ran handlers
META: ran handlers

PLAY RECAP *****************************************************************************************************
192.168.56.11              : ok=4    changed=3    unreachable=0    failed=0

# 到执行服务器上查看文件内容
[root@linux-node1 tmp]# cat devops.file
2018年 07月 12日 星期四 20:00:58 CST

示例

注:若你认为那篇小说尚可请点击下右下角的引荐,有了您的支撑才能鼓舞我更加大的创作热情,分外感激!

本文目录: 1.一 yaml语法和示例 1.2ansible-playbook命令表达及playbook书写简单…

转发请注解出处:http://www.cnblogs.com/f-ck-need-u/p/7567417.html

一.伍 roles示例:批量自动化安装

下边演示的是选取role批量自动安装nginx和mysql(CentOS 六)或maridb(CentOS
7)的言传身教。由于被控节点有CentOS 陆和CentOS
七二种发行版的操作系统,因此除了要挑选对应的数据库,还要让nginx的安排文件适应各操作系统,因为nginx在那四个本子的种类上配置内容有所不一样。在此,nginx、mysql和mariadb是二个role,且让nginx
role注重于mysql或mariadb role。

下边包车型客车事例中,某些地点是不太合理或多余的一言一动,但是作为读书示例,能够很好的知晓roles之间的团伙结构和相关的操作。

先是是文件的结构。

美高梅手机版4858 21

美高梅手机版4858 22

里面site.yml是入站文件,用于调用nginx、mysql和mariadb那三个role,这些文件中的内容如下。它有二个成效:(一)在调用roles在此之前,先根据发行版配置好yum源(pre_tasks);(贰)调用nginx
role,此处没有调用mysql和mariadb那七个role,因为在nginx
role的meta/main.yml文件中定义了nginx
role依赖于那三个role,所以这边能够毫不定义;(三)在推行完nginx
role之后,输出叁个提示音信(post_tasks)。

cat /yaml/site.yml
---
  - hosts: centos
    remote_user: root

 # 根据发行版配置好yum源,使用when进行条件判断   
    pre_tasks: 
        - name: config the yum repo for centos 7
          yum_repository:
              name: epel
              description: epel
              baseurl: http://mirrors.aliyun.com/epel/7/$basearch/
              gpgcheck: no
          when: ansible_distribution_major_version == "7"

        - name: config the yum repo for centos 6
          yum_repository:
              name: epel
              description: epel
              baseurl: http://mirrors.aliyun.com/epel/6/$basearch/
              gpgcheck: no
          when: ansible_distribution_major_version == "6"

    roles: 
        - nginx

# 输出over消息
    post_tasks:
      - shell: echo 'deploy nginx/mysql over'
        register: ok_var
      - debug: msg='{{ ok_var.stdout }}'

以下是nginx role中的各文件内容。在那之中template复制的源文件都以从centos 6nginx和centos 七 nginx上领取的,只可是是重新命名了罢了。

/yaml/roles/nginx/tasks/main.yml 
---
   - name: make sure nginx state is installed
     yum: name=nginx state=installed

   - name: template nginx.conf
# 基于变量赋值配置文件模板,检查配置文件语法,并在必要的时候触发handler
     template: src=nginx{{ ansible_distribution_major_version }}.conf.j2
                  dest=/etc/nginx/nginx.conf
                  validate="/usr/sbin/nginx -t -c %s"  
     notify: 
        - restart nginx

# 基于jinja2渲染模板文件,且改变时也触发重启操作
   - name: copy index.html
     template: src=index.html.j2 dest=/usr/share/nginx/html/index.html
     notify: 
        - restart nginx

   - name: make sure nginx service is running
     service: name=nginx state=started

# 引用变量 nginx_port,在vars/main.yml中定义了
   - name: make sure port is open
     wait_for: port="{{ nginx_port }}"

/yaml/roles/nginx/handlers/main.yml 
---
   - name: restart nginx
     service: name=nginx state=restarted

/yaml/roles/nginx/vars/main.yml 
nginx_port: 80

# 定义nginx依赖于MySQL或mariadb,具体依赖于哪个,是通过条件进行判断的,centos 6表示依赖于mysql,centos 7表示依赖于mariadb
# 同时传递了两个值给变量hi_var,由于是在依赖的时候传递的,所以这两个变量可直接在依赖的role(mysql role或mariadb role)的playbook中引用
/yaml/roles/nginx/meta/main.yml 
---
   dependencies: 
     - { role: mysql,hi_var: "hello mysql",when: "ansible_distribution_major_version == '6'" }
     - { role: mariadb,hi_var: "hello mariadb",when: "ansible_distribution_major_version == '7'" }

地点拷贝了index.html.j二,其内容为:

shell> cat /yaml/roles/nginx/templates/index.html.j2 
<h1>hello from {{ ansible_default_ipv4.address }}<h1>

在template执行时,它会选取jinja贰引擎对文件中的变量实行轮换,使得在拷贝到不一致主机时,该index.html的剧情是依据远程主机ip的。此处使用的变量是采集到的facts中的变量”ansible_default_ipv4.address”。

以下是mysql
role中各文件的始末。注意,MySQL的my.cnf和mariadb的my.cnf暗中认可情形下并不同(mariadb的my.cnf暗许多了1项配置”!includedir
/etc/my.cnf.d”,MySQL须要撤销该项),所以须求各自提供。

/yaml/roles/mysql/tasks/main.yml 
---
    - name: make sure mysql is installed
      yum: name=mysql-server state=installed

# 特别需要注意下面的初始化命令,由于执行的是shell模块,所以要考虑其幂等性,显然初始化动作是一定要实现幂等性的
    - name: do something to initialize mysql
      file: path=/mydata/data state=directory owner=mysql group=mysql mode=0755
    - shell: /usr/bin/mysql_install_db --datadir=/mydata/data --user=mysql creates=/mydata/data/ibdata1

    - name: copy my.cnf
      copy: src=my.cnf dest=/etc/my.cnf
      notify: 
         - restart mysql

    - name: make sure mysql is running
      service: name=mysqld state=started

    - name: make sure mysql port is open
      wait_for: 
         port: "{{ mysql_port }}"
         timeout: 10

# 这里输出了nginx/meta/main.yml中传递的变量
    - name: echo var passed by nginx 
      shell: echo "{{ hi_var }}"
      register: var_result
    - debug: msg="{{ var_result.stdout }}"

/yaml/roles/mysql/handlers/main.yml 
---
   - name: restart mysql
     service: name=mysqld state=restarted

/yaml/roles/mysql/vars/main.yml 
---
    mysql_port: 3306

以下是mariadb
role中各文件的内容,和mysql大体上是如出1辙的。注意,MySQL的my.cnf和mariadb的my.cnf私下认可意况下并不壹致,所以须要各自提供。

/yaml/roles/mariadb/tasks/main.yml 
---
    - name: make sure mariadb is installed
      yum: name=mariadb-server state=installed

    - name: do something to initialize mariadb
      file: path=/mydata/data state=directory owner=mysql group=mysql mode=0755
    - shell: /usr/bin/mysql_install_db --datadir=/mydata/data --user=mysql creates=/mydata/data/ibdata1

    - name: copy my.cnf
      copy: src=my.cnf dest=/etc/my.cnf
      notify: 
         - restart mariadb

    - name: make sure mariadb is running
      service: name=mariadb state=started

    - name: make sure mariadb port is open
      wait_for: 
         port: "{{ mariadb_port }}"
         timeout: 10

    - name: echo var passed by nginx 
      shell: echo "{{ hi_var }}"
      register: var_result
    - debug: msg="{{ var_result.stdout }}"

/yaml/roles/mariadb/handlers/main.yml 
---
    - name: restart mariadb
      service: name=mariadb state=restarted

/yaml/roles/mariadb/vars/main.yml 
---
    mariadb_port: 3306

以下是两台机器的测试结果,一台是centos 七(19二.16八.十0.54),壹台是centos
陆(19二.16八.十0.70)。

PLAY [newhosts] *************************************************************************

TASK [Gathering Facts] ******************************************************************
ok: [192.168.100.70]
ok: [192.168.100.54]

TASK [config the yum repo for centos 7] *************************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [config the yum repo for centos 6] *************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : make sure mysql is installed] *********************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : do something to initialize mysql] *****************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : command] ******************************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : copy my.cnf] **************************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : make sure mysql is running] ***********************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : make sure mysql port is open] *********************************************
skipping: [192.168.100.54]
ok: [192.168.100.70]

TASK [mysql : echo var passed by nginx] *************************************************
skipping: [192.168.100.54]
changed: [192.168.100.70]

TASK [mysql : debug] ********************************************************************
skipping: [192.168.100.54]
ok: [192.168.100.70] => {
    "changed": false, 
    "msg": "hello mysql"
}

TASK [mariadb : make sure mariadb is installed] *****************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : do something to initialize mariadb] *************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : command] ****************************************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : copy my.cnf] ************************************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : make sure mariadb is running] *******************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : make sure mariadb port is open] *****************************************
skipping: [192.168.100.70]
ok: [192.168.100.54]

TASK [mariadb : echo var passed by nginx] ***********************************************
skipping: [192.168.100.70]
changed: [192.168.100.54]

TASK [mariadb : debug] ******************************************************************
skipping: [192.168.100.70]
ok: [192.168.100.54] => {
    "changed": false, 
    "msg": "hello mysql"
}

TASK [nginx : make sure nginx state is installed] ***************************************
changed: [192.168.100.54]
changed: [192.168.100.70]

TASK [nginx : template nginx.conf] ******************************************************
ok: [192.168.100.70]
changed: [192.168.100.54]

TASK [nginx : copy index.html] **********************************************************
changed: [192.168.100.70]
changed: [192.168.100.54]

TASK [nginx : make sure nginx service is running] ***************************************
changed: [192.168.100.54]
changed: [192.168.100.70]

TASK [nginx : make sure port is open] ***************************************************
ok: [192.168.100.70]
ok: [192.168.100.54]

RUNNING HANDLER [mysql : restart mysql] *************************************************
changed: [192.168.100.70]

RUNNING HANDLER [mariadb : restart mariadb] *********************************************
changed: [192.168.100.54]

RUNNING HANDLER [nginx : restart nginx] *************************************************
changed: [192.168.100.54]

TASK [command] **************************************************************************
changed: [192.168.100.54]
changed: [192.168.100.70]

TASK [debug] ****************************************************************************
ok: [192.168.100.54] => {
    "changed": false, 
    "msg": "deploy nginx/mysql over"
}
ok: [192.168.100.70] => {
    "changed": false, 
    "msg": "deploy nginx/mysql over"
}

PLAY RECAP ******************************************************************************
192.168.100.54             : ok=19   changed=14   unreachable=0    failed=0   
192.168.100.70             : ok=18   changed=12   unreachable=0    failed=0

信任看过地点的roles协会示例,对roles的用法和playbook就有了较深的认识。其实,ansible有多个网址专门存放了一大堆的playbook,算是playbook仓库吧。能够下载下来稍作修改就能运用,固然不选择,借鉴他们的写法也是很值得的。地址:ansible
galaxy

其它,依照分化标准组织role只怕会让playbook写起来更易于,例如地方的以身作则中,遵照发行版来划分role比下边遵照设置软件项目划分可能会更简约些。当然,即使在inventory中就分开好centos
陆和centos 柒也是能够的。哪个种类更便宜、复用性更加好就需求活动思量了。

基本语句

注:若你认为那篇作品还不易请点击下右下角的引荐,有了你的帮助才能激发小编更加大的著述热情,万分多谢!

一、条件语句

  • when条件语句

美高梅手机版4858 23美高梅手机版4858 24

devops@devops-virtual-machine:/etc/ansible$ cat f6.yml
---
- hosts : 192.168.56.11,192.168.56.131
  remote_user : root
  tasks:
  - name: "touch flag file"
    command: "touch /tmp/this_is_{{ansible_distribution}}_system"
    when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "7") or
          (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6")


# 执行
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook ./f6.yml

PLAY [192.168.56.11,192.168.56.131] ****************************************************************************

TASK [Gathering Facts] *****************************************************************************************
ok: [192.168.56.131]
ok: [192.168.56.11]

TASK [touch flag file] *****************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.56.11]
changed: [192.168.56.131]

PLAY RECAP *****************************************************************************************************
192.168.56.11              : ok=2    changed=1    unreachable=0    failed=0
192.168.56.131             : ok=2    changed=1    unreachable=0    failed=0

示例

贰、循环语句

美高梅手机版4858 25

 

三、条件循环语句复用 

 示例:

 

格外处理和相关操作

 一、至极处理

  • 忽略错误

暗中同意会检查命令和模块的回到状态,境遇错误就暂停playbook的实施

加盟参数:ignore_errors:yes

美高梅手机版4858 26美高梅手机版4858 27

devops@devops-virtual-machine:/etc/ansible$ cat f11.yml
---
- hosts : 192.168.56.11
  remote_user : root
  tasks :
      - name : ignore false
        command : /bin/false
        ignore_errors: yes
      - name : touch a file
        file : path=/tmp/test2 state=touch mode=0700 owner=root group=root


# 执行
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook ./f11.yml

PLAY [192.168.56.11] ***********************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.56.11]

TASK [ignore false] ************************************************************
fatal: [192.168.56.11]: FAILED! => {"changed": true, "cmd": ["/bin/false"], "delta": "0:00:00.006306", "end": "2018-07-13 14:43:58.815566", "failed": true, "msg": "non-zero return code", "rc": 1, "start": "2018-07-13 14:43:58.809260", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring

TASK [touch a file] ************************************************************
changed: [192.168.56.11]

PLAY RECAP *********************************************************************
192.168.56.11              : ok=3    changed=2    unreachable=0    failed=0

示例

  • 自定义错误

failed_when自定义错误

  • 自定义change状态

美高梅手机版4858 28美高梅手机版4858 29

devops@devops-virtual-machine:/etc/ansible$ cat f13.yml
---
- hosts : 192.168.56.11
  remote_user : root
  tasks :
      - name : get process
        shell : touch /tmp/change_test
        changed_when : false


# 执行就没有change状态了
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook ./f13.yml

PLAY [192.168.56.11] ************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************
ok: [192.168.56.11]

TASK [get process] **************************************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

ok: [192.168.56.11]

PLAY RECAP **********************************************************************************************************************
192.168.56.11              : ok=2    changed=0    unreachable=0    failed=0

示例

tags标签处理

意思:通过tags和职分指标开始展览包扎,控制部分只怕钦命的task执行

  • 打标签

    对二个对象打三个标签
    对三个对象打八个标签
    打标签的对象包罗:单个task职责、include对象、roles对象等

  • 标签使用

美高梅手机版4858 30美高梅手机版4858 31

-t : 执行指定的tag标签任务
--skip-tags : 执行--skip-tags之外的标签任务

# 示例
devops@devops-virtual-machine:/etc/ansible$ cat f14.yml
---
- hosts : 192.168.56.11
  remote_user : root
  tasks :
      - name: create file 1
        shell: touch /tmp/file1.txt
        tags:
            - cfile1
            - cfile3
      - name: create file 2
        shell : touch /tmp/file2.txt
        tags:
            - cfile2


# 执行剧本
# 执行剧本,只执行tags为cfile1的任务
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook ./f14.yml -t cfile1

PLAY [192.168.56.11] ************************************************************************************

TASK [Gathering Facts] **********************************************************************************
ok: [192.168.56.11]

TASK [create file 1]  ************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.56.11]

PLAY RECAP **********************************************************************************************
192.168.56.11              : ok=2    changed=1    unreachable=0    failed=0

# 执行剧本不包含tags为cfile1的任务
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook ./f14.yml --skip-tags cfile1

PLAY [192.168.56.11] ************************************************************************************

TASK [Gathering Facts] **********************************************************************************
ok: [192.168.56.11]

TASK [create file 2] ************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.56.11]

PLAY RECAP **********************************************************************************************
192.168.56.11              : ok=2    changed=1    unreachable=0    failed=0

示例

四、roles剧中人物和场景演习

使用roles

1、include的用法

include_tasks/include: 动态的包含tasks任务列表执行

美高梅手机版4858 32美高梅手机版4858 33

devops@devops-virtual-machine:/etc/ansible$ cat touchfile.yml
---
- name : create file 1
  shell : touch /tmp/file1.txt
  tags :
       - cfile1
       - cfile3
devops@devops-virtual-machine:/etc/ansible$ cat touchfile2.yml
---
- name : create file 2
  shell : touch /tmp/file2.txt
  tags :
       - cfile2

# 把touchfile.yml和touchfile2.yml两个剧本用include_tasks导入
devops@devops-virtual-machine:/etc/ansible$ cat f15.yml
---
- hosts : 192.168.56.11
  remote_user : root
  tasks :
        - include_tasks : touchfile.yml
        - include_tasks : touchfile2.yml


# 执行
devops@devops-virtual-machine:/etc/ansible$ ansible-playbook ./f15.yml

PLAY [192.168.56.11] ********************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.56.11]

TASK [include_tasks] ********************************************************************************************************
included: /etc/ansible/touchfile.yml for 192.168.56.11

TASK [create file 1] ********************************************************************************************************
 [WARNING]: Consider using file module with state=touch rather than running touch

changed: [192.168.56.11]

TASK [include_tasks] ********************************************************************************************************
included: /etc/ansible/touchfile2.yml for 192.168.56.11

TASK [create file 2] ********************************************************************************************************
changed: [192.168.56.11]

PLAY RECAP ******************************************************************************************************************
192.168.56.11              : ok=5    changed=2    unreachable=0    failed=0

示例

2、为啥要求用到roles

  • 什么是roles

    是壹种采用在巨型playbook中的剧本配置情势,有那自个儿一定组织

  • 干什么需求用到roles

    和面向对象开发合计相似
    利用大型的门类任务中,尽大概的将国有的职责、变量等剧情独立

三、官方提出的脚本结构

原文:

大型项目中ansible playbook官方建议的目录结构

美高梅手机版4858 34

ansible官方网址的提出playbook剧本结构如下:

production # 正式环境的inventory文件 
staging #测试环境用得inventory文件 
group_vars/ # 机器组的变量文件 
      group1 
      group2 
host_vars/ #执行机器成员的变量 
      hostname1 
      hostname2 
================================================ 
site.yml # 主要的playbook剧本 
webservers.yml # webserver类型服务所用的剧本 
dbservers.yml # 数据库类型的服务所用的剧本 
roles/ 
      webservers/      #webservers这个角色相关任务和自定义变量 
           tasks/      # 任务存放目录
               main.yml   # 存放任务信息
           handlers/      
               main.yml 
           vars/          # 存放变量的目录
               main.yml   # 存放变量信息
     dbservers/           #dbservers这个角色相关任务和定义变量 
         ... 
     common/ # 公共的 
           tasks/ # 
                main.yml # 
           handlers/ # 
                main.yml # handlers file. 
           vars/             # 角色所用到的变量 
               main.yml # 
=============================================== 
     templates/ # 
           ntp.conf.j2        # 模版文件 
     files/                   # 用于上传存放文件的目录 
           bar.txt # 
           foo.sh # 
     meta/                    # 角色的依赖 
           main.yml # 

 

 

四、剧本设计思路

本子roles设计思路一

美高梅手机版4858 35

本子roles设计思路2

将公共任务、资源、变量等对象尽可能独立

5、场景练习

 Nginx工程措施的编写翻译安装

本子结构

devops@devops-virtual-machine:/etc/ansible$ tree ./
./
├── ansible.cfg
├── files                                      # 存放上传文件的目录
│   ├── imoocc.html                     # 测试用的html文件
│   ├── nginx                               # 系统init中,控制nginx启动脚本
│   └── nginx-1.9.11.tar.gz           # nginx的安装包文件
├── production                            # 线上的主机配置文件
├── roles                                    # roles角色执行的目录
│   ├── apache                           # 空目录可以定义不同角色如:apache、Nginx、MySQL等
│   ├── common                         # 存放公共信息目录
│   │   └── tasks
│   │   │     └── main.yaml
│   │   └── vars                          # 存放一些临时的变量,如:目录服务器(Nginx)压缩包文件存放临时目录,可以把这个临时目录当成变量存放在此目录下
│   │          └── main.yml
│   │  
│   ├── handlers
│   ├── meta                              # 存放不同角色依赖的的目录
│   ├── nginx
│   │   ├── handlers                    # handlers通过notify触发
│   │   │   └── main.yml              # 如:nginx的重启行为
│   │   ├── tasks                         # 任务存放目录
│   │   │   ├── basic.yml
│   │   │   ├── main.yml 
│   │   │   └── nginx.yml
│   │   └── vars
│   │       └── main.yml              # 存放nginx相关的变量
│   ├── tasks
│   │   └── main.yml
│   └── vars
│       └── main.yml
├── staging                                # 线下测试环境使用的主机配置文件
├── templates                            # 模版目录(配置、html)
│   └── imoocc_n.conf                    # nginx的自定义conf文件
├── webserver.retry
└── webserver.yml                     # web服务相关主执行文件

14 directories, 16 files

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有