0
点赞
收藏
分享

微信扫一扫

2、Ansible如何写playbook及playbook中使用变量

ansible的 playbook(按照yaml格式)

三种常见的数据格式

XML  JSON   YAML

YAML支持的几种常用数据类型

标量:单个的、不可再分的值
对象:键值对的集合(字典)
数组:一组按次序排列的值(列表)

playbook命令

--syntax,--syntax-check     #语法检查,功能相当于bash -n 
-C --check                  #模拟执行dry run ,只检测可能会发生的改变,但不真正执行操作 
--list-hosts                #列出运行任务的主机 
--list-tags                 #列出tag 
--list-tasks                #列出task 
--limit                     #主机列表 #只针对主机列表中的特定主机执行 
-i INVENTORY, --inventory INVENTORY #指定主机清单文件,通常一个项对应一个主机清单文件
可放在项目的文件夹下

--start-at-task START_AT_TASK #从指定task开始执行,而非从头开始,START_AT_TASK为任务的 name 
-v -vv -vvv #显示过程

playbook核心组件,写一个简单的playbook
hosts组件、tasks组件

应用在哪些主机上
案例:
[root@ubunt]# mkdir /data/ansible
[root@ubunt]# cd /data/ansible 
[root@ubunt ansible]# vim hello.yaml 
---
# 第一个playbook文件

- hosts: webservers     #被控制主机
  
  tasks:                #任务
    - name: test ping   #第一个任务,测试ping
      ping: 
    
    - name: shell cmd   #第二个任务,执行 shell命令
      shell: 'hostname -I'  
语法检查:[root@ubunt ansible]# ansible-playbook -C hello.yaml
执行:[root@ubunt ansible]# ansible-playbook  hello.yaml

把18上的nginx的配置文件拷贝到100上,并更改配置文件worker——processes 4; 

[root@ubunt ansible]# cat install_nginx.yaml 
---
#安装nginx服务

- hosts: 10.0.0.18     #部署主机
  remote_user: root    #连接时用root的身份进行连接

  tasks:               #任务
    - name: 安装包
      yum: 
        name: nginx    
        state: present #present表示安装
    - name: 配置文件
      copy:
        src: files/nginx.conf    #来源于主控端的配置文件,需要创建files文件夹,存放文件,可不写路径
        dest: /etc/nginx/nginx.conf  #复制到被控制主机的路径
    - name: 数据文件
      copy:
        src: index.html          #在files文件夹下写一个index.html文件,可不写路径
        dest: /usr/share/nginx/html/index.html    
    - name: 启动服务
      service: 
        name: nginx
        state: started   #启动
        enabled: yes     #设为开机启动

创建文件夹        
[root@ubunt ansible]# mkdir files
把nginx配置文件移动到 files中
[root@ubunt ansible]# mv nginx.conf files
写一个index.html文件
[root@ubunt ansible]# vim files/index.html
<h1>ansible website</h1>
[root@ubunt ansible]# ls
files/ hello.yaml install_nginx.yaml

[root@ubunt ansible]# ansible-playbook --syntax-check  install_nginx.yaml  语法检测

playbook: install_nginx.yaml
[root@ubunt ansible]# ansible-playbook install_nginx.yaml  执行

如果配置文件做了修改,nginx的ansible的playbook文件service需更改成restarted(重启)

控制端修改nginx配置文件端口为81,playbook文件修改service的启动方式为restarted
[root@ubunt ansible]# vim install_nginx.yaml 
---
...
省略
...
    - name: 启动服务
      service: 
        name: nginx
        state: restarted   #启动方式
        enabled: yes     #设为开机启动
[root@ubunt ansible]# ansible-playbook --syntax-check  install_nginx.yaml  语法检测

playbook: install_nginx.yaml
[root@ubunt ansible]# ansible-playbook install_nginx.yaml  执行

访问页面
10.0.0.8:81
ansible website

如果修改数据文件页面,nginx的ansible的playbook文件service不需要重启,所以playbook中当达一定条件后,选择重启服务,如配置文件改变 ----handlers触发器

handlers: 与tasks:属于同一级别(两个空格)
如:当达到某一条件后,执行handlers
---
#安装nginx服务

- hosts: 10.0.0.18
  remote_user: root
 
  tasks:
    - name: 安装包
      yum:
        name: nginx
        state: present
- name: 配置文件
      copy:
        src: files/nginx.conf
        dest: /etc/nginx/nginx.conf 
      notify: restart nginx   
    - name: 数据文件
      copy:
        src: index.html
        dest: /usr/share/nginx/html/index.html
    - name: 启动服务
      service:
        name: nginx
        state: started
        enabled: yes

  handlers:
    - name: restart nginx
      service: name=nginx state=restarted
      满足配置文件变动时执行handlers,重启nginx

限制主机清单中的单个主机执行playbook

