Ansible剧本编写


ansible剧本组成部分

剧本组成

ansible剧本编写规范

剧本编写规范:pyyaml

  1. 合理的信息缩进:yaml使用固定的缩进风格表示数据层结构关系,编写ansible-playbook文件一定不能使用tab键进行缩进。
  2. 冒号的使用方法:使用冒号时后面一定要有空格信息,以冒号结尾或冒号信息出现在注释说明中,其后不需要加空格。
  3. 短横线:表示列表,使用一个短横线加一个空格。多个项使用同样的缩进级别作为同一个列表的一部分。

ansible剧本主机规划

外网IP内网IP主机名功能系统版本
10.0.0.61172.16.1.61m01管理主机CentOS 7.x
10.0.0.41172.16.1.41backup被管理主机CentOS 7.x
10.0.0.31172.16.1.31nfs01被管理主机CentOS 7.x
10.0.0.7172.16.1.7web01被管理主机CentOS 7.x

ansible剧本主机清单

主机清单配置文件: /etc/ansible/hosts

  1. 分组配置

    [web] — ansible web -a … 统一操作web组的主机
    172.16.1.7
    172.16.1.8
    172.16.1.9

    [data] — ansible data -a … 统一操作data组的主机
    172.16.1.31
    172.16.1.41

  2. 主机名符号匹配配置

    [web]

    172.16.1.[7:9] 通过IP地址匹配配置

    web[01:03] 通过主机名匹配配置(注意:通过主机名匹配需要在/etc/hosts文件中有主机名和IP的映射)

  3. 加上非标准远程端口(如ssh端口变为52113)

    [web]
    web01:52113
    172.16.1.7:52113

  4. 主机使用特殊的变量

    [web]
    172.16.1.7 ansible_ssh_port=52113 ansible_ssh_user=root ansible_ssh_pass=123456

    [web]
    web01 ansible_ssh_host=172.16.1.7 ansible_ssh_port=52113 ansible_ssh_user=root ansible_ssh_pass=123456

  5. 主机组名嵌入配置

    [rsync:children] — 嵌入子组信息
    rsync_server
    rsync_client
    [rsync_server] — 子组
    172.16.1.41
    [rsync_client] — 子组
    172.16.1.31
    172.16.1.7

    [web:vars] — 嵌入式变量信息
    ansible_ssh_host=172.16.1.7 — 变量
    ansible_ssh_port=52113 — 变量
    ansible_ssh_user=root — 变量
    ansible_ssh_pass=123456 — 变量
    [web] — 该组调用以上变量
    web01

主机清单官方配置方法

ansible剧本编写实践

ad-hoc部署rsync服务

服务端部署

  1. 确认软件安装
    ansible 172.16.1.41 -m yum -a “name=rsync state=installed”
  2. 编写文件
    ansible 172.16.1.41 -m copy -a “src=/etc/ansible/server_file/rsync_server/rsyncd.conf dest=/etc/”
  3. 创建用户
    ansible 172.16.1.41 -m user -a “name=rsync create_home=no shell=/sbin/nologin”
  4. 创建目录
    ansible 172.16.1.41 -m file -a “dest=/backup state=directory owner=rsync group=rsync”
  5. 创建密码文件
    ansible 172.16.1.41 -m copy -a “content=‘rsync_backup:redhat’ dest=/etc/rsync.password mode=600”
  6. 启动服务
    ansible 172.16.1.41 -m service -a “name=rsyncd state=started enabled=yes”

客户端部署

  1. 确认软件安装
    ansible 172.16.1.41,172.16.1.7 -m yum -a “name=rsync state=installed”
  2. 创建密码文件
    ansible 172.16.1.31,172.16.1.7 -m copy -a “content=‘redhat’ dest=/etc/rsync.password mode=600”
  3. 测试
    ansible 172.16.1.31,172.16.1.7 -m file -a “dest=/tmp/test.txt state=touch”
    ansible 172.16.1.31,172.16.1.7 -m shell -a "rsync -avz /tmp/test.txt rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password

playbook部署rsync服务

创建playbook目录

[root@m01 ~]# mkdir /etc/ansible/ansible-playbook

进入playbook目录

[root@m01 ~]# cd /etc/ansible/ansible-playbook/

