ansible playbooks

10.ansible playbooks
10.1简介
(1)playbook是由一个或多个“play”组成的列表
(2)play的主要功能在于将事先归并为一组的主机装扮成事先经过anaible中task定义好的角色。从根本上来将,所谓task无非是调用ansible的一个module,将多个play组织在一个playbook中,便可以让它们联通起来按事先编排的机制同唱一台大戏。
10.2组成结构
Inventory
Modules
Ad hoc commands
Playbooks
Tasks:任务,即调用模块完成的某操做
Variables:变量
Templates:模板
Handlers:处理器,由某时间触发执行的操做
10.3 playbook
基础组件包括:Tasks、Variables、Templates、Handlers、Roles
10.3.1hosts和users
(1)playbook中每个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。
(2)Hosts用于指定要执行指定任务的主机,其能够是一个或多个由冒号分割主机组:
(3)remote_user则用于指定远程主机上的执行任务的用户。如上面实例中的
-hosts:webnodes
remote_user:root
不过,remote_user也可用于各task中,也能够经过指定其经过sudo的方式在远程主机上执行任务,其能够用于play全局或某任务:此外,甚至能够在sudo时使用sudo_user指定sudo时切换的用户html

  • hosts:webnodes //定义一个主机组
    remote_user:zhang //定义登陆时的用户身份
    tasks: //定义任务,能够有多个
  • name: test connection //任务名称
    gather_facts: false 这个参数指定了在如下任务执行前,是否先执行setup模块获取主机相关信息,这在后面的task会使用到task获取的信息,若是不须要,则选项为false,默认开启
    ping: //动做
    remote_user:zhang //在这可使用本身定义的,至关于局部变量
    sudo:yes //是否sudo到root用户
    10.3.2任务列表和action
    (1)Play的主体部分是task list
    (2)Task list 中的各任务按次序逐个在hosts中指定的全部主机上执行,即在全部主机上完成第一个任务后再开始第二个
    (3)在运行自下而上某playbook时,若是中途发生错误,全部已执行任务均可能回滚,所以,在更正playbook后从新执行一次便可
    (4)Task的目的是使用指定的参数执行模块,而在模块参数中可使用变量。模块执行是幂等的,这意味着屡次执行是安全的,由于其结果一致
    (5)每一个task都应该有其name,用于playbook的执行结果输出,建议其内容尽量清晰的秒数任务执行步骤,若是未提供name,则action的结果将用于输出
    (6)定义task的可使用“action:module options”或“module:option”的格式,推荐使用后者以实现向后兼容,前边的只是在较新的版本中才可使用。若是action一行的内容过多,能够在行首使用几个空白字符进行替换
    tasks:
    -name:make sure apache is runing
    service :name-httpd state=running //在运行这个模块时使用后面的参数
    (7)在众多模块中,只有command和shell模块仅须要给定一个列表而无需使用“key-value”格式,例如
    tasks:
    -name:disbles selinux
    command: /sbin/setenforce 0
    (8)若是命令或脚本的退出码不为0,可使用以下方式替代:
    tasks:
    • name: run this command and ignore the result
      shell: /usr/bin/somecommand || /bin/true //强行成功
      (9)使用ignore_errors来忽略错误信息
      tasks:
      -name: run this command and ingore the result
      shell: /usr/bin/somecommand
      ignore errors:True //忽略失败,不影响后续执行
      10.3.3例一
      安装apache服务,并确保服务正常启动
  • hosts: webnodes //只对webnodes组里边的服务器生效,webnodes在inventory中定义
    vars: //在这组主机上定义了一组变量,vars,是一个键值对,值是个字典
    http_port:80
    max_clients:256
    remote_user:root //链接到远程主机时以哪一个用户登陆
    tasks: //用来定义接下来执行的任务有哪些
    • name:ensure apache is at the lastest version //第一个任务
      yum:name=httpd state=latest //基于yum模块来安装程序包
    • name:ensure apache is runing //第二个任务
      service:name=httpd state=started //基于service模块来启动服务
      handlers: //处理器
    • name:restart apache
      service:name=httpd state=restarted
      10.3.4例二
      建立nginx组和用户,复制本地文件到远端服务器
  • hosts: zhang
    remote_user: root
    tasks:
    • name: create nginx group
      group: name=nginx system=yes gid=208
    • name: create nginx user
      user: name=nginx uid=208 group=nginx system=yes
  • hosts: wang
    remote_user: root
    tasks:
    • name: copy file to wang
      copy: src=/etc/passwd dest=/tmp/wang.txt
      ansible playbooks
      执行后结果以下图,changed表示已经在远程主机上已经作了修改,后边有个PLAY RECAP是报告任务的执行状况
      ansible playbooks

