ansible-playbook

使用playbook的好处

  • 官方文档:https://docs.ansible.com/ansible/latest/user_guide/playbooks.html

  • 特点

    • 易读的编排语言
    • 适合配置管理和应用部署
    • 非常适合复杂的工作

playbook实例

  • 编写playbook和测试配置
$ mkdir ansible-demo && cd ansible-demo/
$ vim site.conf        #配置文件
server {
  listen   80;
  server_name  www.cropy.cn;
  location / {
    root /var/www/html/;
    index index.html;
  }
}

$ vim nginx.yml
---
- hosts: webservers
  vars:
    hello: Ansible
  tasks:
  - name: Add Nginx Repo
    yum_repository:
      name: nginx
      description: nginx repo
      baseurl: http://nginx.org/packages/centos/7/$basearch/
      gpgcheck: no
      enabled: 1
  - name: install nginx
    yum:
      name: nginx
      state: latest
  - name: copy nginx config
    copy:
      src: ./site.conf
      dest: /etc/nginx/conf.d/site.conf
  - name: start nginx
    service:
      name: nginx
      state: started
      enabled: yes
  - name: create wwwroot directory
    file:
      dest: /var/www/html
      state: directory
  - name: create test page
    shell: "echo {{ hello }} > /var/www/html/index.html"
$ ansible-playbook nginx.yml --syntax-check        #语法检查&调试
$ ansible-playbook nginx.yml        #部署

yaml 配置文件写法

  • 开始以---开始
  • 不支持制表符,缩进两个空格
  • 缩进代表层级关系
  • #代表注释,不执行

handles

  • 变更时执行操作
---
- hosts: webservers
  gather_facts: no
  tasks:
  - name: copy nginx config
    copy:
      src: ./site2.conf
      dest: /etc/nginx/conf.d/site2.conf
    notify:
      - reload nginx
  handlers:
    - name: reload nginx
      service: name=nginx state=reloaded

任务控制

  • tags: 根据标签执行任务
$  vim nginx.yml 
---
- hosts: webservers
  vars:
    hello: Ansible
  tasks:
  - name: Add Nginx Repo
    yum_repository:
      name: nginx
      description: nginx repo
      baseurl: http://nginx.org/packages/centos/7/$basearch/
      gpgcheck: no
      enabled: 1
    tags: addRepo
  - name: install nginx
    yum:
      name: nginx
      state: latest
    tags: installNginx
  - name: copy nginx config
    copy:
      src: ./site.conf
      dest: /etc/nginx/conf.d/site.conf
  - name: start nginx
    service:
      name: nginx
      state: started
  - name: create wwwroot directory
    file:
      dest: /var/www/html
      state: directory
  - name: create test page
    shell: "echo {{ hello }} > /var/www/html/index.html"
    tags:
      - addHtml
      - addTest

$ ansible-playbook nginx.yml --tags "addRepo"       #指定tags
$ ansible-playbook nginx.yml --tags "addRepo,installNginx" 
$ ansible-playbook nginx.yml --skip-tags "addRepo,installNginx" 

debug信息打印

$ vim debug.yml              
---
- hosts: webservers
  gather_facts: no
  vars:
    hello: Ansible
  tasks:
  - name: debug message
    debug: msg={{ hello }}
$ ansible-playbook debug.yml 

案例

  • 自动部署tomcat
$  vim tomcat.yml
---
- hosts: webservers
  gather_facts: no
  vars:
    tomcat_version: 8.5.56
    tomcat_install_dir: /usr/local
  tasks:
  - name: install jdk
    yum: name=java-1.8.0-openjdk state=present
  - name: Download tomcat
    get_url: url=http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v{{ tomcat_version }}/bin/apache-tomcat-{{ tomcat_version }}.tar.gz dest=/tmp
  - name: unarchive tomcat-{{ tomcat_version }}.tar.gz
    unarchive:
      src: /tmp/apache-tomcat-{{ tomcat_version }}.tar.gz
      dest: "{{ tomcat_install_dir }}"
      copy: no
  - name: start tomcat
    shell: cd {{ tomcat_install_dir }} &&
           mv apache-tomcat-{{ tomcat_version }} tomcat8 &&
           cd tomcat8/bin && nohup ./startup.sh &
