DO447使用过滤器和插件转换器–使用查找模板化外部数据
RHCSA专栏:戏说 RHCSA 认证
RHCE专栏:戏说 RHCE 认证
此文章(第四章 使用过滤器和插件转换器–使用查找模板化外部数据 )收录在RHCA专栏:RHCA 回忆录
📜2.1 查找插件(lookup plug-in)
查找插件是对Jinja2模板的扩展。这些插件使Ansible能够使用来自外部源的数据,比如文件和shell环境。
📜2.2 调用查找插件
您可以使用两个Jinja2模板函数之一(lookup或query)来调用查找插件。这两种方法的语法都非常类似于过滤器。指定函数的名称,并在括号中指定要调用的查找插件的名称和插件需要的任何参数。
例如,下面的变量定义使用文件查找插件将/etc/hosts文件的内容放入Ansible变量myhosts中:
vars:
hosts: "{
{ lookup('file', '/etc/hosts') }}"
您可以在文件插件中包含多个文件名。当使用查找函数调用时。每个文件的内容在模板值中用逗号分隔。
vars:
hosts: "{
{ lookup('file', '/etc/hosts', '/etc/issue') }}"
上面的Jinja2模板表达式会产生以下结构(换行):
在Ansible 2.5及以后版本中,可以使用query函数代替lookup来调用查找插件。两者之间的区别是,query返回的不是用逗号分隔的值,而是一个列表,这样更容易解析和处理。
前面的例子可以这样调用:
vars:
hosts: "{
{ query('file', '/etc/hosts', '/etc/issue') }}"
查询调用将返回这个数据结构(换行):
📜2.3 选择查找插件
在默认的Ansible安装中有几十个插件可用。使用ansible-doc -t lookup -l命令获取可用查找插件的完整列表。关于特定插件的用途和使用方法,请执行ansible-doc -t lookup PLUGIN_NAME命令
下面介绍了一些最有用的插件:
📑读取文件的内容
file文件插件允许Ansible将本地文件的内容加载到一个变量中。如果您提供了一个相对路径,插件就会在剧本的文件目录中查找文件。
下面的示例读取用户公钥文件的内容,并使用authorized_key模块将授权密钥添加到托管主机。该示例使用循环和+操作符在模板中添加字符串,以便查找文件files/fred.key.pub和files/naoko.key.pub文件。
使用file文件插件的一个有用的技巧是,如果文件是YAML或JSON格式的,可以使用from_yaml或from_json过滤器将其解析为适当结构的数据。
my_yaml: "{
{ lookup('file', '/path/to/my.yaml') | from_yaml }}"
**注意:**文件插件读取控制节点上的文件,而不是托管主机上的文件。
📑使用模板应用数据
与file文件插件一样,template模板插件返回文件的内容。不同之处在于template模板插件期望文件内容是Jinja2模板,并计算它的值在应用内容之前使用模板。如果您向模板文件传递一个相对路径,插件将在剧本的模板目录中查找它。
{
{
lookup('template', 'my.template.j2') }}
前面的示例将处理templates/my.template.js模板在你的剧本目录中。例如,假设模板的内容如下:
Hello {
{
name }}.
下面的任务将显示“Hello class.”。
template模板插件允许一些额外的参数,比如定义开始和结束标记序列。如果输出字符串是YAML值,convert_data选项将解析该字符串以提供结构化数据
📑读取控制节点上的环境变量
env插件从控制节点查询环境变量。当控制器主机是一个容器化的应用程序,并且配置映射和秘密被容器管理应用程序(如Kubernetes或Red Hat OpenShift)注入到主机中时,这是非常有用的。
{
{
lookup('env','MY_PASSWORD') }}
📑读取控制节点上的命令输出
pipe管道和lines行插件都在Ansible控制节点上运行命令并返回输出。pipe管道插件返回命令生成的原始输出,而lines插件将该命令的输出分割成行。
假设您有以下jinj2表达式:
{
{
query('pipe', 'ls files') }}
这个表达式将以字符串形式返回ls命令的原始输出。如果使用lines插件,则表达式如下:
{
{
query('lines', 'ls files') }}
该命令生成一个列表,ls将每一行输出作为列表项返回。
这个功能的一个有趣的应用是获取一组命令的输出的第一行(或任何特定的行):
注意:考虑到head命令的存在,此示例可能不是执行此特定任务的最有效方法。
📑从URL获取内容
与file文件插件获取文件内容的方式类似,url插件从url获取内容。
{
{
lookup('url', 'https://my.site.com/my.file') }}
有许多选项可用于控制身份验证、选择web代理或将返回的内容分成行。
然而,使用URL插件的一个优点是,您可以将返回的数据作为变量中的值使用,可能首先使用过滤器处理它。
📑从Kubernetes API获取信息
k8s插件通过openshift Python模块提供了对Kubernetes API的完全访问。要获取Kubernetes对象,必须使用kind选项提供对象类型。提供额外的对象细节,比如namespace命名空间选项或label_selector选项,有助于过滤结果:
{
{
lookup('k8s', kind='Deployment', namespace='ns', resource_name='my_res') }}
注意:当Ansible Playbook管理时,使用openshift作为k8s插件的别名Red Hat OpenShift容器平台实例。
注意:k8s插件是一个查找插件。它的主要目的是从Kubernetes集群中提取信息,而不是更新它。使用k8s模块来管理Kubernetes集群。
📜2.4 处理查找错误
大多数Ansible插件被设计为在失败时中止Ansible Playbook。但是,查找函数将执行委托给其他插件,这些插件可能不需要在失败时中止Ansible Playbook。例如,如果没有找到该文件,该文件插件可能不需要中止Ansible Playbook,但可能需要通过创建丢失的文件来恢复。
为了适应不同的插件需求,查找插件接受错误参数。
{
{
lookup('file', 'my.file', errors='warn') | default("Default file content") }}
error错误选项的默认值是strict。这意味着如果底层脚本失败,lookup查找插件将引发致命错误。如果错误选项的值为warn,则当底层脚本失败并返回空字符串(或空列表)时,查找插件将记录一个警告。如果错误选项的值为ignore,则查找插件将静默地忽略该错误并返回一个空字符串或列表。
📜2.5 课本练习
[student@workstation ~]$ lab data-lookups start
📑第一部分
这个练习由两个部分组成,使用不同的目录。在第一节中,您将创建一个Ansible Playbook,将在纯文本文件中定义的所有用户填充到托管主机中。
📑按要求编写剧本
[student@workstation ~]$ cd ~/DO447/labs/data-lookups/users
# 读取文件内容的方法有很多种,但是在这里将使用行查找插件。
"{
{
query('lines','cat users.txt') }}"
# 这个插件读取cat用户的输出作为单行。查询函数将每行拆分为一个列表项。
# Ansible任务需要遍历这个简单列表中的用户。可以使用loop来做到这一点:
loop: "{
{ query('lines','cat users.txt') }}"
[student@workstation users]$ vim site.yml
- name: Populate users from file
hosts: all
gather_facts: no
tasks:
- name: Create remote user
debug:
msg: "To be done"
loop: "{
{ query('lines','cat users.txt') }}"
# 在创建用户时,创建一个随机密码。password lookup密码查找插件生成随机密码,并可选地将密码存储在本地文件中。
# 前面的步骤在用户上添加了循环,因此可以使用相同的项为每个用户生成相关联的文件。
"{
{
lookup('password', 'credentials/' + item + ' length=9') }}"
# 将密码存储到一个任务变量中,以便于使用。该Yml文件应该如下所示。注意 ' length=9' 中第一个单引号后要包含空格
- name: Populate users from file
hosts: all
gather_facts: no
tasks:
- name: Create remote user
vars:
password: "{
{ lookup('password', 'credentials/' + item + ' length=9') }}"
debug:
msg: "To be done"
loop: "{
{ query('lines','cat users.txt') }}"
# 注意,在使用刚才创建的密码之前,应该对其进行散列处理。update_password: on_create选项只在用户不存在时设置密码。如果用户已经存在,且密码不一致,则不修改密码。
- name: Populate users from file
hosts: all
gather_facts: no
tasks:
- name: Create remote user
vars:
password: "{
{ lookup('password', 'credentials/' + item + ' length=9') }}"
user:
name: "{
{ item }}"
password: "{
{ password | password_hash('sha512') }}"
update_password: on_create
loop: "{
{ query('lines','cat users.txt') }}"
📑运行剧本并验证
[student@workstation users]$ ansible-playbook site.yml
[student@workstation users]$ ssh jonfoo@serverf "cat /etc/passwd"
devops:x:1001:1001::/home/devops:/bin/bash
jonfoo:x:1002:1002::/home/jonfoo:/bin/bash
janebar:x:1003:1003::/home/janebar:/bin/bash
philbaz:x:1004:1004::/home/philbaz:/bin/bash
📑清除实验
[student@workstation users]$ ansible-playbook clean.yml
[student@workstation users]$ ssh serverf "grep jonfoo /etc/passwd"; echo $?
1
📑第二部分
在这个指导练习的第二部分中,将使用查找插件来国际化前面章节中部署的静态web应用程序。每个服务器提供本地化数据应用程序的版本,基于它自己配置的语言环境。如果没有配置语言环境,服务器将使用控制器提供的语言环境。
静态应用程序包含用于部署的项目版本,也称为Infrastructure-as-Code版本(laC版本)。为了简单起见,使用项目的Git提交id作为Ansible项目的laC版本。
📑明确模板
[student@workstation ~]$ cd ~/DO447/labs/data-lookups/i18n/
[student@workstation i18n]$ cat roles/webapp/templates/webapp.en_US.UTF-8.j2
Greetings from {
{
inventory_hostname }}.
App Version: {
{
webapp_version}}
IaC Version: {
{
iac_version }}
[student@workstation i18n]$ cat roles/webapp/templates/webapp.es_ES.UTF-8.j2
Saludos desde {
{
inventory_hostname }}.
App Version: {
{
webapp_version}}
IaC Version: {
{
iac_version }}
📑按要求编写默认变量
要获取控制器主机的区域设置,可以使用env查找插件来检索LANG环境变量的值。在环境变量不可用的情况下,提供一个默认值也是一个好的实践:
controller_lang: "{
{ lookup('env','LANG') | default('en_US.UTF-8') }}"
使用git rev-parse --short HEAD命令获取当前的Ansible项目提交id。使用管道查找来指示Ansible执行该命令:
iac_version: "{
{ lookup('pipe', 'git rev-parse --short HEAD') | quote }}"
注意:quote引号过滤器用于清除字符串中不合适的字符。在这种情况下,git命令不会返回任何有害字符,但是在使用来自外部来源的输入时,使用quote过滤器是一个很好的安全实践。
[student@workstation i18n]$ vim roles/webapp/defaults/main.yml
controller_lang: "{
{ lookup('env','LANG') | default('en_US.UTF-8') }}"
iac_version: "{
{ lookup('pipe', 'git rev-parse --short HEAD')|quote }}"
webapp_version: v1.0
📑编写主任务中页面内容
[student@workstation i18n]$ vim roles/webapp/tasks/main.yml
---
- name: Ensure stub web content is deployed
vars:
locale: "{
{ ansible_facts.env.LANG | default(controller_lang) }}"
copy:
content: "{
{ lookup('template','webapp.' + locale + '.j2') }}"
dest: /var/www/html/index.html
📑设置系统环境变量并执行剧本
[student@workstation i18n]$ LANG=en_US.UTF-8
[student@workstation i18n]$ ansible-playbook site.yml
📑验证执行情况
[student@workstation i18n]$ curl servera
Saludos desde serverb.lab.example.com.
App Version: v1.1a
IaC Version: f716bbe
[student@workstation i18n]$ curl servera
Greetings from serverc.lab.example.com.
App Version: v1.1b
IaC Version: f716bbe
[student@workstation i18n]$ ansible web_servers -m shell -a "printenv LANG"
serverb.lab.example.com | CHANGED | rc=0 >>
es_ES.UTF-8
serverc.lab.example.com | FAILED | rc=1 >>
non-zero return code
📑清除实验
[student@workstation i18n]$ ansible-playbook clean.yml
[student@workstation ~]$ lab data-lookups finish
💡总结
RHCA认证需要经历5门的学习与考试,还是需要花不少时间去学习与备考的,好好加油,可以噶🤪。
以上就是【金鱼哥】对 第四章 使用过滤器和插件转换器–使用查找模板化外部数据 的简述和讲解。希望能对看到此文章的小伙伴有所帮助。
如果这篇【文章】有帮助到你,希望可以给【金鱼哥】点个赞👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【运维技术】感兴趣,也欢迎关注❤️❤️❤️ 【金鱼哥】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!