lookup 函数

在 playbooks 中可以使用一个名为 lookup()的函数,该函数用于 ansible 从外部资源访问数据,根据第一个参数的不同,该函数具有不同的功能,典型的就是读取外部文件内容。lookup()只在本地执行,而不是在远程主机上执行。
例子:

1
2
3
4
5
6
debug: msg="{{ lookup('file', '/etc/foo.txt') }}"
debug: msg="password - {{ lookup('password', '/tmp/random_pass.txt length=10') }}"
debug: msg="{{ lookup('env','HOME') }} is an environment variable"
debug: msg="{{ lookup('pipe','date') }} is the raw result of running this command"
debug: msg="{{ lookup('dnstxt', 'example.com') }} is a DNS TXT record for example.com"
debug: msg="{{ lookup('template', './some_template.j2') }} is a value from evaluation of this template"

k8s 模块使用 lookup 实例

1
2
3
4
- name: Read definition file from file after jinja templating
k8s:
state: present
definition: "{{ lookup('template', '/testing/deployment.yml') | from_yaml }}"

git 模块

简介

此模块用于 checkout 远程 git 仓库中的文件

使用要求(在执行模块的主机上)

git>=1.7.1 (命令行工具)

模块参数

名称 必选 默认值 备注
accept_hostkey no no 如果yes,请确保“-o StrictHostKeyChecking = no”作为 ssh 选项存在。
archive no 使用扩展名指定存档文件路径。 如果指定,则创建包含源树树结构的指定格式的存档文件。 允许的存档格式[“zip”,“tar.gz”,“tar”,“tgz”]
这将从本地目录克隆并执行 git archive
bare no no 如果yes,则将创建存储库作为裸存储库,否则它将是具有工作空间的标准存储库。
clone no yes 如果no,即使它本地不存在,也不要克隆存储库
depth no clone 的深度,最小值为 1, git>=1.9.1 才支持
dest yes 应该检出存储库的路径。 除非将 clone 设置为 no,否则此参数是必需的。
executable no 要使用的 git 可执行文件的路径
force no no 如果yes,则将丢弃工作存储库中的任何已修改文件。
key_file no 私钥存放地址
recursive no yes 如果no,将使用–recursive 选项克隆存储库,跳过子模块。
reference no 参考 git clone –reference
refspec no no 添加要获取的其他 refspec。 如果将版本设置为无法从任何分支或标记访问的 SHA-1,则可能需要此选项来指定包含 SHA-1 的 ref。 使用与’git fetch’命令相同的语法。 示例值可以是“refs / meta / config”。
remote no origin  远程仓库名
repo yes git 仓库地址
separate_git_dir no  设置 git 仓库目录的存储
ssh_opts no ssh 命令参数,覆盖默认的 ssh 参数
track_submodules no no 如果 yes,子模块将跟踪其主分支(或.gitmodules 中指定的其他分支)上的最新提交。 如果no,则子模块将保留在主项目指定的修订版本中。 这相当于为 git 子模块更新指定了–remote 标志。
umask no 在执行任何检出或任何其他存储库维护之前设置的 umask。
update no yes 如果no,请不要从源存储库中检索新修订
verify_commit no no 如果yes,则在克隆或签出版本时验证 GPG 签名提交的签名。git>2.1.0
version no HEAD clone 代码的版本号

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# Example git checkout from Ansible Playbooks
- git:
repo: 'https://foosball.example.org/path/to/repo.git'
dest: /srv/checkout
version: release-0.22

# Example read-write git checkout from github
- git:
repo: git@github.com:mylogin/hello.git
dest: /home/mylogin/hello

# Example just ensuring the repo checkout exists
- git:
repo: 'https://foosball.example.org/path/to/repo.git'
dest: /srv/checkout
update: no

# Example just get information about the repository whether or not it has
# already been cloned locally.
- git:
repo: 'https://foosball.example.org/path/to/repo.git'
dest: /srv/checkout
clone: no
update: no

# Example checkout a github repo and use refspec to fetch all pull requests
- git:
repo: https://github.com/ansible/ansible-examples.git
dest: /src/ansible-examples
refspec: '+refs/pull/*:refs/heads/*'

