金鱼哥RHCA回忆录:DO447使用过滤器和插件转换器--使用查找模板化外部数据

金鱼哥 发表于 2022/06/14 09:59:02 2022/06/14
【摘要】 第四章 使用过滤器和插件转换器--使用查找模板化外部数据

🎹 个人简介:大家好,我是 金鱼哥,CSDN运维领域新星创作者,华为云·云享专家,阿里云社区·专家博主
📚个人资质:CCNA、HCNP、CSNA(网络分析师),软考初级、中级网络工程师、RHCSA、RHCE、RHCA、RHCI、ITIL😜
💬格言:努力不一定成功,但要想成功就必须努力🔥


📜官网:https://docs.ansible.com/ansible/latest/plugins/lookup.html


📜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模板表达式会产生以下结构(换行):

image-20220414213453225

在Ansible 2.5及以后版本中,可以使用query函数代替lookup来调用查找插件。两者之间的区别是,query返回的不是用逗号分隔的值,而是一个列表,这样更容易解析和处理。

前面的例子可以这样调用:

vars:
  hosts: "{{ query('file', '/etc/hosts', '/etc/issue') }}"

查询调用将返回这个数据结构(换行):

image-20220414213537444


📜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文件。

image-20220414213612990

使用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.”。

image-20220414213734730

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将每一行输出作为列表项返回。

这个功能的一个有趣的应用是获取一组命令的输出的第一行(或任何特定的行):

image-20220414213851736

注意:考虑到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门的学习与考试,还是需要花不少时间去学习与备考的,好好加油,可以噶🤪。

以上就是【金鱼哥】对 第四章 使用过滤器和插件转换器–使用查找模板化外部数据 的简述和讲解。希望能对看到此文章的小伙伴有所帮助。

💾红帽认证专栏系列:
RHCSA专栏:戏说 RHCSA 认证
RHCE专栏:戏说 RHCE 认证
此文章收录在RHCA专栏:RHCA 回忆录

如果这篇【文章】有帮助到你,希望可以给【金鱼哥】点个赞👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点。

如果有对【运维技术】感兴趣,也欢迎关注❤️❤️❤️ 【金鱼哥】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。