ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

03-变量

2021-08-28 12:32:08  阅读:181  来源: 互联网

标签:03 变量 nginx ansible user 172.18 name


一、 变量介绍

变量可以说是一个语言的基石,也是灵魂。没有变量,一个程序就变成了一个死的程序了,就不能灵活运用了。

我们在PlayBook⼀节中,将PlayBook类⽐成了Linux中的shell。那么它作为⼀⻔Ansible特殊的语⾔,肯定要涉及到变量定义、控制结构的使⽤等特性。

在这⼀节中主要讨论变量的定义和使⽤。

二、变量名的规则

变量的名字由大小写字母、下划线和数字组成
必须以字母开头
正确:

username: shark
age: 18

错误:

_name: shark
3_age: 18

不能使用如下关键字作为变量名称

add, append, as_integer_ratio, bit_length, capitalize, center, clear, 
conjugate, copy, count, decode, denominator, difference, 
difference_update, discard, encode, endswith, expandtabs, 
extend, find, format, fromhex, fromkeys, get, has_key, hex, 
imag, index, insert, intersection, intersection_update, isalnum, 
isalpha, isdecimal, isdigit, isdisjoint, is_integer, islower, 
isnumeric, isspace, issubset, issuperset, istitle, isupper, 
items, iteritems, iterkeys, itervalues, join, keys, ljust, lower,
 lstrip, numerator, partition, pop, popitem, real, remove,
 replace, reverse, rfind, rindex, rjust, rpartition, rsplit, rstrip,
 setdefault, sort, split, splitlines, startswith, strip, swapcase,
symmetric_difference, symmetric_difference_update, title, 
translate, union, update, upper, values, viewitems, viewkeys,
viewvalues, zfill

三、变量的类型

根据变量的作⽤范围⼤体的将变量分为:

  • 全局变量
  • 剧本变量
  • 资产变量

但只是⼀个⽐较粗糙的划分,不能囊括Ansible 中的所有变量。下
⾯将分别从这三种变量⼊⼿,去介绍变量的使⽤

1、全局变量

全局变量,是我们使⽤ansible 或使⽤ansible-playbook 时,⼿动通过 -e 参数传递给Ansible 的变量。

通过ansible 或 ansible-playbook 的 help 帮助, 可以获取具体格式使⽤⽅式:

# ansible -h |grep var 
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
set additional variables as key=value or YAML/JSON

# ansible-playbook -h |grep var
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
set additional variables as key=value or YAML/JSON

Example

传递普通的key=value 的形式

ansible all -i localhost, -m debug -a "msg='my key is {{ key }}'" -e "key=value"

传递⼀个YAML/JSON 的形式(注意不管是YAML还是JSON,它们的最终格式⼀定要是⼀个字典)

#cat a.json
{"name":"qfedu","type":"school"}
# localhost, 不用远程,本地测试,相当于127.0.0.1
# {{ 变量 }}  可以有空格,可以没有
# 文件写变量,用@符号指定文件名
ansible all -i localhost, -m debug -a "msg='name is {{ name }}, type is {{ type }}'" -e @a.jso
#cat a.yml
---
name: qfedu
type: school
...
ansible all -i localhost, -m debug -a "msg='name is {{ name }}, type is {{ type }}'" -e @a.yml

2、剧本变量

此种变量和PlayBook 有关,定义在PlayBook中的。它的定义⽅式有多种,我们这⾥介绍两种最常⽤的定义⽅式。

通过PLAY 属性 vars 定义

---
- name: test play vars
 hosts: all
 vars:
 user: lilei
 home: /home/lilei

通过PLAY 属性 vars_files 定义

# 当通过vars属性定义的变量很多时,这个Play就会感觉特别臃肿。此时我们可以将变量单独从Play中抽离出来,
# 形成单独的YAML ⽂件。
---
- name: test play vars
 hosts: all
 vars_files:
 - vars/users.yml
# cat vars/users.yml
---
user: lilei
home: /home/lilei

如何在PlayBook中使⽤这些变量

在PlayBook中使⽤变量时,使⽤ {{ 变量名 }} 来使⽤变量

---
- name: test play vars
  hosts: all
  vars:
    user: lilei
    home: /home/lilei
  tasks:
    - name: create the user {{ user }}
      user:
        name: "{{ user }}"
        home: "{{ home }}"

在PlayBook中使用变量的注意点

---
# 这⾥我们将上⾯的Playbook中引⽤变量的部分进⾏修改,去掉了双引号。
- name: test play vars
 hosts: all
 vars:
 user: lilei
 home: /home/lilei
 tasks:
 - name: create the user {{ user }}
 user:
 # 注意这⾥将 "{{ user }}" 改成了 {{ user }}
 name: {{ user }}
 home: "{{ home }}”