创建编辑rsync剧本(剧本文件扩展名尽量写为yaml,方便识别文件是一个剧本文件,且文件编写时会有颜色提示

[root@m01 ansible-playbook]# vim rsync_server.yaml

- hosts: 172.16.1.41
  tasks:
    - name: 01-install rsync
      yum: name=rsync state=installed
    - name: 02-push rsyncd.conf
      copy: src=../server_file/rsync_server/rsyncd.conf dest=/etc/
    - name: 03-create user
      user: name=rsync create_home=no shell=/sbin/nologin
    - name: 04-create backup directory
      file: dest=/backup state=directory owner=rsync group=rsync
    - name: 05-create password file
      copy: content=rsync_backup:redhat dest=/etc/rsync.password mode=600
    - name: 06-start rsync service
      service: name=rsyncd state=started enabled=yes    # 配置文件改变,不重启服务不会生效?

- hosts: 172.16.1.31,172.16.1.7
  tasks:
    - name: 01-install rsync
      yum: name=rsync state=installed
    - name: 02-create password file
      copy: content=redhat dest=/etc/rsync.password mode=600
    - name: 03-create test file  
      file: dest=/tmp/test.txt state=touch 
    - name: 04-test      shell: rsync -avz /tmp/test.txt rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password

如何执行剧本?

  1. 检查剧本的语法格式
    [root@m01 ansible-playbook]# ansible-playbook --syntax-check rsync_server.yaml 
    
  2. 模拟执行剧本(彩排)
    [root@m01 ansible-playbook]# ansible-playbook -C rsync_server.yaml 
    
  3. 正式执行剧本(实干)
    [root@m01 ansible-playbook]# ansible-playbook rsync_server.yaml 
    

ansible剧本常见错误

  • 剧本语法规范错误(空格、冒号、短横线);
  • 剧本模块使用是否正确;
  • 剧本中一个name标识下只能写一个模块任务;
  • 剧本中尽量不要大量使用shell模块。

剧本执行出现错误排查思路/步骤:
1)找到剧本中出现问题关键点;
2)将剧本中的操作转换成单条ad-hoc命令操作;
3)将模块的功能操作转换成linux命令;
4)本地管理主机上执行命令测试;
5)远程被管理主机上执行命令测试。

ansible剧本扩展功能

变量

变量名由字母、数字、下划线组成,变量名需要以字母开头,ansible内置关键字不能作为变量名。

  1. 在剧本文件中编写

    在剧本中定义变量,借助vars关键字

    vars:
    backupdir: /backup
    passfile: rsync.password

    使用{{ 变量名 }}可以引用对应的变量

  2. 在命令行中指定(临时设置)

    ansible-playbook -e backupdir=/backup -e passfile=rsync.password rsync_server.yaml

  3. 在主机清单中编写

    vim /etc/ansible/hosts
    [rsync_server:vars]
    backupdir: /backup
    passfile: rsync.password

三种方式优先级:命令行变量设置>剧本变量设置>主机清单变量设置

注册

注册功能可以在执行剧本时,输出命令结果。

- hosts: rsync_server
  tasks:
    - name: check server port
      shell: netstat -lntup 
      register: get_server_port
    
    - name: display port info
      debug: msg={{ get_server_port.stdout_lines }}

判断

指定判断条件

(ansible_hostname == “nfs01”)
(ansible_hostname == “web01”)

例如

- hosts: rsync_server
  remote_user: root
  tasks:
    - name: Check File
      file: path=/tmp/this_is_{{ ansible_hostname }}_file state=touch
      when: (ansible_hostname == "nfs") or (ansible_hostname == "backup")	

setup模块显示被管理主机系统的详细信息

ansible rsync_server -m setup

setup模块获取被管理主机的内置变量信息

ansible rsync_server -m setup -a “filter=xxx”

常见主机信息

参数作用
ansible_all_ipv4_addresses仅显示ipv4的信息
ansible_devices仅显示磁盘设备信息
ansible_distribution显示是什么系统,例:centos,suse等
ansible_distribution_major_version显示是系统主版本
ansible_distribution_version仅显示系统版本
ansible_machine显示系统类型,例:32位,还是64位
ansible_eth0仅显示eth0的信息
ansible_hostname仅显示主机名
ansible_kernel仅显示内核版本
ansible_lvm显示lvm相关信息
ansible_memtotal_mb显示系统总内存
ansible_memfree_mb显示可用系统内存
ansible_memory_mb详细显示内存情况
ansible_swaptotal_mb显示总的swap内存
ansible_swapfree_mb显示swap内存的可用内存
ansible_mounts显示系统磁盘挂载情况
ansible_processor显示cpu个数(具体显示每个cpu的型号)
ansible_processor_vcpus显示cpu个数(只显示总的个数)

循环

一个name下只能执行一个ad-hoc命令,如果想要执行多条,可以使用循环。

- hosts: all
  remote_user: root
  tasks:
    - name: Add Users
      user: name={{ item.name }} groups={{ item.groups }} state=present
      with_items: 
        - { name: 'testuser1', groups: 'bin' }
        - { name: 'testuser2', groups: 'root' }

标签

指定执行标签任务: ansible-playbook --tags=t2 test.yml
跳过指定标签任务: ansible-playbook --skip-tags=t2 test.yml

