Bootstrap

4、Ansible的变量

1.ansible Variables

变量提供了便捷的方式来管理ansible项目中的动态值

变量名:仅能由字母、数字、下划线组成,且只能以字母开头

 1.变量定义的方式

 (1)通过ansible-playbook命令行传递变量参数定义

 (2)在play文件中定义

        通过vars定义变量

           通过vars_file定义变量

 (3)通过inventory在主机或单个主机中设置变量

           通过host_vars对主机进行定义

           通过group_vars对主机进行定义

           通过inventory-hosts主机清单文件中定义变量

 2.变量常用关键字

1、vars_prompt 关键字 :#创建变量,并提示输入信息 vars_prompt.prompt:表示 提示信息

2、encrypt 关键字 :#表示对用户输入的信息进行哈希

#示例:encrypt: “sha512_crypt”表示使用sha512算法对用户输入的信息进行哈希

3、default 关键字 :#设置变量的默认值

示例:如下4.b

4、private 关键字:#表示变量值为非私有的,可见的,默认情况下 private值为yes,表示不可见。

5、confirm 关键字:#实现类似确认密码的功能,

# 我们在为用户设置密码时,通常需要输入两次完全相同的密码,才能够设置成功,通过“confirm”关键字就能实现类似的效果

 3.引用变量

当我们引用变量时,有两种语法

1、语法1

"{{httpd.conf80}}"

2、语法2

"{{nginx['conf8080']}}"

 4.在playbook中定义变量

 1.使用vars方式定义变量

在playbook的文件中开通通过vars关键字进行定义变量,格式如下:

vars:

- var1: value1

- var2: value2

#使用变量如下

---

- hosts: webservers

  remote_user: root

  vars:

  - var1: test1

  - var2: test2

  - name: test vars

    debug:

      msg:

      - "{{ var1 }}"

      - "{{ var2 }}"

 2.示例:提示用户输入信息并写入变量

使用vars_prompt关键字

---

- hosts: webservers

  remote_user: root

  vars_prompt:

  - name: "your_name"

    prompt: "What is your name"

    private: no  #设置了此参数,表示在下方输入名字和年龄的时候会显示,就是非私有的、可见的

  - name: "your_age"

    prompt: "How old are you"

    private: no

  tasks:

  - name: output vars

    debug:

      msg: Your name is {{ your_name }},You are {{ your_age }} years old.

我们也可以为提示信息设置默认值,即用户不输入任何信息,将默认值赋予变量,示例如下

---

- hosts: webservers

  remote_user: root

  vars_prompt:

  - name: "your_name"

    prompt: "What is your name"

  - name: "your_age"

    prompt: "How old are you\n"

    A: 17\n

    B: 18\n

    C: 19\n

    private: no

  tasks:

  - name: output vars

    debug:

      msg: Your name is {{ your_name }},You are {{ your_age }} years old.

编写playbook,使用户输入用户名,密码,根据用户输入的信息创建系统账户

---

- hosts: webservers

  remote_user: root

  vars_prompt:

  - name: "user_name"

    prompt: "Enter user name"

    private: no

  - name: "user_password"

    prompt: "Enter user password"

    private: no

    encrypt: "sha512_crypt"

    confirm: yes   #通常情况下密码需要输入两遍确认,就是设置这个关键字

  tasks:

  - name: create user

    user:

      name: "{{user_name}}"

      password: "{{user_password}}"

  tasks:

  - name: test password

    debug:

      msg: Your name is {{ user_name }},You are password is {{ user_password }}.

3.使用vars_file方式定义变量

在playbook中使用vars_file指定文件作为变量文件,好处就是其他的playbook也可以调用

示例:

 1、编写一个var_files文件,专门用来存放变量

[root@ansible-server ~]# vi vars.yaml

name: lingqianhui

name2: lingyizhe

name3: xxx

 2、编写playbook

---

- hosts: webservers

  remote_user: root

  vars_files: /etc/ansible/test/vars.yaml

  tasks:

  - name: test vars

    debug:

      msg:

      - "{{ name }}"

      - "{{ name2 }}"

