Ansible自动化运维

第一章

历史

Ansible是一款开源的自动化运维工具,于2012年由Michael DeHaan创建,并于2015年被Red Hat收购。以下是Ansible的历史:

2012年:Michael DeHaan创建了Ansible,最初是为了解决他在其他自动化工具中遇到的限制和不足。

2013年:Ansible发布了第一个版本1.0,并获得了很好的反响。Ansible的设计理念是“简单、易用、灵活”,与其他自动化工具相比,它更加轻量级,易于学习和使用。

2015年:Red Hat收购了Ansible,将其纳入自己的产品线中,并推出了Ansible Tower,这是一款专业版的Ansible,提供了更加完善的功能和支持。

2016年:Ansible 2.0发布,引入了许多新特性和改进,如支持Windows平台、提高了性能和可靠性等。

2017年:Ansible成为了DevOps领域最流行的自动化工具之一,广泛应用于云计算、容器化、网络自动化等领域。

2018年:Ansible 2.7发布,增强了Ansible Tower的集成能力和扩展性,引入了更多的网络自动化功能等。

2019年:Ansible 2.8发布,进一步增强了网络自动化能力,并引入了很多新特性,如模块增强、F5 BIG-IP支持等。

2020年:Ansible发布了2.10版本,引入了Ansible Collection的概念,允许用户将Ansible模块、插件和其他资源组合成可重用的集合,并提供了更多的扩展性和灵活性。

在过去的几年中,Ansible不断发展壮大,成为DevOps自动化领域中的重要工具之一。它的简单易用、灵活性高以及广泛的社区支持,使其受到越来越多的开发者和运维人员的青睐。

简介

第二章 部署ansible

规划

节点 角色
workstation 管理节点|ansible
servera 受管节点|python、SSH
serverb 受管节点|python、SSH
serverc 受管节点|python、SSH
serverd 受管节点|python、SSH
bastion 网关
classroom 软件仓库、DNS等

部署

自己部署

添加软件仓库、yum安装即可

网站:
# https://fedoraproject.org/wiki/EPEL
# yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
镜像站方式:
# https://www.centos.org/
# http://mirrors.163.com/centos/8/
# https://developer.aliyun.com/mirror/centos?spm=a2c6h.13651102.0.0.3e221b11ZQrqR5

培训环境

【workstation】
# dnf -y install ansible

ansible配置文件优先级

# dnf -y install ansible
# ansible --version
# ifconfig
# rpm -qc ansible
# vim /etc/ansible/ansible.cfg
# ansible --version
# ansible --version|grep config
# ansible --version|grep 'config file'
# mkdir ansible
# cp /etc/ansible/ansible.cfg ansible/
# cd ansible/
# ansible --version|grep 'config file'
# pwd
# cd /mnt/ansi
# mkdir /mnt/ansi
# cd /mnt/ansi
# cp /etc/ansible/ansible.cfg ansible/
# cp /etc/ansible/ansible.cfg .
# ansible --version|grep 'config file'
# cd ~/ansible/
# ansible --version|grep 'config file'
# cd
# cp /etc/ansible/ansible.cfg .ansible.cfg
# ls -la
# ansible --version|grep 'config file'
# cd /mnt/
# ansible --version|grep 'config file'
# cd /root/ansible/
# ansible --version|grep 'config file'
# vim /etc/profile
# source /etc/profile
# ansible --version|grep 'config file'
# cd
# ansible --version|grep 'config file'
# echo $ANSIBLE_CONFIG
# ls /mnt/ansi/ansible.cfg
# vim /etc/profile
# ansible --version|grep 'config file'
# cd ansible/
# ansible --version|grep 'config file'
# ls -ld /mnt/
# cp /etc/ansible/ansible.cfg /opt/
# vim /etc/profile
# tail -n 3 /etc/profile
#export ANSIBLE_CONFIG=/opt/ansible.cfg
export ANSIBLE_CONFIG=/root/ansible/ansible.cfg
# source /etc/profile
# ls /opt/ansible.cfg
# ansible --version|grep 'config file'
# vim /etc/profile
# source /etc/profile
# ansible --version|grep 'config file'
# vim /etc/profile
# source /etc/profile
# ansible --version|grep 'config file'
# history
# history -w
# pwd
# ls
# pwd
# ansible --version|grep 'config file'
# pwd
# vim /etc/profile
# source /etc/profile
# ansible --version|grep 'config file'
# ls

清单、多清单

# cp /etc/ansible/hosts inventory
# vim inventory


[webservers]
servera.lab.example.com Name=servera
serverb.lab.example.com Name=serverb
[dbservers]
serverc.lab.example.com
serverd.lab.example.com
[servers:children]
webservers
dbservers
[dbservers:vars]
Name="serverc+serverd"
[all:vars]
course=rh294


# ansible-inventory --g
# vim inventory
# ansible-inventory --g
# vim inventory
# ansible-inventory --g
# vim inventory
# ansible-inventory --g
# ansible --help
# ansible --list-hosts all
# ansible --list-hosts webserver
# ansible --list-hosts dbserver
# ansible-inventory --g
# vim inventory
# ansible-inventory --g
# ansible --list-hosts storage
# vim inventory
# ansible --list-hosts dbserver
# vim inventory
# history
# ansible --list-hosts storage
# vim inventory
# ansible --list-hosts storage
# vim inventory
# ansible-inventory --g
# ansible --list-hosts servers
# vim inventory
# ansible-inventory --g
# vim inventory
# ansible-inventory --g
# history -w
# vim ansible.cfg
# ls
# mkdir hosts
# ls
# mv inventory ../
# ls
# cp ../inventory hosts/webserver
# cp ../inventory hosts/dbserver
# cp ../inventory hosts/storage
# cd hosts/
# vim webserver
# vim dbserver
# vim storage
# cd ..
# pwd
# ls
# ansible-inventory --g
# ansible --list-hosts webserver
# ansible --list-hosts dbserver
# ansible --list-hosts storage
# grep inve ansible.cfg | grep ^[^#]
# tree hosts/
# vim hosts/webserver
ansible webserver -m shell -a 'whoami'
# ansible --list-hosts storage
# ls
# ls -ld hosts/
# grep inve ansible.cfg | grep ^[^#]
# tree hosts/
# l
# ls
# vim hosts/webserver


多清单课上实验:
[root@workstation ansible]# tree inventory/
inventory/
├── db
├── servers
└── web

0 directories, 3 files
[root@workstation ansible]# cat inventory/db 
[db]
serverc.lab.example.com
serverd.lab.example.com
[root@workstation ansible]# cat inventory/web 
[web]
servera.lab.example.com
serverb.lab.example.com

[root@workstation ansible]# cat inventory/servers 
[web]
[db]
[servers:children]
web
db

清单规则

主机 主机组 嵌套组 范围
Web1.example.com [web-servers] [Web-servers] 【START:END】
Web2.example.com Web1.example.com Web2.example.com Web1.example.com Web2.example.com Server[01:20].example.com
db1.example.com [db-servers] [Db-servers] [a:d].dns.example.com
db1.example.com db1.example.com db2.example.com db1.example.com db2.example.com
192.168.10.20 172.17.25.8 172.17.25.8
[Servers:children]
Web-servers

AD-HOC

格式