# Example Create git archive from repo
- git:
repo: https://github.com/ansible/ansible-examples.git
dest: /src/ansible-examples
archive: /tmp/ansible-examples.zip

# Example clone a repo with separate git directory
- git:
repo: https://github.com/ansible/ansible-examples.git
dest: /src/ansible-examples

expect 模块

简介

  • expect模块用于在给的的节点上执行一个命令并响应提示。
  • 它不会通过 shell 处理命令,因此不支持像$HOME这样的变量和,以及<, >, |, ;&等都是无效的。也就是在command模块中无法使用管道符。

使用要求(在执行模块的主机上)

python >= 2.6
pexpect >= 3.3

模块参数

名称 必选 默认值 备注
chdir no 运行 command 命令前先 cd 到这个目录
command yes 命令模块执行命令运行
echo no no 是否回显你的回应字符串
responses yes 期望的字符串/正则表达式和字符串的映射来响应。 如果响应是一个列表,则连续的匹配将返回连续的响应。 列表功能是 2.1 中的新功能。
creates no 如果这个参数对应的文件存在,就不运行 command
removes no 如果这个参数对应的文件不存在,就不运行 command,与 creates 参数的作用相反
timeout no 30 以秒为单位等待预期时间

示例

  • 在远程主机上执行脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- name: Case insensitve password string match
expect:
command: passwd username
responses:
(?i)password: "MySekretPa$$word"

- name: Generic question with multiple different responses
expect:
command: /path/to/custom/command
responses:
Question:
- response1
- response2
- response3

注意事项

  • 如果你想通过 shell 运行一个命令(比如你正在使用<,>,|等),你必须在命令中指定一个 shell,比如/bin/bash -c "/path/to/something | grep else"
  • responses下关键是一个 python 正则表达式匹配,不区分大小写的搜索用前缀?i。
  • 默认情况下,如果多次遇到问题,则会重复其字符串响应。 如果连续问题匹配需要不同的响应,而不是字符串响应,请使用字符串列表作为响应。
  • expect模块设计用于简单场景,对于更复杂的需求,应该考虑在shellscript模块中使用 expect 代码

Ansible 执行命令小技巧

  1. 执行时选择在某个 host 组而不在另一个 host 组的机器
1
$ ansible all:'!masters' --list-hosts
  1. 如果主机的密码都是一样的,可以在 inventory 中添加变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[k8s:children]
masters
infras
nodes

[k8s:vars]
ansible_user=root
ansible_password=password

[masters]
master1.example.com ansible_host=192.168.0.2
master2.example.com ansible_host=192.168.0.3

[infras]

[nodes]

Ansible 注册结果数据

ansible playbook 中使用 register 注册数据,实现不同 playbook 中数据共享。当完成 regster 后,下游 playbook 可以直接使用注册的变量,这时获取的数据为第一个 hosts 中匹配的服务器执行完成任务后注册的数据。
如果需要获取全部数据,需要通过hostvars获取,它会根据主机名为 key,注册的数据为 value 保存在 hostvars 中。
例如:

1
2
3
4
5
6
7
8
9
10
11
- name: get results
get_results:
register: results
- name: out host1 result
run_once: yes
debug:
msg: "{{ hostvars['host1'].results }}"
- name: out host2 result
run_once: yes
debug:
msg: "{{ hostvars['host2'].results }}"

另外通过ansible_play_hosts可获取当前运行任务的所有主机。

Ansible 学习资料

  1. ansible 学习之一:Getting Started
  2. ansible 学习之二:Inventory
  3. ansible 学习之三:Host Patterns
  4. ansible 学习之四:Playbooks
  5. ansible 学习之五:Roles and Include Statements
  6. https://sapser.github.io/ansible/2014/07/21/ansible-variables
  7. ansible 学习之七:条件判断
  8. ansible 学习之八:循环
  9. https://sapser.github.io/ansible/2014/07/22/ansible-tags
  10. ansible 学习之十:Error Handling In Playbooks
  11. https://sapser.github.io/ansible/2014/07/22/ansible-prompts
  12. ansible 学习之十二:Using Lookups