单任务
---
- hosts: all #在所有主机执行
tasks: #任务
- name: first playbook ~~~ #任务的名字,自定义,运行时方便区分任务
ping: #执行任务用的模块
[root@test ansible]# ansible-playbook test.yaml
PLAY [all] *****************************************************************************
TASK [Gathering Facts] *****************************************************************
ok: [node1]
TASK [first playbook ~~~] **************************************************************
ok: [node1]
PLAY RECAP *****************************************************************************
node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
多个任务
---
- hosts: node1,node2,database #修改为在个别主机与组执行
tasks:
- name: first playbook ~~~
ping: #任务
- shell: mkdir /opt/book #多增加一个任务,也可以不定义name
多个play,多个任务
---
- hosts: node1 #第1个play(剧)
tasks:
- name: first playbook ~~~
ping:
- file:
name: /opt/book
state: directory
- hosts: node1 #第2个play(剧)
tasks:
- copy:
src: /etc/hostname
dest: /
创建账户,安装软件包,启动服务
---
- hosts: node1
tasks:
- name: add user #name不写也行
user: #使用user模块
name: tom #账户名
shell: /bin/bash #解释器
uid: 1500 #uid号
group: bin #基本组
password: "{{'123456'|password_hash('sha512')}}" #密码
- name: http
yum: #使用yum模块
name: httpd #安装httpd软件包
- service: #使用service模块
name: httpd #操作的服务名
state: started #操作目的是打开服务
yum grouplist 组包 管理逻辑卷
---
- hosts: node1
tasks:
- yum:
name: "@RPM Development Tools" #安装组包,前面加@代表是组包
- yum:
name: '*' #所有软件包
state: latest #升级
- hosts: node1 #第2个play(剧),换成node2执行
tasks:
- parted: #使用分区模块
device: /dev/sdb #为sdb硬盘分区
label: gpt #分区表类型gpt
number: 1 #分区序号,第1个分区
state: present #执行分区,如果删除就是absent
part_end: 1GiB #从头分1G给新分区
- lvg: #继续使用lvg模块
vg: myvg #创建名为myvg的卷组
pvs: /dev/sdb1 #使用sda1分区
- lvol: #再使用逻辑卷模块
lv: mylv #创建mylv逻辑卷
size: 512m #大小512m
vg: myvg #空间来自myvg卷组
ansible系统变量 ansible 主机名 -m setup
ansible_facts用于采集被管理设备的系统信息,所有收集的信息都被保存在变量中,每次执行playbook默认第一个任务就是Gathering Facts,使用setup模块可以查看收集到的facts信息
常见系统变量:
ansible_bios_version #版本
ansible_memtotal_mb #内存总大小
ansible_hostname #主机名
ansible_devices.sda.partitions.sda1.size #每级缩进的变量用点隔开
]# ansible node1 -m setup #列出变量
]# ansible node1 -m setup | less #列出变量,翻行查看
node1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.1.17"
PLAY [all] ******************************************************************
TASK [Gathering Facts] *******************************************************************************
ok: [node1]
TASK [debug] ******************************************************************
ok: [node1] => {
"msg": [
"192.168.1.17"
]
}
TASK [debug]******************************************************************
ok: [node1] => {
"msg": "主机名称是:git"
}
TASK [debug]*********************************************************************
ok: [node1] => {
"msg": "git"
}
ansible变量的常见种类:
inventory 自定义变量 在被控主机清单文件中添加
[test]
node1 myvar1="dc" #为node1主机添加变量名字是myvar1
host Facts 变量 由系统定义
]# ansible node1 -m setup | less #列出变量,翻行查看
playbook 自定义变量 使用关键词vars
---
- hosts: all
vars: #定义针对该剧的变量,执行该剧的所有主机都生效
test01: 'abc666' #变量的具体内容,test01是变量名称 abc666是变量的值
test02: '123456' #数字加引号会变成字符串,作为配置密码时使用
tasks:
- user:
name: "{{test01}}" #创建用户时调用变量
password: "{{test02|password_hash('sha512')}}" #直接调用变量,密码123456
#password: "{{'test02'|password_hash('sha512')}}"#若加引号,密码为test02
- debug:
msg: "{{test01}}{{test02}}"
vars_files: 使用文件自定义变量
]# vim vars.yml #创建文档用来存储变量
---
var01: abc
var02: xyz
var03: opq
---
- hosts: node1
vars_files: vars.yml #在剧本中调用变量文件,即可让执行任务的主机使用文本中的变量
tasks:
- debug:
msg: "{{var01,var02,var03}}"
TASK [debug] ***************************************************
ok: [node1] => {
"msg": "(u'abc', u'xyz', u'opq')"
}
template模块
copy模块可以将一个文件拷贝给远程主机,但是如果希望每个拷贝的文件内容都不一样,
可以使用template模块配合文档中的变量实现。
[root@control ansible]# ansible node1 -m setup | less #搜索对应的网卡ip地址的变量名称
[root@control ansible]# vim index.html #准备测试文档
welcome to {{ansible_hostname}} on {{ansible_ens160.ipv4.address}}
---
- hosts: all
tasks:
- template: #template模块可以在传递的文件中调用变量的值
src: /root/ansible/index.html #源文件
dest: /var/www/html/ #目标位置
force: yes #如果目标已经有文件,则覆盖
error错误处理
默认ansible在遇到error会立刻停止,使用ignore_errors可以忽略错误,继续后续的任务。
如果一个剧本里面有多个任务,执行到第1个时失败,则不再往下执行其他任务。
模块中某个任务忽略错误
---
- hosts: node1
tasks:
- copy:
src: /xyz01
dest: /
ignore_errors: true #如果copy任务失败,则忽略,继续执行后面任务
- debug:
msg: abc
tasks上方全局忽略错误
---
- hosts: node1
ignore_errors: true #无论什么任务失败,都忽略,继续执行后面任务
tasks:
- copy:
src: /xyz01
dest: /
- debug:
msg: abc
触发任务 任务changed,notify(通知) handlers执行相应的任务,
handlers任务最后才执行,只会执行一次
---
- hosts: all
tasks:
- template:
src: /root/ansible/index.html
dest: /var/www/html/
force: yes
notify: test01 #调用handlers中的任务名称
handlers: #不一定执行,除非上面有任务调用且成功后是changed状态
- name: test01 #test01 预备的任务名称,如果该任务被之前任务调用多次也
file:
path: /opt/666
state: touch
when条件判断 ==、!=、>、>=、<、<=
多个条件可以使用and(并且)或or(或者)分割,when表达式中调用变量不要使用{{ }}
单一条件:
---
- hosts: node1
tasks:
- debug: #该任务要满足when条件时才执行
msg: ok
when: ansible_hostname != "node1" #该条件满足就执行debug任务
多个条件:
---
- hosts: node1
tasks:
- debug: #该任务要满足when条件时才执行
msg: ok
when: ansible_hostname != "node1" and ansible_memfree_mb > 100
---
- hosts: node1
tasks:
- debug: #该任务要满足when条件时才执行
msg: ok
when: > # 如果条件比较多可以使用>符号,系统认为一行
ansible_hostname != "node1"
and ansible_memfree_mb > 100
block、rescue、always组合执行任务
在block任务执行失败时要执行rescue的其他任务,always语句定义无论block任务是否成功,都要执行的任务
---
- hosts: node1
tasks:
- block:
- name: yum01
yum:
name: httpdddd
rescue: #救援任务,仅block任务失败时执行
- name: yum02
yum:
name: vsftpd
always: #无论block是否成功,都会执行
- name: yum03
yum:
name: unzip
loop循环,相同任务需要多次执行时避免重复写模块语句
item变量中每次循环只有一个值
---
- hosts: node1
tasks:
- file:
name: /opt/{{item}} #可以创建二个文件,item变量内容来自loop里面
state: touch
loop: #这里定义item变量中的内容
- aaaa #每次循环的变量有1个值
- bbbb
情况2:item变量中每次循环有多个值
---
- hosts: node1
tasks:
- user:
name: "{{item.iname}}" #每次循环,user模块创建用户会读取loop里面的第1个值,值的名字是iname
password: "{{item.ipass|password_hash('sha512')}}" #每次循环,user模块配密码会读取loop里面的第2个值,值的名字是ipass
loop:
- {iname: 'aaaa',ipass: '123456'} #每次循环的变量有2个值
- {iname: 'bbbb',ipass: '654321'}
- {iname: 'cccc',ipass: '987654'}
ansible-vault encrypt,decrypt 加密
[root@test ansible]# ansible-vault encrypt vars.yml #加密文件(可以是任意文件)
[root@test ansible]# cat vars.yml
$ANSIBLE_VAULT;1.1;AES256
6266646439383630633035383966 #看到的是加密后的信息
[root@test ansible]# ansible-vault view vars.yml #查看,需要输入密码
[root@test ansible]# ansible-vault rekey vars.yml #修改密码
Vault password: #先输入旧密码
New Vault password: #再输入两次新密码
Confirm New Vault password:
[root@test ansible]# ansible-vault decrypt vars.yml #取消密码
利用文件加密
[root@test ansible]# echo qwerty234ji > pass #将密码存在文件中
]# ansible-vault encrypt --vault-id=pass vars.yml #利用pass文件中的密码加密
]# ansible-vault decrypt --vault-id=pass vars.yml #利用pass文件中的密码解密
ansible角色roles
Role(角色)是管理ansible文件的一种规范(目录结构),Role(角色)会按照标准的规范,自动到特定的目录和文件中读取数据。
第一步:ansible-galaxyinit初始化角色
[root@control ansible]# mkdir roles #创建存放角色的目录
[root@control ansible]# ansible-galaxy init roles/test #创建角色test, init初始化
[root@test ansible]# tree roles/test
roles/test
├── defaults
│ └── main.yml #定义变量的缺省值,优先级较低
├── files #存储静态文件的目录,如tar包、音乐、视频等
├── handlers
│ └── main.yml #定义handlers
├── meta
│ └── main.yml #写作者、版本等描述信息
├── README.md #整个角色(role)的描述信息
├── tasks
│ └── main.yml #定义任务的地方
├── templates #存放动态数据文件的地方(文件中包含了变量的模板文件)
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml #定义变量,优先级高
第二步:准备 数据模板file/template 创建tasks playbook
[root@control ansible]# vim roles/test/templates/index.html #创建模板文件template
{{ansible_hostname}}
]# vim roles/test/tasks/main.yml #编写test角色的任务,会被调用不需要写hosts
---
# tasks file for roles/test
- yum:
name: httpd #装包
- template: #拷贝文件
src: index.html #该文件在角色的templates目录下,可以不用写路径
dest: /var/www/html
- service: #开启的服务
name: httpd #开启网站服务
state: started #开启
enabled: yes #开机自启
- firewalld: #配置防火墙
service: http #对http协议的服务
state: enabled #放行
permanent: yes #永久生效
immediate: yes #立即生效
[root@test ansible]# vim role.yml
---
- hosts: node1
roles: #调用角色test
- test
ansible搭建nginx集群
[root@test ansible]# ls roles/test/files/
install_nginx.sh nginx.conf nginx-1.17.6.tar.gz #准备资料
[root@test ansible]# vim role.yml
---
- hosts: node1
roles: #调用角色test
- test
---
# tasks file for roles/test
- copy:
src: nginx-1.17.6.tar.gz # test/files/
dest: /home/
- copy: #拷贝提前准备好的配置文件
src: nginx.conf
dest: /usr/local/nginx/conf/
forece=yes
- script: install_nginx.sh #执行的安装nginx脚本,需要另外准备
args:
creates: /usr/local/nginx/sbin/nginx #如果nginx已经安装,则不执行script模块的任务
- shell: /usr/local/nginx/sbin/nginx #开启服务
args:
creates: /usr/local/nginx/logs/nginx.pid #这个文件存在的话,说明nginx服务已经开
#args是关键词,设置script模块的参数,通过creates参数做判断,如果creates判断文件存在的话就不再执行script模块对应的命令。