ansible基础:playbook剧本

作用:用户复杂的任务处理,以及要管理经常要完成的任务。

   playbook也是通过模块和它的参数,在特定主机上执行任务

   playbook是一个文件,该文件中需要通过yaml格式进行书写

yaml语法规范

  1. yaml文件的文件名,一般以yml或yaml作为扩展名
  2. 文件一般以---作为第一行,不是必须的,但是常用
  3. 键值对使用冒号:表示,冒号后面必须有空格。
  4. 数组使用-表示,-后面必须有空格。
  5. 相同的层级必须有相同的缩进。如果缩进不对,则有语法错误。每一级缩进,建议2个空格。
  6. 全文不能使用tab,必须使用空格。

环境准备:

1.配置vim适应yaml语法
 

vim   ~/.vimrc

set ai            #设置自动缩进
set ts=2          #设置按tab键为两个空格
ser et            #将tab转换成相应个数的空格
set cursorcolumn  #能看到对齐

:wq

编写playbook使用方式

1.一个剧本可以有多个play

2.每个play用于指定主机上,通过模块和参数执行相应的任务

3.每个play可以包含多个任务

4.任务由模块和参数构成

#编写用于测试连通性的playbook,相当于执行ansible all -m ping

vim test01.yml

---
- name: test network         # play的名字,可选项
  host: all                  # 作用于所有的主机
  task:                      # 任务
    - name: test ping        # 第1个任务的名字,可选项
      ping:                  # 第1个任务使用的模块


ansible-playbook test01.yml
# 在dbs组的主机和web1上创建/tmp/demo目录,权限是0755。将控制端/etc/hosts拷贝到目标主机的/tmp/demo中

vim test02.yml

---
- name: cteate directory and copy file
  hosts: dbs,web1                     # 这里的名称,必须出现在主机清单文件中
  tasks:
    - name: create dir
      file:
        path: /tmp/demo
        mode:0755
        state: directory

    - name: copy file
      copy:
        src: /etc/hosts
        dest: /tmp/demo/hosts    


ansible-playbook test02.yml
# 在webservers组中的主机上,创建用户bob,附加组是adm;在db1主机上,创建/tmp/hi.txt,其内容为Hello World.

vim test03.yml

---
- name: create user
  hosts: webservers
  tasks:
    - name: create bob
      user:
        name: bob
        groups: adm

- name: create file
  hosts: db1
    - name: make file
      copy:
        dest: /tmp/hi.txt
        content: "Hello World"


ansible-playbook test03.yml

补充知识:

 | 保留换行符

 > 把多行合并成一行

# 通过copy模块创建/tmp/1.txt,文件中有两行内容,分别是Hello World和ni hao

vim test04.yml

---
- name: play1
  hosts: webservers
  tasks:
    - name: mkfile
      copy:
        dest: /tmp/1.txt
        content: |
          Hello World
          ni hao

执行成功后,在webservers组的主机中查看结果

# 在webservers组中的主机上创建john用户,它的uid是1040,主组是daemon,密码为123

vim test04.txt

---
- name: create user
  hosts: websevers
  tasks:
    - name: create user jhon
      user:
        name: jhon
        uid: 1040
        group: daemon
        passwoed: "{{'123' | password_hash('sha512')}}"

# 在webservers组中的主机上创建john用户,它的uid是1040,主组是daemon,密码为123
[root@pubserver ansible]# vim user_john.yml
---
- name: create user
  hosts: webservers
  tasks:
    - name: create user john
      user:
        name: john
        uid: 1040
        group: daemon
        password: "{{'123'|password_hash('sha512')}}"
[root@pubserver ansible]# ansible-playbook user_john.yml


# 在webservers组中的主机上删除用户john
[root@pubserver ansible]# vim del_john.yml
---
- name: delete user
  hosts: webservers
  tasks:
    - name: delete user john
      user:
        name: john
        state: absent
[root@pubserver ansible]# ansible-playbook del_john.yml

硬盘管理

  常用的分区表类型有:MBR(主引导记录)、GPT(GUID分区表)

   MBR最多支持4个主分区,或3个主分区加1个扩展分区。最大支持2.2TB左右的硬盘

   GPT最多支持128个主分区。支持大硬盘

parted模块:

用于硬盘分区管理

常用选项:

  • device:待分区的设备
  • number:分区编号
  • state:present表示创建,absent表示删除
  • part_start:分区的起始位置,不写表示从开头
  • part_end:表示分区的结束位置,不写表示到结尾
