Ansible Playbook入门使用

Ansible Playbook

单任务

---
- 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模块对应的命令。

你可能感兴趣的:(ansible使用,运维,linux,centos)