在playbook中定义变量
在playbook中,可以直接定义变量,如下所示:
- hosts: webservers
vars:
http_port: 80
YAML语法要求如果值以{{ foo }}开头的话我们需要将整行用双引号包起来.这是为了确认你不是想声明一个YAML字典.该知识点在 YAML 语法 页面有所讲述.
这样是不行的:
- hosts: app_servers
vars:
app_path: {{ base_path }}/22
应该这么做
- hosts: app_servers
vars:
app_path: "{{ base_path }}/22"
还有其它地方可以获取变量,这些变量是自动发现的,而不是用户自己设置的.
Facts通过访问远程系统获取相应的信息. 一个例子就是远程主机的IP地址或者操作系统是什么. 使用以下命令可以查看哪些信息是可用的:
ansible hostname -m setup
可以在playbook中这样引用以上例子中第一个硬盘的模型:
{{ ansible_devices.sda.model }}
同样,作为系统报告的主机名如以下所示:
{{ ansible_nodename }}
不合格的主机名显示了句号(.)之前的字符串:
{{ ansible_hostname }}
在模板和条件判断(请看 playbook_conditionals )中会经常使用Facts.
- hosts: whatever
gather_facts: no
另外 ,关闭了facts,ansible执行的速度会快很多
注册变量
变量的另一个主要用途是在运行命令时,把命令结果存储到一个变量中.不同模块的执行结果是不同的.运行playbook时使用-v选项可以看到可能的结果值. 在ansible执行任务的结果值可以保存在变量中,以便稍后使用它
示例:
- hosts: web_servers
tasks:
- shell: /usr/bin/foo
register: foo_result
ignore_errors: True
- shell: /usr/bin/bar
when: foo_result.rc == 5
有些提供的facts,比如网络信息等,是一个嵌套的数据结构.访问它们使用简单的 {{ foo }} 语法并不够用,
当仍然很容易.如下所示:
{{ ansible_eth0["ipv4"]["address"] }}
或者这样写:
{{ ansible_eth0.ipv4.address }}
相似的,以下代码展示了我们如何访问数组的第一个元素:
{{ foo[0] }}
命令行中传递变量
如果你想编写一个通用的发布playbook时则特别有用,你可以传递应用的版本以便部署:
ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"
其它场景中也很有用,比如为playbook设置主机群组或用户.
---
- hosts: '{{ hosts }}'
remote_user: '{{ user }}'
tasks:
- ...
ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"
Ansible 1.2中你也可以给extra-vars传递JSON,比如:
--extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'
key=value形式非常简单,但很实用!
Ansible 1.3中,实用”@”语法可以为extra-vars传递JSON文件:
--extra-vars "@some_file.json"
同样在Ansible 1.3中,我们可以为extra-vars传递YAML格式,无论直接通过命令行还是放置在文件中.
如:添加用户的剧本,用传递了json文件
---
- hosts: "{{ host }}"
gather_facts: no
remote_user: root
vars:
UserName: "{{ user }}"
UserPassword: "{{ pass }}"
tasks:
- name: create new user {{ UserName }}
user: name={{ UserName }} shell=/bin/bash password={{ UserPassword |password_hash('sha512') }} update_password=always append=yes
- name: Config /etc/sudoers
lineinfile: dest=/etc/sudoers state=present line='{{ item }}' validate='visudo -cf %s'
with_items:
- "{{ user }} ALL=(ALL) NOPASSWD:ALL,!/bin/rm,!/bin/su,!/usr/bin/passwd,!/usr/sbin/visudo,!/sbin/shutdown,!/sbin/reboot,!/sbin/halt"
- "Defaults: {{ user }} !requiretty"
ansible-playbook useradd.yml -e "host=192.168.20.110 user=zhangsan pass=12345678"
在上例中,new_pass是密码,如果new_pass里有特殊的字符,或者new_pass是一串数组的话,它将被转义。若不想被转义,可以使用如下方法:
# cat user.json
host: web #ansible里面定义的主机组
user: zhangsan #添加的用户名
pass: 'Fxx6unM$R%I$Jna&' #添加的用户的密码,可以用百度上随机密码生成器生成
指定user,json文件执行剧本:
# ansible-playbook useradd.yml -e "@user.json" #使用JSON格式的文件即可,-e 传递变量,优先级最高
删除web组中所有用户
# ansible web -m user -a 'name=zhangsan state=absent remove=yes'
* extra vars (在命令行中使用 -e)优先级最高
* 然后是在inventory中定义的连接变量(比如ansible_ssh_user)
* 接着是大多数的其它变量(命令行转换,play中的变量,included的变量,role中的变量等)
* 然后是在inventory定义的其它变量
* 然后是由系统发现的facts
* 然后是 "role默认变量", 这个是最默认的值,很容易丧失优先权
转载于:https://blog.51cto.com/12262646/2090879