# 在web1主机上,对/dev/vdc进行分区,创建1个1GB的主分区


---
- name: disk mange
  hosts: web1
  tasks:
    - name: create  a partition
      parted:
        device: /dev/vdc
        number: 1
        state: present
        part_end: 1GiB



执行成功后进web1主机通过 lsblk 查看结果

# 继续编辑disk.yml,对/dev/vdc进行分区,创建1个新的5GB的主分区


....
    - name: create a new
      parted:
        device: /dev/vdc
        number: 2
        state: present
        part_start: 1GiB
        parted_end: 6GiB
  

执行成功后进web1主机通过 lsblk 查看结果

容量的大是结束位置减去起始位置的结果

 继续编辑disk.yml,创建名为my_vg的卷组,它由上面创建的vdc1和vdc2构成

 继续编辑disk.yml,在my_vg卷组上创建名为my_lv的逻辑卷,大小1G

 继续编辑disk.yml,格式化my_lv为ext4

 继续编辑disk.yml,将my_lv挂载到/data

---
- name: disk manage
  hosts: web1
  tasks:
    - name: create a partition
      parted:
        device: /dev/vdc
        number: 1
        state: present
        part_end: 1GiB


    - name: add a new partition
      parted:
        device: /dev/vdc
        number: 2
        state: present
        part_start: 1GiB
        part_end: 6GiB


    - name: create my_vg
      lvg:
        vg: my_vg
        pvs: /dev/vdc1,/dev/vdc2


    - name: create my_lv
      lvol:
        vg: my_vg
        lv: my_lv
        size: 1G
        
    - name: mkfs my_lv
      filesystem:
        dev: /dev/my_vg/my_lv
        fstype: ext4


    - name: mount my_lv
      mount:
        path: /data
        src: /dev/my_vg/my_lv
        fstype: ext4
        state: mounted

根据功能等,可以将一系列软件放到一个组中,安装软件包组,将会把很多软件一起安装上。比如gcc、java等都是开发工具,安装开发工具包组,将会把它们一起安装。

yum grouplist   # 列出所有的软件包组

yum groupinstall "Development Tools"

# 如果列出的组名为中文,可以这样进行:

LANG=C yum grouplist

---
- name: install pkgs
  hosts: webservers
  tasks:
    - name: install web pkgs    # 此任务通过yum安装三个包
      yum:
        name:
          - httpd
          - php
          - php-mysqlnd
        state: present


    - name: install dev group    # 此任务通过yum安装一组包
      yum:
        name: "@Development Tools"   # @表示后面的名字是组名
        state: present

    - name: update system    # 相当于yum update命令
      yum:
        name: "*"       # 表示系统已经安装的所有包
        state: latest

facts变量

   facts变量是ansible自带的预定义变量,用于描述被控端软硬件信息。

    facts变量通过setup模块获得。

通过setup模块查看所有facts变量

 ansible webservers -m setup
  • acts变量是一个大的由{}构成的键值对字典。在{}中,有很多层级的嵌套。可以通过参数过滤出第一个层级的内容。

ansible webservers -m setup -a "filter=ansible_all_ipv4_addresses"
查看所有的IPV4地址,filter是过滤的意思


ansible webservers -m setup -a "filter=ansible_memfree_mb"
# 查看可用内存


常用的facts变量
  ansible_all_ipv4_addresses:所有的IPV4地址
  ansible_bios_version:BIOS版本信息
  ansible_memtotal_mb:总内存大小
  ansible_hostname:主机名
在playbook中使用变量    debug模块用于输出信息,常用的参数是msg,用于输出指定内容

# 显示远程主机的主机名和内存大小。在ansible中,变量使用{{}}表示
# debug模块用于输出信息,常用的参数是msg,用于输出指定内容
---
- name: display host info
  hosts: webservers
  tasks:
    - name: display hostname and memory
      debug:    # debug是模块,它的选项msg可以输出指定信息
        msg: "hostname: {{ansible_hostname}}; mem: {{ansible_memtotal_mb}} MB"

# 显示远程主机的主机名和内存大小。在ansible中,变量使用{{}}表示
# debug模块用于输出信息,常用的参数是msg,用于输出指定内容
[root@pubserver ansible]# vim debug.yml
---
- name: display host info
  hosts: webservers
  tasks:
    - name: display hostname and memory
      debug:    # debug是模块,它的选项msg可以输出指定信息
        msg: "hostname: {{ansible_hostname}}; mem: {{ansible_memtotal_mb}} MB"


