Ansible Playbook剧本配置文件

目录

一、执行文件

修改hosts文件

Playbook的核心元素包含:

用法

实验案例

1.语法检查

2.预测试

3.列出主机

4.列出任务

5.列出标签

6.进行测试

7.测试查看

二、触发器

handlers触发器的实验实例如下

预执行

执行

查看结果

三、角色

/etc/ansible/roles/为角色集合,该目录下有自定义的各个子目录

每个角色的定义,以特定的层级目录结构进行组织,以Mariadb(mysql角色)为例

实验案例

1. 被管理端配置yum源

2. 配置数据库角色

3、Ansible端验证

四、变量

4.1、在playbook中使用自定义变量

4.2、在playbook中使用ansible的内置变量

5.Template模板

5.1、利用template模块下发可变的配置文件

5.2、下发配置文件里面使用判断语法

六、基于Playbook部署Nginx综合案例

1、创建目录结构

2、目录查看结构

3、定义一个主调用文件

4、files:存储由copy或script等模块调用的文件;

5、handlers:此目录中至少应该有一个名为main.yml的文件,用于定义各handler;其它的文件需要由main.yml进行“包含”调用;

6、tasks:目录至少应该有一个名为main.yml的文件,用于定义各task;其它的文件需要由main.yml进行“包含”调用;

7、templates:存储由template模块调用的模板文本;

8、vars:此目录中至少应该有一个名为main.yml的文件,用于定义各variable;其它的文件需要由main.yml进行“包含”调用;

9、其他:

10、测设部署

11、检验


一、执行文件

Playbook配置文件使用YAML语法,具有简

洁明了,结构清晰等特点。Playbook配置文件类似于shell脚本,是一个YAML格式的文件,用于保存针对特定需求的任务列表,前面介绍的ansible命令虽然可以完成各种任务,但是当配置一系列任务时,逐条输入命令就显得效率非常低下,更有效的方式在playbook配置中配置所有的任务代码,利用ansible-playbook命令执行该文件,可以实现自动化运维,YAML文件的扩展名通常为.yaml或.yml

YAML语法和其他高级语言类似,其结构通过缩进来展示,通过“-“来表达选项,通过冒号“:”来分隔键和值。整个文件以“---”开始并以“”结束,如下所示

修改hosts文件

[root@ansible ~]# vim /etc/ansible/hosts

[test01]
192.168.2.222

[test02]
192.168.2.223

[root@ansible ~]# vim /etc/ansible/test1.yml	#创建test,yml文件

---										        #开头格式(可忽略)
- hosts: test01							        #表示对test01(192.168.200.112)的操作
  remote_user: root						        #远端执行用户身份root
  tasks:									    #任务列表
    - name: adduser						        #任务名称
      user: name=user2 state=present		    #执行user模块创建用户
      tags:								        #创建tag标签
      - testa								    #tag标签为testa
    - name: addgroup						    #任务名称
      group: name=tests system=yes		        #执行group模块创建一个组账号
      tags:								        #创建tag标签
      - testb							    	#tag标签为testb
- hosts: test02							        #表示对test02(192.168.200.113)的操作
  remote_user: root						        #远端执行用户身份root
  tasks:								    	#任务列表
    - name: cf							        #任务名称
      copy: src=/etc/passwd dest=/home	        #执行copy模块复制文件
      tags:								        #创建tag标签
      - testc								    #tag标签为testsc
...										        #结尾格式(可忽略)

所有的“-”和“:”后面均有空格,而且要注意缩进和对齐

Playbook的核心元素包含:

  1. hosts:任务的目标主机,多个主机用冒号分隔,一般调用/etc/ansible/hosts中的分组信息
  2. remote_user:远程主机上,运行此任务的默认为root运行
  3. tasks:任务,即定义的具体任务,由模块定义的操作列表
  4. handlers:触发器,类似tasks,只是在特定的条件下才会触发任务。某任务的状态在运行后changed时,可通过“notify”通知给相应的handlers进行触发执行。
  5. roles:角色,将hosts剥离出去,由tasks,handlers等所组成的一种特定的结构集合。

用法

Playbook 文件定义的任务需要通过ansible-playbook命令进行调用并执行,ansible-playbook命令用法如下

