codecamp

Ansible 用 Roles 部署 LNMP 网页应用程式(下)

上一章「Ansible 用 Roles 部署 LNMP 网页应用程式(上)」我们挑选了 Nginx, MySQL 和 PHP 的 Roles,接下来就让冻仁展示怎么用 Roles 简化大型的 TestLink Playbooks 吧!

automate_with_ansible_practice-26.jpg

怎么用 Roles 撰写强化版的 Playbooks?

在这份 Playbooks 与「Ansible 维护大型的 Playbooks」不同的是,冻仁除了把 variables, tasks, handlers 拆开写以外,还加入 Roles 的部份。

取得范例档

为避免版面过于混乱,冻仁已上传范例档,还请大家先至 GitHub 下载。

Git

  1. 取得 demo code。

    $ git clone https://github.com/chusiang/automate-with-ansible.git
    
  2. 进入 testlink 目录。

    $ cd automate-with-ansible/lab/ch23/testlink
    

Zip

  1. 若不想使用 Git,可改下载 zip 档。

    $ wget https://github.com/chusiang/automate-with-ansible/archive/master.zip
    
  2. 解压缩。

    $ unzip automate-with-ansible-master.zip
    
  3. 进入 testlink 目录。

    $ cd automate-with-ansible-master/lab/ch23/testlink/
    

从 Galaxy 下载 Roles

通过冻仁定义好的 requirements.yml 下载多个 Roles,详情请参考 Installing multiple roles from a file | Ansible Documentation 一文。

在 Python 的世界里,我们可借由 requirements.txt 批次下载 pip 套件,而在 Ansible 的世界里则是 requirements.yml

$ ansible-galaxy install -f -p roles -r requirements.yml

使用 Vagrant 建立开发环境

由于这次的 Vagrantfile 有设置 provision (配置) ansible 的语法,故使用 vagrant up 时会一并执行 playbook。详情请参考「Ansible 用Vagrant练习Ansible」一文。

  1. 观看 Vagrantfile 內容。

    $ cat Vagrantfile
    # -*- mode: ruby -*-
    
    Vagrant.configure("2") do |config|
     config.vm.box = "ubuntu/trusty64"
     config.vm.provider "virtualbox" do |vb|
       vb.memory = "1024"
     end
     config.vm.provision "ansible" do |ansible|
       ansible.playbook = "setup.yml"
       ansible.sudo = true
       #ansible.verbose = "vvv"
     end
    end
    
    # vi: set ft=ruby :
    