5.针对每个主机定义变量

 1.Inventory文件中定义变量

示例:

分别为每个主机设置变量,和设置组的公共的变量

1、先在hosts 文件中定义

[webservers]  #组名

192.168.134.138 myid=1 state=master   #定义变量 myid=1 state=master

[webservers:vars]  #定义webservers这个组的 共同的端口为80

port=80

2、打印测试

---

- hosts: webservers

  remote_user: root

 

  tasks:

 

  - name: test vars

    debug:

      msg:

      - "{{ myid }}-{{ state }}-{{ port }}"

 2.使用host_vars定义变量

注意:在host_vars目录中定义的变量,只能给对应的主机使用,没有定义变量的主机不能使用此处的变量

在项目目录中创建,host_vars目录,然后在创建一个文件夹,文件的文件名称要与inventory清单中的主机名称要保持完全一致,如果是IP地址,则创建相同IP地址的文件即可:

1.先创建host_vars目录

[root@ansible-server ~]# mkdir host_vars

[root@ansible-server ~]# cd host_vars/

2.创建与主机清单文件中主机名称一致的文件

[root@ansible-server host_vars]# vi 192.168.100.20

name: lingqianhui

name2: lingyizhe

[root@ansible-server ~]# vi test.yaml

- hosts: webservers

  remote_user: root

  tasks:

  - name: test vars

    debug:

      msg:

      - "{{ name }}"

      - "{{ name2 }}"

3.使用group_vars定义变量

在项目目录中创建group_vars目录,然后再创建一个文件,文件的文件名称要与清单文件中定义的组名保持完全一致。

示例:

[root@ansible-server ~]# mkdir group_vars

[root@ansible-server ~]# cd group_vars

[root@ansible-server group_vars]# vi webservers

name: lingqianhui

name2: lingqianhui2

 3.使用group_vars定义变量

 在项目目录中创建group_vars目录

 6.通过执行playbook传递变量

在执行playbook时,可以通过命令行 --extra-vars 或者 -e 外置参数设定变量

示例:

---

- hosts: webservers

  remote_user: root

  tasks:

  - name: test vars

    debug:

      msg:

      - "{{ name2 }}"

      - "{{ name }}"

 7.变量定义的优先级

 (1)命令行传递的变量;

(2)playbook中定义的vars_files;

(3)playbook中定义的vars;

(4)在host_vars中定义的变量;

(5)在inventory中定义的主机变量;

(6)在group_vars中定义的组变量:group_vars/group_name;

(7)在group_vars中定义的all文件中的变量:group_vars/all;

(8)在inventory中定义的主机组变量

2.ansible的变量注册Register

Ansible模块运行时,都会返回一些result结果,类似于执行脚本,我们需要获取这些结果,判断上一步是否执行成功,默认情况下,ansible的result并不会显示出来,所以,我们可以把这些返回值存储到变量之中,通过调用对应的变量名,获取这些result。这种将模块的返回值写入到变量的方法叫做变量注册。

示例:

---

- hosts: webservers

  remote_user: root

  tasks:

  - name: Register test

shell: df -h

当执行这个命令时,并不会返回结果,只会返回changed时候改变,这时使用变量注册

---

- hosts: webservers

  remote_user: root

 

  tasks:

  - name: Register test

    shell: df -h

    register: df

  - name: return result

    debug:

      msg: "{{ df.stdout_lines }}"

3.层级定义变量

示例:

1.编辑变量文件

[root@ansible-server test]# vi vars.yaml

information:

  name: lingqianhui

  age: 10

  gender: female

 

information2:

  name: lingyizhe

  age: 11

  gender: male

  2.编辑剧本

[root@ansible-server test]# vi test.yaml

---

- hosts: webservers

  remote_user: root

  vars_files: vars.yaml

  tasks:

  - name: debug information

    debug:

      msg: "{{ information.name }}"

  - name: debug information

    debug:

      msg: "{{ information.age }}"

  - name: debug information

    debug:

      msg: "{{ information.gender }}"

  - name: debug information

    debug:

      msg: "{{ information2.name }}"

  - name: debug information

    debug:

      msg: "{{ information2.age }}"

  - name: debug information

    debug:

      msg: "{{ information2.gender }}"

