day45-Ansible流程控制

发布于:2025-08-31 ⋅ 阅读:(24) ⋅ 点赞:(0)

1.每日复盘与今日内容

1.1复盘

  • 在play中定义变量
  • 在当前目录group_vars host_vars 定义变量🍟🍟🍟🍟🍟
  • 变量注册register🍟🍟🍟🍟🍟
  • 使用Facts内置变量 ansible_hostname 获取客户端主机名称等...🍟🍟🍟🍟🍟

1.2今日内容

  • when判断🍟🍟🍟🍟🍟、Handlers
  • 循环语句
  • 任务标签、文件复用
  • jinjia2模板
  • roles模板🍟🍟🍟🍟🍟

2.Ansible-流程控制

playbook条件语句
不管是shell还是各大编程语言中,流程控制,条件判断这些都是必不可少的,在我们使用Ansible的过程中,条件判断的使用频率极其高。
例如:
1.我们使用不同的系统的时候,可以通过判断系统来对软件包进行安装。
2.在nfs和rsync安装过程中,客户端服务器不需要推送配置文件,之前我们都是写多个play,会影响效率。
3.我们在源码安装nginx的时候,执行第二遍就无法执行了,此时我们就可以进行判断是否安装过。

1. when判断

案例1.客户端WEB01卸载 wget WEB02卸载tree命令

- hosts: webs
  tasks:
    - name: Install wget
      yum:
        name: wget
        state: present
      when: ansible_hostname == "WEB01"

    - name: Remove tree
      yum:
        name: tree
        state: absent
      when: ansible_hostname == "WEB02"

ansible-playbook  --syntax-check when.yml

ansible-playbook  when.yml

案例2.并且关系 主机名称是WEB01并且IP地址是10.0.0.7

[root@m01 ansible]# cat when.yml 
- hosts: webs
  tasks:
    - name: Install wget
      yum:
        name: wget
        state: present
      when: (ansible_hostname == "web01") and (ansible_default_ipv4.address == "10.0.0.7")
      
或者使用列表的方式
[root@m01 ansible]# cat when.yml 
- hosts: webs
  tasks:
    - name: Install wget
      yum:
        name: wget
        state: present
      when: 
        - ansible_hostname == "web01"
        - ansible_default_ipv4.address == "10.0.0.7"

案例3.或者关系 or

[root@m01 ansible]# cat when.yml 
- hosts: webs
  tasks:
    - name: Install wget
      yum:
        name: wget
        state: present
      when: ( ansible_hostname == "web01") or (ansible_default_ipv4.address == "10.0.0.8")

2. Nginx-when判断实战

[root@m01 ansible]# cat nginx.yml
- hosts: 10.0.0.8
  tasks:
    - name: Configure Nginx Repo
      yum_repository:
        name: nginx
        description: Nginx YUM repo
        baseurl: http://nginx.org/packages/centos/7/$basearch/
        gpgcheck: no
        enabled: yes
              
    - name: Install Nginx Server
      yum:
        name: nginx
        state: present

    - name: Create Group www
      group:
        name: www
        gid: 666
        state: present

    - name: Create User www
      user:
        name: www
        uid: 666
        group: www
        shell: /sbin/nologin
        create_home: false

    - name: Configure Nginx Server
      copy:
        src: nginx.conf
        dest: /etc/nginx/

    - name: nginx check to ng_re
      command: nginx -t
      register: ng_re
      ignore_errors: yes  # 当结果错误时候忽略掉、继续向下执行
    - name: Restart Nginx Server
      systemd:
        name: nginx
        state: restarted
        enabled: yes
      when: ng_re is search "successful"   # 判断ng_re变量中是否存在successful


或者使用其他的返回值作为执行标准
    - name: Restart Nginx Server
      systemd:
        name: nginx
        state: restarted
        enabled: yes
      when: ng_re.rc is match "0"



#when条件表达式
when:  ansible_hostname == "web01"
when:  ansible_hostname is match "web01"
when:  ansible_hostname is search "web01"
ansible_hostname is search "web"   # 只要主机名称有web则运行
ansible_hostname is match "web"    # 只要主机名称有web则运行