用法:ansible-playbook [option] /PATH/TO/PLAYBOOK.yaml

其中[option]部分的功能包括

1.--syntax-check:检测yaml文件的语法
2.-C(--check):测试,不会改变主机的任何配置
3.--list-hosts:列出yaml文件影响的主机列表
4.--list-tasks:列出yaml文件的任务列表
5.--list-tags:列出yaml文件中的标签
6.-t TAGS(--tags=TAGS):表示只执行指定标签的任务
7.--skip-tags=SKIP_TAGSS:表示除了指定标签任务,执行其他任务
8.--start-at-task=START_AT:从指定任务开始往下运行

实验案例

1.语法检查

[root@ansible ~]# ansible-playbook --syntax-check /etc/ansible/test1.yml 

playbook: /etc/ansible/test1.yml			#没有报错提示

2.预测试

[root@ansible ~]# ansible-playbook -C /etc/ansible/test1.yml 

PLAY [test01] *****************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.200.112]

TASK [adduser] ****************************************************************************************************
changed: [192.168.200.112]

TASK [addgroup] ***************************************************************************************************
changed: [192.168.200.112]

PLAY [test02] *****************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.200.113]

TASK [cf] *********************************************************************************************************
changed: [192.168.200.113]

PLAY RECAP ********************************************************************************************************
192.168.200.112            : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
  192.168.200.113            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3.列出主机

[root@ansible ~]# ansible-playbook --list-hosts /etc/ansible/test1.yml 

playbook: /etc/ansible/test1.yml

  play #1 (test01): test01	TAGS: []
    pattern: [u'test01']
    hosts (1):
      192.168.2.222

  play #2 (test02): test02	TAGS: []
    pattern: [u'test02']
    hosts (1):
      192.168.2.223

4.列出任务

[root@ansible ~]# ansible-playbook --list-tasks /etc/ansible/test1.yml 

playbook: /etc/ansible/test1.yml

  play #1 (test01): test01	TAGS: []
    tasks:
      adduser	TAGS: [testa]
      addgroup	TAGS: [testb]

  play #2 (test02): test02	TAGS: []
    tasks:
      cf	TAGS: [testc]

5.列出标签

[root@ansible ~]# ansible-playbook --list-tags /etc/ansible/test1.yml 

playbook: /etc/ansible/test1.yml

  play #1 (test01): test01	TAGS: []
      TASK TAGS: [testa, testb]

  play #2 (test02): test02	TAGS: []
      TASK TAGS: [testc]

6.进行测试

[root@ansible ~]# ansible-playbook  /etc/ansible/test1.yml 

PLAY [test01] *****************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.200.112]

TASK [adduser] ****************************************************************************************************
changed: [192.168.2.222]

TASK [addgroup] ***************************************************************************************************
changed: [192.168.2.222]

PLAY [test02] *****************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.2.223]

TASK [cf] *********************************************************************************************************
changed: [192.168.2.223]

PLAY RECAP ********************************************************************************************************
192.168.2.222            : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
  192.168.2.223            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

7.测试查看

[root@client1 ~]# tail -1 /etc/passwd

user2:x:1002:1002::/home/user2:/bin/bash

[root@client1 ~]# tail -1 /etc/group

tests:x:981:

[root@client2 ~]# ls /home/
passwd  Rich  test

        通常情况下会先执行ansible-playbook -C /PATH/TO/PLAYBOOK.yml命令进行测试,测试没问题后再执行ansible-playbook /PATH/TO/PLAYBOOK.yml命令

二、触发器

        需要触发才能执行的任务,当之前定义在tasks中的任务执行完成后,若希望在基础上触发其他的任务,这时就需要定义handlers。例如,当通过ansible的模块对目标主机的配置文件进行修改之后,如果任务执行成功,可以触发一个触发器,在触发器中定义目标主机的服务重启操作,以便配置文件生效,handlers触发器具有以下优点。

  1. handlers是Ansible提供的条件机制之一,handlers和task很类似,但是他在被task通知的时候才会触发执行
  2. handlers只会在所有任务执行完成后执行,而且即使被通知了很多次,它也只会执行一次,handlers按照定义的顺序依次执行