执⾏以上的PlayBook 时,会出现以下错误

The offending line appears to be:
 user:
 name: {{ user }}
 ^ here
We could be wrong, but this one looks like it might
be an issue with
missing quotes. Always quote template expression
brackets when they
start a value. For instance:
 with_items:
 - {{ foo }}
Should be written as:
 with_items:
 - "{{ foo }}"
这样错误的主要原因是PlayBook 是YAML 的⽂件格式, 当Ansible分析YAML ⽂件时,有可能会误认为字典。name: {{ user }} 是⼀个字典的开始。因此加针对变量的使⽤,加上了双引号,避免Ansible错误解析。

3、资产变量

在之前的课程中学习了资产。资产共分为静态资产和动态资产。

这⼀节中学习的资产变量,就是和资产紧密相关的⼀种变量。

资产变量分为主机变量和主机组变量,分别针对资产中的单个主机和主机组。

主机变量

以下资产中,定义了⼀个主机变量 lilei ,此变量只针对172.18.0.3 这台服务器有效

# cat hostsandhostvars[webservers]172.18.0.3 user=lilei port=3309172.18.0.4

验证

# 获取定义的变量值
# ansible 172.18.0.3 -i hostsandhostvars -m debug
-a "msg='{{user}} {{port}}'"
172.18.0.3 | SUCCESS => {
 "user": "lilei"
}
# 未获取到定义的变量值,因为 user 这个变量针对 172.18.0.4主机⽆效。
# ansible 172.18.0.4 -i hostsandhostvars -m debug
-a "var=user"
172.18.0.4 | SUCCESS => {
 "user": "VARIABLE IS NOT DEFINED!"
}

主机组变量

以下资产中,定义了⼀个组变量home ,此变量将针对webservers 这个主机组中的所有服务器有效

# cat hostsandgroupvars
[webservers]
172.18.0.3 user=lilei
172.18.0.4
[webservers:vars]
home="/home/lilei"

验证

# home 是 web_servers 的组变量,会针对这个组内的所有服务器⽣效。
# ansible webservers -i hostsandgroupvars -m debug
-a "var=home"
172.18.0.3 | SUCCESS => {
 "home": "/home/lilei"
}
172.18.0.4 | SUCCESS => {
 "home": "/home/lilei"
}

主机变量 VS 主机组变量

当主机变量和组变量在同⼀个资产中发⽣重名的情况,会有什么效果呢?

# cat hosts_v2[webservers]172.18.0.3 user=lilei172.18.0.4[webservers:vars]user=tom

验证

#在资产中定义了主机变量和组变量 user, 此时发现 172.18.0.3这台机器的主机变量 user 的优先级更⾼。# ansible webservers -i hosts_v2 -m debug -a"var=user"172.18.0.3 | SUCCESS => { "user": "lilei"}172.18.0.4 | SUCCESS => { "user": "tom"}

4、变量的继承

在介绍资产时说过资产的继承,那么变量是否也存在继承关系呢?

# cat hosts_v3
[webservers]
172.18.0.3
[dbservers]
172.18.0.4
[allservers]
[allservers:children]
dbservers
webservers
[allservers:vars]
user=lilei

验证

# 在资产继承的同时,对应的变量也发⽣了继承
# ansible allservers -i hosts_v3 -m debug -a
"var=user"
172.18.0.4 | SUCCESS => {
 "user": "lilei"
}
172.18.0.3 | SUCCESS => {
 "user": "lilei"
}
# ansible dbservers -i hosts_v3 -m debug -a
"var=user"
172.18.0.4 | SUCCESS => {
 "user": "lilei"
}
# ansible webservers -i hosts_v3 -m debug -a
"var=user"
172.18.0.3 | SUCCESS => {
 "user": "lilei"
}

5、Inventory 内置变量的说明

内置变量⼏乎都是以 ansible_ 为前缀。

ansible_ssh_host
#将要连接的远程主机名与你想要设定的主机的别名不同的话,可通过此变量设置.

ansible_ssh_port
#ssh端⼝号.如果不是默认的端⼝号,通过此变量设置.

ansible_ssh_user
#默认的 ssh ⽤户名

ansible_ssh_pass
#ssh 密码(这种⽅式并不安全,官⽅强烈建议使⽤ --askpass 或 SSH 密钥)

ansible_sudo_pass
#udo 密码(这种⽅式并不安全,官⽅强烈建议使⽤ --asksudo-pass)

ansible_sudo_exe (new in version 1.8)
#udo 命令路径(适⽤于1.8及以上版本)