10.3.5例三
安装httpd服务,使用本地配置文件,启动服务node

  • hosts: zhang
    remote_user: root
    tasks:
    • name: install httpd package
      yum: name=httpd state=latest
    • name: install configuration file for httpd
      copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
    • name: start httpd service
      service: enabled=true name=httpd state=started
      ansible playbooks
      ansible playbooks

10.3.6例四
使用两个花括号来表示引用变量值linux

  • hosts: zhang
    remote_user: root
    vars:
    • package: httpd
    • service: httpd
      tasks:
    • name: install httpd package
      yum: name={{ package }} state=latest
    • name: install configuration file for httpd
      copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
      notify: restart httpd
    • name: start {{ service }} service
      service: enabled=true name=httpd state=started
      handlers:
    • name: restart httpd
      service: name=httpd state=restarted
      ansible playbooks
      10.3.7 handlers
      (1)用于当关注的资源发生变化时采起必定的操做
      (2)举例说明,好比上面的实例二,当从新修改httpd.conf的时候,须要重启下服务,可是ansible并无这么作,因此须要使用handlers这个action
      (3)“notify”这个action可用于在每一个play的最后被触发,这样能够避免屡次有改变发生时每次都执行指定的操做,取而代之,仅在全部的变化发生完成后一次性的执行指定操做,(4)在notify中列出的操做称为handler,也即notify中调用handler中定义的操做,当有改变的时候notify通知handler执行下边的操做。
      若是配置文件改变,将重启apache和memcache
  • name: template configuration file
    template: src=template.j2 dest=/etc/foo.conf
    notify: //指明触发哪个操做
    • restart memcached
    • restart apache
      handlers:
    • name: restart memcached
      service: name=memcached state=restarted
    • name: restart apache
      service: name=apache state=restarted
      (5)headles跟tasks是同级,须要定义,通常不会执行,只有当触发了某一条件的时候才会执行。好比能够将上述例二修改成以下,这样就能够确保,当配置文件发生改变的时候,服务也会重启,配置文件将重读一次。
      能够监控另一个task,只有当这个task改变的时候才会触发notify执行
  • hosts: zhang
    remote_user: root
    tasks:
    • name: install httpd package
      yum: name=httpd state=latest
    • name: install configuration file for httpd
      copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
      notify: restart httpd
    • name: start httpd service
      service: enabled=true name=httpd state=started
      handlers:
    • name: restart httpd
      service: name=httpd state=restarted
      ansible playbooks
      ansible playbooks

(6)hendlers还能够监听某一个handers A,当A触发的时候,会触发这个handlers,这样多个handler监听A的时候,当触发了A,那么监听A的handlers都会被触发
handlers:nginx

  • name: restart memcached
    service:
    name: memcached
    state: restarted
    listen: "restart web services"
  • name: restart apache
    service:
    name: apache
    state:restarted
    listen: "restart web services"

tasks:git

  • name: restart everything
    command: echo "this task will restart the web services"
    notify: "restart web services"
    10.3.8条件测试
    (1)when用于条件判断,只有知足条件的主机才会执行这个任务,这个信息能够在setup收集回来的信息上取值
    (2)例如:
    • hosts: all
      remote_user: root
      vars:
    • username: user10
      tasks:
    • name: create {{ username }} user
      user: name={{ username }}
      when: ansible_fqdn == "glusterfs.tarena.com"
      ansible playbooks
      以下,不知足条件的就被跳过了
      ansible playbooks
      10.3.9 迭代
      (1)简介:当有须要重复执行的任务时,可使用迭代机制,其使用格式为将须要迭代的内容定义为item变量引用,并经过with_items语句来指明迭代的元素
      (2)item_items中可使用元素还可为hashes
      (3)item是固定的变量名,会循环with_items列表中的每个值来替代,至关于遍历式的迭代循环
      (4)with_items中的列表还也能够是字典,可是引用时须要使用item.key
      (5)ansible的循环机制还有更多的高级功能,具体能够参见官方文档http://docs.ansible.com/playbooks_loops.html
      例1:增长多个用户
    • name: add serveral users
      user: name={{ item }} state=present groups=wheel
      with_items:
      • testuser1
      • testuser2
        例2:增长多个用户而且指定组
    • name: add serveral users
      user: name={{ item }} state=present groups={{ item.groups }}
      with_items:
  • { name: 'testuser1',groups: 'wheel'}
  • { name: 'testuser2',groups: 'root'}
    10.3.10算数和比较运算符
    (1)容许使用计算值,不多用到,可是为了完成性,容许其存在
    (2)支持 + - * / //(取整) % **(幂)
    (3)支持比较运算符 != == > >= < <=
    (4)可使用变量
    (5)全部运算都必须在{{}}中
    10.3.11 Tags
    (1)Tags用于有选则的运行playbook中的代码,能够选择只运行有标签的代码,即调用playbook中的某一个任务
    (2)Ansible具备幂等性,所以会自动跳过没有变化的部分,即便如此,有些代码为测试其没有发生变化的时间依然会很是长。此时,若是确信其没有变化,就可使用tags跳过这些代码片断
    (3)always_tags,这个选项的意思是不管如何被这个标记的任务都会执行
    Tags: t3,always
    (4)能够在play级别写,也能够在tasks级别写,写到play级别下边的tasks自动继承play的tags名称
    (5)一个name能够有多个tag,以下
    Tags: ts,http
    (6)ansible playbooks

例:web

  • name: install httpd package
    yum: name={{ package }} state=latest
    tags:
    • conf
      10.3.12 roles
      10.3.12.1简介
      (1)Ansible自1.2版本引入的新特性,用于层次性、结构化的组织playbook
      (2)roles可以根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只须要在playbook中使用include命令便可。简单来说,roles就是经过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并能够便捷的include它们的一种机制。
      (3)角色通常用于基于主机构建服务的场景中,但也能够是用于构建守护进程等场景中
      10.3.12.2案例
      一个roles的案例以下:
      roles/
      common/
      files/ //分别将一些须要的东西放到对应的目录中
      templates/
      tasks/
      handlers/
      vars/
      meta/
      webservers/
      files/
      templates/
      tasks/
      handlers/
      vars/
      meta/
      而在playbook中,能够这样使用roles,直接调用roles里边的参数
    • hosts: webservers
      roles:
    • common
    • webservers
      也能够向roles传递参数,例如
    • hosts: webservers
      roles:
  • common
  • { role: foo_app_instance, dir: '/opt/a', port:5000 }
  • { role: foo_app_instance, dir: '/opt/b', port:5001 }
    甚至也能够条件式的使用roles,例如:
    • hosts: webservers
      roles:
      • { role: som_role, when: "ansible_os_family == 'Redhat'" }
        10.3.12.3建立role的步骤
        (1)构建以role命名的目录
        (2)在roles目录中分别建立以各角色名称命名的目录,如webservers等
        (3)在每一个角色命名的目录中分别建立files、handlers、meta、tasks、templates和var目录;用不到的目录能够建立为空目录,也能够不建立
        (4)在playbook文件中,请用各角色
        10.3.12.4role内各目录中可用的文件
        Tasks目录:至少应该包含一个名为main.yml的文件,其定义的此角色的任务列表:此文件可使用include包含其它的位于此目录中的task文件
        Files目录:存放由copy或scripts等模块调用的文件
        Template目录:template模块会自动在此目录中寻找jinja2模板文件
        Handlers目录:此目录中应当包含一个main
        Yml文件:用于定义此角色用到的各handlers;在handlers中使用include包含的其它handler文件也应该位于此目录中
        Vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量
        Meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;ansible1.3及其之后的版本才支持
        Default目录:为当前角色设定默认变量时才使用此目录,应当包含一个main.yml文件
        10.3.13 lookups
        Lookup插件能够用来从外部数据读取信息,而后赋给一个变量。获取外部数据信息的种类包括:读取文件内容、随机生成password、执行shell命令、读取redis的键值等等。注意,lookup全部的运算都是在ansible中控机上完成的,而不是远程目标机
        10.3.13.1 第一个参数为file
        第一个参数为file,表示获取外部文件内容
    • name: test
      hosts: self
      vars:
      contents: "{{ lookup('file', '/etc/foo.txt') }}"
      tasks:
    • debug: msg="the value of foo.txt is {{ contents }}"
    • debug: msg="the value of foo.txt is {{ lookup('file','/etc/foo.txt') }}"
      ansible playbooks
      10.3.13.2第一个参数为password
      第一个参数为password,表示生成一个随机明文密码,并存储到指定文件中,生成的密码包括大小写字母、数字和.,:-_,长度为20个字符,该长度能够经过传递一个额外参数length=<length>修改

除了length外,还可使用chars=<chars>参数,用于自定义生成密码的字符集
chars=’ ascii_letters,digits,hexdigits,punctuation,,’ ,号自己用,号redis

  • hosts: self
    gather_facts: false
    tasks:
  • debug: msg="password - {{ lookup('password', '/tmp/random_pass.txt length=10')}}"
    ansible playbooks
    10.3.13.3其它类型
  • hosts: all
    tasks:shell

    • debug: msg="{{ lookup('env','HOME') }} is an environment variable"apache

    • debug: msg="{{ lookup('pipe','date') }} is the raw result of running this command"安全

    • debug: msg="{{ lookup('redis_kv', 'redis://localhost:6379,somekey') }} is value in Redis for somekey"

    • debug: msg="{{ lookup('dnstxt', 'example.com') }} is a DNS TXT record for example.com"

    • debug: msg="{{ lookup('template', './some_template.j2') }} is a value from evaluation of this template"
      10.3.14循环
      ansible playbooks
相关文章
相关标签/搜索