handlers触发器的实验实例如下

[root@ansible ~]# vim /etc/ansible/httpd.yml

---										    #固定开头格式
- hosts: Rich								#指定运行主机为Rich组
  remote_user: root						    #指定对端运行用户的身份
  tasks:									#任务列表
    - name: xxx							    #定义任务名称
      command: sed -i 's/Listen 80/Listen 8080/g' /etc/httpd/conf/httpd.conf		#模块为command:使用sed命令替换监听端口为8080
      notify:								#完成任务后调用restart httpd server触发器
        - rehttpd 
  handlers:								    #配置触发器
    - name: rehttpd						    #指定触发器名字
      service: name=httpd state=restarted	#指定触发条件为重启httpd服务
...										    #结尾句

预执行

[root@ansible ~]# ansible-playbook -C /etc/ansible/httpd.yml 

PLAY [Rich] *******************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.2.223]
ok: [192.168.2.222]

TASK [xxx] ********************************************************************************************************
skipping: [192.168.2.223]
skipping: [192.168.2.222]

PLAY RECAP ********************************************************************************************************
192.168.2.222            : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0 
  192.168.2.223            : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

执行

[root@ansible ~]# ansible-playbook  /etc/ansible/httpd.yml 

PLAY [Rich] *******************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [192.168.200.113]
ok: [192.168.200.112]

TASK [xxx] ********************************************************************************************************
[WARNING]: Consider using the replace, lineinfile or template module rather than running 'sed'.  If you need to
use command because replace, lineinfile or template is insufficient you can add 'warn: false' to this command task
or set 'command_warnings=False' in ansible.cfg to get rid of this message.
changed: [192.168.2.223]
changed: [192.168.2.222]

RUNNING HANDLER [rehttpd] *****************************************************************************************
changed: [192.168.2.222]
changed: [192.168.2.223]

PLAY RECAP ********************************************************************************************************
192.168.2.222            : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
  192.168.2.223            : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

查看结果

[root@client1 ~]# netstat -lnpt | grep httpd

tcp6       0      0 :::8080                 :::*                    LISTEN      79542/httpd      

[root@client2 ~]# netstat -lnpt | grep httpd

tcp6       0      0 :::8080                 :::*                    LISTEN      79051/httpd     

三、角色

        将多种不同的tasks的文件集中存储在某个目录下,则该目录就是角色,角色一般存放在/etc/ansible/roles/目录中,可通过ansible的配置文件来调整默认的角色目录。/etc/ansible/roles目录下有很多的子目录,其中每一个子目录对应一个角色。每个角色也有自己的目录结构。

Ansible Playbook剧本配置文件_第1张图片

/etc/ansible/roles/为角色集合,该目录下有自定义的各个子目录

  1. mariadb:mysql角色
  2. apache:httpd角色
  3. nginx:nginx角色

每个角色的定义,以特定的层级目录结构进行组织,以Mariadb(mysql角色)为例

  1. file:存放copy或script等模块调用的文件
  2. templates:存放template模块查找所需要的模板文件的目录,如mysql配置文件等模板
  3. tasks:任务存放目录
  4. handlers:存放相关触发执行器的目录
  5. vars:变量存放的目录
  6. meta:用于存放此角色元数据
  7. default:默认变量存放目录,文件中定义了此角色使用的默认变量

        上述目录中tasks,handlers,vars,meta,default至少应该包含一个main.yml,该目录下也可以有其他的yml文件,但是需要在main.yml文件中用include指定将其他.yml文件包含进来。

        有了角色之后,可以直接在yaml文件中(playbook配置文件)中调用角色示例如下

- hosts: test01

  remote_user: root

  roles:

    - mysql #调用角色名

    - httpd #调用角色名

        可以只调用一个角色,也可以调用多个角色,当定义了角色后,用ansible-playbook PLAYBOOK文件执行即可,此时ansible会到角色集合的目录(/etc/ansible/roles)去找mysql和httpd目录,然后依次运行mysql目录和httpd目录下的所有代码。

实验案例

        下面通过一个实例配置数据库角色,要求被管理主机自动安装Mariadb,安装完成后上传提前准备好的配置文件到远端主机。重启服务,然后新建testdb数据库,并允许test用户对其拥有所有权限。