4.facts内置变量

ansible facts是在客户端主机通过ansible自动采集发现的变量,facts包含每台特定主机的信息,如被控端的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态。

facts的获取方法:

  被控制端的主机是通过ansible的setup模块来获取信息,使用filter 参数可以过滤指定的Facts变量。

可以使用 命令行参数  查看下被控端变量信息

由于信息太多 我们直接把内容输出到文件中

ansible web -m setup > ./a.txt

facts中的变量可以直接引用,不用获取

 1.常用变量信息

 使用变量的setup模块

ansible_distribution:获取到主机的发行版本

ansible webservers -m setup -a 'filter=ansible_distribution'

ansible_fqdn  获取主机名、或者 ansible_hostname

ansible webservers -m setup -a 'filter=ansible_fqdn'

ansible_distribution_version   获取系统版本

ansible webservers -m setup -a 'filter=ansible_distribution_version'

ansible_default_ipv4:获取IP地址,网关、等网络信息

ansible webservers -m setup -a 'filter=ansible_default_ipv4'

ansible_date_time   :获取时间相关信息

ansible webservers -m setup -a 'filter=ansible_date_time'

查看系统版本信息

ansible webservers -m setup -a 'filter=*version'

2.在playbook中直接调用facts变量

[root@ansible-server variables]# vi test.yaml

---

- hosts: webservers

  remote_user: root

  tasks:

  - name: Output ansible variables facts

    debug:

      msg: hostname "{{ ansible_fqdn }}" and IP "{{ ansible_default_ipv4.address }}"

3.通过set_fact模块定义变量

set_fact是一个模块,我们可以使用set_fact模块在tasks中定义变量;

---

- hosts: webservers

  remote_user: root

 

  tasks:

  - name: test set_fact

    set_fact:

      test: "lingqianhui"

  - name: debug test

    debug:

      msg: "{{ test }}"

也可以通过set_fact将一个变量赋值给另一个变量

---

- hosts: webservers

  remote_user: root

  vars:

    testvar1: test1_string

  tasks:

  - shell: 'echo "123456"'

    register: shellreturn

  - set_fact:

      testsf1: "{{ testvar1 }}"

      testsf2: "{{ shellreturn.stdout }}"

  - debug:

      msg: "{{testsf1}} {{ testsf2 }}"

     # var: shellreturn

用vars定义了一个变量testvar1,又使用register 将shell 模块的返回值注册到了变量shellreturn 中,之后 使用set_fact模块将testvar1变量的值赋予了变量testsf1,将shellreturn变量中的stdout信息赋值给了testsf2变量

通过set_fact模块创建的变量还有一个特殊性,通过set_fact创建的变量就像主机上的facts信息一样,可以在之后的play中被引用。

示例:

---

- hosts: webservers

  remote_user: root

  vars:

    test1: tv1

  tasks:

  - name: test_fact

    set_fact:

      test2: tv2

  - name: debug

    debug:

      msg: "{{ test1 }} ------ {{ test2 }}"

- hosts: web

  remote_user: root

  tasks:

  - name: test play1 test1

    debug:

      msg: "{{ test2 }}"

  - name: test play test2

    debug:

      msg: "{{ test1 }}"

可以发现,这两个变量在第一个play中都可以正常的输出。但是在第二个play中,testvar2可以被正常输出了,testvar1却不能被正常输出,会出现未定义testvar1的错误,因为在第一个play中针对testB主机进行操作时,testvar1是通过vars关键字创建的,而testvar2是通过set_fact创建的,所以testvar2就好像testB的facts信息一样,可以在第二个play中引用到,而创建testvar1变量的方式则不能达到这种效果,虽然testvar2就像facts信息一样能被之后的play引用,但是在facts信息中并不能找到testvar2,只是”效果上”与facts信息相同

;