#ignore_errors: yes  当tasks执行错误时、忽略继续执行。

3. Handlers

什么是handlers?

handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。

案例: 当nginx.conf配置文件被修改才会触发重启动作、如果不修改则不重启

[root@m01 ansible]# cat nginx.yml
- hosts: 10.0.0.8
  tasks:
    - name: Configure Nginx Repo
      yum_repository:
        name: nginx
        description: Nginx YUM repo
        baseurl: http://nginx.org/packages/centos/7/$basearch/
        gpgcheck: no
        enabled: yes
              
    - name: Install Nginx Server
      yum:
        name: nginx
        state: present

    - name: Create Group www
      group:
        name: www
        gid: 666
        state: present

    - name: Create User www
      user:
        name: www
        uid: 666
        group: www
        shell: /sbin/nologin
        create_home: false

    - name: Configure Nginx Server
      copy:
        src: nginx.conf
        dest: /etc/nginx/
      notify: Restart Nginx Server

    - name: nginx -t
      command: nginx -t
      register: ng_re
      ignore_errors: yes
      
    - name: Start Nginx Server
      systemd:
        name: nginx
        state: started
        enabled: yes


  handlers:
    - name: Restart Nginx Server
      systemd:
        name: nginx
        state: restarted
        enabled: yes
      when: ng_re.rc is match "0"

4. playbook循环语句

之前的学习过程中,我们经常会有传送文件,创建目录之类的操作,创建2个目录就要写两个file模块来创建,如果要创建100个目录,我们需要写100个file模块???妈耶~~~~ 当然不是,只要有循环即可,减少重复性代码。

案例1.创建多个文件

[root@m01 ansible]# cat a.yml 
- hosts: webs
  tasks:
    - name: touch a.txt b.txt
      file:
        path: "{{ item }}"
        state: touch
      loop:
        - a.txt
        - b.txt

案例2.拷贝多个文件

[root@m01 ansible]# cat copy.yml
- hosts: 10.0.0.8
  tasks:
    - name: copy a.txt to /root , b.txt to /opt
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
      loop:
        - { src: a.txt,dest: /root/ }
        - { src: b.txt,dest: /opt/ }

案例3.a.txt到/root 属主属主为root 权限644, b.txt到/opt属主属组www 权限600

[root@m01 ansible]# cat copy.yml
- hosts: 10.0.0.8
  tasks:
    - name: copy a.txt to /root , b.txt to /opt
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        owner: "{{ item.owner }}"
        group: "{{ item.group }}"
        mode: "{{ item.mode }}"
      loop:
        - { src: a.txt,dest: /root/,owner: root,group: root,mode: '0644' }
        - { src: b.txt,dest: /opt/,owner: www,group: www,mode: '0600' }

案例4.创建两个组

oldboy01 组 gid 778
oldboy02 组 gid 779
[root@m01 ansible]# cat group.yml
- hosts: web02
  tasks:
    - name: create groups
      group:
        name: "{{ item.name }}"
        gid: "{{ item.gid }}"
      loop:
        - { name: oldboy01,gid: '778' }
        - { name: oldboy02,gid: '779' }

案例5.创建两个用户

oldboy01 uid gid 778的普通账号
oldboy02 uid gid 779的虚拟账号
[root@m01 ansible]# cat user.yml
- hosts: web02
  tasks:
    - name: Create User
      user: 
        name: "{{ item.name }}"
        uid: "{{ item.uid }}"
        group: "{{ item.group }}"
        shell: "{{ item.shell }}"
        create_home: "{{ item.home }}"
        state: present
      loop:
        - { name: oldboy01,uid: '778',group: oldboy01,shell: /bin/bash,home: true }
        - { name: oldboy02,uid: '779',group: oldboy02,shell: /sbin/nologin,home: false }
[root@m01 ansible]# ansible-playbook  user.yml

5. playbook任务标签