1. 被管理端配置yum源

[root@client1 ~]# cd /etc/yum.repos.d/

[root@client1 yum.repos.d]# ls

backup  CentOS-Media.repo

[root@client1 yum.repos.d]# yum clean all

2. 配置数据库角色

[root@ansible ~]# mkdir -pv /etc/ansible/roles/mariadb/{files,tasks,handlers}
mkdir: 已创建目录 "/etc/ansible/roles/mariadb"
mkdir: 已创建目录 "/etc/ansible/roles/mariadb/files"
mkdir: 已创建目录 "/etc/ansible/roles/mariadb/tasks"
mkdir: 已创建目录 "/etc/ansible/roles/mariadb/handlers"

#创建需要的文件路径 注意不要写错

[root@ansible ~]# vim /etc/ansible/mariadb.yml
---
- hosts: test01:test02
  remote_user: root
  roles: 
    - mariadb
...
[root@ansible ~]# cd /etc/ansible/roles/mariadb/


[root@ansible mariadb]# ls

files  handlers  tasks

[root@ansible mariadb]# cd tasks/

[root@ansible tasks]# vim main.yml

---			                                    //固定开头格式
- name: install mariadb			                //指定任务名称安装mariadb数据库
  yum: name=mariadb-server state=present		//执行yum模块安装mariadb
- name: move config file		                //指定任务名称移除原有配置文件
  shell: "[ -e /etc/my.cnf ] && mv /etc/my.cnf /etc/my.cnf.bak"          //判断有就移除
- name: provide a new config file				//创建一个新的配置文件
  copy: src=my.cnf dest=/etc/my.cnf		        //src源会自动到files文件去找my.cnf文件
- name: reload mariadb					        //指定任务名称为重启mariadb
  shell: systemctl restart mariadb              //shell模块重启
- name: create database testdb		            //按要求添加执行如下sql语句
  shell: mysql -u root -e "create database testdb;grant all privileges on testdb.* to [email protected].% identified by 'test123';flush privileges;"
  notify:				                        //配置触发器
  - restart mariadb		                        //为重启mariadb
...

[root@ansible mariadb]# cd ../handlers/

[root@ansible handlers]# vim main.yml

---
- name: restart mariadb				//引用上面配置的触发器
  service: name=mariadb state=restarted   //触发后重启mariadb
...


[root@ansible handlers]# cd ../files/

[root@ansible files]# cp /etc/my.cnf /etc/ansible/roles/mariadb/files/

[root@ansible files]# ls

my.cnf				//准备my.cnf文件

[root@ansible files]# cd /etc/ansible/

[root@ansible ansible]# tree			
.
├── ansible.cfg
├── hosts
├── httpd.yml
├── mariadb.retry
├── mariadb.yml
├── roles
│   └── mariadb
│       ├── files
│       │   └── my.cnf
│       ├── handlers
│       │   └── main.yml
│       └── tasks
│           └── main.yml
└── test.yml

[root@ansible ansible]# cd

[root@ansible ~]# ansible-playbook -C /etc/ansible/mariadb.yml 		//预执行

PLAY [test01] **********************************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [192.168.2.222]

TASK [mariadb : install mariadb] ***************************************************************************************************************************************
changed: [192.168.2.222]

TASK [mariadb : move config file] **************************************************************************************************************************************
skipping: [192.168.2.222]

TASK [mariadb : provide a new config file] *****************************************************************************************************************************
ok: [192.168.2.222]

TASK [mariadb : reload mariadb] ****************************************************************************************************************************************
skipping: [192.168.2.222]

TASK [mariadb : create database testdb] ********************************************************************************************************************************
skipping: [192.168.2.222]

PLAY RECAP *************************************************************************************************************************************************************
192.168.2.222            : ok=3    changed=1    unreachable=0    failed=0   
                                                    

                    //无报错直接执行  注意sql语句不要写错 

    
[root@ansible ~]# ansible-playbook /etc/ansible/mariadb.yml         //直接执行


PLAY [test01] **********************************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [192.168.2.222]