[root@pubserver ansible]# ansible-playbook debug.yml

找对应数据的方法:

ansible web1 -m setup | less 搜寻对应的数据后,单词以ansible开头,找到对应的值后,往上找到最上一级的以ansible开头。语法:通过.调用子键,eg :ansible_eth0.ipv4.address

# 配置nginx服务
[root@pubserver ansible]# vim firewall.yml
---
- name: configure webservers
  hosts: webservers
  tasks:
    - name: install nginx pkg   # 这里通过yum模块装httpd
      yum:
        name: nginx
        state: present


    - name: start nginx service   # 这里通过service模块启httpd服务
      service:
        name: nginx
        state: started
        enabled: yes
        
[root@pubserver ansible]# ansible-playbook firewall.yml
[root@pubserver ansible]# curl http://192.168.88.11/  # 可访问


# 安装并启动firewalld
[root@pubserver ansible]# vim firewall.yml
---
- name: configure webservers
  hosts: webservers
  tasks:
    - name: install nginx pkg   # 这里通过yum模块装httpd
      yum:
        name: nginx
        state: present


    - name: start nginx service   # 这里通过service模块启httpd服务
      service:
        name: nginx
        state: started
        enabled: yes
  
    - name: install firewalld pkg   # 这里通过yum模块装firewalld
      yum:
        name: firewalld
        state: present


    - name: start firewalld service   # 这里通过service模块启firewalld服务
      service:
        name: firewalld
        state: started
        enabled: yes
  
[root@pubserver ansible]# ansible-playbook firewall.yml
[root@pubserver ansible]# curl http://192.168.88.11/  # 被拒绝
curl: (7) Failed to connect to 192.168.88.11 port 80: 没有到主机的路由


# 配置防火墙规则,放行http协议
[root@pubserver ansible]# vim firewall.yml
---
- name: configure webservers
  hosts: webservers
  tasks:
    - name: install nginx pkg   # 这里通过yum模块装httpd
      yum:
        name: nginx
        state: present


    - name: start nginx service   # 这里通过service模块启httpd服务
      service:
        name: nginx
        state: started
        enabled: yes
  
    - name: install firewalld pkg   # 这里通过yum模块安装firewalld
      yum:
        name: firewalld
        state: present


    - name: start firewalld service   # 这里通过service模块启service服务
      service:
        name: firewalld
        state: started
        enabled: yes
  
    - name: set firewalld rules   # 通过firewalld模块开放80端口
      firewalld:
        port: 80/tcp
        permanent: yes
        immediate: yes
        state: enabled


[root@pubserver ansible]# ansible-playbook firewall.yml 
[root@pubserver ansible]# curl http://192.168.88.11/  # 可访问
template模块
  • copy模块可以上传文件,但是文件内容固定
  • template模块可以上传具有特定格式的文件(如文件中包含变量)
  • 当远程主机接收到文件之后,文件中的变量将会变成具体的值
  • template模块上传的文件,使用的语法叫Jinja2。
  • 常用选项:
    • src:要上传的文件
    • dest:目标文件路径
# 使用template模块将含有变量的文件上传到webservers组中的主机
[root@pubserver ansible]# vim index.html
Welcome to {{ansible_hostname}} on {{ansible_eth0.ipv4.address}}


[root@pubserver ansible]# vim templ.yml
---
- name: upload index
  hosts: webservers
  tasks:
    - name: create web index
      template:
        src: index.html
        dest: /usr/share/nginx/html/index.html


[root@pubserver ansible]# ansible-playbook templ.yml
[root@pubserver ansible]# curl http://192.168.88.11/
Welcome to web1 on 192.168.88.11
[root@pubserver ansible]# curl http://192.168.88.12
Welcome to web2 on 192.168.88.12
[root@web1 ~]# cat /usr/share/nginx/html/index.html
Welcome to web1 on 192.168.88.11
[root@web2 ~]# cat /usr/share/nginx/html/index.html
Welcome to web2 on 192.168.88.12

进阶语法

错误处理

  • 默认:当Playbook中包含很多任务时,没有由上而下执行,当某一个任务遇到错误,它将崩溃,终止执行后续任务