ansible_ssh_private_key_file
#sh 使⽤的私钥⽂件.适⽤于有多个密钥,⽽你不想使⽤ SSH代理的情况.

ansible_python_interpreter
#标主机的 python 路径.适⽤于的情况: 系统中有多个Python, 
#者命令路径不是"/usr/bin/python",⽐如 /usr/local/bin/python3

四、Facts变量

Facts变量不包含在前⽂中介绍的全局变量、剧本变量及资产变量之内。

Facts变量不需要我们⼈为去声明变量名及赋值。

它的声明和赋值完全有Ansible 中的 setup 模块帮我们完成。

它收集了有关被管理服务器的操作系统版本、服务器IP地址、主机名,磁盘的使⽤情况、CPU个数、内存⼤⼩等等有关被管理服务器的私有信息。

在每次PlayBook运⾏的时候都会发现在PlayBook执⾏前都会有⼀个Gathering Facts的过程。这个过程就是收集被管理服务器的Facts信息过程。

1、手动收集Facts 变量

# ansible all -i localhost, -c local -m setup
localhost | SUCCESS => {
 "ansible_facts": {
 "ansible_all_ipv4_addresses": [
 "192.168.122.130"
 ],
 "ansible_all_ipv6_addresses": [
 "fe80::20c:29ff:fede:b5b"
 ],
 "ansible_apparmor": {
 "status": "disabled"
 },
 "ansible_architecture": "x86_64",
 "ansible_bios_date": "07/02/2015",
 "ansible_bios_version": "6.00",
 "ansible_cmdline": {
 "KEYBOARDTYPE": "pc",
 "KEYTABLE": "us",
 "LANG": "en_US.UTF-8",
 "SYSFONT": "latarcyrheb-sun16",
 "nomodeset": true,
 "quiet": true,
 "rd_LVM_LV": "vg_mouse00/lv_root",
 "rd_NO_DM": true,
 "rd_NO_LUKS": true,
 "rd_NO_MD": true,
 "rhgb": true,
 "ro": true,
 "root": "/dev/mapper/vg_mouse00-lv_root"
 },
 ...
 ...

2、 过滤Facts

通过刚刚的⼿动收集Facts,我们发现facts 信息量很⼤。 能不能有针对性的显示我们想要的信息呢?

可以通过使⽤Facts 模块中的filter参数去过滤我们想要的信息。

仅获取服务器的内存情况信息

# ansible all -i localhost, -m setup -a "filter=*memory*" -c local
localhost | SUCCESS => {
 "ansible_facts": {
 "ansible_memory_mb": {
 "nocache": {
 "free": 508,
 "used": 473
 },
 "real": {
 "free": 59,
 "total": 981,
 "used": 922
 },
 "swap": {
 "cached": 0,
 "free": 1981,
 "total": 1983,
 "used": 2
 }
 }
 },
 "changed": false
}

仅获取服务器的磁盘挂载情况

# ansible all -i localhost, -m setup -a "filter=*mount*" -c local
localhost | SUCCESS => {
 "ansible_facts": {
 "ansible_mounts": [
 {
 "device": "/dev/mapper/vg_mouse00-
lv_root",
 "fstype": "ext4",
 "mount": "/",
 "options": "rw",
 "size_available": 5795786752,
 "size_total": 18435350528,
 "uuid": "N/A"
 },
 {
 "device": "/dev/sda1",
 "fstype": "ext4",
 "mount": "/boot",
 "options": "rw",
 "size_available": 442216448,
 "size_total": 499355648,
 "uuid": "N/A"
 }
 ]
 },
 "changed": false
}

3、在PlayBook中去使用Facts 变量

默认情况下,在执⾏PlayBook的时候,它会去⾃动的获取每台被管理服务器的facts信息。

---- name: a play example hosts: all remote_user: root tasks: - name: install nginx package yum: name=nginx state=present - name: copy nginx.conf to remote server copy: src=nginx.confdest=/etc/nginx/nginx.conf - name: start nginx server service: name: nginx enabled: true state: started

执行

# ansible-playbook myplaybook.yml
PLAY [a play example]
****************************************************
****************************************************
****************************************************
***
# 执⾏PLAYBOOK时,⾃动收集facts 信息
TASK [Gathering Facts]
****************************************************
****************************************************
****************************************************
**
ok: [172.18.0.4]
ok: [172.18.0.3]
TASK [install nginx package]
****************************************************
****************************************************
************************************************
ok: [172.18.0.3]
ok: [172.18.0.4]
......
......

可以像使⽤其他变量⼀样,去使⽤facts 变量

---
- name: print facts variable
 hosts: all
 tasks:
 - name: print facts variable
 debug:
 msg: "The default IPV4 address is {{
ansible_default_ipv4.address }}"