TASK [mariadb : install mariadb] ***************************************************************************************************************************************
changed: [192.168.2.222]

TASK [mariadb : move config file] **************************************************************************************************************************************
changed: [192.168.2.222]

TASK [mariadb : provide a new config file] *****************************************************************************************************************************
changed: [192.168.2.222]

TASK [mariadb : reload mariadb] ****************************************************************************************************************************************
changed: [192.168.2.222]

TASK [mariadb : create database testdb] ********************************************************************************************************************************
changed: [192.168.2.222]

RUNNING HANDLER [mariadb : restart mariadb] ****************************************************************************************************************************
changed: [192.168.2.222]

PLAY RECAP *************************************************************************************************************************************************************
192.168.2.222            : ok=7    changed=6    unreachable=0    failed=0   





3、Ansible端验证

[root@ansible ~]# ansible test01 -m shell -a 'mysql -u root -e "show databases;"'

192.168.200.112 | SUCCESS | rc=0 >>
Database
information_schema
mysql
performance_schema
test
testdb                #client端验证授权

[root@client1 ~]# mysql

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.56-MariaDB MariaDB Server

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show grants for test@'192.168.2.%';
+-----------------------------------------------------------------------------------------------------------------+
| Grants for [email protected].%                                                                                   |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test'@'192.168.2.%' IDENTIFIED BY PASSWORD '*676243218923905CF94CB52A3C9D3EB30CE8E20D' |
| GRANT ALL PRIVILEGES ON `testdb`.* TO 'test'@'192.168.2.%'                                                    |
+-----------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

MariaDB [(none)]> exit
Bye

四、变量

4.1、在playbook中使用自定义变量

[root@ansible ~]# vim /etc/ansible/test_vars.yml

---
- hosts: all
  vars:                     #定义变量
  - name: "cloud"           #第一个name变量
    age: "3"                #第二个age变量
  tasks:
  - name: "{{ name }}"      #{{}}两对大括号引用变量,变量名两头空格
    shell: echo "myname {{ name }},myage {{ age }}"
    register: var_result
  - debug: var=var_result
...


特别提示:引用变量需要在双引号中引用。


[root@ansible ~]# ansible-playbook /etc/ansible/test_vars.yml

 [WARNING]: Found variable using reserved name: name	#这里提示,name是一个保留的内置变量,我们在自定义时不能用


PLAY [all] **************************************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************************
ok: [192.168.2.222]
ok: [192.168.2.223]

TASK [cloud] ********************************************************************************************************************************************************
changed: [192.168.2.223]
changed: [192.168.2.222]

TASK [debug] ************************************************************************************************************************************************************
ok: [192.168.2.223] => {
    "var_result": {
        "changed": true, 
        "cmd": "echo \"myname cloud,myage 3\"", 
        "delta": "0:00:00.040323", 
        "end": "2019-05-15 22:45:38.739879", 
        "failed": false, 
        "rc": 0, 
        "start": "2019-05-15 22:45:38.699556", 
        "stderr": "", 
        "stderr_lines": [], 
        "stdout": "myname cloud,myage 3", 
        "stdout_lines": [
            "myname cloud,myage 3"
        ]
    }
}
ok: [192.168.2.222] => {
    "var_result": {
        "changed": true, 
        "cmd": "echo \"myname cloud,myage 3\"", 
        "delta": "0:00:00.039473", 
        "end": "2019-05-15 22:45:38.740609", 
        "failed": false, 
        "rc": 0, 
        "start": "2019-05-15 22:45:38.701136", 
        "stderr": "", 
        "stderr_lines": [], 
        "stdout": "myname cloud,myage 3", 
        "stdout_lines": [
            "myname cloud,myage 3"
        ]
    }
}

PLAY RECAP **************************************************************************************************************************************************************
192.168.2.222            : ok=3    changed=1    unreachable=0    failed=0   
192.168.2.223            : ok=3    changed=1    unreachable=0    failed=0 

我们修改一下name这个变量再发送,就不会出警告了

[root@ansible ~]# vim /etc/ansible/test_vars.yml