[root@ubunt ansible]# ansible-playbook --limit 10.0.0.8 install_nginx.yaml

-i指定之际清单。把主机清单放在当前项目下,让ansible用当前目录下的主机清单,不再更改全局主机清单

拷贝全局主机清单到项目目录下
[root@ubunt ansible]# cp /etc/ansible/hosts .
[root@ubunt ansible]# ls
files/  hello.yaml  hosts  install_nginx.yaml
[root@ubunt ansible]# mv hosts inventory

指定主机清单运行playbook
[root@ubunt ansible]# ansible-playbook -i inventory
设置默认在当前目录下找主机清单,不在-i指定主机清单
拷贝主配置文件到当前目录,其优先级大于默认配置文件路径
[root@ubunt ansible]# cp /etc/ansible/ansible.cfg ansible.cfg
修改当前目录下的配置文件主机清单路径
[root@ubunt ansible]# vim ansible.cfg
inventory   = ./inventory

忽略错误:ignore_errors

如果一个task出错,默认将不会继续执行后续的其它task 
利用 ignore_errors: yes 可以忽略此task的错误,继续向下执行playbook其它task
[root@ubunt ansible]# cat test_ignore.yml 
--- 
- hosts: webservers
  tasks: 
    - name: error     
      command: /bin/false     
      ignore_errors: yes     #跳过错误,允许出错,继续执行下面任务
    - name: continue     
      command: wall continue

贴标签tags: data 贴两个标签tags: [ data , page ]

- name: 配置文件
      copy:
        src: files/ nginx.conf
        dest: /etc/nginx/nginx.conf
      notify: restart nginx
    - name: 数据文件
      copy:
        src: index.html
        dest: /usr/share/nginx/html/index.html
      tags: [ data , page ]
对页面文件进行修改
[root@ubunt ansible]# vim files/index.html
<h1>ansible website v2.0</h1>
只执行贴标签的任务
[root@ubunt ansible]# ansible-playbook -t data install_nginx_yaml


多个任务可用一个标签及一个动作可用多个标签
- name: 配置文件
      copy:
        src: files/ nginx.conf
        dest: /etc/nginx/nginx.conf
      notify: restart nginx
      tags: data
    - name: 数据文件
      copy:
        src: index.html
        dest: /usr/share/nginx/html/index.html
      tags: data

按照page标签执行
[root@ubunt ansible]# ansible-playbook -t page install_nginx_yaml

playbook中使用变量(变量名:仅能由字母、数字和下划线组成,且只能以字母组成)

变量来源:

1、ansible 的 setup facts 远程主机的所有变量都可直接调用根据变量生成文件
2、通过命令行指定变量,优先级最高
ansible-playbook -e varname=value test.yml
3、在playbook文件中定义
vars:
  var1: value1 
  var2: value2
4、在独立的变量YAML文件中定义
- hosts: all 
  vars_files:
    - vars.yml
5、在主机清单文件中定义
6、在项目中针对主机和主机组定义 (在项目目录中创建 host_vars和group_vars目录)
7、在role中定义

变量的优先级从高到低如下

-e选项定义变量-->playbook中vars_files-->playbook中vars变量定义-->host_vars/主机名文件-->主机清单中主机变量-->group_/主机名文件-->主机清单中主机变量-->组/主机组名文件-->组_vars/all文件-->主机清单组变量

变量调用方式:

通过{{ variable_name }}调用变量,且变量名前后建议加空格,有时用"{{variable_name}}"才生效

1、用set up模块取内置变量并把变量引用

范例:本地连接(可以复用,节省主机)

[root@ubunt ansible]# vim inventory
127.0.0.1 ansible_connection=local
[root@ubunt ansible]# ansible localhost -m setup  执行查看,其中可以用set up模块把变量引用
[root@ubunt ansible]# vim var1.yaml
- hosts: webservers
  
  tasks:
  - name: create file
    file:
      name: /tmp/{{ ansible_fqdn }}.log
      state: touch
[root@ubunt ansible]# ansible-playbook var1.yaml  
去webservers下的主机/tmp/下去查看,是否有主机名+log的文件

修改主机名(不能设置gather_facts:no,设置之后set up模块收集不了主机信息)

- hosts: webservers
  
  tasks:
  - name: create file
    file:
      name: /tmp/{{ ansible_hostname }}.log
      state: touch
  - name: change hostname
    hostname:
      name: "ubuntu-{{ ansible_eth0.ipv4.address.split('.')[-1] }}" 
[root@ubuntu2004 ~]#hostname -I
ubuntu-101

性能优化
每次执行playbook,默认会收集每个主机的所有facts变量,将会导致速度很慢,可以采用下面方法加速

当使用 gather_facts: no 关闭 facts,确实能加速 Ansible 执行,但是有时候又需要使用 facts 中的内 容,还希望执行的速度快,这时候可以设置facts 的缓存,将facts变量信息存在redis服务器中