# 在webservers组中的主机上启动mysqld服务,然后创建/tmp/service.txt
# 因为目标主机上没有mysqld服务,所以它将崩溃,终止执行。即,不会创建/tmp/service.txt文件
[root@pubserver ansible]# vim myerr.yml
---
- name: my errors
  hosts: webservers
  tasks:
    - name: start mysqld service  # 通过service模块启动mysqld服务
      service:
        name: mysqld
        state: started
        enabled: yes
        
    - name: touch a file   # 通过file模块创建文件
      file:
        path: /tmp/service.txt
        state: touch


# 执行playbook,第1个任务就会失败
[root@pubserver ansible]# ansible-playbook myerr.yml
# 到node1上查看,因为第2个任务没有执行,所以文件不会创建
[root@web1 ~]# ls /tmp/service.txt
ls: cannot access '/tmp/service.txt': No such file or directory
  • 可以指定某一个任务如果出现错误,则忽略它
# 编辑myerr.yml,如果myslqd服务无法启动,则忽略它
[root@pubserver ansible]# vim myerr.yml
---
- name: my errors
  hosts: webservers
  tasks:
    - name: start mysqld service
      service:
        name: mysqld
        state: started
        enabled: yes
      ignore_errors: yes    # 即使这个任务失败了,也要继续执行下去


    - name: touch a file
      file:
        path: /tmp/service.txt
        state: touch


[root@pubserver ansible]# ansible-playbook myerr.yml
[root@web1 ~]# ls /tmp/service.txt   # 第2个任务已执行
/tmp/service.txt
  • 通过全局设置,无论哪个任务出现问题,都要忽略
[root@pubserver ansible]# vim myerr.yml
---
- name: my errors
  hosts: webservers
  ignore_errors: yes
  tasks:
    - name: start mysqld service
      service:
        name: mysqld
        state: started
        enabled: yes


    - name: touch a file
      file:
        path: /tmp/mysql.txt
        state: touch


[root@pubserver ansible]# ansible-playbook myerr.yml
[root@web1 ~]# ls /tmp/mysql.txt 
/tmp/mysql.txt

触发执行任务

  • 通过handlers定义触发执行的任务
  • handlers中定义的任务,不是一定会执行的
  • 在tasks中定义的任务,通过notify关键通知handlers中的哪个任务要执行
  • 只有tasks中的任务状态是changed才会进行通知。
# 下载web1上的/etc/nginx/nginx.conf
[root@pubserver ansible]# vim get_conf.yml
---
- name: download nginx.conf
  hosts: web1
  tasks:
    - name: get nginx.conf
      fetch:
        src: /etc/nginx/nginx.conf
        dest: ./
        flat: yes    # 直接下载文件,不要目录
[root@pubserver ansible]# ansible-playbook get_conf.yml


