设为首页 收藏本站
查看: 2262|回复: 1

[经验分享] ansible task/play/role篇

[复制链接]

尚未签到

发表于 2018-1-2 17:42:00 | 显示全部楼层 |阅读模式

  • task
  • play
  • role
task


  • name : 可选配置, 用于提示task 的功能. 另, ansible-playbook --start-at-task  可以调用 name, 从 task 的中间开始执行.
  •   模块(功能) : 必选配置, 有模块的名称组成的 key 和 模块参数组成的 value.
      从 Ansible 前段所使用的 YAML 解析器角度看, 参数将被按照字符串处理, 而不是字典
      

    apt: name=nginx update_cache=yes
  •   复杂参数:
      ansible 提供一个将模块调用分隔成多行的选择, 可以传递 key 为变量名的字典, 而不是传递字符串参数. 这种方式, 在调用拥有复杂参数的模块时, 十分有用. 如 ec2 模块.
      

    - name: install pip pkgs  pip:
      name: "{{ item.name }}"
      version: "{{ item.version }}"
      virtualenv: "{{ venv_path }}"
      with_items:
      - {name: mazzanine, version: 3.1.10}
      - {name: gunicorn, version: 19.1.1}

  •   environment : 设置环境变量
      传入包含变量名与值的字典, 来设置环境变量.
      

    - name: set the site>script: scripts/setsite.py  environment:
      PATH: "{{ venv_path }}/bin"
      PROJECT_DIR: "{{ proj_path }}"
      ADMIN_PASS: "{{ admin_pass }}"

  •   sudo, sudo_user

  •   notify
      触发 handler 任务.

  •   when
      当 when 表达式返回 True 时, 执行该 task , 否则不执行.

  •   local_action : 运行本地任务
      在控制主机本机上(而目标主机)执行命令.
      如果目标主机为多台, 那么, local_action 执行的task 将执行多次, 可以指定 run_once , 来限制 local_action 的执行次数.
      

    # 调用 wait_for 模块 : 注: inventory_hostname 的值仍然是远程主机, 因为这些变量的范围仍然是远程主机, 即使 task 在本机执行.  
    - name: wait for ssh server to be running
      local_action: wait_for port=22 host="{{ inventory_hostname }}" search_regex=OpenSSH
      

      
    # 调用 command 模块
      
    - name: run local cmd
      hosts: all
      gather_facts: False
      tasks:
      - name: run local shell cmd
      local_action: command touch /tmp/new.txtxt

  •   delegate_to: 在涉及主机之外的主机上运行 task

    使用场景:

    • 在报警主机中, 启用基于主机的报警, 如 Nagios
    •   向负载均衡器中, 添加一台主机, 如 HAProxy
        

      # 配置 Nagios 示例, inventory_hostname 仍然指 web 主机, 而非 nagios_server.example.com .  
      - name: enable alerts for web servers
        hosts: web
        tasks:
        - name: enable alerts
        nagios: action=enanle_alerts service=web host={{ inventory_hostname }}
        delegate_to: nagios_server.example.com
        

        
      ---
        
      # This playbook does a rolling update for all webservers serially (one at a time).
        
      # Change the value of serial: to adjust the number of server to be updated.
        
      #
        
      # The three roles that apply to the webserver hosts will be applied: common,
        
      # base-apache, and web. So any changes to configuration, package updates, etc,
        
      # will be applied as part of the rolling update process.
        
      #
        

        
      # gather facts from monitoring nodes for iptables rules
        
      - hosts: monitoring
        tasks: []
        

        
      - hosts: webservers
        serial: 1
        

        # These are the tasks to run before applying updates:
        pre_tasks:
        - name: disable nagios alerts for this host webserver service
        nagios: 'action=disable_alerts host={{ inventory_hostname }} services=webserver'
        delegate_to: "{{ item }}"
        with_items: groups.monitoring
        

        - name: disable the server in haproxy
        haproxy: 'state=disabled backend=myapplb host={{ inventory_hostname }} socket=/var/lib/haproxy/stats'
        delegate_to: "{{ item }}"
        with_items: groups.lbservers
        

        roles:
        - common
        - base-apache
        - web
        

        # These tasks run after the roles:
        post_tasks:
        - name: wait for webserver to come up
        wait_for: 'host={{ inventory_hostname }} port=80 state=started timeout=80'
        

        - name: enable the server in haproxy
        haproxy: 'state=enabled backend=myapplb host={{ inventory_hostname }} socket=/var/lib/haproxy/stats'
        delegate_to: "{{ item }}"
        with_items: groups.lbservers
        

        - name: re-enable nagios alerts
        nagios: 'action=enable_alerts host={{ inventory_hostname }} services=webserver'
        delegate_to: "{{ item }}"
        with_items: groups.monitoring


  •   run_once : 值为 True/False
      该 task 是否只运行一次, 与 local_action 配合十分好用.

  •   changed_when & failed_when
      使用 changed_when 和 failed_when 语句改变 Ansible 对 task 是 chenged 状态还是 failed 状态的认定.
      
    需要了解命令的输出结果
      

    - name: initialize the database  django_manage:
      command: createdb --noinput --nodata
      app_path: "{{ proj_path }}"
      virtualenv: "{{ venv_path }}"
      register: result
      changed_when: not result.failed and "Creating tables" in result.out
      failed_when: result.failed and "Database already created" not in result.msg

  •   循环