[root@ansible ~]# cat /etc/ansible/ansible.cfg 
[defaults] 
# smart 表示默认收集 facts,但 facts 已有的情况下不会收集,即使用缓存facts 
# implicit 表示默认收集 facts,要禁止收集,必须使用 gather_facts: False 
# explicit 则表示默认不收集,要显式收集,必须使用gather_facts: True 

gathering = smart                           #在使用 facts 缓存时设置为smart 
fact_caching_timeout = 86400                #缓存时长 fact_caching = redis #缓存存在redis中 fact_caching_connection = 10.0.0.100:6379:0 #0表示redis的0号数据库 #若redis设置了密码 fact_caching_connection = 10.0.0.100:6379:0:password

范例

[root@ubunt ansible]# apt -y install redis
[root@ubunt ansible]# vim ansible.cfg
inventory      = ./inventory      
gathering = smart
fact_caching_timeout = 86400
fact_caching_connection = 127.0.0.1:6379:0

先执行进行收集到redis中
[root@ubunt ansible]# ansible-playbook var1.yaml  
然后加上gather_facts: no不收集
- hosts: webservers
  gather_facts: no
  tasks:
  - name: create file
    file:
      name: /tmp/{{ ansible_hostname }}.log
      state: touch
  - name: change hostname
    hostname:
      name: "ubuntu-{{ ansible_eth0.ipv4.address.split('.')[-1] }}"

2、register注册变量

在playbook中可以使用register将捕获命令的输出保存在临时变量中,方便后续调用此变量,比如可以使用debug模块进行显示输出

范例:利用debug 模块输出变量
[root@ubunt ansible]# vim register.yaml
- hosts: dbservers 
  tasks:    
    - name: get variable     
      shell: hostname     
      register: name    
    - name: "print variable"     
      debug:       
        msg: "{{ name }}"
执行playbook
[root@ubunt ansible]# ansible-playbook register.yaml

只取出stdout的键值信息
[root@ubunt ansible]# vim register.yaml
- hosts: dbservers 
  tasks:    
    - name: get variable     
      shell: hostname     
      register: name    
    - name: "print variable"     
      debug:       
        #msg: "{{ name }}"
        msg: "{{ name.stdout }}" 
执行playbook
[root@ubunt ansible]# ansible-playbook register.yaml

分行打印
[root@ubunt ansible]# vim register.yaml
- hosts: dbservers 
  tasks:    
    - name: get variable     
      shell: ss -ntl     
      register: name    
    - name: "print variable"     
      debug:       
        #msg: "{{ name }}"
        msg: "{{ name.stdout_lines }}" 
执行playbook
[root@ubunt ansible]# ansible-playbook register.yaml

3、在playbook命令行中定义变量

范例:
[root@ubunt ansible]# vim var2.yaml
- hosts: webservers 
  remote_user: root 
  tasks: 
    - name: install package
      yum: name={{ pkname }} state=present 
给变量赋值      
[root@ubunt ansible]# ansible-playbook -e pkname=httpd var2.yml

4、在playbook文件中定义变量

范例:
[root@ubunt ansible]# vim var2.yaml
- hosts: webservers 
  remote_user: root 
  vars:
    pkname: apache2
  tasks: 
    - name: install package
      yum: name={{ pkname }} state=present 
给变量赋值      
[root@ubunt ansible]# ansible-playbook var2.yml

5、使用专用的公共的变量文件

可以在一个独立的playbook文件中定义公共变量,在其它的playbook文件中可以引用变量文件中的变量 
此方式比playbook中定义的变量优化级高

范例:
[root@ubunt ansible]# vim vars.yml
pkname: redis

引用变量
[root@ubunt ansible]# vim var3.yaml
- hosts: webservers 
  remote_user: root 
  vars_files:
    -vars.yaml   
  tasks: 
    - name: "install package {{ pkname }}"
      yum: name={{ pkname }} state=present

6、在主机清单中定义主机和主机组的变量

[root@ubunt ansible]# vim inventory
[webservers]
10.0.0.101     #主机变量,只针对101有效  host=web01
10.0.0.102     #主机变量,只针对102有效  host=web02

[webservers:vars] #分组变量,只针对webservers组下的主机有效
domain=meng

[appservers]
10.0.0.[7:8]
127.0.0.1 ansible_connection=local

[all:vars]       #针对所有分组都有效的变量
suffix=edu

引用变量
[root@ubunt ansible]# vim var3.yaml
- hosts: webservers
  tasks: set hostname
  hostnama: 
    name: "{{ host }}. {{ domain }}. {{ suffix }}"
执行并去查看是否更改
[root@ubunt ansible]# ansible-playbook var3.yaml

举报

相关推荐

0 条评论