Ansible Playbooks

Playbooks是Ansible的配置/部署/任务编排使用的语言。

Ansible Playbooks配置用例说明

  • lamp_simple的目录层次如下,README.md包含一些简单的说明

    1. lamp_simple
    2. ├── LICENSE.md
    3. ├── README.md
    4. ├── group_vars
    5. ├── all
    6. └── dbservers
    7. ├── hosts
    8. ├── roles
    9. ├── common
    10. ├── handlers
    11. └── main.yml
    12. ├── tasks
    13. └── main.yml
    14. └── templates
    15. └── ntp.conf.j2
    16. ├── db
    17. ├── handlers
    18. └── main.yml
    19. ├── tasks
    20. └── main.yml
    21. └── templates
    22. └── my.cnf.j2
    23. └── web
    24. ├── handlers
    25. └── main.yml
    26. ├── tasks
    27. ├── copy_code.yml
    28. ├── install_httpd.yml
    29. └── main.yml
    30. └── templates
    31. └── index.php.j2
    32. └── site.yml
  • 文件hosts是inventory file,定义了需要被playbooks配置的节点信息

    1. # []内定义了组名称,一般可以把相同用途的节点放在一个组里
    2. [webservers]
    3. # 节点名称,需要能被解析为IP地址;也可以直接填写IP地址
    4. web3
    5. [dbservers]
    6. web2
  • 目录roles定义了节点需要被配置的角色类型,例如web,db(可以根据服务类型自定义名称)等;每个角色可以包含一份或者多份playbooks, 此处定义了三种角色类型:common,db,web

    1. roles/
    2. ├── common
    3. ├── handlers
    4. └── main.yml
    5. ├── tasks
    6. └── main.yml
    7. └── templates
    8. └── ntp.conf.j2
    9. ├── db
    10. ├── handlers
    11. └── main.yml
    12. ├── tasks
    13. └── main.yml
    14. └── templates
    15. └── my.cnf.j2
    16. └── web
    17. ├── handlers
    18. └── main.yml
    19. ├── tasks
    20. ├── copy_code.yml
    21. ├── install_httpd.yml
    22. └── main.yml
    23. └── templates
    24. └── index.php.j2
  • 每种角色类型的目录下可以定义handlers/tasks/templates/files这4个子目录,.yml的文件就是playbook

    • tasks目录内的playbook用作多任务编排
    • handlers目录内的playbook定义的任务一般只有在执行变更动作的时候才被触发(比如tasks目录的playbook内的任务变更了nginx配置, 可以触发handlers的playbook内重启nginx服务任务的执行)
    • templates目录内定义了配置模板,在远程主机上会根据配置模板生成配置文件
    • files目录内定义了配置文件,内容会直接同步到远程主机的配置文件
  • roles/common/handlers/main.yml定义了多个可被触发的任务;任务通过module来定义
    执行ansible-doc -l列出所有内置的module
    执行ansible-doc [module]获取module的选项和用法

    1. ---
    2. # Handler to handle common notifications. Handlers are called by other plays.
    3. # See http://docs.ansible.com/playbooks_intro.html for more information about handlers.
    4. # 定义任务名称,执行playbook时会显示
    5. - name: restart ntp
    6. # 调用`service`module重启ntpd
    7. service: name=ntpd state=restarted
    8. - name: restart iptables
    9. service: name=iptables state=restarted
  • roles/common/tasks/main.yml定义了多个相互依赖的任务(安装ntp包 -> 配置ntp -> 启动ntpd -> 检查selinux是否运行), 任务根据文件内容从上往下顺序执行;一个playbook内定义的多个任务实际就是配置一个服务执行的相关步骤

  1. ---
  2. # This playbook contains common plays that will be run on all nodes.
  3. - name: Install ntp
  4. yum: name=ntp state=present
  5. # 可以对任务做标记(tags),运行playbook的时候可以加上-t参数执行指定tag的任务
  6. tags: ntp
  7. - name: Configure ntp file
  8. template: src=ntp.conf.j2 dest=/etc/ntp.conf
  9. tags: ntp
  10. # notify就是触发handlers目录内playbook定义的`restart ntp`任务执行
  11. notify: restart ntp
  12. - name: Start the ntp service
  13. service: name=ntpd state=started enabled=yes
  14. tags: ntp
  15. - name: test to see if selinux is running
  16. command: getenforce
  17. # registry把getenforce执行的结果保存到sestatus变量
  18. register: sestatus
  19. # 此处定义只有当`setstatus`值是`false`时才会执行变更
  20. changed_when: false
  • 配置模板基于Jinja2模板引擎解析,可以加上.j2后缀作为标识

    • 模板引擎查找group_vars里的变量文件
    • group_vars里存放多份变量文件时,如果存在和节点所在组名称相同的文件,在此文件中查找变量替换值
    • group_vars/all是默认的变量文件
    1. # roles/web/templates/index.php.j2
    2. <html>
    3. <head>
    4. <title>Ansible Application</title>
    5. </head>
    6. <body>
    7. </br>
    8. # {{ }}内定义了变量
    9. # `ansible_default_ipv4.address`是远程主机的系统信息,可以通过`setup`modules获取所有系统信息
    10. # 具体参考官方文档:http://docs.ansible.com/ansible/setup_module.html
    11. <a href=http://{{ ansible_default_ipv4.address }}/index.html>Homepage</a>
    12. </br>
    13. <?php
    14. Print "Hello, World! I am a web server configured using Ansible and I am : ";
    15. echo exec('hostname');
    16. Print "</BR>";
    17. echo "List of Databases: </BR>";
    18. # Jinja2支持{% %}内定义简单的条件和循环
    19. # `groups`/`hostvars`是Ansible内置变量
    20. # `groups['dbservers']`是inventory file里定义的[dbservers]
    21. # `hostvars[host]`可以查询对应主机的变量值
    22. {% for host in groups['dbservers'] %}
    23. $link = mysqli_connect('{{ hostvars[host].ansible_default_ipv4.address }}', '{{ hostvars[host].dbuser }}', '{{ hostvars[host].upassword }}') or die(mysqli_connect_error($link));
    24. {% endfor %}
    25. $res = mysqli_query($link, "SHOW DATABASES;");
    26. while ($row = mysqli_fetch_assoc($res)) {
    27. echo $row['Database'] . "\n";
    28. }
    29. ?>
    30. </body>
    31. </html>
  • playbook支持- include: another.yml,可以写多份playbook,然后在main.yml中include其他playbook
    playbook支持在module里使用变量,执行时在group_vars里查找变量文件
    playbook支持循环,参考:http://docs.ansible.com/ansible/playbooks_loops.html
    playbook支持条件判断,参考:http://docs.ansible.com/ansible/playbooks_conditionals.html

  • 文件site.yml是全局playbook,定义了节点组和角色类型的对应关系

    1. ---
    2. # This playbook deploys the whole application stack in this site.
    3. - name: apply common configuration to all nodes
    4. hosts: all
    5. # ssh远程执行用户
    6. remote_user: root
    7. # 节点组对应的角色
    8. roles:
    9. - common
    10. - name: configure and deploy the webservers and application code
    11. hosts: webservers
    12. remote_user: root
    13. roles:
    14. - web
    15. - name: deploy MySQL and configure the databases
    16. hosts: dbservers
    17. remote_user: root
    18. roles:
    19. - db
  • 执行playbook

    1. $ cd lamp_simple
    2. $ ansible-playbook site.yml -i hosts