ansible 模块_您需要了解的Ansible模块

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的功能。 了解它们很重要,这样您才能知道何时使用一种而不是另一种。

插件分为几个类别,分别具有不同的目标,例如操作,缓存,回调,连接,过滤器,查找和变量。 最受欢迎的插件是:

  • 连接插件:这些插件实现了一种与清单中的服务器进行通信的方式(例如SSH,WinRM,Telnet); 换句话说,自动化代码如何通过网络传输以执行。
  • 过滤器插件:这些插件可让您在剧本中操作数据。 这是Ansible所利用的Jinja2功能,可以解决基础架构即代码的问题。
  • 查找插件:这些插件从外部来源(例如,env,文件,Hiera,数据库,HashiCorp Vault)获取数据。

Ansible的官方文档是开发插件的好资源。

什么时候应该开发模块?

尽管Ansible随附了许多模块,但仍有可能您的问题尚未解决或问题过于具体(例如,仅在您的组织中有意义的解决方案)。 幸运的是,官方文档为开发模块提供了出色的指导。

重要说明:开始进行新工作之前,请务必检查是否有打开的请求,请在#ansible-devel(IRC / Freenode)上询问开发人员,或搜索开发列表和/或现有工作组以查看模块是否存在或在其中。发展。

您需要一个新模块而不是使用现有模块的迹象包括:

  • 常规的配置管理方法(例如,模板,文件,get_url,lineinfile)无法正确解决您的问题。
  • 您必须使用命令,外壳程序,过滤器,带有魔术正则表达式的文本处理以及使用curl进行API调用的复杂组合才能实现目标。
  • 您的剧本是复杂的,命令性的,非幂等的,甚至是不确定的。

在理想情况下,该工具或服务已经具有用于管理的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
: "*.*"

这种基于自定义模块的方法的优点包括:

  • 它是声明性的-资源在YAML中正确表示。
  • 这是幂等的。
  • 它从声明的状态收敛到当前状态
  • 它是人类可读的。
  • 它很容易参数化或重复使用。

实施自定义模块

让我们以一个开放源代码Java应用服务器WildFly为例,为我们不太好的剧本引入自定义模块:


   
   
- 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'

问题:

  • 这不是声明性的。
  • JBoss-CLI以类似JSON的语法返回纯文本。 因此,这种方法非常脆弱,因为我们需要一种表示法的解析器。 甚至看似简单的解析器也可能太复杂而无法处理许多异常
  • JBoss-CLI只是一个将请求发送到管理API(端口9990)的接口。
  • 发送HTTP请求比打开新的JBoss-CLI会话,连接和发送命令更有效。
  • 它没有收敛到期望的状态。 它仅在不存在时创建资源。

为此的自定义模块如下所示:


   
   
- 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, 泄漏抽象定律

自定义Ansible模块101

  • stdout中的JSON (JavaScript对象表示法):这就是合同!
  • 它们可以用任何语言编写,但是…
  • Python通常是最好的选择(或第二好的选择)
  • Ansible附带的大多数模块( lib / ansible / modules )都是用Python编写的,应该支持兼容版本。

Ansible方式

  • 第一步:
     git clone https://github.com/ansible/ansible.git 
    
  • 浏览lib / ansible / modules /并阅读现有的模块代码。
  • 您的工具是:Git,Python,virtualenv,pdb(Python调试器)
  • 有关全面的说明,请参阅官方文档

替代方法:将其放在库目录中


   
   
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
  • 开始更容易。
  • 除了Ansible和您最喜欢的IDE /文本编辑器之外,不需要任何其他功能。
  • 如果要在内部使用,这是最好的选择。

提示:例如,如果需要修补模块,则可以使用此目录布局覆盖现有模块。

第一步

您可以自己完成操作(包括使用另一种语言),也可以使用AnsibleModule类,因为按照Ansible期望的方式( msgmeta ,将JSON放入stdout( exit_json()fail_json() )更容易。 has_changedresult ),也更容易处理输入( 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示例,请检查此pull request

运行测试

Ansible方式

所述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"

另一种选择:将模块与您的角色捆绑在一起

这是一个简单角色内的完整示例

分子 + 流浪 + pytestmolecule init (内角色/)

它提供了更大的灵活性来选择:

  • 简化设置
  • 如何提升基础架构:例如,Vagrant,Docker,OpenStack,EC2
  • 如何验证基础架构测试:Testinfra和Goss

但是您的测试必须使用带有Testinfra或Goss的pytest编写,而不是简单的Ansible。 如果您想了解有关测试Ansible角色的更多信息,请参阅有关使用Molecule的文章。

翻译自: https://opensource.com/article/19/3/developing-ansible-modules

ansible 模块

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值