ansible变量、获取hosts中主机ip
变量的定义:
变量名应该由字母、数字下划数组成
变量名必须以字母开头
ansible内置关键字不能作为变量名
一、在Inventory中定义变量
1、 定义主机变量(在主机清单里定义)
1.1 内置主机变量
所谓内置变量其实就是ansible.cfg配置文件中的选项,在其前加上ansible_
即成为内置变量。当然内置变拥有比ansible.cfg中选项更高的优先级,而且针对不同的主机,可以定义不同的值。
# 一般连接 ansible_ssh_host #用于指定被管理的主机的真实IP ansible_ssh_port #用于指定连接到被管理主机的ssh端口号,默认是22 ansible_ssh_user #ssh连接时默认使用的用户名 # 特定ssh连接 ansible_connection #SSH连接的类型:local, ssh, paramiko,在ansible 1.2 之前默认是paramiko,后来智能选择,优先使用基于ControlPersist的ssh(如果支持的话) ansible_ssh_pass #ssh连接时的密码 ansible_ssh_private_key_file #秘钥文件路径,如果不想使用ssh-agent管理秘钥文件时可以使用此选项 ansible_ssh_executable #如果ssh指令不在默认路径当中,可以使用该变量来定义其路径 # 特权升级 ansible_become #相当于ansible_sudo或者ansible_su,允许强制特权升级 ansible_become_user #通过特权升级到的用户,相当于ansible_sudo_user或者ansible_su_user ansible_become_pass # 提升特权时,如果需要密码的话,可以通过该变量指定,相当于ansible_sudo_pass或者ansible_su_pass ansible_sudo_exec #如果sudo命令不在默认路径,需要指定sudo命令路径 # 远程主机环境参数 ansible_shell_executable # 设置目标机上使用的shell,默认为/bin/sh ansible_python_interpreter #用来指定python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径 ansible_*_interpreter #其他解释器路径,用法与ansible_python_interpreter类似,这里"*"可以是ruby或才perl等其他语言
实例:
[test] 192.168.1.1 ansible_ssh_user=root ansible_ssh_pass='P@ssw0rd' 192.168.1.2 ansible_ssh_user=breeze ansible_ssh_pass='123456' 192.168.1.3 ansible_ssh_user=bernie ansible_ssh_port=3055 ansible_ssh_pass='456789'
1.2 定义主机组变量
变量也可以通过组名,应用到组内的所有成员:
[wuhan] web1 web2 [suizhou] web4 web3 [hubei:children] wuhan suizhou [hubei:vars] ntp_server=192.168.1.10 zabbix_server=192.168.1.10
二、在Playbook中定义变量
2.1 变量的定义方式
2.1.1 通过vars关键字定义
- name: use vars define invrionmemnt hosts: test user: ansible vars: http_port: 80 server_name: localhost conf_file: /etc/nginx/conf/default.conf
2.1.2 通过vars_files关键字引入变量文件
- hosts: all remote_user: root vars: favcolor: blue vars_files: - vars/external_vars.yml - vars/user_vars.yml # vars/user_vars.yml示例: users: bjones: first_name: Bob last_name: Jones home_dirs: /users/bjones acook: first_name: Anne last_name: Cook home_dirs: /users/acook
2.1.3 在playbook中通过host_vars和group_vars目录定义变量
下面这是一个项目的playbook目录结构。这个项目中,包含一个ansible.cfg文件,一个inventory文件,一个playbook.yml文件,一个group_vars
目录和一个host_vars
目录:
# tree /etc/ansible/playbooks/project /etc/ansible/playbooks/project ├── ansible.cfg ├── group_vars │ ├── datacenter1 │ ├── datacenter2 │ └── datacenters ├── host_vars │ ├── demo1.example.com │ ├── demo2.example.com │ ├── demo3.example.com │ └── demo4.example.com ├── inventory └── playbook.yml
其中inventory文件的示例如下:
[datacenter1] demo1.example.com demo2.example.com [datacenter2] demo3.example.com demo4.example.com [datacenters:children] datacenter1 datacenter2
可以看到group_vars目录中,定义了三个文件,分别以inventory文件中的三个主机组命名,所以这三个文件中定义的就分别是这三个组可以使用的变量。
此种自定义变量比较常见,inventory.ini主机清单中主机组的[datacenter1]对应group_vars下的datacenter1.yml文件
在host_vars目录中,定义了三个文件,分别以inventory文件中的四个主机命名,所以这四个文件中定义的就分别是这四个主机可以使用的变量。
# cat demo1.example.com package: httpd # cat demo2.example.com package: apache # cat demo3.example.com package: mariadb-server # cat demo4.example.com package: mysql-server
假如主机组定义的变量与主机冲突,主机变量优先级最高
2.1.4 注册变量
在有些时候,可能需要将某一条任务执行的结果保存下来,以便在接下的任务中调用或者做些判断。可以通过register关键字来实现将某一任务结果保存为一个变量。
- name: register variables hosts: test tasks: - name: capture output of whoami command command: whoami register: login
注册变量的应用场景:
- 在一台远端的服务器获取一个目录下的一列表的文件,然后下载这些文件
- 在handler执行之前,发现前面一个task发生了changed,然后执行一个指定的task
- 获取远端服务器的ssh key的内容,构建出known_hosts文件
2.1.5 设置变量set_fact
--- - hosts: 192.168.40.132 remote_user: root tasks: - set_fact: testvar: "2022-1-9" - debug: msg: "{{testvar}}"
--- - hosts: 192.168.40.133 remote_user: root tasks: - name: test vars set_fact: _consul_data: '{{ consul.local_dir | default("/root/zjz" ~ "/consul") }}/data' _consul_config: '{{ consul.local_dir | default("/root/test" ~ "/consul") }}/config' - name: print vars debug: var: "_consul_data, _consul_config"
此处~的作用:拼接
"/root/zjz" ~ "/consul" 等价于 "/root/zjz/consul"
+号运算符:可以完成数字相加,字符串相加,列表相加。但是并不推荐使用+运算符来操作字符串,字符串相加应该使用~运算符。 -号运算符:只能针对两个数字相减。 /号运算符:对两个数进行相除。 %号运算符:取余运算。 *号运算符:乘号运算符,并且可以对字符进行相乘。 **号运算符:次幂运算符,比如2**3=8。 in操作符:跟python中的in一样使用,比如{{1 in [1,2,3]}}返回true。 ~号运算符:拼接多个字符串,比如{{"Hello" ~ "World"}}将返回HelloWorld。
2.1.6 通过命令行设置变量
--- - hosts: '{{ hosts }}' remote_user: '{{ user }}' tasks: - ... ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck" 或者 --extra-vars '{"hosts":"vipers","user":"starbuck"}'
三、获取主机ip案例
1、背景:
需要在特定的主机上设置定时任务,且里面涉及ip变量。如何拿到ip地址是重点
写法一:
{{ hostvars[groups['master'][0]]['ansible_host'] }}
-
hostvars
是一个特殊的变量,它包含了Ansible在当前Playbook运行过程中,关于所有主机的所有变量,可以理解为一个大字典。关于每一台主机的具体信息,你可以通过hostvars[hostname]
的方式进行访问。 -
groups
是一个包含了所有分组及其成员主机的字典。比如在你的inventory文件中存在一个叫做'master'的组,你可以通过groups['master']
来获取到这个组下的所有主机清单。 -
groups['master'][0]
表示你要获取'master'这个分组中的第一台主机。 -
['ansible_host']
接在hostvars[groups['master'][0]]
后面,表示你要获取传入主机的ansible_host
属性,也就是主机的地址。
因此,{{ hostvars[groups['master'][0]]['ansible_host'] }}
的含义是:获取'master'组里的第一台主机的IP地址或者主机名。
写法二:
{{ hostvars['swarm-01']['ansible_default_ipv4']['address'] }}
2、代码
- hosts: all vars: registry_ip: "{{ hostvars[groups['master'][0]]['ansible_host'] }}" es2_ip: "{{ hostvars[groups['es2'][0]]['ansible_host'] }}" tasks: - name: Configure cron file copy: content: | #0 18 * * 6 /bin/bash /healsci/scripts/archive_cluster.sh /var/log/backup/image.log 2>&1 #20 18 * * 6 /bin/bash /healsci/scripts/archive_image.sh -b /var/log/backup/image.log 2>&1 #40 18 1 * * /bin/bash /healsci/scripts/archive_es.sh -h${{ es2_ip }} -r${{ registry_ip }} backup /var/log/backup/es.log 2>&1 #40 18 2 * * /bin/bash /healsci/scripts/archive_minio.sh -b /var/log/backup/minio.log 2>&1 #0 18 3 * * /usr/bin/ansible-playbook /healsci/scripts/archive_config_playbook.yml /var/log/backup/config.log 2>&1 dest: /var/spool/cron/root owner: root group: root mode: '0600' when: "inventory_hostname == groups['docker_swarm_worker'][-1]"
3、补充:拼接用法
docker_swarm_interface: "{{ ansible_default_ipv4['interface'] }}"
docker_registry: "{{hostvars[groups['docker_swarm_manager'][0]]['ansible_' + docker_swarm_interface]['ipv4']['address'] }}:5000"
-
'ansible_' + docker_swarm_interface
**:- 假设
docker_swarm_interface
的值为"eth0"
,那么这个表达式会动态生成字符串'ansible_eth0'
。这是一个键名,通常在 Ansible Playbook 中定义的主机变量中存储网络接口信息。
- 假设
-
**
hostvars[swarm-01]['ansible_eth0']
**:- 通过上面的动态键名,获取存储在
swarm-01
主机中的ansible_eth0
变量。这通常是一个字典,包含关于eth0
接口的信息。
- 通过上面的动态键名,获取存储在
-
**
['ipv4']['address']
**:'ipv4'
是一个嵌套字典,通常包含该网络接口的 IPv4 地址等信息。['address']
获取这个字典中的address
字段,它包含实际的 IP 地址。
四、变量优先级
1、ansible中变量的优先级
- -e (--extra-vars 选项指定的变量)最高
- inventory 主机清单中定义的变量(ansible_ssh_user等)
- play剧本中vars、vars_files定义的变量
- 系统的facts变量
- 角色定义的默认变量 最低
从上到下优先级逐渐降低,高优先级会覆盖掉低优先级的变量
extra vars (always win precedence) task vars (only for the task) block vars (only for tasks in block) role and include vars set_facts registered vars play vars_files play vars_prompt play vars host facts playbook host_vars playbook group_vars inventory host_vars inventory group_vars inventory vars role defaults
五、常见的内置变量
1. 与主机相关的变量
inventory_hostname
: 当前主机的ipansible_hostname
: 当前系统主机名ansible_fqdn
: 当前主机的完全限定域名(FQDN)ansible_host
: 主机 IP 地址ansible_port
: ssh 连接的端口号(默认是 22)。
- debug: msg: "The inventory hostname is {{ inventory_hostname }} and the OS is {{ ansible_distribution }} {{ ansible_distribution_version }}." #### ok: [192.168.1.111] => { "msg": "Inventory Hostname: 192.168.1.111, Ansible Host: 192.168.1.111" }
2. 与平台信息相关的变量
ansible_distribution
: 操作系统的名称(如 Ubuntu、CentOS)。ansible_distribution_version
: 操作系统的版本号。ansible_os_family
: 操作系统的家族(如 RedHat、Debian)。ansible_kernel
: 系统内核版本。ansible_architecture
: 系统架构(如 x86_64)。
3. 与网络相关的变量
ansible_default_ipv4
: 主机的默认 IPv4 地址及相关信息(如 netmask、gateway)。ansible_interfaces
: 主机上的所有网络接口的列表。
4. 以组为单位的变量
group_names
: 当前主机所在的组的列表。groups
: 所有组的字典,每个组名称对应一个主机列表。
5. 与用户相关的变量
ansible_user
: 用于连接的用户名称。ansible_ssh_user
: ssh 连接时使用的用户。
6. 特殊变量
playbook_dir
: 当前 playbook 所在目录的路径。inventory_dir
: 当前 inventory 文件所在目录的路径。-
role_path:当前角色的路径。这个变量对角色开发者特别有用,可以用来引用角色内的文件或模板。
hostvars
: 所有主机的变量字典,可以通过hostvars['hostname']
访问特定主机的变量。
7. 其他有用的变量
ansible_version
: Ansible 的版本信息。ansible_env
: 当前主机环境变量的字典。
8. 自定义变量
- 可以在 playbook 或 inventory 文件中自定义变量,这些变量在任务中也可以通过
{{ variable_name }}
进行访问。
https://www.cnblogs.com/mauricewei/p/10054300.html 很详细