- hosts: all
  ignore_errors: yes
  remote_user: root
  tasks:
    - name: Check File
      file: path=/tmp/this_is_{{ ansible_hostname }}_file state=touch
      when: (ansible_hostname == "nfs01") or (ansible_hostname == "backup")
      tags: t1
    
    - name: install httpd
      yum: name=httpd state=installed
      when: (ansible_all_ipv4_addresses == ["172.16.1.7","10.0.0.7"])
      tags: t2
    
    - name: install httpd2
      yum: name=httpd2 state=installed
      when: (ansible_distribution == "ubuntu")
      tags: t3

触发

- hosts: backup
  remote_user: root
  tasks:
    - name: 01 Install rsync
      yum: name=rsync state=present
        
    - name: 02 push config file
      copy: src=./file/{{ item.src }} dest=/etc/{{ item.dest }} mode={{ item.mode }} 
      with_items:
        - { src: "rsyncd.conf", dest: "rsyncd.conf", mode: "0644" }
        - { src: "rsync.password", dest: "rsync.password", mode: "0600" }
      notify: restart rsync server

  handlers:    # 当notify发出时,handlers起作用
    - name: restart rsync server
      service: name=rsyncd state=restarted   

忽略错误

默认playbook会检查命令和模块的返回状态,如遇到错误就中断playbook的执行,可以加入ignore_errors: yes忽略错误。

- hosts: all
  remote_user: root
  tasks:
    - name: Ignore False
      command: /bin/false
      ignore_errors: yes
    - name: touch new file
      file: path=/tmp/oldboy_ignore state=touch	

整合剧本

  1. include_tasks: playbook.yaml

    [root@m01 ansible-playbook]# cat main.yml
    - hosts: all(host与include_tasks剧本中的host冲突)
      tasks:
        - include_tasks: rsync-server.yml
        - include_tasks: nfs-server.yml
    
  2. include: playbook.yml(设置gather_facts: no可提高执行速度)

    [root@m01 ansible-playbook]# cat main.yml
    - include:rsync-server.yml	
    - include:nfs-server.yml
    
  3. - import_playbook(主要使用该方法进行汇总)

    [root@m01 ansible-playbook]# vim main.yml 
    - import_playbook: rsync.yml    
    - import_playbook: nfs.yml      
    

ansible剧本角色信息

待解决问题:

  1. 目录结构不够规范?
  2. 编写好的任务如何重复调用?
  3. 服务端配置文件改动,客户端参数信息如何自动变化?
  4. 汇总剧本中如何显示主机角色信息?
  5. 一个剧本内容信息过多,不容易进行阅读,如何进行拆分?

规范目录结构

创建相应角色目录

[root@m01 ~]# cd /etc/ansible/roles/
[root@m01 roles]# mkdir {rsync,nfs-server,nfs-client}

创建角色子目录

[root@m01 roles]# mkdir {rsync,nfs-server,nfs-client}/{vars,tasks,templates,handlers,files}

查看目录结构

[root@m01 roles]# tree /etc/ansible/roles/
/etc/ansible/roles/
|-- nfs-server
|   |-- files    -- 保存需要分发的文件
|   |-- handlers    -- 保存触发器配置文件
|   |-- tasks    -- 保存要执行的动作信息文件
|   |-- templates    -- 保存需要分发的模板文件,模板文件中可以设置变量(调取var目录中的变量值)
|   `-- vars    -- 保存变量信息文件
......

roles目录下创建文件

以部署NFS服务端为例:

  1. 编写tasks目录中main.yml文件

    [root@m01 tasks]# vim main.yml
    - name: 01-copy nfs conf file    
      copy: src=exports dest=/etc/ - name: 02-create data dir    -- 自动去往file目录寻找exports文件
      file: path={{ Data_dir }} state=directory owner=nfsnobody group=nfsnobody
      notify: restart nfs server 
    - name: 03-start server
      service: name={{ item }} state=started enabled=yes
      with_items:    
        - rpcbind
        - nfs
    
  2. 编写vars目录中main.yml文件

    [root@m01 tasks]# cd ../vars
    [root@m01 vars]# vim main.yml
    Data_dir: /data
    
  3. 编写files目录中需要分发的文件

    [root@m01 vars]# cd ../files/
    [root@m01 files]# echo '/data172.16.1.0/24(rw,sync)' > exports
    
  4. 编写handlers目录中main.yml文件

    [root@m01 tasks]# cd ../handlers/
    [root@m01 handlers]# vim main.yml
    [root@m01 handlers]# cat main.yml 
    - name: restart nfs server
      service: name=nfs state=restarted
    
  5. 编写好的目录结构

    [root@m01 nfs-server]# tree
    .
    |-- files
    |   `-- exports
    |-- handlers
    |   `-- main.yml
    |-- tasks
    |   `-- main.yml
    |-- templates
    `-- vars
        `-- main.yml
    
    5 directories, 4 files
    

编写主剧本文件

- hosts: nfs_server
  roles:
    - nfs-server

- hosts: nfs_client
  roles:
    - nfs-client

版权声明:本文为hawava原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。