---
- hosts: all
  vars:                                  #定义变量
  - names: "cloud"                       #第一个name变量
  age: "3"                              #第二个age变量
  tasks:
  - name: "{{ names }}"                  #{{}}两对大括号引用变量,变量名两头空格
  shell: echo "myname {{ names }},myage {{ age }}"
  register: var_result
  - debug: var=var_result
...

4.2、在playbook中使用ansible的内置变量

使用ansible all -m setup | more查看ansible内置变量

[root@ansible ~]# vim /etc/ansible/test_setupvars.yml

---
- hosts: all
 gather_facts: True                            #使用ansible内置变量
 tasks:
 - name: setup var
  shell: echo "ip {{ ansible_all_ipv4_addresses[1] }} cpu {{ ansible_processor_count }}"                            #查看cpu及内核情况
  register: var_result
 - debug: var=var_result
...

[root@ansible ~]# ansible-playbook /etc/ansible/test_setupvars.yml

PLAY [all] ****************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************
ok: [192.168.2.222]
ok: [192.168.2.223]

TASK [setup var] **********************************************************************************************************************
changed: [192.168.2.222]
changed: [192.168.2.223]

TASK [debug] **************************************************************************************************************************
ok: [192.168.2.223] => {
    "var_result": {
        "changed": true, 
        "cmd": "echo \"ip 192.168.2.223 cpu 1\"", 
        "delta": "0:00:00.042725", 
        "end": "2019-05-16 09:09:02.193466", 
        "failed": false, 
        "rc": 0, 
        "start": "2019-05-16 09:09:02.150741", 
        "stderr": "", 
        "stderr_lines": [], 
        "stdout": "ip 192.168.2.223 cpu 1", 
        "stdout_lines": [
            "ip 192.168.2.223 cpu 1"
        ]
    }
}
ok: [192.168.2.222] => {
    "var_result": {
        "changed": true, 
        "cmd": "echo \"ip 192.168.2.222 cpu 1\"", 
        "delta": "0:00:00.042745", 
        "end": "2019-05-16 09:09:02.206099", 
        "failed": false, 
        "rc": 0, 
        "start": "2019-05-16 09:09:02.163354", 
        "stderr": "", 
        "stderr_lines": [], 
        "stdout": "ip 192.168.2.222 cpu 1", 
        "stdout_lines": [
            "ip 192.168.2.222 cpu 1"
        ]
    }
}

PLAY RECAP ****************************************************************************************************************************
192.168.2.222            : ok=3    changed=1    unreachable=0    failed=0   
192.168.2.223            : ok=3    changed=1    unreachable=0    failed=0

[root@ansible ~]# vim /etc/ansible/test_setupvars.yml 

---
- hosts: all
 gather_facts: True                                #使用ansible内置变量
 tasks:
 - name: setup var
  shell: echo "ip {{ ansible_all_ipv4_addresses[1] }} cpu {{ ansible_processor_count }}" >> /tmp/test  
- name: setup var2
  shell: echo "time {{ ansible_date_time["date"] }}" >> /tmp/test         #添加时间
  register: var_result
 - debug: var=var_result
...

执行继续查看变化

5.Template模板

配置文件如果使用copy模块去下发的话,那么所有主机的配置都是一样的; 如果下发的配置文件里有可变的配置,需要用到template模块。

5.1、利用template模块下发可变的配置文件

[root@ansible ~]# vim /tmp/test

my name is {{ myname }}                                 #自定义变量
my name is {{ ansible_all_ipv4_addresses[1] }}          #系统变量

[root@ansible ~]# vim /etc/ansible/filevars.yml
---
- hosts: all
  gather_facts: True                                    #开启系统变量
  vars:
  - myname: "cloud"                                     #自定义变量
  tasks:
  - name: template test
    template: src=/tmp/test dest=/root/test             #使用template下发可变配置文件
...

[root@ansible ~]# ansible-playbook /etc/ansible/filevars.yml

PLAY [all] ************************************************************************

TASK [Gathering Facts] ************************************************************
ok: [192.168.2.222]
ok: [192.168.2.223]

TASK [template test] **************************************************************
changed: [192.168.2.223]
changed: [192.168.2.222]

PLAY RECAP ************************************************************************
192.168.2.222            : ok=2    changed=1    unreachable=0    failed=0   
192.168.2.223            : ok=2    changed=1    unreachable=0    failed=0  