# 修改nginx.conf的端口为变量
[root@pubserver ansible]# vim +39 nginx.conf
... ...
    server {
        listen       {{http_port}} default_server;
        listen       [::]:{{http_port}} default_server;
        server_name  _;
... ...


# 修改nginx服务的端口为8000,重启nginx
[root@pubserver ansible]# vim trigger.yml
---
- name: configure nginx
  hosts: webservers
  vars:
    http_port: "8000"   # 定义nginx.conf中的变量和值
  tasks:
    - name: upload nginx.conf   # 上传nginx.conf
      template:
        src: ./nginx.conf
        dest: /etc/nginx/nginx.conf


    - name: restart nginx    # 重启服务
      service:
        name: nginx
        state: restarted
# 第一次执行trigger.yml,上传文件和重启服务两个任务的状态都是黄色changed
[root@pubserver ansible]# ansible-playbook trigger.yml
# 第二次执行trigger.yml,上传文件的任务状态是绿色的ok,重启服务任务的状态是黄色changed
[root@pubserver ansible]# ansible-playbook trigger.yml


# 既然配置文件没有改变,那么服务就不应该重启
# 修改Playbook,只有配置文件变化了,才重启服务
[root@pubserver ansible]# vim trigger.yml
---
- name: configure nginx
  hosts: webservers
  vars:
    http_port: "80"
  tasks:
    - name: upload nginx.conf
      template:
        src: ./nginx.conf
        dest: /etc/nginx/nginx.conf
      notify: restart nginx   # 通知restart httpd需要执行


  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted
# 第一次运行Playbook,因为第1个任务是黄色的changed,所以handlers中的任务也被触发执行
[root@pubserver ansible]# ansible-playbook trigger.yml 
# 第二次运行Playbook,因为第1个任务是绿色的OK,也就不会再触发执行其他任务了
[root@pubserver ansible]# ansible-playbook trigger.yml

when条件

  • 只有满足某一条件时,才执行任务
  • 常用的操作符:
    • ==:相等
    • !=:不等
    • >:大于
    • <:小于
    • <=:小于等于
    • >=:大于等于
  • 多个条件或以使用and或or进行连接
  • when表达式中的变量,可以不使用{{}} ,

×××××××× 没有上下的执行顺序,都要先执行when语句

# 当dbs组中的主机内存大于2G的时候,才安装mysql-server
[root@pubserver ansible]# vim when1.yml
---
- name: install mysql-server
  hosts: dbs
  tasks:
    - name: install mysql-server pkg
      yum:
        name: mysql-server
        state: present
      when: ansible_memtotal_mb>2048


# 如果目标主机没有2GB内存,则不会安装mysqld-server
[root@pubserver ansible]# ansible-playbook when1.yml






# 多条件。系统发行版是Rocky8才执行任务
# /etc/motd中的内容,将会在用户登陆时显示在屏幕上
取消可以卸载软件 yum remove cowsay
 域名-有install cowsay  cowsay -l   cowsay -f kiss laalalal
[root@pubserver ansible]# vim motd
 _____________
< hello world >
 -------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


[root@pubserver ansible]# vim when2.yml
---
- name: when condition
  hosts: webservers
  tasks:
    - name: modify /etc/motd
      copy:
        dest: /etc/motd
        src: motd
      when: >     # 以下三行合并成一行
        ansible_distribution == "Rocky"
        and
        ansible_distribution_major_version == "8"


[root@pubserver ansible]# ansible-playbook when2.yml

register注册变量

Ansible的“register”模块是用于捕获和保存任务执行结果的,它允许将其他任务的输出作为变量使用。register是一个关键字,可以将任务执行的结果赋值给指定的变量名称。这个变量可以在后续任务中使用。register模块可以捕获各种类型的输出,包括stdout、stderr、rc、changed等。它可以与其他模块一起使用,例如“when”条件、“loop”循环等。 存的是字典。键值对的方式,可以通过 字典名「“key”」或者 字典名.键调用值

# 在web1组的主机上执行任务,创建/tmp/regfile1.txt,并打印创建结果
[root@pubserver ansible]# vim reg1.yml
---
- name: create file /tmp/regfile1.txt
  hosts: web1
  tasks:
    - name: create file
      file:
        path: /tmp/rgefile1.txt
        state: touch
      register: result


    - name: display output
      debug:
        msg: "{{result}}"


# 在web1主机上执行任务,创建文件/tmp/ademo/abc。如果创建不成功,则通过debug输出create failed
[root@pubserver ansible]# vim reg2.yml
---
- name: create file /tmp/ademo/abc
  hosts: web1
  ignore_errors: yes
  tasks:
    - name: create file
      file:
        path: /tmp/ademo/abc
        state: touch
      register: result


    - name: debug output
      debug:
        msg: "create failed"
      when: result.failed              

cowsay:

# cowsay是一个软件,可以在以下地址获得
# https://rpmfind.net/linux/epel/8/Everything/x86_64/Packages/c/cowsay-3.04-16.el8.noarch.rpm
# 使用方式如下:
[root@pubserver ansible]# yum install -y /root/cowsay-3.04-16.el8.noarch.rpm
[root@pubserver ansible]#  
< ni hao a >
----------
  \   ^__^
   \  (oo)\_______
      (__)\       )\/\
          ||----w |
          ||     ||


# 查看其他形象
[root@pubserver ansible]# cowsay -l
Cow files in /usr/share/cowsay:
beavis.zen blowfish bud-frogs bunny cheese cower default dragon
dragon-and-cow elephant elephant-in-snake eyes flaming-sheep fox
ghostbusters head-in hellokitty kiss kitty koala kosh luke-koala
mech-and-cow meow milk moofasa moose mutilated ren sheep skeleton small
stegosaurus stimpy supermilker surgery telebears three-eyes turkey turtle
tux udder vader vader-koala www
[root@pubserver ansible]# cowsay -f elephant are you ok?
_____________
< are you ok? >
-------------
\     /\  ___  /\
\   // \/   \/ \\
((    O O    ))
\\ /     \ //
 \/  | |  \/
  |  | |  |
  |  | |  |
  |   o   |
  | |   | |
  |m|   |m|