# ansible host-pattern –m module [-a ‘module arguments’] [-i inventory]
# vim hosts/dbserver
# ansible dbserver -m ping
# ansible all -m user -a 'name=easthome state=present'
# cd hosts/
# ls
# vim storage
# ansible all -m shell -a 'id easthome'
# id easthome
# history
# ansible all -m user -a 'name=easthome state=absent'
# ansible all -m user -a 'id easthome'
# ansible all -m shell -a 'id easthome'
# ansible all -m user -a 'name=easthome state=present comment=admin uid=2000 shell=/sbin/nologin'
# ansible all -m shell -a 'id easthome'
# ansible all -m shell -a 'grep easthome /etc/passwd'
# ansible all -m user -a 'name=easthome state=absent comment=admin uid=2000 shell=/sbin/nologin'
# ansible all -m shell -a 'grep easthome /etc/passwd'

常用选项
  -k 询问密码
  -C 空运行
  -u 指定用户
  -m 指定模块
  -a 模块参数
  -f 并行数量
  -i 清单文件
  -c 连接方式
  -t 记录日志
  -o 单行输出
  -T 超时时间
  -e 传入变量
  # vim hosts/dbserver
# ansible dbserver -m ping
# ansible all -m user -a 'name=easthome state=present'
# cd hosts/
# ls
# vim storage
# ansible all -m shell -a 'id easthome'
# id easthome
# history
# ansible all -m user -a 'name=easthome state=absent'
# ansible all -m user -a 'id easthome'
# ansible all -m shell -a 'id easthome'
# ansible all -m shell -a 'grep easthome /etc/passwd'
# ansible servers --list-hosts
# ls
# ansible webserver --list-hosts
# cd ..
# ansible webserver -a 'whoami'
# ansible webserver -m shell -u student -a 'whoami'
# ansible webserver -m shell -u student -t logs/ 'whoami;pwd'
# ansible webserver -m shell -u student -t logs/ -a 'whoami;pwd'
# ls
# tree logs/
# vim logs/servera.lab.example.com
# vim logs/serverb.lab.example.com
# ansible --help
# ansible webserver --list-host
# ansible webserver --list-hosts
# ansible webserver -u student -a 'whoami'
# ansible webserver -u student -b --become-method=sudo --become-user=root -a 'whoami'
# ansible webserver -u student -b --become-method=sudo --become-user=root -K -a 'whoami'
# ansible webserver -u student -b --become-method=sudo --become-user=root --ask-become-pass -a 'whoami'

帮助

# ansible-doc -l|grep file
# ansible-doc file /EX /string
# history -w
# ansible-doc -j user
# ansible-doc -s user

命令模块

# command
# shell
# script
# raw


# ansible webserver -u student -a 'whoami'
# ansible webserver -u student -a 'useradd easthome'
# ansible webserver -a 'useradd easthome'
# ansible webserver -a 'useradd test'
# ansible webserver -a 'echo mima|passwd --stdin test'
# ansible webserver -m shell -a 'echo mima|passwd --stdin test'
# ansible webserver -a 'pwd;touch myfile;whoami'
# ansible webserver -m shell -a 'pwd;touch myfile;whoami'
# ls
# vim info.sh
# ls
# sh info.sh
# pwd
# ansible webserver -m script -a '/root/ansible/info.sh'
# ls
# vim test.py
# ansible webserver -m script -a '/root/ansible/test.py'

第三章 playbook

[root@workstation ansible]# cat apache.yaml 
#ansible web -m yum -a 'name=httpd state=present'
#ansible web -m service -a 'name=httpd state=started enabled=yes'
#ansible web -m copy -a 'content="welcome to apache\n" dest=/var/www/html/index.html'
#ansible web -m firewalld -a 'service=http permanent=yes state=enabled immediate=yes'
#curl servera.lab.example.com
---
- name: deploy apache
  hosts: db
  tasks:
  - name: install httpd
    yum: 
      name: httpd
      state: present

  - name: start service
    service:
      name: httpd
      state: started
      enabled: yes

  - name: copy content
    copy:
      content: "welcome to db server apache\n"
      dest: /var/www/html/index.html

  - name: allow httpd from firewalld
    firewalld:
      service: http
      permanent: yes
      state: enabled
      immediate: yes
- name: web test
  hosts: web
  tasks:
  - name:
    shell: curl serverb.lab.example.com
    register: result

  - name: print result
    debug:
      msg: "{{ result }}"

apache

[root@workstation ansible]# cat apache.yaml 
---
- name: p1
  hosts: web
  tasks:
  - name: p1-t1
    yum:
      name: httpd
      state: present

  - name: p1-t2
    copy:
      content: "HELLO WORLD\n" 
      dest: /var/www/html/index.html

  - name: p1-t3
    service:
      name: httpd
      state: started
      enabled: yes
 
  - name: p1-t4
    firewalld:
      service: http
      permanent: yes
      state: enabled
      immediate: yes
- name: p2
  hosts: db
  tasks:
  - name: p2-t1
    uri:
      url: http://serverb.lab.example.com
      return_content: yes
    register: this

  - name: p2-t2
    debug:
      var: this

nfs

[root@workstation ansible]# cat nfs.yaml 
---
- name: p1
  hosts: web
  tasks:
  - name: p1-t1
    yum:
      name: nfs-utils
      state: present

  - name: p1-t2
    service:
      name: nfs-server
      state: started
      enabled: yes

  - name: p1-t3
    copy:
      content: '/share *(rw)'
      dest: /etc/exports
  
  - name: p1-t4
    file:
      name: /share
      state: directory
  
  - name: p1-t5
    service:
      name: nfs-server
      state: restarted
   
  - name: p1-t6
    firewalld:
      service: nfs
      permanent: yes
      state: enabled
      immediate: yes

  - name: p1-t7
    firewalld:
      service: rpc-bind
      permanent: yes
      state: enabled
      immediate: yes

  - name: p1-t8
    firewalld:
      service: mountd
      permanent: yes
      state: enabled
      immediate: yes
- name: p2
  hosts: serverc.lab.example.com
  tasks:
  - name: p2-t1
    file:
      name: /myshare
      state: directory
  
  - name: p2-t2
    mount:
      path: /myshare
      src: servera.lab.example.com:/share
      fstype: nfs
      opts: ro,noauto
      state: mounted

命令模块

# command
# shell
# script
# raw


# ansible webserver -u student -a 'whoami'
# ansible webserver -u student -a 'useradd easthome'
# ansible webserver -a 'useradd easthome'
# ansible webserver -a 'useradd test'
# ansible webserver -a 'echo mima|passwd --stdin test'
# ansible webserver -m shell -a 'echo mima|passwd --stdin test'
# ansible webserver -a 'pwd;touch myfile;whoami'
# ansible webserver -m shell -a 'pwd;touch myfile;whoami'
# ls
# vim info.sh
# ls
# sh info.sh
# pwd
# ansible webserver -m script -a '/root/ansible/info.sh'
# ls
# vim test.py
# ansible webserver -m script -a '/root/ansible/test.py'

playbook ad-hoc对比

三板斧

语法 描述
缩进 YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不能使用tabs
冒号 以冒号结尾的除外,其他所有冒号后面所有必须有空格
短横线 表示列表项,使用一个短横线加一个空格,多个项使用同样的缩进级别作为同一列表

vim编辑器设置

# 调整tab键缩进
vim ~/.vimrc
:help
:help usr_05.txt
/auto
# help usr_05.txt找到autocmd FileType
$ vim ~/.vimrc   生产环境你可能没有root权限那么做一个自己的vimrc比较合适
set number 
autocmd FileType text  setlocal
修改:
autocmd FileType yaml   setlocal ts=2 sw=2  et

httpd

[root@workstation ansible]# cat first.yaml 
---
- name: first play
  hosts: webserver
  tasks:
  - name: install apache
    dnf:
      name: httpd
      state: present
  
  - name: START HTTPD
    service:
      name: httpd
      state: started
      enabled: yes
  
  - name: firewalld allow
    firewalld:
      service: http
      permanent: yes
      state: enabled
      immediate: yes 

  - name: copy content
    copy: 
      content: "hello world\n"
      dest: /var/www/html/index.html
- name: test web server
  hosts: workstation
  tasks:
  - name: task1
    uri:
      url: http://servera.lab.example.com
      return_content: yes
    register: result1

  - name: tesk2
    debug:
      msg: "{{ result1 }}"

  - name: task3
    uri:
      url: http://serverb.lab.example.com
      return_content: yes
    register: result2

  - name: task4
    debug:
      msg: "{{ result2 }}"

nfs

[root@workstation ansible]# cat nfs.yaml 
---
- name: play1
  hosts: servera
  tasks:
  - name: task1
    yum: 
      name: nfs-utils
      state: present

#  - name: task2
#    shell: echo '/share 172.25.250.0/24(rw,sync)' > /etc/exports.d/share.exports

  - name: task2
    copy:
      content: /share 172.25.250.0/24(rw,sync)
      dest: /etc/exports.d/share.exports

  - name: task3
    file:
      path: /share
      state: directory

  - name: task4
    service:
      name: rpcbind
      state: started
      enabled: yes

  - name: task5
    service:
      name: nfs-server
      state: started
      enabled: yes

  - name: task6
    firewalld:
      service: nfs
      permanent: yes
      state: enabled
      immediate: yes
    
  - name: task7
    firewalld:
      service: mountd
      permanent: yes
      state: enabled
      immediate: yes

  - name: task8
    firewalld:
      service: rpc-bind
      permanent: yes
      state: enabled
      immediate: yes

- name: mount nfs
  hosts: workstation
  tasks:
  - name:
    shell: mount -t nfs 172.25.250.10:/share /mnt
#  - name:
#    mount: 
#      path: /mnt
#      src: 172.25.250.10:/share
#      fstype: nfs
#      state: mounted

输出任务的详细程度

ansible-playbook -v nfs.yaml
ansible-playbook  nfs.yaml
ansible-playbook -vv nfs.yaml
ansible-playbook -vv nfs.yaml > test
vim test
ansible-playbook -vvv nfs.yaml > test
vim test
ansible-playbook -vvvv nfs.yaml > test
选项 描述
-v 显示任务结果
-vv 任务结果和任务配置都会显示
-vvv 包含关于与受管主机连接的信息
-vvvv 增加了连接插件相关的额外详细程度选项, 包括受管主机上用于执行脚本的用户,以及所执行的脚本

校验

ansible-playbook --syntax-check nfs.yaml
vim nfs.yaml
ansible-playbook --syntax-check nfs.yaml
vim nfs.yaml
ansible-playbook --syntax-check nfs.yaml
ansible-playbook -C nfs.yaml

第四章 变量管理

变量作用

# 在Ansible中支持设置主机变量、组变量,变量支持嵌套使用,定义好了的变量可以在playbook中引用。由于Ansible是在每个主机上单独运行命令,所以不同的主机去调用同样的变量,也可以取到不同的值的,这样进行一些配置就更灵活合理。

变量命名

无效变量名称 有效变量名称
web server web_server
remote.file remote_file
1st file file_1、file1
remoteserver$1 remote_server_1、remote_server1
有效的变量名 无效vim
foo *foo,Python关键字,例如asynclambda
foo_env 剧本关键字,例如environment
foo_port foo-port,,foo port``foo.port
foo5_foo 5foo12

简单变量定义

---
- name: first play
  hosts: servera
  vars:
    remote_create_dir: /myshare
  tasks:
  - name: print info
    debug:
      msg: "{{ remote_create_dir }}"
#  - name:
#    command: mkdir {{ remote_create_dir }}

变量引用

---
- name: first play
  hosts: servera
  vars:
    remote_create_dir: /test
    state: directory
  tasks:
  - name: print info
    debug:
      msg: "{{ remote_create_dir }}"
  - name:
    file:
      name: "{{ remote_create_dir }}"
      state: "{{ state }}"
      mode: 0777
      owner: root
      group: root
  - name:
    copy:
      src: /etc/hosts
      dest: "{{ remote_create_dir }}"
  - name:
    command: ls -l {{ remote_create_dir }}
    register: result
  - name:
    debug:
      msg: "{{ result }}"

play task 变量优先级

主机变量优先于组变量,但playbook中定义的变量的优先级比这两者更高

主机变量、主机组变量及他们拆分文件变量定义

# cd ansible/
# ls
# ansible --version
# pwd
# ls
# ansible --version
# ansible-inventory --g
# ansible servera -m ping
# vim ~/.vimrc
# ls
# vim example.yml
# cp example.yml vars.yml
# vim vars.yml
# ansible-playbook --syntax-check vars.yml
# ansible-playbook vars.yml
# ansible-playbook --syntax-check vars.yml
# ansible-playbook vars.yml
# ansible servera -a 'ls -ld /myshare'
# cp example.yml varsa.yml
# cp vars.yml varsa.yml
# vim varsa.yml
# ansible servera -a 'ls -ld /myshare'
# ansible-playbook varsa.yml
# ansible servera -a 'ls -ld /myshare'
# vim varsa.yml
# ansible-playbook varsa.yml
# vim varsa.yml
# ansible-playbook varsa.yml
# vim varsa.yml
# cp example.yml users.yml
# vim users.yml
# vim users_var.yml
# ansible-playbook users.yml
# vim users.yml
# ansible-playbook users.yml
# ansible-playbook users.yml
# vim users.yml
# pwd
# ls
# grep inventory ansible.cfg
# echo $ANSIBLE_CONFIG
# cd hosts/
# ls
# cd ..
# vim hosts/servera
# ansible servera -m debug -a 'msg={{ name }}'
# ansible servera -m debug -a 'msg="The name is: {{ name }}"'
# vim hosts/serverb
# ansible serverb -m debug -a 'msg="The name is: {{ name }}"'
# pwd
# ls
# ansible-inventory --g
# ansible webserver --list-hosts
# ansible webserver -m debug -a 'msg="The name is: {{ name }}"'
# vim hosts/webserver
# ansible webserver -m debug -a 'msg="The name is: {{ name }}"'
# vim hosts/webserver
# ls
# mkdir /bakcup
# mv hosts/ /bakcup/
# ls
# ls -l /bakcup/
# ls -l /bakcup/hosts/
# ls
# vim ansible.cfg
# history
# ls
# vim ansible.cfg
# cp /etc/ansible/hosts .
# l
# ls
# vim hosts
# ansible-inventory --g
# vim hosts
# ansible webserver -m ping
# vim hosts
# vim hosts
# ansible webserver -m debug -a 'msg="The name is: {{ name }}"'
# ansible webserver -m debug -a 'msg="The name is: {{ name,workdir }}"'
# vim hosts
# ansible webserver -m debug -a 'msg="The name is: {{ name,workdir }}"'
# cp example.yml hostvar.yml
# vim hostvar.yml
# vim hosts
# ansible all -m debug -a 'msg="The name is: {{ name }}"'
# vim hosts
# ansible all -m ping
# ls
# mkdir host_vars
# mkdir groups_vars     # 注意是group 后面mv改过来了
# ls
# cat hosts
# vim host_vars/servera.lab.example.com
# ansible webserver -m debug -a 'msg="{{message}}"'
# cp host_vars/servera.lab.example.com host_vars/serverb.lab.example.com
# vim host_vars/serverb.lab.example.com
# ansible webserver -m debug -a 'msg="{{message}}"'
# vim groups_vars/webserver
# cp host_vars/servera.lab.example.com groups_vars/webserver
# vim groups_vars/webserver
# ansible webserver -m debug -a 'msg="{{message}}"'
# vim groups_vars/webserver
# ansible webserver -m debug -a 'msg="{{message,name}}"'
# vim hosts
# vim groups_vars/webserver
# ansible webserver -m debug -a 'msg="{{message,hostname}}"'
# vim groups_vars/
# vim groups_vars/webserver
# ansible webserver -m debug -a 'msg="{{message,name}}"'
# ansible webserver -m debug -a 'msg="{{message,name,NAME}}"'
# vim hosts
# mv groups_vars/ group_vars/
# ansible webserver -m debug -a 'msg="{{message,name,NAME}}"'

从命令行传递变量

# ansible-playbook -e name=jack comment='admins' shell='/bin/bash' uid=10000 users.yml
# ansible-playbook -e name=jack -e comment='admins' -e shell='/bin/bash' -e uid=10000 users.yml
# ansible webserver -m debug -a 'msg={{ name }}'
# ansible webserver -e name=test -m debug -a 'msg={{ name }}'
# ansible webserver -e Name=test -m debug -a 'msg={{ Name }}'
# ls
# vim nfs.yaml
# ansible-playbook nfs.yaml
# ansible-playbook -e share_path="/myshare" nfs.yaml
# vim nfs.yaml
# ansible-playbook -e share_path="/myshare" nfs.yaml
# mount -t nfs 172.25.250.10:/myshare /mnt
# vim nfs.yaml
# ansible-playbook -e share_path="/myshare" nfs.yaml
# df -TH
# umount /mnt
# ansible-playbook -e share_path="/serverashare" nfs.yaml
# df -TH
# vim nfs.yaml
[root@workstation ansible]# cat nfs.yaml 
---
- name: play1
  hosts: servera
  tasks:
  - name: task1
    yum: 
      name: nfs-utils
      state: present

#  - name: task2
#    shell: echo '/share 172.25.250.0/24(rw,sync)' > /etc/exports.d/share.exports

  - name: task2
    copy:
      content: "{{ share_path }} 172.25.250.0/24(rw,sync)"
      dest: /etc/exports.d/share.exports

  - name: task3
    file:
      path: "{{ share_path }}"
      state: directory

  - name: task4
    service:
      name: rpcbind
      state: started
      enabled: yes

  - name: task5
    service:
      name: nfs-server
      state: restarted
      enabled: yes

  - name: task6
    firewalld:
      service: nfs
      permanent: yes
      state: enabled
      immediate: yes
    
  - name: task7
    firewalld:
      service: mountd
      permanent: yes
      state: enabled
      immediate: yes

  - name: task8
    firewalld:
      service: rpc-bind
      permanent: yes
      state: enabled
      immediate: yes

- name: mount nfs
  hosts: workstation
  tasks:
  - name:
    shell: mount -t nfs 172.25.250.10:{{ share_path }} /mnt
#  - name:
#    mount: 
#      path: /mnt
#      src: 172.25.250.10:/share
#      fstype: nfs
#      state: mounted

列表变量定义与使用

---
- name: first play
  hosts: servera
#  vars:
#    address:
#      - beijing
#      - hebei
#      - tianjin
  vars_files:
    address_vars.yml
  tasks:
  - name: print list vars
    debug:
      msg:
      - "{{ beifang[0] }}"
      - "{{ nanfang[0] }}"
     # - "{{ address[1] }}"
     # - "{{ address[2] }}"
nanfang:
  - guangzhou
  - xianggang
  - taiwan
beifang:
  - beijing
  - hebei
  - tianjin

字典变量

# 字典将数据存储在键值对中。通常,词典用于存储相关数据,例如ID或用户个人资料中包含的信息。
您可以使用YAML字典定义更复杂的变量。YAML字典将键映射到值。例如:
foo:
  field1: one
  field2: two

注册变量

[root@workstation ansible]# cat registr.yml 
---
- name: first play
  hosts: servera
  tasks:
  - name:
    command:
      argv:
      - cat
      - /etc/hosts
    register: result
  - name:
    debug:
      msg:
      - "{{ result['rc'] }}"
      - "{{ result['stdout_lines'] }}"

管理机密

# ansible-vault -h
# cat example.yml
# ansible-vault encrypt example.yml
# cat example.yml
# ansible-playbook example.yml
# ansible-playbook view example.yml
# cat example.yml
# ansible-vault decrypt example.yml
# cat example.yml
# ansible-vault encrypt example.yml
# ansible-vault view example.yml
# ansible-vault edit example.yml
# ansible-vault rekey example.yml
# ansible-vault view example.yml
# ansible-vault view example.yml --vault-password-file=passwd.txt
# ansible-vault view example.yml --vault-id==passwd.txt
# ansible-vault view example.yml --vault-id=passwd.txt
# ansible-vault edit example.yml --vault-id=passwd.txt
# ansible-vault edit example.yml
# pwd
# vim ansible.cfg
# ansible-vault edit example.yml
# ansible-vault rekey example.yml
# ansible-vault edit example.yml
# cat passwd.txt
# cat example.yml
# vim example.yml
# ansible-playbook example.yml
# vim example.yml
# cat example.yml
# ansible-vault create locker.yml --vault-password-file=passwd.txt
# ansible-vault create locker.yml --vault-password-file=/root/ansible/passwd.txt
# ansible-vault create --vault-password-file=/root/ansible/passwd.txt locker.yml
# ls
# cat passwd.txt
# ansible-vault create locker.yml
# cat locker.yml
# ansible-vault view locker.yml
# ansible-vault create locker1.yml
# cat locker1.yml
# ansible-vault view locker1.yml
# vim ansible.cfg
/vault
#vault_password_file = /root/ansible/passwd.txt

# ansible-vault create --vault-password-file=/root/ansible/passwd.txt lk.yml
# ansible-vault view lk.yml
# ansible-vault view --vault-password-file=/root/ansible/passwd.txt lk.yml

管理事实变量

# ansible webserver -m setup 
# ansible webserver -m setup > webserver.txt
# vim webserver.txt
# ansible webserver -m setup -a filter=*fqdn*
# ansible webserver -m setup -a filter=*hostname*
# ansible webserver -m setup -a filter=*device*
# ansible webserver -m setup -a filter=*bios*
# cp example.yml hw.yml
# vim hw.yml
# rm -rf hw.yml
# vim hw.yml
# ansible webserver -m shell -a 'cat /root/hwreport.txt'
# ansible-playbook hw.yml
# vim hw.yml
# ansible-playbook hw.yml
# vim hw.yml
# ansible webserver -m shell -a 'cat /root/hwreport.txt'
# vim hw.yml
[root@workstation ansible]# cat hw.yml 
---
- name:
  hosts: webserver
  tasks:
  - name:
    copy:
      content: |
        HOST={{ ansible_hostname }}
        MEMORY={{ ansible_memtotal_mb }}
        BIOS={{ ansible_bios_version }}
        IPV4={{ ansible_default_ipv4['address'] }}
        VDA_DISK_SIZE={{ ansible_devices['vda']['size'] }}
      dest: /root/hwreport.txt

魔法变量

# ansible webserver -m debug -a var=inventory_hostname
# ansible webserver -m debug -a msg={{ inventory_hostname }}
# ansible webserver -m debug -a 'msg={{ inventory_hostname }}'
# ansible webserver -m debug -a var=inventory_hostname
# ansible webserver -m debug -a var=groups
# ansible webserver -m debug -a var=group_names
# ansible dbbserver -m debug -a var=group_names
# ansible dbserver -m debug -a var=group_names
# ansible all -m debug -a var=group_names
# ansible all -m debug -a var=hostvars
# ansible webserver -m debug -a var=hostvars
# vim hostvars.yml
# ansible-playbook hostvars.yml
# vim hostvars.yml
# ansible-playbook hostvars.yml
# vim hostvars.yml
# ansible-playbook hostvars.yml
# ansible-playbook hostvars.yml > test.txt
# vim test.txt
# vim hostvars.yml
---
- name:
  hosts: webserver
  tasks:
  - name:
    debug:
      msg:
      #- "{{ hostvars['servera']['ansible_version']['string'] }}"
      - "{{ groups }}"
      - "{{ group_names }}"
      - "{{ inventory_hostname }}"
      - "{{ hostvars }}

主机 主机组变量

[webservers]
servera.lab.example.com Name=servera
serverb.lab.example.com Name=serverb
[dbservers]
serverc.lab.example.com
serverd.lab.example.com
[servers:children]
webservers
dbservers
[dbservers:vars]
Name="serverc+serverd"
[all:vars]
course=rh294
1、恢复快照到INIT
2、挂载光盘, 启动连接勾选上
3、验证光盘是否挂载
[kiosk@foundation0 ~]$ mount | grep sr0
/dev/sr0 on /run/media/kiosk/CDROM type iso9660 (ro,nosuid,nodev,relatime,nojoliet,check=s,map=n,blocksize=2048,uid=1000,gid=1000,dmode=500,fmode=400,uhelper=udisks2)
4、使用kiosk用户身份安装挂载点里面的rpm包
[kiosk@foundation0 ~]$ ssh root@localhost 'yum -y install /run/media/kiosk/CDROM/*'
5、等待
快 10分钟 慢 20分钟
6、部署好以后关机做一个快照

第五章 实施任务控制

循环列表

# vim install_packages.yml
---
- name: example yaml file
  hosts: web
#  vars:
#    packages:
#      - httpd
#      - lrzsz
#      - dnf
  vars_files:
    - user.yml
  tasks:
#  - name: install the latest version of Apache
#    yum:
#      name: httpd
#      state: latest
#  - name: install the latest version of Apache
#    yum:
#      name: lrzsz
#      state: latest
#  - name: install the latest version of Apache
#    yum:
#      name: dnf
#      state: latest
  - name: install the latest version of Apache
    yum:
      name: "{{ item }}"
      state: latest
    loop:
      "{{ packages }}"

    #with_items: #旧版本写法,现在不建议使用了,了解有这个用法即可
  #  loop:
  #    - httpd
  #    - lrzsz
  #    - dnf

判断

# 需求:在所有受管节点执行 web安装httpd db 安装包组 web db 更新所有软件包
---
  tasks:
  - name: install the latest version of Apache
    dnf:
      name: "{{ item }}"
      state: latest
    loop:
      - httpd
      - lrzsz
      - dnf
    when: inventory_hostname in groups['web']
    #when: '"web" in group_names'    #两种主机判断方法
  - name: install the 'Development tools' package group
    dnf:
      name: '@Development tools'
      state: present
    when: inventory_hostname in groups['db']
   #when: '"db" in group_names'
  - name: upgrade all packages
    dnf:
      name: "*"
      state: latest
    when: inventory_hostname in groups['web'] or inventory_hostname in groups['db']
    #when: '"web" in group_names or "db" in group_names'
---
- name: example yaml file
  hosts: web
  tasks:
  - name:
    debug:
      msg: vda is exist
    when: ansible_devices.vda is defined #以变量是否定义为标准
  - name:
    debug:
      msg: vdb is exist
    when: ansible_devices.vdb is defined
  - name:
    debug:
      msg: vdc is exist
    when: ansible_devices.vdc is defined
  - name:
    debug:
      msg: vdc is not exist
    when: ansible_devices.vdc is not defined
  - name:
    debug:
      msg: vdc is not exist
    when: not ansible_devices.vdc is defined
  - name:
    debug:
      msg: 'true'
    when: true
  - name:
    debug:
      msg: 'true'
    when: 1
  - name:
    debug:
      msg: 'true'
    when: yes
  - name:
    debug:
      msg: 'true'
    when: yes
  - name:
    debug:
      msg: vda is 10.00 GB
    when: ansible_devices.vda.size == '10.00 GB' #字符串判断
  - name:
    debug:
      msg: ansible_memtotal_mb equal 821
    when: ansible_memtotal_mb == 821

判断条件

操作 示例
等于 值为字符串 ansible_machine == “x86_64”
等于 值为数字 max_memory == 512
小于 min_memory < 128
大于 min_memory > 256
小于等于 min_memory <= 256
大于等于 min_memory >= 512
不等于 min_memory != 512
操作 示例
变量存在 variable is defined
变量不存在 variable is not defined|not variable is defined
布尔变量 true|1|yes 求值为true
布尔变量 false|0|no 求值为false
第一个变量的值存在,作为第二个变量的列表中的值 variable in variable

忽略任务失败

---
- name: example yaml file
  hosts: web
  tasks:
  - name:
    shell: mkdir /easthome
    ignore_errors: yes
  - name:
    shell: ls -ld /easthome
  - name:
    shell: cp -r /etc /easthome
---
- name: example yaml file
  hosts: web
  tasks:
  - name:
    shell: ls -ld /easthome
    register: result
    ignore_errors: yes
  - name:
    debug:
      msg: "{{ result.rc }}"
  - name:
    shell: mkdir /easthome
    when: result.rc != 0
  - name:
    shell: cp -r /etc /easthome

小结

BLOCK RESCUE ALWAYS

# Block: 定义要运行的主要任务
# Rescue:定义要在block子句中定义的任务失败时运行的任务
# Always:定义始终都在独立运行的任务,不论block和rescue子句中定义的任务是成功还是失败
---
- name: play1
  hosts: all
  tasks:
  - block:
    - name: Create a volume group on top of /dev/sdb with physical extent size = 8M
      lvg:
        vg: myvg
        pvs: /dev/vdb
        pesize: 8M
    - name: create 8000
      lvol:
        vg: myvg
        lv: mylv
        size: 8000
    - name: Create a xfs filesystem on mylv
      filesystem:
        fstype: xfs
        dev: /dev/myvg/mylv
    rescue:
    - debug:
        msg: Could not create logical volume of that size
    - name:
      lvol:
        vg: myvg
        lv: mylv
        size: 1000
    - name: Create a xfs filesystem on mylv
      filesystem:
        fstype: xfs
        dev: /dev/myvg/mylv
      when: ansible_lvm.vgs.myvg is definde
