本文共 9355 字,大约阅读时间需要 31 分钟。
ansible 模块
Ansible通过连接到节点并发送称为模块的小型程序来远程执行工作。 这使得它成为一个推式架构,其中配置从Ansible推到没有代理的服务器,这与基于代理的配置管理系统中通常会拉取配置的拉取模型相反。
这些模块映射到资源及其各自的状态 ,这些状态在YAML文件中表示。 它们使您几乎可以管理所有具有可以与之交互的API,CLI或配置文件的内容,包括网络设备,例如负载平衡器,交换机,防火墙,容器协调器,容器本身,甚至虚拟机管理程序或操作系统中的虚拟机实例。公共(例如,AWS,GCE,Azure)和/或私有(例如,OpenStack,CloudStack)云,以及存储和安全设备以及系统配置。
使用Ansible的内置电池模型时,包含了数百个模块,并且剧本中的任何任务都在其后方有一个模块。
标准输出中的JSON 。 YAML文件中声明的配置通过SSH / WinRM或任何其他连接插件通过网络传递,作为要在目标服务器中执行的小脚本。 尽管大多数Ansible模块(Windows PowerShell除外)都是使用Ansible API用Python编写的(这简化了新模块的开发),但是模块可以用任何能够返回JSON的语言编写。模块是扩展Ansible功能的一种方法。 其他选择,例如动态清单和插件,也可以提高Ansible的功能。 了解它们很重要,这样您才能知道何时使用一种而不是另一种。
插件分为几个类别,分别具有不同的目标,例如操作,缓存,回调,连接,过滤器,查找和变量。 最受欢迎的插件是:
Ansible的官方文档是的好资源。
尽管Ansible随附了许多模块,但仍有可能您的问题尚未解决或问题过于具体(例如,仅在您的组织中有意义的解决方案)。 幸运的是,官方文档为提供了出色的指导。
重要说明:开始进行新工作之前,请务必检查是否有打开的请求,请在#ansible-devel(IRC / Freenode)上询问开发人员,或搜索和/或现有以查看模块是否存在或在其中。发展。
您需要一个新模块而不是使用现有模块的迹象包括:
在理想情况下,该工具或服务已经具有用于管理的API或CLI,并且它返回某种结构化数据(JSON,XML,YAML)。
“做爱,但不要在YAML中创建shell脚本。”
那么,是什么让一部糟糕的剧本呢?
- name : Read a remote resource command : "curl -v http://xpto/resource/abc" register : resource changed_when : False - name : Create a resource in case it does not exist command : "curl -X POST http://xpto/resource/abc -d '{ config:{ client: xyz, url: http://beta, pattern: *.* } }'" when : "resource.stdout | 404" # Leave it here in case I need to remove it hehehe #- name: Remove resource # command: "curl -X DELETE http://xpto/resource/abc" # when: resource.stdout == 1
除了非常脆弱之外(如果资源状态在某处包含404,该怎么办?),并要求额外的代码具有幂等性,该剧本在状态改变时也无法更新资源。
用这种方式编写的剧本不尊重许多基础架构即代码原则。 它们不为人类所理解,难以重用和参数化,并且不遵循大多数配置管理工具所鼓励的声明性模型。 它们也不能成为幂等并收敛到声明的状态。
错误的剧本可能会危害您的自动化采用。 它们没有利用配置管理工具来提高速度,而是与基于脚本和命令执行的命令式自动化方法存在相同的问题。 这会创建一个场景,在该场景中,您将使用Ansible作为传递旧脚本的一种方式,将已经拥有的脚本复制到YAML文件中。
这是重写此示例以遵循基础结构即代码原则的方法。
- name : XPTO xpto : name : abc state : present config : client : xyz url : http://beta pattern : "*.*"
这种基于自定义模块的方法的优点包括:
让我们以一个开放源代码Java应用服务器为例,为我们不太好的剧本引入自定义模块:
- name : Read datasource command : "jboss-cli.sh -c '/subsystem=datasources/data-source=DemoDS:read-resource()'" register : datasource - name : Create datasource command : "jboss-cli.sh -c '/subsystem=datasources/data-source=DemoDS:add(driver-name=h2, user-name=sa, password=sa, min-pool-size=20, max-pool-size=40, connection-url=.jdbc:h2:mem:demo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE..)'" when : 'datasource.stdout | outcome => failed'
问题:
为此的自定义模块如下所示:
- name : Configure datasource jboss_resource : name : "/subsystem=datasources/data-source=DemoDS" state : present attributes : driver-name : h2 connection-url : "jdbc:h2:mem:demo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" jndi-name : "java:jboss/datasources/DemoDS" user-name : sa password : sa min-pool-size : 20 max-pool-size : 40
该剧本是声明性的,幂等的,更具可读性的,并且无论当前状态如何,都可以收敛到所需状态。
学习如何构建定制模块的充分理由包括:
“……抽象为我们节省了工作时间,但并没有节省我们学习的时间。” — Joel Spolsky,
git clone https://github.com/ansible/ansible.git
library/ # if any custom modules, put them here (optional) module_utils/ # if any custom module_utils to support modules, put them here (optional) filter_plugins/ # if any custom filter plugins, put them here (optional) site.yml # master playbook webservers.yml # playbook for webserver tier dbservers.yml # playbook for dbserver tier roles/ common/ # this hierarchy represents a "role" library/ # roles can also include custom modules module_utils/ # roles can also include custom module_utils lookup_plugins/ # or other types of plugins, like lookup in this case
提示:例如,如果需要修补模块,则可以使用此目录布局覆盖现有模块。
您可以自己完成操作(包括使用另一种语言),也可以使用AnsibleModule类,因为按照Ansible期望的方式( msg , meta ,将JSON放入stdout( exit_json() , fail_json() )更容易。 has_changed , result ),也更容易处理输入( params [] )和记录其执行( log() , debug() )。
def main ( ) : arguments = dict ( name = dict ( required = True , type = 'str' ) , state = dict ( choices = [ 'present' , 'absent' ] , default = 'present' ) , config = dict ( required = False , type = 'dict' ) ) module = AnsibleModule ( argument_spec = arguments , supports_check_mode = True ) try : if module. check_mode : # Do not do anything, only verifies current state and report it module. exit_json ( changed = has_changed , meta = result , msg = 'Fez alguma coisa ou não...' ) if module. params [ 'state' ] == 'present' : # Verify the presence of a resource # Desired state `module.params['param_name'] is equal to the current state? module. exit_json ( changed = has_changed , meta = result ) if module. params [ 'state' ] == 'absent' : # Remove the resource in case it exists module. exit_json ( changed = has_changed , meta = result ) except Error as err: module. fail_json ( msg = str ( err ) )
注意: check_mode (“ 空运行”)允许执行剧本或仅验证是否需要更改,但不执行更改。 另外, module_utils目录可用于不同模块之间的共享代码。
对于完整的Wildfly示例,请检查 。
所述Ansible代码库是大量测试,每次提交触发器在它的持续集成(CI)服务器,构建 ,其包括掉毛,单元测试和集成测试。
对于集成测试,它使用容器和Ansible本身来执行设置和验证阶段。 这是自定义模块的示例代码的测试用例(用Ansible编写):
- name : Configure datasource jboss_resource : name : "/subsystem=datasources/data-source=DemoDS" state : present attributes : connection-url : "jdbc:h2:mem:demo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" ... register : result - name : assert output message that datasource was created assert : that : - "result.changed == true" - "'Added /subsystem=datasources/data-source=DemoDS' in result.msg"
这是一个简单角色内的 :
+ + : molecule init
(内角色/)
它提供了更大的灵活性来选择:
但是您的测试必须使用带有Testinfra或Goss的pytest编写,而不是简单的Ansible。 如果您想了解有关测试Ansible角色的更多信息,请参阅有关文章。
翻译自:
ansible 模块
转载地址:http://tqczd.baihongyu.com/