$ ansible-playbook tomcat.yml --syntax-check   #语法检查
$ ansible-playbook tomcat.yml 

playbook变量定义与使用

命令行定义使用变量

$ ansible-playbook nginx/nginx.yml  --list-tags
$ ansible-playbook nginx/nginx.yml  --list-tasks
$ vim demo1.yml
---
- hosts: webservers
  gather_facts: no
  remote_user: root
  tasks:
  - name: test var
    debug: msg="{{ work_dir }}"
$ ansible-playbook demo1.yml -e work_dir="/root/dadda"     #-e指定变量

inventory中定义变量

$ mkdir /etc/ansible/group_vars
$ vim /etc/ansible/group_vars/webservers.yml
http_port: 8080
server_name: 222.baidu.com
$ vim /etc/ansible/hosts          #去掉此处定义的vars             
[webservers]
192.168.56.11 ansible_ssh_user=root ansible_ssh_pass=yeecallk8s http_port=80
192.168.56.12 ansible_ssh_user=root ansible_ssh_pass=yeecallk8s
192.168.56.13 ansible_ssh_user=root ansible_ssh_pass=yeecallk8s
192.168.56.14 ansible_ssh_user=root ansible_ssh_pass=yeecallk8s

在playbook中定义变量

vim demo2.yml
---
- hosts: webservers
  gather_facts: no
  vars:
    - work_dir: /usr/local
    - nginx_version: 1.18
  tasks:
  - name: create dir
    shell: mkdir -p "{{ work_dir }}/{{ nginx_version }}"

注册变量

---
- hosts: webservers
  gather_facts: no
  vars:
    - work_dir: /usr/local
    - nginx_version: 1.18
  tasks:
  - name: create dir
    shell: mkdir -p "{{ work_dir }}/{{ nginx_version }}"
  - name: register var
    command: date +%F_%T
    register: datetime
  - name: touch file
    file: dest=/tmp/r_{{ datetime.stdout }} state=touch

系统信息变量

playbook文件复用

include&import的区别
  • include: 在运行时导入
    • --list-tags--list-tasks不会输出显示
    • 不能使用notify触发来自include内部处理程序名称(handlers)
  • import: 在playbook解析时预先导入
    • 不能与循环一起使用
    • 将变量用于目标文件或者角色名称时,不能使用inventory中的变量
import_playbook
  • 目录结构
├── hosts       #主机文件
├── lnmp.yml    #lnmp入口
├── lnmt.yml    #lnmt入口
├── mysql.yml   #mysql入口
├── nginx.yml   #nginx入口
├── php.yml     #PHP入口
└── tomcat.yml  #tomcat入口
  • 代码详情
$ cat  hosts
[lnmp]
192.168.56.11
192.168.56.12

$ cat lnmp.yml
---
- import_playbook: nginx.yml
- import_playbook: mysql.yml
- import_playbook: php.yml

$ cat lnmt.yml
---
- import_playbook: nginx.yml
- import_playbook: mysql.yml
- import_playbook: tomcat.yml

$ cat mysql.yml
---
- hosts: lnmp
  gather_facts: no
  tasks:
  - name: Install Mysql
    debug: msg="install mysql..."

$ cat nginx.yml
---
- hosts: lnmp
  gather_facts: no
  tasks:
  - name: Install Ngigx
    debug: msg="install nginx..."
    
$ cat php.yml
---
- hosts: lnmp
  gather_facts: no
  tasks:
  - name: Install PHP
    debug: msg="install php..."
    
$ cat tomcat.yml
---
- hosts: lnmp
  gather_facts: no
  tasks:
  - name: Install Tomcat
    debug: msg="install tomcat..."
  • 测试执行
$ ansible-playbook -i hosts lnmt.yml        #部署lnmt
$ ansible-playbook -i hosts lnmp.yml        #部署lnmp
include_tasks
  • 目录结构
├── hosts       #主机文件
├── main.yml    #任务入口文件
├── task1.yml   #task1
└── task2.yml   #task2
  • 代码详情
$ cat  hosts
[lnmp]
192.168.56.11
192.168.56.12

$ cat  main.yml
---
- hosts: lnmp
  gather_facts: no
  tasks:
  - include_tasks: task1.yml
  - include_tasks: task2.yml
  
$ cat  task1.yml
---
- name: task1
  debug: msg="task1"
  
$ cat  task2.yml
---
- name: task2
  debug: msg="task2"
  • 测试执行
$ ansible-playbook -i hosts main.yml 

控制语法

条件判断
  • 实例一
$ vim if_case.yml              
---
- hosts: webservers
  gather_facts: yes
  tasks:
  - name: host 192.168.56.11 run this task
    debug: msg={{ansible_default_ipv4.address}}
    when: ansible_default_ipv4.address == '192.168.56.11'
$ ansible-playbook if_case.yml 
  • 实例二
$ vim demo2.yml
---
- hosts: webservers
  tasks:
  - name: Update Apache Version - yum
    yum: name=httpd state=present
    when: ansible_pkg_mgr == 'yum'
    notify: restart httpd
  - name: Update Apache Version -apt
    apt: name=httpd state=present
    when: ansible_pkg_mgr == 'apt'
    notify: restart apache2
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted
  - name: restart apache2
    service: name=apache2 stste=restarted
$ ansible-playbook demo2.yml
循环语句
  • 实例一
$ vim demo1.yml
---
- hosts: webservers
  gather_facts: no
  tasks:
  - name: loop list
    debug: msg={{ item }}
    loop:
      - one
      - two
      - three
$ ansible-playbook demo1.yml 

使用场景: 循环序列,比如多个用户创建等

  • 实例二
$ vim adduser.yml
---
- hosts: webservers
  gather_facts: no
  tasks:
  - name: add user and group
    user: name={{item.name}} group={{item.groups}} state=present
    with_items:
      - {name: 'zhangsan',groups: 'nginx'}
      - {name: 'lisi', groups: 'nginx'}

Jinja2 模板语法

  • 条件和循环
$ vim test.yml
---
- hosts: webservers
  gather_facts: no
  vars:
    hello: Ansible
  tasks:
  - template: src=f.j2 dest=/tmp/f.j2
$ vim f.j2
{% set list=['a','b','c'] %}
{% set dict='{"zhangsan":23, "lisi": 19}' %}
{% for i in list %}
  {% if i == 'b' %}
     -> b
  {% elif loop.index == 3 %}
     -> 3
  {% else %}
     {{ i }}
  {% endif %}
{% endfor %}
{{ hello }}
{% for key,value in dict.iteritems() %}
  {{ key }} ====> {{ value }}
{% endfor %}
$ ansible-playbook test.yml 
$ cat /tmp/f.j2 
       a
         -> b
         -> 3
  Ansible
  lisi ====> 23
  zhangsan ====> 19
  • nginx配置文件管理案例
$ cat site.j2 
upstream {{ server_name }} {
{% set list=[10,12,15,18] %}

upstream {{ server_name }} {
  {% for i in list %}
     server 192.168.56.{{ i }}:80;
  {% endfor %}
}

server {
  listen   {{ listen_port }};
  server_name  {{ server_name }};
  location / { 
    root /var/www/html/;
    index index.html;
  } 
} 
$ cat add_config.yml
---
- hosts: webservers
  gather_facts: no
  vars:
    listen_port: 80
    server_name: www.cropy.com
  tasks:
  - name:
    template: src=./site.j2 dest=/etc/nginx/conf.d/site.conf
    notify: restart nginx
  handlers:
  - name: restart nginx
    service: name=nginx state=restarted
$ ansible-playbook add_config.yml