#     when: ansible_lvm.lvs.mylv is defined 这里使用vg做判断,如果使用lv第二遍运行才可以,因为第一次运行的时候事实变量已经收集,这个时候lvm还没有被创建出来
---
- name: example yaml file #前面加入了分区模块,其实多看看ansible-doc就可以了
  hosts: web
  tasks:
  - name: Create a new primary partition
    parted:
      device: /dev/vdb
      number: 1
      state: present
      part_end: 200MiB
  - name: Create a new primary partition
    parted:
      device: /dev/vdb
      number: 2
      state: present
      part_start: 200MiB
      part_end: 400MiB
  - name: Create a volume group on top of /dev/sda1 with physical extent size = 32MB
    lvg:
      vg: myvg
      pvs: /dev/vdb1
      pesize: 8
  - block:
    - name: Create a logical volume of 512m
      lvol:
        vg: myvg
        lv: mylv
        size: 512
    rescue:
    - name:
      shell: lvsa
      when: ansible_lvm.vgs.myvg is not defined
    always:
    - name:
      shell: lvdisplay

第六章 受管节点文件管理

模块名 说明
blockinfile 插入、更新 、删除,自定义标记先包围的多行文本块
file 设置权限、所有者、SElinux上下文及常规文件、符号连接、硬链接等
copy 远程copy,类似file,可以设置文件属性、SElinux上下文
fetch 和copy类似,相反工作方式,从远端拷贝到控制节点
lineinfile 改文件某一行时使用
stat 检测文件状态,类似linux 中stat命令
synchronize 围绕rsync一个打包程序。
template 模板模块

文件管理常用模块

[root@workstation ansible]# cat file.yml 
---
- name: example yaml file
  hosts: web
  tasks:
  - name: Add the user 'johnd' with a specific uid and a primary group of 'admin'
    user:
      name: foo
      comment: John Doe
      uid: 5000
  - name: Change file ownership, group and permissions
    file:
      path: /etc/foo.conf
      owner: foo
      group: foo
      mode: '0644'
      state: touch
#  - name:
#    file:
#      path: '/tmp/{{ item.src }}'
#      state: touch
#    with_items:
#      - { src: x, dest: y }
#      - { src: z, dest: k }
  - name: Create two hard links
    file:
      src: '/tmp/{{ item.src }}'
      dest: '/tmp/{{ item.dest }}'
      state: link
      force: yes
    with_items:
      - { src: x, dest: y }
      - { src: z, dest: k }
    
[root@workstation ansible]# cat fetch.yml 
---
- name: example yaml file
  hosts: web
  tasks:
  
  - name: Store file into /tmp/fetched/host.example.com/tmp/somefile
    fetch:
      src: /tmp/shishi
      dest: /tmp
[root@workstation ansible]# cat lineinfile.yml 
---
- name: example yaml file
  hosts: web
  tasks:
  - name: Ensure SELinux is set to enforcing mode
    lineinfile:
      path: /etc/selinux/config
      regexp: '^SELINUX='
      state: absent
[root@workstation ansible]# cat blockinfile.yml 
---
- name: example yaml file
  hosts: web
  tasks:
  - name: Add mappings to /etc/hosts
    blockinfile:
      path: /etc/hosts
      block: |
        {{ item.ip }} {{ item.name }}
        hello world
        easthome
      #marker: "# {mark} ANSIBLE MANAGED BLOCK {{ item.name }}"
    with_items:
    - { name: host1, ip: 10.10.1.10 }
    - { name: host2, ip: 10.10.1.11 }
    - { name: host3, ip: 10.10.1.12 }
  
[root@workstation ansible]# cat debug.yml 
---
- name: example yaml file
  hosts: 172.25.250.10
  tasks:
  - name:
    debug:
      msg: "{{ hostvars['172.25.250.10']|to_nice_json }}"
#  - name:
#    debug:
#      msg: vda is exist
#    when: ansible_devices.vda is defined 
#  - name:
#    debug:
#      msg: vdb is exist
#    when: ansible_devices.vdb is defined 
#  - name:
#    debug:
#      msg: vdc is exist
#    when: ansible_devices.vdc is defined 
#  - name:
#    debug:
#      msg: vdc is not exist
#    when: ansible_devices.vdc is not defined 
#  - name:
#    debug:
#      msg: vdc is not exist
#    when: not ansible_devices.vdc is defined 
#  - name:
#    debug:
#      msg: 'true'
#    when: true
#  - name:
#    debug:
#      msg: 'true'
#    when: 1
#  - name:
#    debug:
#      msg: 'true'
#    when: yes
#  - name:
#    debug:
#      msg: 'true'
#    when: yes
#  - name:
#    debug:
#      msg: vda is 10.00 GB
#    when: ansible_devices.vda.size == '10.00 GB'
#  - name:
#    debug:
#      msg: ansible_memtotal_mb equal 821
#    when: ansible_memtotal_mb == 821

模板

# web安装apache服务,共享内容为welcome to hostname() on IP()

[root@workstation ansible]# cat web.yml 
---
- name: example yaml file
  hosts: web
  tasks:
  - name: install the latest version of Apache
    yum:
      name: httpd
      state: latest
  - name: Start service httpd, if not started
    service:
      name: httpd
      state: started
  - firewalld:
      service: http
      permanent: yes
      state: enabled
      immediate: yes
  - name: Copy using inline content
    copy:
      content: '# This file was moved to /etc/other.conf'
      dest: /var/www/html/index.html
  - name: Template a file to /etc/files.conf
    template:
      src: /root/ansible/index.j2
      dest: /var/www/html/index.html
[root@workstation ansible]# cat index.j2 
Welcome to {{ ansible_fqdn }} on {{ ansible_default_ipv4.address }} #模板文件一般加入变量,运行到对应主机的时候变量替换为真实的值
# 在web受管节点/etc/myhosts文件追加内容,格式如下
# 172.25.250.10   servera.lab.example.com 	servera
# IP 			  FQDN 				        HOSTNAME

all
只写到单个服务器组
[root@workstation ansible]# cat hosts.yml
---
- name: example yaml file
  hosts: web
  tasks:
  - name:
    template:
      src: /root/ansible/host.j2
      dest: /etc/myhosts
[root@workstation ansible]# cat host.j2 
{% for host in groups['web'] %}
{{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }} {{ hostvars[host]['ansible_facts']['fqdn'] }} {{ hostvars[host]['ansible_facts']['hostname'] }}
{% endfor %}

第七章 管理大型项目

主机模式选择

# All
# ungrouped
# *.example.com
# 172.17.25.8
# Servera,serverb,serverc
# Servera,*.example.com,172.17.25.8
# Webserver,&dbserver
# Webserver,!dbserver

管理多清单

配置文件 指定清单目录

文件名字=主机组名字

管理并行

使用分叉在ansible中配置并行
Forks = 5
Ansbile-playbook –f 5
Ansible-playbook –forks 5
[greg@bastion ansible]$ vim /etc/ansible/ansible.cfg 
#forks          = 5

管理滚动更新

 - name: sync file
   hosts: all
   serial: 2  #在这可以使用数字指定机器数量 也可以指定百分比
   tasks:

import、include

[root@workstation ansible]# cat apache_yum.yaml 
---
- name: install the latest version of Apache
  yum:
    name: httpd
    state: latest
[root@workstation ansible]# cat apache_service.yaml 
---
- name:
  service:
    name: httpd
    state: started
    enabled: yes