# 如果执行playbook时也会出现奶牛,则可以使用以下方式取消
[root@pubserver ansible]# echo 'nocows = 1' >> ansible.cfg

# 在test组中的主机上创建5个目录/tmp/{aaa,bbb,ccc,ddd,eee}
[root@pubserver ansible]# vim loop1.yml
---
- name: use loop
  hosts: webservers
  tasks:
    - name: create directory
      file:
        path: /tmp/{{item}}
        state: directory
      loop: [aaa,bbb,ccc,ddd,eee]


# 上面写法,也可以改为:
---
- name: use loop
  hosts: webservers
  tasks:
    - name: create directory
      file:
        path: /tmp/{{item}}
        state: directory
      loop: 
        - aaa
        - bbb
        - ccc
        - ddd
        - eee


[root@pubserver ansible]# ansible-playbook loop1.yml




# 使用复杂变量。创建zhangsan用户,密码是123;创建lisi用户,密码是456
# item是固定的,用于表示循环中的变量
# 循环时,loop中每个-后面的内容作为一个整体赋值给item。
# loop中{}中的内容是自己定义的,写法为key:  val 注意空格
# 取值时使用句点表示。如下例中取出用户名就是{{item.uname}}
[root@pubserver ansible]# vim loop_user.yml
---
- name: create users
  hosts: webservers
  tasks:
    - name: create multiple users
      user:
        name: "{{item.uname}}"
        password: "{{item.upass|password_hash('sha512')}}"
      loop:
        - {"uname": "zhangsan", "upass": "123"}
        - {"uname": "lisi", "upass": "456"}
[root@pubserver ansible]# ansible-playbook  loop_user.yml

role角色

  • 为了实现playbook重用,可以使用role角色
  • 角色role相当于把任务打散,放到不同的目录中,目录不需要全都有,可以删掉
  • 再把一些固定的值,如用户名、软件包、服务等,用变量来表示
  • role角色定义好之后,可以在其他playbook中直接调用

切换上一个目录 cd - 可以来回切

roles 和tasks没有顺序,roles先执行,tasks后执行,但里面的任务由上而下执行

# 使用常规playbook,修改/etc/motd的内容
# 1. 创建motd模板文件
[root@pubserver ansible]# vim motd
Hostname: {{ansible_hostname}}     # facts变量,主机名
Date: {{ansible_date_time.date}}   #  facts变量,日期
Contact to: {{admin}}              # 自定义变量


# 2. 编写playbook
[root@pubserver ansible]# vim motd.yml
---
- name: modifty /etc/motd
  hosts: webservers
  vars:
    admin: root@tedu.cn            # 自定义名为admin的变量
  tasks:
    - name: modify motd
      template:
        src: motd
        dest: /etc/motd


[root@pubserver ansible]# ansible-playbook motd.yml
[root@web1 ~]# cat /etc/motd 
Hostname: web1
Date: 2021-11-01
Contact to: root@tedu.cn




# 创建角色
# 1. 声明角色存放的位置
[root@pubserver ansible]# vim ansible.cfg 
[defaults]
inventory = hosts
roles_path = roles    # 定义角色存在当前目录的roles子目录中


# 2. 创建角色目录
[root@pubserver ansible]# mkdir roles


# 3. 创建名为motd的角色
[root@pubserver ansible]# ansible-galaxy init roles/motd  名字自定义
[root@pubserver ansible]# ls roles/
motd     # 生成了motd角色目录
[root@pubserver ansible]# yum install -y tree
[root@pubserver ansible]# tree roles/motd/
roles/motd/
├── defaults         # 定义变量的目录,优先级最低
│    └── main.yml
├── files            # 保存上传的文件(如copy模块用到的文件)
├── handlers         # handlers任务写到这个目录的main.yml中
│    └── main.yml
├── meta             # 保存说明数据,如角色作者、版本等
│    └── main.yml
├── README.md        # 保存角色如何使用之类的说明
├── tasks            # 保存任务
│    └── main.yml
├── templates        # 保存template模块上传的模板文件
├── tests            # 保存测试用的playbook。可选
│    ├── inventory
│    └── test.yml
└── vars             # 定义变量的位置,推荐使用的位置
     └── main.yml


# 4. 将不同的内容分别写到对应目录的main.yml中
# 4.1 创建motd模板文件
[root@pubserver ansible]# vim roles/motd/templates/motd
Hostname: {{ansible_hostname}}
Date: {{ansible_date_time.date}}
Contact to: {{admin}}