[root@client2 ~]# vim /root/test 

my name is cloud 
my name is 192.168.2.223

5.2、下发配置文件里面使用判断语法

[root@ansible ~]# vim /tmp/if.j2

{% if PORT %}                   #if PORT存在
ip=0.0.0.0:{{ PORT }}
{% else %}                      #否则的话
ip=0.0.0.0:80
{% endif %}                     #结尾

[root@ansible ~]# vim /etc/ansible/test_ifvars.yml

---
- hosts: all
  gather_facts: True                #开启系统内置变量
  vars:
  - PORT: 90                        #自定义变量
  tasks:
  - name: jinja2 if test
    template: src=/tmp/if.j2 dest=/root/test
...

[root@ansible ~]# ansible-playbook /etc/ansible/test_ifvars.yml

PLAY [all] ************************************************************************

TASK [Gathering Facts] ************************************************************
ok: [192.168.2.222]
ok: [192.168.2.223]

TASK [jinja2 if test] *************************************************************
changed: [192.168.2.222]
changed: [192.168.2.223]

PLAY RECAP ************************************************************************
192.168.2.222            : ok=2    changed=1    unreachable=0    failed=0   
192.168.2.223            : ok=2    changed=1    unreachable=0    failed=0  

[root@client1 ~]# cat /root/test 
                    #if PORT存在
ip=0.0.0.0:90
                    #结尾

如果我们将变量PORT值为空的话,就会是另外的结果

[root@ansible ~]# vim /etc/ansible/test_ifvars.yml

---
- hosts: all
  gather_facts: True            #开启系统内置变量
  vars:
  - PORT:                       #变量为空
  tasks:
  - name: jinja2 if test
    template: src=/tmp/if.j2 dest=/root/test
...

[root@ansible ~]# ansible-playbook /etc/ansible/test_ifvars.yml

PLAY [all] ************************************************************************

TASK [Gathering Facts] ************************************************************
ok: [192.168.2.222]
ok: [192.168.2.223]

TASK [jinja2 if test] *************************************************************
changed: [192.168.2.222]
changed: [192.168.2.223]

PLAY RECAP ************************************************************************
192.168.2.222            : ok=2    changed=1    unreachable=0    failed=0   
192.168.2.223            : ok=2    changed=1    unreachable=0    failed=0

[root@client1 ~]# cat /root/test 
                          #否则的话
ip=0.0.0.0:80
                          #结尾

六、基于Playbook部署Nginx综合案例

1、创建目录结构

[root@ansible ~]# mkdir -pv /etc/ansible/roles/nginx/{files,handlers,tasks,templates,vars}
mkdir: 已创建目录 "/etc/ansible/roles/nginx"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/files"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/handlers"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/tasks"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/templates"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/vars"

2、目录查看结构

[root@ansible ansible]# tree 
.
├── ansible.cfg
├── hosts
├── nginx.retry
├── nginx.yaml
└── roles
    └── nginx
        ├── files
        │   └── nginx-1.16.0.tar.gz
        ├── handlers
        │   └── main.yaml
        ├── tasks
        │   └── main.yaml
        ├── templates
        │   └── nginx.conf
        └── vars
            └── main.yaml

7 directories, 9 files

3、定义一个主调用文件

[root@ansible ansible]# vim /etc/ansible/nginx.yaml 

---
- hosts: crushlinux     #执行的主机范围
  gather_facts: True    #开启系统内置变量
  remote_user: root
  roles:                #启用roles原型配置
  - nginx               #执行nginx原型模组
...

4、files:存储由copy或script等模块调用的文件;

[root@ansible ansible]# ls -l /etc/ansible/roles/nginx/files/nginx-1.16.0.tar.gz 

-rw-r--r-- 1 root root 1032345 5月  16 00:30 /etc/ansible/roles/nginx/files/nginx-1.16.0.tar.gz

5、handlers:此目录中至少应该有一个名为main.yml的文件,用于定义各handler;其它的文件需要由main.yml进行“包含”调用;

[root@ansible ansible]# vim /etc/ansible/roles/nginx/handlers/main.yaml 