默认情况下,Ansible在执行一个playbook时,会执行playbook中定义的所有任务,Ansible的标签(tag)功能可以给单独任务甚至整个playbook打上标签,然后利用这些标签来指定要运行playbook中的个别任务,或不执行指定的任务。

#第一步给一个task打标签
vim nginx.yml
..
    - name: Configure Nginx Server
      copy:
        src: nginx.conf
        dest: /etc/nginx/
      notify: Restart Nginx Server
      tags: config

    - name: nginx -t
      command: nginx -t
      register: ng_re
      ignore_errors: yes
      tags: config

...




#第二步: 查看yml中所有的标签
[root@m01 ansible]# ansible-playbook nginx.yml --list-tags

playbook: nginx.yml

  play #1 (web02): web02	TAGS: []
      TASK TAGS: [config]


#第三步: 通过-t指定某个标签运行
[root@m01 m01]# ansible-playbook tag.yml --list-tags  # 查看当前的所有tag
[root@m01 m01]# ansible-playbook tag.yml -t config   # 只运行带有config标签的tasks
[root@m01 m01]# ansible-playbook tag.yml --skip-tags config # 跳过带有config标签的tasks

6. playbook文件复用

在之前写playbook的过程中,我们发现,写多个playbook没有办法,一键执行,这样我们还要单个playbook挨个去执行,很鸡肋。所以在playbook中有一个功能,叫做`include`用来动态调用task任务列表。

#需求 nfs服务器上安装nfs服务 web02上安装nginx服务
#第一步准备两个tasks文件
[root@m01 ansible]# cat a.yml
- name: Install nfs Server
  yum:
    name: nfs-utils
    state: present

[root@m01 ansible]# cat b.yml
- name: Install nginx Server
  yum:
    name: nginx
    state: present
      
#第二步: 准备一个文件将上面两个文件包含引入
[root@m01 ansible]# cat all.yml
- hosts: all
  tasks:
    - include_tasks: a.yml
      when: ansible_hostname is match "nfs"
    - include_tasks: b.yml
      when: ansible_hostname is match "web02"
[root@m01 ansible]# ansible-playbook  --syntax-check all.yml

playbook: all.yml
[root@m01 ansible]# ansible-playbook  all.yml

7. 抑制changed

目标已经变成我想要的了,将changed改为ok

 - name: nginx -t
      command: nginx -t
      register: ng_re
      ignore_errors: yes
      tags: config
      changed_when: false   # 将黄色修改为绿色

8. jiaja2模板

什么是jiaja2?

jinja2是Python的全功能模板引擎

Jinja2与Ansible啥关系?

Ansible通常会使用jinja2模板来修改被管理主机的配置文件等

Ansible如何使用Jinja2?

使用Ansible的jinja2模板也就是使用template模块,该模块和copy模块一样,都是将文件复制到远端主机上去,但是区别在于,template模块可以获取到文件中的变量,而copy则是原封不动的把文件内容复制过去。之前我们在推送rsync的backup脚本时,想把脚本中的变量名改成主机名,如果使用copy模块则推送过去的就是{{ ansible_fqdn }},不变,如果使用template,则会变成对应的主机名。

案例1.将motd.j2拷贝到目标主机的/root下

[root@m01 ansible]# cat copy.yml
- hosts: web02
  tasks:
    - name: copy motd.j2 to web02
      template:
        src: motd.j2
        dest: /root/motd
[root@m01 ansible]# ansible-playbook  copy.yml

查看目标内容
[root@web02 ~]# cat motd 
Welcome to web02
This system total mem is : 948 MB
This system free mem is: 148 MB
This system ip address is : 10.0.0.8

案例2.生成负载均衡的配置文件

[root@m01 ansible]# cat lb.conf.j2 
upstream {{ server_name }} {
{% for n in range(7,9) %} 
        server 172.16.1.{{ n }}:{{ up_port }};
{% endfor %}
}

server {
        listen 80;
        server_name {{ server_name }};

        location / {
                root /code;
                index index.html;
                proxy_pass http://{{ server_name }};
                proxy_set_header Host $http_host;
        }
}