执行 Playbooks

  1. 启用虚拟机并执行 Playbook。

    $ vagrant up
    

    2016-12-23-ansible-testlink-1.gif

  2. 若过程中有问题,可使用 provision 重新执行 Ansible。

    $ vagrant provision
    
  3. 执行完毕后,开启浏览器 (Browsers) 并进入 TestLink 网站 (http://192.168.33.10),其帐号密码皆为 admin

    2016-12-23-ansible-testlink-2.gif

TestLink Playbooks 架构解说

$ tree -L 2
.
├── README.md
├── Vagrantfile
├── defaults
│   └── main.yml            # main vars.
├── handlers
│   └── main.yml            # main handler.
├── requirements.yml        # for Roles.
├── roles
│   ├── chusiang.php7
│   ├── geerlingguy.mysql
│   └── williamyeh.nginx
├── setup.yml               # main playbook.
├── tasks
│   ├── check.yml
│   ├── main.yml            # main task.
│   ├── setting_nginx.yml
│   ├── setting_php-fpm.yml
│   ├── setting_testlink.yml
│   └── setup_testlink.yml
└── templates
    ├── config_db.inc.php.j2
    ├── nginx-testlink.conf.j2
    ├── php7-cli.ini.j2
    └── php7-fpm.ini.j2

8 directories, 16 files
  1. README.md:可先从这里取得较详细的资讯。
  2. requirements.yml:这里定义了相应的 Roles。

    $ cat requirements.yml
    # Nginx 1.10
    - src: williamyeh.nginx
     path: roles/
    
    # PHP 7
    - src: chusiang.php7
     path: roles/
    
    # MySQL 5.6
    - src: geerlingguy.mysql
     path: roles/
    
  3. setup.yml:前面提到 Vagrant provision 进入点是这里,故我们可从这个 playbook 了解主要架构。

    $ cat setup.yml
    01 #!/usr/bin/env ansible-playbook
    02
    03 ---
    04 - name: play 'setup testlink'
    05   hosts: all
    06   become: true
    07 
    08   vars_files:
    09     - defaults/main.yml
    10 
    11   roles:
    12     - williamyeh.nginx
    13     - chusiang.php7
    14     - {
    15         role: geerlingguy.mysql,
    16         mysql_packages: ['mysql-server-5.6', 'mysql-client-5.6','python-mysqldb'],
    17       }
    18
    19   tasks:
    20     - name: include main task
    21       include: tasks/main.yml
    22
    23     - name: include check task
    24       include: tasks/check.yml
    25
    26   handlers:
    27     - include: handlers/main.yml
    28
    29 # vim:ft=ansible:
    
    • 在第 6 行里,用了 become: yes 来取得 root 权限。
    • 在第 8, 9 行里,载入了定义好的 defaults/main.yml 变数档案,这里宣告了所有会用到的变数。
    • 在第 11-17 行里,载入了 Nginx, MySQL 和 PHP 的 Roles。
    • 在第 20, 21 行里,载入了主要的 tasks。
    • 在第 23, 24 行里,载入了检查用的 tasks。
    • 在第 26, 27 行里,载入了主要的 handler。
  4. defaults/main.yml:覆盖 Roles 预设变数和 TestLink 会用到的相关变数皆宣告于此。

  5. tasks/

    1. main.yml:tasks 的主要进入点,并借由它载入预设执行的 tasks。

      $ cat tasks/main.yml
      ---
      # tasks file for testlink
      
      - name: setup testlink
        include: setup_testlink.yml
      
      - name: setting php-fpm
        include: setting_php-fpm.yml
      
      - name: setting nginx
        include: setting_nginx.yml
      
      - name: setting testlink
        include: setting_testlink.yml
      
      # vim:ft=ansible:
      
    2. setup_testlink.yml:所有关于安装 TestLink 会用到 tasks。

    3. setting_php-fpm.yml:设定 PHP 的 tasks。
    4. setting_nginx.yml:设定 Nginx 的 tasks。
    5. setting_testlink.yml:设定 TestLink 的 tasks。
    6. check.yml:检查状态用的 tasks。
  6. templates/
    1. config_db.inc.php.j2:TestLink 的 Database 设定档模板。
    2. nginx-testlink.conf.j2:Nginx 设定档模板。
    3. php7-cli.ini.j2:php7-cli 设定档模板。
    4. php7-fpm.ini.j2:php7-fpm 设定档模板。
  7. handlers/main.yml:主要的 handler,主要用来重新启动 php-fpm 和 nginx。

    $ cat handlers/main.yml
    ---
    # handlers file for testlink
    
    - name: restart php-fpm
     service: name=php7.0-fpm enabled=yes state=restarted
    
    - name: restart nginx
     service: name=nginx enabled=yes state=restarted
    

以上,当我们整合好 Roles 后,只需撰写部署 TestLink 的 Playbooks 即可。仔细算一算这份范例的 Tasks 行数加起来还不到 220 行呢!

$ wc -l setup.yml tasks/*
      29 setup.yml
      42 tasks/check.yml
      16 tasks/main.yml
      25 tasks/setting_nginx.yml
      18 tasks/setting_php-fpm.yml
      11 tasks/setting_testlink.yml
      78 tasks/setup_testlink.yml
     219 total

后话

原先冻仁想从实作环境、建立 Playbooks、下载 Roles ... 等手把手一步步带领着大家,但事后发现成效不佳,无法逐一说明,所以才会改用重点式介绍。

若您实作后无法正常执行,可于下方留言给冻仁,或至 GitHub 开 issues

相关连结


Ansible 用 Roles 部署 LNMP 网页应用程式(上)
Ansible 用 Roles 部署 TestLink
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }