xlid 发表于 2018-1-2 17:42:00

ansible task/play/role篇


[*]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 [--help]

[*]  检索
  
$ 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 由一个模块构成.

  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 文件.
  

  
testserver ansible_ssh_host=127.0.0.1 ansible_ssh_port=22
  

YAML 文件格式


[*]  文件开始.
  

---  

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

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

[*]  标准列表
  

- My Fair Lady  
- Oklahoma
  
- The Pirates of Penzance

[*]  内联式列表
  



[*]  字典:

[*]  标准字典
  

name: tom  
age: 12
  
job: manager

[*]  内联式字典
  

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

[*]  折行: 使用大于号(>)表示折行

nagios 发表于 2018-1-2 18:10:17

`````````
页: [1]
查看完整版本: ansible task/play/role篇