[root@workstation ansible]# cat apache_template.yaml 
---
- name: Template a file to /etc/files.conf
  template:
    src: /root/ansible/index.html.j2
    dest: /var/www/html/index.html
[root@workstation ansible]# cat apache_firewall.yaml 
---
- firewalld:
    service: http
    permanent: yes
    state: enabled
    immediate: yes
[root@workstation ansible]# cat apache_include.yaml
---
- name:
  hosts: web
  vars:
    my_tasks:
    - apache_yum.yaml
    - apache_service.yaml
    - apache_template.yaml
    - apache_firewall.yaml
  tasks:
  - include_tasks: "{{ item }}"
    loop: "{{ my_tasks }}"

第七章 管理大型项目

主机模式选择

# All
# ungrouped
# *.example.com
# 172.17.25.8
# Servera,serverb,serverc
# Servera,*.example.com,172.17.25.8
# Webserver,&dbserver
# Webserver,!dbserver

管理多清单

配置文件 指定清单目录

文件名字=主机组名字

管理并行

使用分叉在ansible中配置并行
Forks = 5
Ansbile-playbook –f 5
Ansible-playbook –forks 5
[greg@bastion ansible]$ vim /etc/ansible/ansible.cfg 
#forks          = 5

管理滚动更新

 - name: sync file
   hosts: all
   serial: 2  #在这可以使用数字指定机器数量 也可以指定百分比
   tasks:

第八章 角色管理

角色目录结构

defaults	角色变量默认值
files	  引用的静态文件
handlers 处理程序
meta  作者、readme 、依赖关系
tasks  任务列表   角色的功能以及任务
templates  模板jinja2
tests  测试角色
vars  变量值

初始化角色

# mkdir /root/ansible/roles
# vim ansible.cfg 
roles_path    = /etc/ansible/roles:/root/ansible/roles:/usr/share/ansible/rols/
# cd roles
# ansible-galaxy init apache
# ansible-galaxy list
[root@workstation ansible]# tree roles/apache/
roles/apache/
├── defaults
│   └── main.yml
├── files
│   └── ansible.cfg
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
│   └── index.j2
├── tests
│   ├── inventory
│   └── test.yml
└── vars
[root@workstation ansible]# cat roles/apache/tasks/main.yml 
---
# tasks file for apache
- name: install the latest version of Apache
  yum:
    name: "{{ packeage_name }}"
    state: "{{ packeage_state }}"
- name:
  debug:
    msg:
    - "{{ packeage_name }}"
    - "{{ packeage_state }}"
- name: Start service httpd, if not started
  service:
    name: httpd
    state: started
- firewalld:
    service: http
    permanent: yes
    state: enabled
    immediate: yes
- name:
  copy:
    src: ansible.cfg
    dest: /root
- name: Copy using inline content
  copy:
    content: '# This file was moved to /etc/other.conf'
    dest: /var/www/html/index.html
- name: Template a file to /etc/files.conf
  template:
    src: index.j2
    dest: /var/www/html/index.html
[root@workstation ansible]# cat roles/apache/defaults/main.yml 
---
# vars file for apache
packeage_name: httpd
packeage_state: present
[root@workstation ansible]# cat roles/apache/templates/index.j2 
Welcome to {{ ansible_fqdn }} on {{ ansible_default_ipv4.address }}

如何调用角色

---
- name: example yaml file
  hosts: web
  pre_tasks:
  - name:
    debug:
      msg:
  roles:
    - apache
  post_tasks:
  - name:
    debug:
      msg:
  tasks:

角色复用

---
- name: example yaml file
  hosts: db
  roles:
    - apache
  tasks:
  - name:
    group:
      name: webdev
      state: present
  - name:
    file:
      path: /webdev
      state: directory
      group: webdev
      mode: '2775'
  - name:
    file:
      src: /webdev
      dest: /var/www/html/webdev
      state: link
  - name:
    copy:
      content: "Development\n"
      dest: /webdev/index.html
      setype: httpd_sys_content_t

系统角色

# yum install -y rhel-system-roles.noarch
# ansible-galaxy list
# ansible-galaxy list
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
....
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
 [WARNING]: - the configured path /home/greg/.ansible/roles does not exist.

# rpm -ql rhel-system-roles.noarch

如果想使用自己的角色以及系统角色
# cd /root/ansible/
# vim ansible.cfg
roles_path    = /home/greg/ansible/roles:/usr/share/ansible/roles
# ansible-galaxy list
使用系统角色前,规划好角色路径,内容查看上面系统角色部分。
$ rpm -ql rhel-system-roles.noarch
$ cp /usr/share/doc/rhel-system-roles/timesync/example-timesync-playbook.yml /home/greg/ansible/timesync.yml

[greg@bastion ansible]$ vim timesync.yml
---
- hosts: all 
  vars:
    timesync_ntp_servers:
      - hostname: 172.25.254.254
        iburst: yes 
  roles:
    - rhel-system-roles.timesync

测试结果
$ ansible all -a 'chronyc sources -v'

系统角色selinux

rpm -ql rhel-system-roles.noarch|grep example
cp /usr/share/doc/rhel-system-roles/selinux/example-selinux-playbook.yml .
ansible-inventory --g
vim example-selinux-playbook.yml
ansible-playbook example-selinux-playbook.yml

---
- hosts: servrpm -ql rhel-system-roles.noarch|grep example
cp /usr/share/doc/rhel-system-roles/selinux/example-selinux-playbook.yml .
ansible-inventory --g
vim example-selinux-playbook.yml
ansible-playbook example-selinux-playbook.yml
era.lab.example.com
  vars:
    selinux_policy: targeted
    selinux_state: disabled
  tasks:
    - name: execute the role and catch errors
      block:
        - include_role:
            name: rhel-system-roles.selinux
      rescue:
        # Fail if failed for a different reason than selinux_reboot_required.
        - name: handle errors
          fail:
            msg: "role failed"
          when: not selinux_reboot_required

        - name: restart managed host
          shell: sleep 2 && shutdown -r now "Ansible updates triggered"
          async: 1
          poll: 0
          ignore_errors: true

        - name: wait for managed host to come back
          wait_for_connection:
            delay: 10
            timeout: 300

        - name: reapply the role
          include_role:
            name: rhel-system-roles.selinux

开发角色推荐做法

# 1、用版本库控制自己角色,也可以通过github
# 2、存储库不建议存放敏感信息
# 3、使用ansible-galaxy init 创建角色的目录中以及存放角色目录中不要放没用的目录信息 | 在角色目录中
# 4、写好readme,和mate,功能、版本、用途、依赖
# 5、建议针对不同功能创建多个不同角色,而不是一个角色承载多个任务
# 6、经常重构角色,让你的角色更加完善。

控制执行顺序

--
- name: install apache
  hosts: all
  pre_tasks:    在roles任务之前执行的tasks
    - name: xxxx
      copy:
       src:
       dest:
  roles:
    - user.example
    - nfs

  post_tasks:     在roles任务之后执行的tasks
    - name: xxxx
      copy:
        src:
        dest:

第九章 故障排查

日志收集

调试模块

debug
  msg: 直接输出信息
  var: 变量名称

事实收集

开关与否,关系到事实变量的收集与输出

语法检查

# ansible-playbook --syntax-check apache.yml

查看play的执行输出详细程度

-v -vv -vvv -vvvv

空运行