# 4.2 创建变量
[root@pubserver ansible]# vim roles/motd/vars/main.yml  # 追加一行
admin: zzg@tedu.cn


# 4.3 创建任务
[root@pubserver ansible]# vim roles/motd/tasks/main.yml  # 追加
- name: modify motd
  template:
    src: motd      # 这里的文件,自动到templates目录下查找
    dest: /etc/motd


# 5. 创建playbook,调用motd角色
[root@pubserver ansible]# vim role_motd.yml
---
- name: modify motd with role
  hosts: webservers
  roles:
    - motd


# 6. 执行playbook
[root@pubserver ansible]# ansible-playbook role_motd.yml

role练习

  1. 创建名为pkgs的角色。用于装包。包名使用变量pkg代表
  2. 创建inst_nginx.yml,调用pkgs角色,安装nginx
  3. 创建inst_mysql.yml,调用pkgs角色,安装mysql
# 1. 创建名为pkgs的角色。
# 1.1 创建角色目录
[root@pubserver ansible]# ansible-galaxy init roles/pkgs
# 1.2 创建装包的任务,包名使用变量pkg代表
[root@pubserver ansible]# vim roles/pkgs/tasks/main.yml 
---
# tasks file for roles/pkgs
- name: install rpm pkg
  yum:
    name: "{{pkg}}"
    state: present
# 1.3 定义变量
[root@pubserver ansible]# vim roles/pkgs/defaults/main.yml 
---
# defaults file for roles/pkgs
pkg: nginx


# 2. 创建inst_nginx.yml,调用pkgs角色,安装nginx
[root@pubserver ansible]# vim inst_nginx.yml
---
- name: install nginx pkg
  hosts: webservers
  roles:
    - pkgs
[root@pubserver ansible]# ansible-playbook inst_nginx.yml


# 3. 创建inst_mysql.yml,调用pkgs角色,安装mysql-server
[root@pubserver ansible]# vim inst_mysql.yml 
---
- name: install mysql pkg
  hosts: dbs
  vars:
    pkg: mysql-server
  roles:
    - pkgs
[root@pubserver ansible]# ansible-playbook inst_mysql.yml
# 在公共仓库中搜索与nginx相关的角色
[root@myhost ~]# ansible-galaxy search nginx
# 如果找到相应的角色,如名字为mynginx,可以下载它到roles目录
[root@myhost ~]# ansible-galaxy install mynginx -p roles/

ansible加解密文件

  • ansible加解密文件使用ansible-vault命令
[root@pubserver ansible]# echo "Hi ni hao" > hello.txt 
[root@pubserver ansible]# cat hello.txt
Hi ni hao


# 加密文件
[root@pubserver ansible]# ansible-vault encrypt hello.txt
New Vault password: 123456
Confirm New Vault password: 123456
Encryption successful
[root@pubserver ansible]# cat hello.txt
$ANSIBLE_VAULT;1.1;AES256
37373366353566346235613731396566646533393361386131313632306563633336333963373465
6164323461356130303863633964393339363738653036310a666564313832316263393061616330
32373133323162353864316435366439386266616661373936363563373634356365326637336165
6336636230366564650a383239636230623633356565623461326431393634656666306330663533
6235


# 解密
[root@pubserver ansible]# ansible-vault decrypt hello.txt
Vault password: 123456
Decryption successful
[root@pubserver ansible]# cat hello.txt 
Hi ni hao




# 加密后更改密码
[root@pubserver ansible]# ansible-vault encrypt hello.txt 
New Vault password: 123456
Confirm New Vault password: 123456
Encryption successful


[root@pubserver ansible]# ansible-vault rekey hello.txt   # 改密码
Vault password: 123456    # 旧密码
New Vault password: abcd  # 新密码
Confirm New Vault password: abcd
Rekey successful


# 不解密文件,查看内容
[root@pubserver ansible]# ansible-vault view hello.txt 
Vault password: abcd
Hi ni hao