playbook 执行后, 跟踪主机状态.

play
  play 可以想象为连接到主机(host)上执行任务(task)的事务.
  选项:


  •   host : 必选配置, 需要配置的一组主机

  •   task : 必选配置, 需要在主机上执行的任务

  •   name : 可选配置, 一段注释, 用来描述 play 的功能, ansible 在 play 开始执行的时候, 会把 name 打印出来.

  •   sudo : 可选配置, 如果为真, ansible 会在运行每个 task 的时候, 都是用 sudo 命令切换为 (默认) root.

  •   vars : 可选配置, 变量与其值组成的列表. 任何合法的 YAML 对象都可以作为变量的值. 变量不仅可以在 tasks 中使用, 还可以在 模板文件 中使用.

  •   vars_files : 可选, 把变量放到一个或者多个文件中.

  •   gather_facts : 是否收集 fact.

  •   handlers : 可选, ansible 提供的 条件机制, 和 task 类似, 但只有在被 task 通知的时候才会运行. 如果 ansible 识别到 task 改变了系统的状态, task 就会触发通知机制. task 将 handler 的名字作为参数传递, 依此来通知 handler.
      handler 只会在所有任务执行完成之后执行, 而且即使被通知了多次, 也只会执行一次. handler 按照play 中定义的顺序执行, 而不是被通知的顺序.
      handler 常见的用途就是重启服务和重启服务器.

  •   serial, max_fail_percentage
      默认情况下, Ansible 会并行的在所有相关联主机上执行每一个 task.
      可以使用 serial 限制并行执行 play 的主机数量.
      一般来说, 当 task 失败时, Ansible 会停止执行失败的那台主机上的任务, 但是继续对其他主机执行. 在负载均衡场景中, 可能希望 Ansible 在所有主机都发生失败前让整个 play 停止执行, 否则将会导致, 所有主机都从 负载均衡器上移除, 并且全部执行失败, 最终负载均衡器上没有任何主机的局面. 此时, 可以使用 serial 和 max_fail_percentage 语句来指定, 最大失败主机比例达超过 max_fail_percentage 时, 让整个 play 失败.
      如果希望 Ansible 在任何主机出现 task 执行失败的时候, 都放弃执行, 则需要设置max_fail_percentage=0.
      

    - name: upgrade packages on servers behind load balancer  hosts: myhosts
      serial: 1
      max_fail_percentage: 25
      tasks:

      - name: get the ec2 instance>  ec2_facts:
      

      - name: task the out of the elastic load balancer
      local_action: ec2_elb
      args:
      instance_id: "{{ ansible_ec2_instance_id }}"
      state: absent
      

      - name: upgrade packages
      apt: update_cache=yes upgrade=yes
      

      - name: put the host back in the elastic load balancer
      local_action: ec2_elb
      args:
      instance_id: "{{ ansible_ec2_instance_id }}"
      state: present
      ec2_elbs: "{{ item }}"
      with_items: ec2_elbs

  • roles
  • pre-task
  •   post-task

role
  role 是将 playbook 分隔为多个文件的主要机制, 他大大简化了复杂 playbook 的编写, 同时使得 role 更加易于复用.

