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自动化领域中的重要工具之一。它的简单易用、灵活性高以及广泛的社区支持,使其受到越来越多的开发者和运维人员的青睐。
节点 | 角色 |
---|---|
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
# 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 |
格式
# 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'
[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 }}"
[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
[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'
语法 | 描述 |
---|---|
缩进 | YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不能使用tabs |
冒号 | 以冒号结尾的除外,其他所有冒号后面所有必须有空格 |
短横线 | 表示列表项,使用一个短横线加一个空格,多个项使用同样的缩进级别作为同一列表 |
# 调整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
[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 }}"
[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关键字,例如async 和lambda |
foo_env | 剧本关键字,例如environment |
foo_port | foo-port ,,foo port``foo.port |
foo5 , _foo | 5foo , 12 |
---
- 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 }}"
主机变量优先于组变量,但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:定义要在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:
[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'
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
-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当中
[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和文件。