拷贝到目标主机
[root@m01 ansible]# cat copy.yml
- hosts: web02
  vars:
    - server_name: www.wp.com
    - up_port: 8080
  tasks:
    - name: copy lb.conf to web02
      template:
        src: lb.conf.j2
        dest: /root/lb.conf

案例3.将keepliaved.conf.j2拷贝到两台web

routeid 都以自身主机名称生成
web01生成是角色master 票数150
web02生成的角色backup 票数100
[root@m01 ansible]# cat keepalived.conf.j2
global_defs {
    router_id {{ ansible_hostname }}
}

vrrp_instance VI_1 {
{% if ansible_fqdn == "web01" %}
    state MASTER
    priority 150
{% else %}
    state BACKUP
    priority 100
{% endif %}

    interface eth0
    virtual_router_id 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {         
        10.0.0.3
    }
}


[root@m01 ansible]# cat copy.yml 
- hosts: webs
  tasks:
    - name: copy keepalived.conf.j2 to webs
      template:
        src: keepalived.conf.j2
        dest: /root/keepalived.conf

9. Roles角色

roles对playbook的一种重新编排。

  • 前期准备
root@Ansible01 ~# mkdir roles
root@Ansible01 ~# cd roles/
root@Ansible01 ~/roles# ansible-galaxy init backup
- Role backup was created successfully
root@Ansible01 ~/roles# tree backup/
backup/
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

8 directories, 8 files

root@Ansible01 ~/roles/backup# rm -fr defaults/ meta/ README.md tests/
root@Ansible01 ~/roles/backup# ll
total 0
drwxr-xr-x 2 root root  6 Aug 30 12:10 files
drwxr-xr-x 2 root root 22 Aug 30 12:10 handlers
drwxr-xr-x 2 root root 22 Aug 30 12:10 tasks
drwxr-xr-x 2 root root  6 Aug 30 12:10 templates
drwxr-xr-x 2 root root 22 Aug 30 12:10 vars

案例: roles重构backup服务

41恢复快照
41和81做免密钥

#1.安装rsync
#2.配置rsync 收集rsync.conf
#3.rsync.conf中配置变量练习
#4.启动rsync

root@Ansible01 ~/roles/backup/tasks# vim main.yml 

- name: Install rsync Server
  yum:
    name: rsync
    state: present

- name: Configure Rsync Server
  template:
    src: "{{ item.src }}"
    dest: "{{ item.dest }}"
    mode: "{{ item.mode }}"
  notify: Restart rsync Server
  loop:
    - { src: rsyncd.conf.j2,dest: /etc/rsyncd.conf,mode: '0644' }
    - { src: rsync.passwd,dest: /etc/,mode: '0600' }


- name: Create Group
    state: directory
    owner: www
    group: www

- name: Start backup Server
  systemd:
    name: rsyncd
    state: started
    enabled: yes


[root@m01 templates]# pwd
/root/roles/backup/templates
[root@m01 templates]# cat rsyncd.conf.j2 
uid = {{ user }}
gid = {{ user }}
port = {{ port }}
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
#####################################
[backup]
comment = welcome to oldboyedu backup!
path = {{ code_dir }}

#密码文件
[root@m01 templates]# pwd
/root/roles/backup/templates
[root@m01 templates]# cat rsync.passwd
    rsync_backup:123

#变量文件内容
[root@m01 backup]# pwd
/root/roles/backup
[root@m01 backup]# cat vars/main.yml 
user: www
port: 873
code_dir: /backup

#handlers配置文件
[root@m01 backup]# cat handlers/main.yml
- name: Restart rsync Server
  systemd:
    name: rsyncd
    state: restarted

#site配置文件
root@Ansible01 ~/roles# vim site.yml
- hosts: all
  roles:
    - role: backup
      when: ansible_hostname is match "backup"
      

测试成功

3.今日总结

  • when判断🍟🍟🍟🍟🍟、Handlers
  • 循环语句
  • 任务标签、文件复用
  • jinjia2模板
  • roles模板🍟🍟🍟🍟🍟


网站公告

今日签到

点亮在社区的每一天
去签到