【Ansible】关于创建自定义模块时调用变量的方法
我是一位有半年经验的新手基础设施工程师。
首先
我是一名在某个公司担任基础设施工程师的人,每天都忙于创建ansible的角色和playbook。
虽然我才使用ansible半年,但是最近终于逐渐熟悉了开发和运维。
在这期间,出现了一个任务,需要我创建一个“自定义模块”。
Ansible有许多已实现的模块。
(请参阅官方网站: http://docs.ansible.com/ansible/list_of_all_modules.html)
但是,这次的要求是与现有模块不兼容的。
我只是一个刚从一个月前开始学习Python的新手,因此一开始很担心自己是否能够完成这样一个很酷的工作,即创建自己的模块。
我感到不安,但是!
Ansible的模块,出人意料地可以很容易地创建。
只要创建,门槛就不高。
然而,独立模块与ansible是分离的,
所以如果不知道如何调用在ansible中定义的变量,
就有可能面临无法调用的压力和困扰。
话不多说,开始进入正题了。
在这个页面上,我们将介绍初学者在面对这种压力时可能会遇到的变量调用方法。
根据您提供的信息,我们可以使用任何语言进行开发。但是,我将使用我正在学习的Python语言来解释。
环境
・CentOS 7.2 -> CentOS 7.2
・Python 2.7.5 -> Python 2.7.5
准备好
首先,准备一个专属的模块存放位置。
在playbook内创建一个名为”library”的文件夹。
※请使用标准的文件夹名称,如果更改名称,将无法加载模块。
这次将在执行的角色内进行创建。
角色的结构如下所示。
ansible-test-playbook
|_test-server.yml
|_group_vars
|_host_vars
|_vars
|_inventory
|_roles
|_role_test
|_defaults
|_main.yml
|_tasks
|_main.yml
|_templates
|_library ⬅︎new!
|_test.py ⬅︎new!
由于准备工作已经完成,接下来我们将创建自定义模块。
即使只有简单的shell脚本也能运行,但这次我们将重点写“在 ansible 中声明的变量在模块中读取并执行”的方法。
在ansible中,一旦定义了变量,就可以自由地在其他地方调用它,对吧?
但是,在自定义模块中直接调用变量却行不通。
因此,需要通过任务(task)指定要调用的变量,并将其传递给自定义模块。
下面将说明如何将变量传递给自定义模块并将执行结果返回给ansible。
创建defaults/main.yml文件
本次调用的变量可以通过defaults进行声明,具体如下。(变量的书写方式本页面不进行展示)
un: "Hello"
deux: "World"
创建tasks/main.yml
接下来是准备任务。
在任务中,写如下所示。
- name: get hello world
test: # .pyを除いた実行する独自モジュール名
un: "{{ un }}" # 独自モジュールで使用したい変数
deux: "{{ deux }}"
register: cinq # 独自モジュールの実行結果を格納する変数名
创建独立的模块
让我们创建一个模块。
在库目录下创建一个名为“test.py”的文件。
#!/usr/bin/env python
# coding: utf-8
# 必要なものをインポート
import json, urllib2
from ansible.module_utils.basic import *
def main():
# varsから情報を取得するおまじないのようなものです
# この時に変数名を、taskで宣言したものと一致するように書いてください
module = AnsibleModule(
argument_spec=dict(
un=dict(required=True, type='str'),
deux=dict(required=True, type='str')
),
# no skip
supports_check_mode=True,
)
# 上記で取得した情報を格納して、モジュール内で使用できるようにする
un = module.params['un']
deux = module.params['deux']
# このモジュールで実行する内容
trois = un + deux
# 実行結果を辞書型で格納
# 後述のansible_factsが辞書型の形式で作られているので、この形は必須です
quatre = {"quatre": trois}
# 実行結果をansible側に引き渡す
module.exit_json(changed=True, ansible_facts=quatre)
if __name__ == '__main__':
main()
执行
现在准备工作已经就绪,我将执行上述内容。
PLAYBOOK: test-server.yml ********************************************************
1 plays in test-server.yml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [role-test : get hello world] *******************************************
changed: [localhost] => {
"ansible_facts": {
"quatre": "HelloWorld" ⬅︎実行結果
},
"changed": true,
"invocation": {
"module_args": {
"deux": "World",
"un": "Hello"
},
"module_name": "test"
}
}
明白了独立模块的执行结果被存储在ansible_facts中。
那么,如果我们想在ansible端调用执行结果,应该如何编写呢?
"{{ cinq.ansible_facts.quatre }}"
如果在任务中的注册步骤中指定的变量名为「taskの中のregisterで指定した変数名.ansible_facts.独自モジュール内で宣言した辞書型のkey」,则可以在ansible中使用此写法来使用执行结果。
工作已经完成了。
作者留言
您对此有何感受?
能够稍微帮助到遇到类似困扰的人们,我将感到非常幸福。
因为今后还会持续接触ansible和python,所以如果有新的学习经历,我会继续发布。
非常感谢您的观看。