---
- name: start nginx
  raw: /usr/local/nginx/sbin/nginx
...

6、tasks:目录至少应该有一个名为main.yml的文件,用于定义各task;其它的文件需要由main.yml进行“包含”调用;

[root@ansible ansible]# vim /etc/ansible/roles/nginx/tasks/main.yaml 

---
- name: yum install
  yum: name={{ item }} state=latest
  with_items:
    - openssl-devel
    - pcre-devel
    - zlib-devel
    - gcc
    - gcc-c++
    - make

- name: user nginx
  shell: useradd -M -s /sbin/nologin nginx

- name: package
  copy: src=nginx-1.16.0.tar.gz dest=/usr/src

- name: install nginx
  shell: cd /usr/src ; tar xf nginx-1.16.0.tar.gz -C /usr/src ; cd /usr/src/nginx-1.16.0 ; ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module  --with-pcre && make && make install
- name: copy conf file
  template: src=nginx.conf dest=/usr/local/nginx/conf/nginx.conf

  notify:
    - start nginx
...

7、templates:存储由template模块调用的模板文本;

[root@ansible ansible]# vim /etc/ansible/roles/nginx/templates/nginx.conf 

user  nginx;
worker_processes  {{ ansible_processor_vcpus }};
{% if ansible_processor_vcpus == 1 %}
worker_cpu_affinity 10;
{% elif ansible_processor_vcpus == 2 %}
worker_cpu_affinity 01 10;
{% elif ansible_processor_vcpus == 4 %}
worker_cpu_affinity 0001 0010 0100 1000;
{% elif ansible_processor_vcpus == 8 %}
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
{% else %}
worker_cpu_affinity 0001 0010 0100 1000;
{% endif %}

error_log  logs/error.log;
pid        logs/nginx.pid;


events {
    use epoll;
    worker_connections  65535;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    keepalive_timeout  65;
    gzip  on;

    server {
        listen       {{ nginxport }};
        server_name  {{ server_name}};

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

8、vars:此目录中至少应该有一个名为main.yml的文件,用于定义各variable;其它的文件需要由main.yml进行“包含”调用;

[root@ansible ansible]# vim /etc/ansible/roles/nginx/vars/main.yaml 

---
nginxport: "80"
server_name: "www.crushlinux.com"
...

9、其他:

meta:此目录中至少应该有一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其它的文件需要由main.yml进行“包含”调用;

default:此目录中至少应该有一个名为main.yml的文件,用于设定默认变量;

10、测设部署

[root@ansible ansible]# vim hosts

[web]
192.168.2.222
192.168.2.223


[root@ansible ansible]# ansible-playbook /etc/ansible/nginx.yaml 

PLAY [crushlinux] *******************************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************************
ok: [192.168.2.223]
ok: [192.168.2.222]

TASK [nginx : yum install] **********************************************************************************************************************************************
ok: [192.168.2.222] => (item=[u'openssl-devel', u'pcre-devel', u'zlib-devel', u'gcc'])
ok: [192.168.2.223] => (item=[u'openssl-devel', u'pcre-devel', u'zlib-devel', u'gcc'])

TASK [nginx : user nginx] ***********************************************************************************************************************************************
changed: [192.168.2.222]
changed: [192.168.2.223]

TASK [nginx : package] **************************************************************************************************************************************************
ok: [192.168.2.223]
ok: [192.168.2.222]

TASK [nginx : install nginx] ********************************************************************************************************************************************
changed: [192.168.2.222]
changed: [192.168.2.223]

TASK [nginx : copy conf file] *******************************************************************************************************************************************
ok: [192.168.2.222]
ok: [192.168.2.223]


PLAY RECAP **************************************************************************************************************************************************************
192.168.2.222            : ok=6    changed=2    unreachable=0    failed=0   
192.168.2.223            : ok=6    changed=2    unreachable=0    failed=0  

11、检验

[root@client1 ~]# netstat -anptl | grep nginx

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      13778/nginx: master 

[root@client2 ~]# netstat -anptl | grep nginx

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      13778/nginx: master 

Ansible Playbook剧本配置文件_第2张图片

你可能感兴趣的:(流程步骤,基础知识,基础知识命令,ansible,linux,运维)