在PlayBook中去关闭Facts 变量的获取

若在整个PlayBook 的执⾏过程中,完全未使⽤过 Facts 变量,此
时我们可以将其关闭,以加快PlayBook的执⾏速度。

---
- name: a play example
 hosts: webservers
 # 关闭 facts 变量收集功能
 gather_facts: no
 remote_user: root
 tasks:
 - name: install nginx package
 yum: name=nginx state=present
 - name: copy nginx.conf to remote server
 copy: src=nginx.conf
dest=/etc/nginx/nginx.conf
 - name: start nginx server
 service:
 name: nginx
 enabled: true
 state: started

执行

# ansible-playbook -i hosts myplaybook2.yml

PLAY [a play example]
****************************************************
******
TASK [install nginx package]
***************************************************
ok: [172.18.0.4]
TASK [copy nginx.conf to remote server]
****************************************
ok: [172.18.0.4]
TASK [start nginx server]
****************************************************
**
ok: [172.18.0.4]
PLAY RECAP
****************************************************
*****************
172.18.0.4 : ok=3 changed=0 
unreachable=0 failed=0 skipped=0 rescued=0
 ignored=0

五、注册变量

往往⽤于保存⼀个task任务的执⾏结果, 以便于debug时使⽤。

或者将此次task任务的结果作为条件,去判断是否去执⾏其他task任务。

注册变量在PlayBook中通过register关键字去实现。

---- name: install a package and print the result hosts: webservers remote_user: root tasks: - name: install nginx package yum: name=nginx state=present register: install_result - name: print result debug: var=install_result

执行

# ansible-playbook myplaybook3.yml
PLAY [install a package and print the result]
**********************************
TASK [Gathering Facts]
****************************************************
*****
ok: [172.18.0.4]
TASK [install nginx package]
***************************************************
ok: [172.18.0.4]
TASK [print result]
****************************************************
********
ok: [172.18.0.4] => {
 "install_result": {
 "changed": false,
 "failed": false,
"msg": "",
 "rc": 0,
 "results": [
 "1:nginx-1.16.1-1.el7.ngx.x86_64
providing nginx is already installed"
 ]
 }
}
PLAY RECAP
****************************************************
*****************
172.18.0.4 : ok=3 changed=0 
unreachable=0 failed=0 skipped=0 rescued=0
 ignored=0

六、变量优先级

⽬前介绍了全局变量、剧本变量、资产变量、Facts变量及注册变量。

其中Facts变量不需要⼈为去声明、赋值;注册变量只需通过关键字register去声明,⽽不需要赋值。

⽽全局变量、剧本变量及资产变量则完全需要⼈为的去声明、赋值。

变量的优先权讨论,也将着重从这三类变量去分析。

假如在使⽤过程中,我们同时在全局变量、剧本变量及资产变量声

明了同⼀个变量名,那么哪⼀个优先级最⾼呢? 下⾯我们将以实验的形式去验证变量的优先级

环境准备

1、定义⼀份资产、且定义了资产变量user

[dbservers]
172.18.0.3
[webservers]
172.18.0.4 ansible_ssh_port=2222
[allservers:children]
dbservers
webservers
[allservers:vars]
user=tomcat

2、编写⼀份PlayBook、同样定义剧本变量user

---
- name: test variable priority
 hosts: all
 remote_user: root
 vars:
 user: mysql
 tasks:
 - name: print the user value
 debug: msg='the user value is {{ user }}'

验证测试

同时使用全局变量、剧本变量、资产变量

当变量user同时定义在全局变量、剧本变量及资产变量中时,全局变量的优先级最⾼。
# ansible-playbook -i hosts priority.yml -e "user=www"

同时使用剧本变量和资产变量

取消全局变量,发现剧本变量的优先级要⾼于资产变量的优先级。
# ansible-playbook -i hosts priority.yml

只是⽤资产变量的情况

不使⽤全局变量、且注释掉剧本变量后,资产变量才最终⽣效。
---
- name: test variable priority
 hosts: all
 remote_user: root
 #vars:
 # user: mysql
 tasks:
 - name: print the user value
 debug: msg='the user value is {{ user }}'
# ansible-playbook -i hosts priority.yml

变量优先级结论

当⼀个变量同时在全局变量、剧本变量和资产变量中定义时,

优先级最⾼的是全局变量;其次是剧本变量;最后才是资产变量。

1

标签:03,变量,nginx,ansible,user,172.18,name
来源: https://www.cnblogs.com/yzgblogs/p/15196542.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有