role 的基本构成.
  每个 role 都会用一个名字, 如 'database', 与该 role 相关的文件都放在 roles/database 目录下. 其结构如下: 每个单独文件都是可选的


  • task:  
    task 定义
      
    roles/database/tasks/main.yml

  • files  
    需要上传到目标主机的文件:
      
    roles/database/files/

  • templates  
    Jinja2 模板文件
      
    roles/database/templates

  • handlers  
    handler
      
    roles/database/handler/main.yml

  • vars  
    不应被覆盖的变量
      
    roles/database/vars/main.yml

  • defaults  
    可以被覆盖的默认变量
      
    roles/database/default/main.yml

  • meta  
    role 的依赖信息
      
    roles/database/meta/main.yml

  default 变量与 vars 变量:


  • default : 希望在 role 中变更变量的值.
  • vars : 不希望变量的值变更.
  role 中变量命名的一个良好实践: 变量建议以 role 的名称开头, 因为在 Ansible 中不同的 role 之间没有命名空间概念, 这意味着在其他 role 中定义的变量, 或者再 playbook 中其他地方定义的变量, 可以在任何地方被访问到. 如果在两个不同的 role 中使用了同名的变量, 可能导致意外的行为.

role 的存放位置


  • playbook 并列的 roles 目录下;
  • /etc/ansible/roles/ 下
  • ansible.cfg 中 default 段 roles_path 指向的位置
  • 环境变量 ANSIBLE_ROLES_PATH 指向的位置
在 playbook 中使用 role
  

# mezzaning-single-host.yml  
- name: deploy mezzanine on vagrant
  hosts: web
  vars_file:
  - secrets.yml
  roles:
  - role: database
  database_name: "{{ mezzanine_proj_name }}"        # 定义覆盖变量
  database_pass: "{{ mezzanine_proj_name }}"        # 定义覆盖变量
  

  - role: mezzanine
  live_hostname: 192.168.33.10.xip.io
  domains:
  - 192.168.33.10.xip.io
  - www.192.168.33.10.xip.io
  

  
# mezzaning-across-host.yml
  
- name: deploy postgres vagrant
  hosts: db
  vars_files:
  - secrets.yml
  roles:
  - role: database
  database_name: "{{ mezzanine_proj_name }}"        # 定义覆盖变量
  database_pass: "{{ mezzanine_proj_name }}"        # 定义覆盖变量
  

  
- name: deploy mezzanine on vagrant
  hosts: web
  vars_files:
  - secrets.yml
  roles:
  - role: mezzanine
  database_host: "{{ hostvars.db.ansible_eth1.ipv4.address }}"
  live_hostname: 192.168.33.10.xip.io
  domains:
  - 192.168.33.10.xip.io
  - www.192.168.33.10.xip.io
  

pre-task & post-task
  pre-task : 定义在 role 执行之前, 执行的 task
  
post-task : 定义在 role 执行之后, 执行的 task.
  

- name: deploy mezzanine on vagrant  hosts: web
  vars_files:
  - secrets.yml
  pre_tasks:
  - name: update the apt cache
  apt: update_cache=yes
  

  roles:
  - role: mezzanine
  database_host: "{{ hostvars.db.ansible_eth1.ipv4.address }}"
  live_hostname: 192.168.33.10.xip.io
  domains:
  - 192.168.33.10.xip.io
  - www.192.168.33.10.xip.io
  post_tasks:
  - name: notify Slack that the servers have been updated
  local_action:>
  slack
  domain=acme.slack.com
  token={{ slack_token }}
  msg="web server {{ inventory_hostname }} configured"
  

inclued
  用于调用位于同一目录下的其他 定义文件, 可用于 Tasks,Playbook, Vars, Handler, Files 等.
  

# task example  
---
  
- name: install apt packages
  apt: pkg={{ item }} update_cache=yes cache_valid_time=3600
  sudo: True
  with_items:
  - git
  - libjpeg-dev
  - libpq-dev
  - memcached
  - nginx
  

  
- include: django.yml
  
- include: nginx.yml
  

  
# example 2
  
---
  
- name: check host environment
  include: check_environment.yml
  

  
- name: include OS family/distribution specific variables
  include_vars: "{{ item }}"
  with_first_found:
  - "../defaults/{{ ansible_distribution | lower }}-{{ ansible_distribution_version | lower }}.yml"
  - "../defaults/{{ ansible_distribution | lower }}.yml"
  - "../defaults/{{ ansible_os_family | lower }}.yml"
  

  
- name: debug variables
  include: debug.yml
  tags:
  - debug
  

ansible-galaxy : 创建 role 初始文件和目录


  •   创建初始 role 文件和目录
      

    $ ansible-galaxy init -p playbook/roles web  -p /path/to/roles : 指定 roles 的目录, 未指定则为当前目录.

  •   从 role 仓库中检索, 安装,删除 role.
      
    ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options]

    •   检索
        
      $ ansible-galaxy search ntp

    •   安装
        

      $ ansible-galaxy install -p ./roles bennojoy.ntp
    •   列出
        

      $ ansible-galaxy list
    •   删除
        

      $ ansible-galaxy remove bennojoy.ntp

  •   在线网站 https://galaxy.ansible.com