# 使用密码文件进行加解密
# 1. 将密码写入文件
[root@pubserver ansible]# echo 'tedu.cn' > pass.txt
# 2. 创建明文文件
[root@pubserver ansible]# echo 'hello world' > data.txt
# 3. 使用pass.txt中的内容作为密码加密文件
[root@pubserver ansible]# ansible-vault encrypt --vault-id=pass.txt data.txt
Encryption successful
[root@pubserver ansible]# cat data.txt    # 文件已加密
# 4. 使用pass.txt中的内容作为密码解密文件
[root@pubserver ansible]# ansible-vault decrypt --vault-id=pass.txt data.txt
Decryption successful
[root@pubserver ansible]# cat data.txt 
hello world
  • 使用ansible管理远程主机,存储敏感数据时(如,文件中包含密码),应该将其加密
  • 执行playbook时,通过--ask-vault-password选项提示输入密码
# 1. 编写有密码的playbook
[root@pubserver ansible]# vim user_zhangsan.yml
---
- name: create a user
  hosts: webservers
  tasks:
    - name: create user zhangsan
      user:
        name: zhangsan
        password: "{{'123'|password_hash('sha512')}}"


# 2. 加密playbook
[root@pubserver ansible]# ansible-vault encrypt user_zhangsan.yml
New Vault password: 123456
Confirm New Vault password: 123456
Encryption successful


# 3. 直接执行playbook,报错
[root@pubserver ansible]# ansible-playbook user_zhangsan.yml
ERROR! Attempting to decrypt but no vault secrets found


# 4. 使用--ask-vault-password选项
[root@pubserver ansible]# ansible-playbook --ask-vault-password user_zhangsan.yml
Vault password: 123456
起
通过 ansible-playbook --help | less 查询

sudo命令

  • 一般用于普通用户执行需要root权限的命令
  • 在web1上配置zhangsan拥有sudo权限
# 如果没有zhangsan,手工创建
[root@web1 ~]# visudo   # 将会打开vi,在尾部追加以下一行
zhangsan        ALL=(ALL)       ALL
# 中间的ALL=(ALL)在集中认证的域环境中才有效,单机忽略即可
# zhangsan是用户名,最后的ALL表示zhangsan可以以管理员的身份执行所有命令


# 切换成zhangsan用户,执行命令
[root@web1 ~]# su - zhangsan
[zhangsan@web1 ~]$ useradd wangwu   # 失败,因为还是张三身份
[zhangsan@web1 ~]$ sudo useradd wangwu  # 以管理员身份执行
... ...
[sudo] password for zhangsan: # 输入zhangsan的密码,不是root




# 配置lisi不输入密码可以直接运行sudo
[root@web1 ~]# visudo    # 在最后追加一行
lisi    ALL=(ALL)       NOPASSWD: ALL


# 切换成lisi运行
[root@web1 ~]# su - lisi
[lisi@web1 ~]$ ls /root/   # 没权限
ls: cannot open directory '/root/': Permission denied
[lisi@web1 ~]$ sudo ls /root/    # 成功运行,无需输入密码
a3.txt  anaconda-ks.cfg

特殊的主机清单变量

  • 如果远程主机没有使用免密登陆,如果远程主机ssh不是标准的22端口,可以设置特殊的主机清单变量
  • ansible_ssh_user:指定登陆远程主机的用户名
  • ansible_ssh_pass:指定登陆远程主机的密码
  • ansible_ssh_port:指定登陆远程主机的端口号
# 删除远程主机的/root/.ssh/authorized_keys,以便恢复通过密码登陆
[root@pubserver ansible]# ansible all -m file -a "path=/root/.ssh/authorized_keys state=absent"


# 创建新的工作目录
[root@pubserver ~]# mkdir myansible
[root@pubserver ~]# cd myansible
[root@pubserver myansible]# vim ansible.cfg
[defaults]
inventory = inventory
[root@pubserver myansible]# vim inventory
[group1]
web1
web2
db1
[root@pubserver myansible]# ansible all -m ping  # 报错,因为无法免密执行


# 修改web1 ssh服务的端口为220
[root@web1 ~]# systemctl stop firewalld
[root@web1 ~]# echo 'Port 220' >> /etc/ssh/sshd_config
[root@web1 ~]# systemctl restart sshd
# 退出再登陆时,需要指定端口号
[root@myhost ~]# ssh -p220 192.168.88.11 






# 配置ssh通过用户名、密码管理远程主机,通过220端口连接web1
[root@pubserver myansible]# vim inventory 
[group1]
web1 ansible_ssh_user=root ansible_ssh_pass=a ansible_ssh_port=220
web2 ansible_ssh_user=root ansible_ssh_pass=a
db1 ansible_ssh_user=root ansible_ssh_pass=a


[root@pubserver myansible]# ansible all -m ping

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值