# ansible-playbook -C apache.yml

排错点

练习 练习 使用
1、配置文件
- 注释取消
- 连接问题 连接用户 用户存在 密码 公钥私钥 提权问题
- 清单文件指定(file|directory)
- 角色路径配置  加入系统角色路径 
2、清单文件
名称
内容
关键字 嵌套组 变量定义
3、playbook
熟练 yaml语法 缩进 - :
模块使用
ansible-doc -l|grep 'tem|co|file|block'
ansible-doc moudle_name /EX 用法 复制 (考试)作用|选项|
报错信息 变量未定义 文件已存在
hosts: 主机模式 清单文件存在
4、角色排错
角色路径 role_path
创建角色 init
任务文件 关注格式
变量优先级 命令行-playbook-vars-defaults
引用角色
5、playbook
PPT当中

第十章 自动执行linux管理任务

软件仓库管理

[root@workstation ansible]# cat yum_repository.yml 
---
- name: example yaml file
  hosts: db
  tasks:
  - name: Add multiple repositories into the same file (1/2)
    yum_repository:
      name: test123
      description: myrepo by ansible
      file: test123456
      baseurl: http://content.example.com/rhel8.0/x86_64/dvd/BaseOS
      gpgcheck: no
      enabled: yes
  
  - name: Add multiple repositories into the same file (1/2)
    yum_repository:
      name: test123
      description: myrepo by ansible
      file: test123456
      baseurl: http://content.example.com/rhel8.0/x86_64/dvd/AppStream
      gpgcheck: no
      enabled: yes

用户和组管理

[root@workstation ansible]# cat users.yml 
---
- name: example yaml file
  hosts: web
#  vars_files:
#    - user.yml
  vars:
    users:
    - name: east
      uid: 3000
      shell: /bin/bash
      comment: east
      pd: east123
    - name: west
      uid: 3001
      shell: /sbin/nologin
      comment: west
      pd: west123
    - name: keyi
      uid: 3002
      shell: /bin/bash
      comment: keyi
      pd: keyi123
  tasks:
  - name: Add the user 'johnd' with a specific uid and a primary group of 'admin'
    user:
      name: "{{ item.name }}"
      uid: "{{ item.uid }}"
      shell: "{{ item.shell }}"
      comment: "{{ item.comment }}"
      password: "{{ item.pd | password_hash('sha512') }}"
    loop: "{{ users }}"

计划任务

---
- name:
  hosts: dev
  tasks:
  - name: Schedule a command to execute in 20 minutes as root
    at:
      command: ls -d / >/dev/null
      count: 20
      units: minutes
      
默认是创建一个任务,给root,删除的话使用选项state:absent


[greg@bastion ansible]$ cat cron.yml 
---
- name:
  hosts: dev
  tasks:
  - name: Ensure a job that runs at 2 and 5 exists. 
    cron:
      name: "check dirs"
      minute: "*/2"
      hour: "5,2"
      day: 1-10
      user: harry
      job: "ls -alh > /dev/null"

[greg@bastion ansible]$ ansible dev -m shell -a 'crontab -u harry -l'

存储管理

[root@workstation ansible]# cat block.yml 
---
- name: example yaml file
  hosts: web
  tasks:
  - name: Create a new primary partition
    parted:
      device: /dev/vdb
      number: 1
      state: present
      part_end: 200MiB
  - name: Create a new primary partition
    parted:
      device: /dev/vdb
      number: 2
      state: present
      part_start: 200MiB
      part_end: 400MiB
  - name: Create a volume group on top of /dev/sda1 with physical extent size = 32MB
    lvg:
      vg: myvg
      pvs: /dev/vdb1
      pesize: 8
  - block:
    - name: Create a logical volume of 512m
      lvol:
        vg: myvg
        lv: mylv
        size: 100
    rescue:
    - name:
      shell: lvsa
      when: ansible_lvm.vgs.myvg is not defined
    always:
    - name:
      shell: lvdisplay
- name:
  hosts: web
  tasks:
  - name: Create a ext2 filesystem on /dev/sdb1
    filesystem:
      fstype: xfs
      dev: /dev/myvg/mylv
  - name: Create an insecure file
    file:
      path: /mountpoint
      owner: root
      group: root
      mode: '0777'
      state: directory
  - name: Mount up device by label
    mount:
      path: /mountpoint
      src: /dev/myvg/mylv
      fstype: xfs
      state: mounted
 - name: Touch a directory    创建一个挂载点
    file:
      path: /mnt/dir1
      state: directory

  - name: 将lvm文件系统挂载到/mnt/dir1上
    mount:
      path: /mnt/dir1
      src: /dev/vg100/lv100
      fstype: xfs
      opts: defaults
      state: mounted
      
      总结:
      state:
      present    将配置信息写入/etc/fstab,不挂载
      mounted	 将配置信息写入/etc/fstab,挂载
      unmounted  不改变/etc/fstab信息,卸载
      absent     删除/etc/fstab信息,并卸载
[root@workstation ansible]# cat nfs.yaml 
---
- name: play1
  hosts: servera
  tasks:
  - name: task1
    yum: 
      name: nfs-utils
      state: present

#  - name: task2
#    shell: echo '/share 172.25.250.0/24(rw,sync)' > /etc/exports.d/share.exports

  - name: task2
    copy:
      content: /share 172.25.250.0/24(rw,sync)
      dest: /etc/exports.d/share.exports

  - name: task3
    file:
      path: /share
      state: directory

  - name: task4
    service:
      name: rpcbind
      state: started
      enabled: yes

  - name: task5
    service:
      name: nfs-server
      state: started
      enabled: yes

  - name: task6
    firewalld:
      service: nfs
      permanent: yes
      state: enabled
      immediate: yes
    
  - name: task7
    firewalld:
      service: mountd
      permanent: yes
      state: enabled
      immediate: yes

  - name: task8
    firewalld:
      service: rpc-bind
      permanent: yes
      state: enabled
      immediate: yes

- name: mount nfs
  hosts: workstation
  tasks:
  - name:
    shell: mount -t nfs 172.25.250.10:/share /mnt
#  - name:
#    mount: 
#      path: /mnt
#      src: 172.25.250.10:/share
#      fstype: nfs
#      state: mounted
1、目标机器:servera
2、3个主分区,每个分区300M
3、利用以上分区创建卷组myvg,逻辑卷mylv,大小640M
4、创建挂载点/mylv,mylv过载过来,永久挂载
5、/mylv,NFS共享出去,权限rw

1、目标机器:serverb
2、挂载点/servera_nfs_mylv
3、永久挂载
4、autofs实现按需挂载

第一种:shell方式一点一点
第二种:脚本
第三种:ansible(重点) 尽量使用角色
[root@workstation ansible]# cat part_lv_nfs.yaml 
---
- name: p1
  hosts: servera.lab.example.com
  roles:
    - parted
    - lvm
    - nfs
- name: p2
  hosts: serverb.lab.example.com
  roles:
    - mount
    - autofs
每个角色部署内容参考ansible.tar.gz,可以用自己的想法优化。
练习:
1、在卷组myvg 上  创建 800M 逻辑卷 
2、空间不够,提示信息
3、300M 逻辑卷 MYLV1
4、创建挂载点/mylv1

后续

可以把ansible.tar.gz 导入到workstation,里面包括了课上所有跑过的playbook和文件。

你可能感兴趣的:(运维,运维,ansible,自动化)