ansible之playbook使用、判断、循环和roles

ansible 第三篇playbook之条件判断、循环和roles分层管理

1. ansible playbook之判断、循环语法:

在ansible playbook里面可以使用when语法来实现判断,通过with_items来实现循环,具体的示例如下:

---
vim httpd_v4.yaml
- hosts: websrvs
  remote_user: '{{uservar}}'
  vars:                  #定义变量,变量的值为列表
    software:
      - python-setuptools
      - httpd
      - mariadb
  tasks:
    - name: run this command ans ignore the result
      shell: hostname
      ignore_errors: True  #忽略错误,可以继续执行
      register: result     #将上面shell的结果赋值给result变量
    - debug: msg='{{result.stdout}}'

    - name: install mysql and httpd
      yum: name={{ software }} state=installed #通过调用循环的变量内容来实现批量安装软件
      become: yes
      with_items:   #循环调用software里面的变量
       - '{{software}}'
      tags: init

    - name: guarantee httpd2 is running
      service: name=httpd state=started
      become: yes

    - name: transfer httpd configfile to remote
      template: src=./httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf  #使用模板,传送jinja2文件,也可以用copy模块传送普通文件
      notify:
        - restart httpd
      when: result.stdout == 'rainbondnode01'  #通过判断主机名是'rainbondnode01才执行拷贝模板文件

  handlers:  #触发器
  - name: restart httpd
    service: name=httpd state=restarted
    become: yes

在此示例中用到了几个技术点:

  1. when是条件判断的语法;
  2. with_items是循环列表;
  3. register表示将tasks执行的结果赋予变量;
  4. become是sudo的意思;
  5. 执行此playbook可以使用ansible-playbook -e uservar=gytest --check httpd_v4.yaml,-e 表示执行命令的时候传递变量;

2. ansible playbook之role分层结构管理:

1. 什么场景下会用到roles?

  假如我们现在有3个被管理主机,第一个要配置成httpd,第二个要配置成php服务器,第三个要配置成MySQL服务器。我们如何来定义playbook?
  第一个play用到第一个主机上,用来构建httpd,第二个play用到第二个主机上,用来构建php,第三个play用到第三个主机上,用来构建MySQL。这些个play定义在playbook中比较麻烦,将来也不利于模块化调用,不利于多次调。比如说后来又加进来一个主机,这个第4个主机既是httpd服务器,又是php服务器,我们只能写第4个play,上面写上安装httpd和php。这样playbook中的代码就重复了。
  为了避免代码重复,roles能够实现代码重复被调用。定义一个角色叫websrvs,第二个角色叫phpappsrvs,第三个角色叫dbsrvs。那么调用时如下来调用:

hosts: host1
role:
- websrvs

hosts: host2
role:
- phpappsrvs

hosts: host3
role:
- dbsrvs

hosts: host4
role:
- websrvs
- phpappsrvs

这样代码就可以重复利用了,每个角色可以被独立重复调用。下面举例说明使用方式。

2. 使用roles来安装lamp+wordpress论坛:

  roles需要有一定的目录结构,我实验的lamp的目录结构如下:

[root@rainbondmanager gytest]# tree
.
├── group_vars
│   └── websrvs
├── hosts
├── roles
│   ├── mysql
│   │   ├── files
│   │   │   └── mysql_init.sh
│   │   ├── handlers
│   │   │   └── main.yaml
│   │   ├── tasks
│   │   │   ├── configure.yml
│   │   │   └── main.yaml
│   │   ├── templates
│   │   │   └── my.cnf
│   │   └── vars
│   │       └── main.yaml
│   ├── php
│   │   ├── files
│   │   ├── handlers
│   │   ├── meta
│   │   ├── tasks
│   │   │   └── main.yaml
│   │   ├── templates
│   │   └── vars
│   │       └── main.yaml
│   └── webserver
│       ├── files
│       │   └── wordpress.tar.gz
│       ├── handlers
│       │   └── main.yaml
│       ├── meta
│       │   └── main.yaml
│       ├── tasks
│       │   └── main.yaml
│       └── templates
│           └── httpd.conf.j2
└── site.yaml

第一级至少要有一个site.yml文件,是执行playbook的入口文件;至少要有一个roles目录。roles目录下面是分类创建的目录,比如我需要安装httpd php mysql三个软件,那么就分了3个目录;每一个目录下面的子目录也是固定的,一般大致可以分为files、handlers、tasks、templates、vars、 meta. files目录放的文件一般是通过copy模块调用的本地路径文件,handlers是配置触发器的yaml文件,tasks就是任务文件了,templates是模板文件,一般存放.j2格式的文件,vars是变量定义文件,meta是依赖定义的文件;

接下来我将所有的配置文件内容列出来,并做简单的解释:

[root@rainbondmanager gytest]# cat site.yaml
---
- hosts: websrvs
  remote_user: root

  roles:
    - webserver
- hosts: 10.83.32.130
  remote_user: root

  roles:
    - php

site是入口文件,表示执行的主机、远程执行用户,调用的roles对象。本配置表示websrvs主机组上面安装httpd应用;10.83.32.130这台主机安装php应用;

[root@rainbondmanager gytest]# cat hosts
[websrvs]
10.83.32.130
10.83.32.131

在主目录我还定义了一个hosts文件,使用ansible-playbook -i hosts的方式指定使用这个单独的hosts清单配置,在hosts文件里面也可以定义变量,比如

[websrvs]
10.83.32.130 http_port=80
10.83.32.131 http_port=8080

如果没有用私钥的方式,也可以在hosts文件里面指定ssh用户,ssh端口,ssh密码等

[websrvs]
10.83.32.130 ansible_ssh_user=gytest ansible_ssh_pass=123456
10.83.32.131 ansible_ssh_user=gytest ansible_ssh_pass=123456

主目录还有一个组变量的目录,里面有一个以组名称命名的文件,里面的变量值针对整个组生效,要应用到那个主机组,文件名就需要是哪个主机组

[root@rainbondmanager gytest]# cat group_vars/websrvs
http_port: 8080
[root@rainbondmanager gytest]#

下面我们来分析httpd服务器安装的roles内容

# 第一个是tasks文件内容,里面的copy文件路径直接写相对路径,就是表明file下面的内容,template模板文件也是同理,使用相对路径
[root@rainbondmanager gytest]# cat roles/webserver/tasks/main.yaml
---
- name: installed httpd
  yum:  name=httpd state=present
  tags: install
- name: keep httpd is running
  service: name=httpd state=started enabled=true
  tags: install
- name: insert iptables rules
  shell: iptables -I INPUT -p tcp --dport {{http_port}} -j ACCEPT
- name: transfer index html
  copy: src=wordpress.tar.gz dest=/var/www/html/wordpress.tar.gz
  tags: install
- name: unzip wordpress
  unarchive: src=/var/www/html/wordpress.tar.gz dest=/var/www/html/ copy=no
  ignore_errors: True
  tags: install
- name: mv wordpress
  shell: mv /var/www/html/wordpress/* /var/www/html/
- name: wait for httpd to start
  wait_for: port=8080
  tags: install
- name: transfer httpd configure file
  template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  tags: conf
  notify:
    - restart httpd

cat roles/webserver/handlers/main.yaml
- name: restart httpd
  service: name=httpd state=restarted
# tasks任务里面调用的notify通知,默认就是handlers目录下面的文件内容;

cat roles/webserver/templates/httpd.conf.j2 |grep "{{"
Listen {{http_port}}
ServerAdmin {{ansible_fqdn}}

# 模板文件里面调用了facts变量和自定义变量

cat roles/webserver/meta/main.yaml
dependencies:
  - {role: mysql, echo_wars: hello_mysql}
# meta目录下面定义了依赖关系,也就是安装httpd的时候,先要确定mysql运行

ls roles/webserver/files/wordpress.tar.gz
roles/webserver/files/wordpress.tar.gz
# file目录是wordpress的源码包,通过copy模块拷贝到远程主机,并通过解压模块解压

然后我们在看看mysql数据库服务器安装的roles文件内容:

[root@rainbondmanager gytest]# cat roles/mysql/tasks/main.yaml
---
- name: install mariadb databases
  yum:  name={{software}} state=present
  with_items:
    - '{{software}}'
  tags: install
- name: keep mariadb is running
  service: name=mariadb state=started enabled=true
  tags: install
- name: insert iptables rules
  shell: iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
- name: echo_vars
  shell: echo '{{echo_vars}}'
  register: result
  tags: install
- name: excute mysql init scrpts
  script: /data/playbooks/gytest/roles/mysql/files/mysql_init.sh
- include: configure.yml
# tasks定义了安装mariadb服务器,启动服务,设置防火墙,执行数据库初始脚本等;
[root@rainbondmanager gytest]# cat roles/mysql/tasks/configure.yml
---
- name: transfer mysql configure file
  template: src=my.cnf dest=/etc/my.cnf
  notify:
    - restart mysql
  tags: configure
[root@rainbondmanager gytest]#
# main.yml包含了这个configure.yml,拷贝mysql配置文件到目标机器
[root@rainbondmanager gytest]# cat roles/mysql/handlers/main.yaml
---
- name: restart mysql
  service: name=mysql state=restarted
[root@rainbondmanager gytest]#
# 触发器的配置,配置文件更改之后重启mysql
[root@rainbondmanager gytest]# cat roles/mysql/vars/main.yaml
---
software:
  - mariadb
  - mariadb-server
echo_vars:
  - hello_mysql
mysql_port:
  - '3306'
[root@rainbondmanager gytest]#
# 变量文件定义,定义了安装mysql的软件包和其他变量

[root@rainbondmanager gytest]# cat roles/mysql/files/mysql_init.sh
#!/bin/bash
#

mysql -uroot -pwordpress2018 -e "update mysql.user set password=password('wordpress2019') where user='root' and host='localhost';"
mysql -uroot -pwordpress2018 -e "grant all privileges ON *.* TO root@'%';"
mysql -uroot -pwordpress2019 -e "flush privileges;"
mysql -uroot -pwordpress2019-e "create database wordpress"
[root@rainbondmanager gytest]#
# mysql初始化脚本,更改root密码,创建wordpress数据库,并给root账户赋权;
[root@rainbondmanager gytest]# cat roles/mysql/templates/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d

# mysql的配置文件内容

最后我们一起再来看看php的安装

cat roles/php/tasks/main.yaml
---
- name: installed php-fpm
  yum:  name={{ software }} state=present
  tags: install

# 定义安装php的任务
  [root@rainbondmanager gytest]# cat roles/php/vars/main.yaml
  ---
  software:
    - php
    - php-mysql
    - php-gd
    - php-imap
    - php-ldap
    - php-odbc
    - php-pear
    - php-xml
    - php-xmlrpc
# 定义安装php的软件包

ansible之playbook使用、判断、循环和roles
今天的博文就写到这里了,关于ansible系列的专题就写到这里,更多关于ansible playbook的例子可以参考github地址https://github.com/ansible/ansible-examples

博文的更详细内容请关注我的个人微信公众号 “云时代IT运维”,本公众号旨在共享互联网运维新技术,新趋势; 包括IT运维行业的咨询,运维技术文档分享。重点关注devops、jenkins、zabbix监控、kubernetes、ELK、各种中间件的使用,比如redis、MQ等;shell和python等运维编程语言;本人从事IT运维相关的工作有十多年。2008年开始专职从事Linux/Unix系统运维工作;对运维相关技术有一定程度的理解。本公众号所有博文均是我的实际工作经验总结,基本都是原创博文。我很乐意将我积累的经验、心得、技术与大家分享交流!希望和大家在IT运维职业道路上一起成长和进步;ansible之playbook使用、判断、循环和roles

猜你喜欢

转载自blog.51cto.com/zgui2000/2425425
今日推荐