dependent role:
  dependent role 用于指定 role 依赖的其他一个或多个 role, Ansible 会确保被指定依赖的role 一定会优先被执行.
  Ansible 允许向 dependent role 传递参数
  dependent role 一般在 myrole/meta/main.yml 中指定.
  

# roles/web/meta/main.yml  
dependencies:
  - { role: ntp, ntp_server=ntp.ubuntu.com }
  - { role: common }
  - { role: memcached }
  

playbook : 用于实现 ansible 配置管理的脚本.
  playbook 其实就是一个字典组成的列表. 一个 playbook 就是一组 play 组成的列表. 一个 play 由 host 的无序集合与 task 的有序列表组成. 每一个 task 由一个模块构成.
DSC0000.png

  ansible 中的 True/False 和 yes/no
  
模块参数(如 update_cache=yes)对于值的处理, 使用字符串传递:


  •   真值
      

    yes,on,1,true
  •   假值
      

    no,off,0,false  
    其他使用 YAML 解析器来处理:

  •   真值
      

    true,True,TRUE,yes,Yes,YES,on,On,ON,y,Y
  •   假值
      

    false,False,FALSE,no,No,NO,off,Off,OFF,n,N
  推荐做法:


  • 模块参数: yes/no
  • 其他地方: True,False
  playbook 文件的执行方法:


  •   使用 ansible-playbook 命令
      

    $ ansible-playbook myplaybook.yml
  •   shebang
      

    $ chmod +x myplaybook.yml  
    $ head -n 1 myplaybook.yml
      #!/usr/bin/env ansible-playbook
      
    $ ./myplaybook.yml

  当 Ansible 开始运行 playbook 的时候, 他做的第一件事就是从他连接到的服务器上收集各种信息. 这些信息包括操作系统,主机名,网络接口等.

建立 nginx web 服务器
  

$ cat web-notls.yml  
- name: Configure webserver with nginx and tls
  hosts: webservers
  sudo: true
  vars:
  key_file: /etc/nginx/ssl/nginx.key
  cert_file: /etc/nginx/ssl/nginx.crt
  conf_file: /etc/nginx/sites-available/default
  server_name: localhost
  tasks:
  - name: install nginx
  apt: name=nginx update_cache=yes cache_valid_time=3600
  

  - name: create directories for ssl certificates
  file: path=/etc/nginx/ssl state=directory
  

  - name: copy TLS key
  copy: src=files/nginx.key desc={{ key_file }} owner=root mode=06--
  notify: restart nginx
  

  - name: copy TLS certificate
  copy: src=files/nginx.crt dest={{ cert_file }}
  notify: restart nginx
  

  - name: copy nginx config file
  copy: src=files/nginx.conf.j2 dest={{ conf_file }}
  notify: restart nginx
  - name: enable configuration
  file: dest=/etc/nginx/sites-enabled/default src={{ conf_file }} state=link
  notify: restart nginx
  - name: copy index.html
  template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html mode=0644
  

  handlers:
  - name: restart nginx
  service: name=nginx state=restarted
  

内部变量


  • ansible_managed : 和模板文件生成时间相关的信息.
inventory 文件
  使用 .ini 格式, 默认为 hosts 文件.
  

[webservers]  
testserver ansible_ssh_host=127.0.0.1 ansible_ssh_port=22
  

YAML 文件格式


  •   文件开始.
      

    ---  

      如果没有---标记, 也不影响 ansible 的运行.

  • 注释: #
  • 字符串 : 即使字符串中有空格, 也无需使用引号.
  • 布尔型 : 有多种, 推荐使用 True/False
  •   列表: 使用-作为分隔符

    •   标准列表
        

      - My Fair Lady  
      - Oklahoma
        
      - The Pirates of Penzance

    •   内联式列表
        

      [My Fair Lady, Oklahoma, The Pirates of Penzance]

  •   字典:

    •   标准字典
        

      name: tom  
      age: 12
        
      job: manager

    •   内联式字典
        

      {name: tom, age: 12, job: manager}

  •   折行: 使用大于号(>)表示折行


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-430885-1-1.html 上篇帖子: 【Ansible 文档】【译文】Playbooks 变量 下篇帖子: Ansible自动化运维笔记2(Ansible的组件介绍)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表