Ansible 如何配置Jinja配置文件以包含基于通用值的服务检查?

Ansible 如何配置Jinja配置文件以包含基于通用值的服务检查?,ansible,jinja2,ansible-playbook,Ansible,Jinja2,Ansible Playbook,我公司的ansible配置为为为某些服务构建Nagios模板 例如: define service { use rabbit-critical-service ; Name of service template to use service_description RabbitMQ {{ queue_name }} queue size check

我公司的ansible配置为为为某些服务构建Nagios模板

例如:

      define service {
            use                     rabbit-critical-service         ; Name of service template to use
            service_description     RabbitMQ {{ queue_name }} queue size
            check_command                   check_graphite_data!1000!15000!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
            host_name               {{ rabbitmq_server }}
            notifications_enabled   1
            servicegroups           rabbitmq
    }
该模板为所有队列自动生成具有相同阈值的检查。队列名称在
ansible_playbooks/roles/nagios/defaults/main.yml
下的不同文件中配置,并使用Jinja自动生成

我的任务是以一种比较简单的方式编辑配置,以包含一些特定检查的不同阈值,但我很难理解如何做

我想到了这样的事情: 向服务检查模板添加如下内容:

{% if queue_size_specific_vars is not defined %}
create the check using the current configuration...
{% else %}
create the check using the specific configuration which will be found in the `default/main.yml` file in the newly created generic value "queue_size_specific_vars" which is supposed to include two values, one for warning value and one for critical value.
{% endif %}
我的问题是:

  • 我如何实现我的目标(同时考虑两个价值观而不是一个)
  • 我不确定这是实现我目标的最佳方式,你知道更好的方式吗
  • 编辑#1:

    似乎我没有正确地解释我自己,让我向您展示模板的更大部分:

    {% for queue_name in queues %}
    define service {
            use                     rabbit-critical-service         ; Name of service template to use
            service_description     RabbitMQ {{ queue_name }} queue active consumers
            check_command                   check_graphite_data!0.9!0.9!rabbitmq._.rabbitmq_consumers.{{ queue_name }}!reverse
            host_name               {{ rabbitmq_server }}
            notifications_enabled   1
            servicegroups           rabbitmq
            max_check_attempts      4
    }
    
    {% if vars_production is not defined %}
    define service {
            use                     generic-service
            service_description     RabbitMQ {{ queue_name }} queue read/write ratio
            check_command                   check_graphite!'http://{{ graphite_server }}:{{ graphite_port }}/render/?from=-10minutes&target=scale(divideSeries(offset(prod-rabbit-1.rabbitmq._.rabbitmq_messages.{{queue_name}}.value,1),offset(derivative(sumSeries(prod-rabbit-1.rabbitmq._.rabbitmq_deliver_get.{{queue_name}})),1)),100)&rawData'!1500!2000!avg
            host_name               {{ rabbitmq_server }}
            notifications_enabled   1
            servicegroups           rabbitmq
            max_check_attempts      4
    }
    {% endif %}
    define service {
            use                     rabbit-critical-service         ; Name of service template to use
            service_description     RabbitMQ {{ queue_name }} queue size
            check_command                   check_graphite_data!1000!15000!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
            host_name               {{ rabbitmq_server }}
            notifications_enabled   1
            servicegroups           rabbitmq
    }
    
    {% endfor %}
    
    这意味着我应该在队列级别而不是主机名级别实现更改,因为ansible只知道主机,不知道队列

    我们需要为每个队列设置“RabbitMQ{{queue\u name}}}queue size”选项,并将其余的都设置为默认值。 我希望做的更改应该发生在模板文件本身中

    例如:

    {% if special_queue_exists %}
    do ....
    {% else %}
    create it in the normal method
    {% endif %}
    
    编辑#2:

    我的经理希望我以类似以下的方式进行: 我已经有了包含所有队列的文件,让我们称这个文件为“队列文件”。 他想让我创建另一个文件,其中包含一个特定检查值列表(警告和严重),我们称这个文件为“特定值”

    然后像这样做:

    queues_with_specific_metrics:
      - entities:
        - warn: "1000"
        - crit: "20000"
    
    {{ queues_with_specific_metrics.queue.warn | default(1000) }}
    
    然后检查我正在运行的队列(来自for循环)是否在“specific_values”文件中具有特定配置,如果是,则“specific_values”文件中的设置应覆盖默认设置。 然后,我可以这样做:

    queues_with_specific_metrics:
      - entities:
        - warn: "1000"
        - crit: "20000"
    
    {{ queues_with_specific_metrics.queue.warn | default(1000) }}
    
    我是Ansible和Jinja的新手,这就是为什么我不那么容易理解,抱歉

    编辑#3: 我已经按照您的建议编辑了配置,但我不确定如何编写if语句

    defaults/main.yml包含所有队列名称的列表

    我打开了一个名为
    spec_params.yml
    的新文件,它作为
    main.yml
    文件驻留在默认文件夹中

    spec_params.yml
    文件:

    nagios_specific_queue_params:
      queue1: {}
      entities:
        warn: 2000
        crit: 20000
    
    以及
    rabbitmq.cfg.j2
    的相关部分:

    {% if queue_name in nagios_specific_queue_params %}
    define service {
            use                     rabbit-critical-service         ; Name of service template to use
            service_description     RabbitMQ {{ queue_name }} queue size
            check_command           check_graphite_data!{{ queues[queue_name] ['warn'] |default(1000) }}!{{ queues[queue_name] ['crit'] | default(15000) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
            host_name               {{ rabbitmq_server }}
            notifications_enabled   1
            servicegroups           rabbitmq
    }
    {% else %}
    define service {
            use                     rabbit-critical-service         ; Name of service template to use
            service_description     RabbitMQ {{ queue_name }} queue size
            check_command                   check_graphite_data!1000!15000!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
            host_name               {{ rabbitmq_server }}
            notifications_enabled   1
            servicegroups           rabbitmq
    }
    {% endif %}
    
    运行playbook时,出现以下错误:

    fatal: [monitoring] => {'msg': "TypeError: argument of type 'StrictUndefined' is not iterable", 'failed': True}
    fatal: [monitoring] => {'msg': 'One or more items failed.', 'failed': True, 'changed': False, 'results'
    
    知道为什么失败了吗


    提前感谢

    角色中的变量//默认值/可以被任何上级变量(在/vars、group\u vars、host\u vars和inventory vars中的变量)覆盖

    因此,如果您定义了一个变量
    队列大小
    ,那么在默认情况下,您可以在组/主机变量文件中覆盖它

    # file: roles/nagios/deaults/main.yml
    queue_size: "1000!15000"
    
    # file: host_vars/host1.yml
    queue_size: "2000!25000"
    
    # file: host_vars/host2.yml
    queue_size: "1000!5000"
    
    # file: roles/nagios/templates/check.j2
          define service {
                use                     rabbit-critical-service         ; Name of service template to use
                service_description     RabbitMQ {{ queue_name }} queue size
                check_command                   check_graphite_data!{{ queue_size }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
                host_name               {{ rabbitmq_server }}
                notifications_enabled   1
                servicegroups           rabbitmq
        }
    
    这应该能回答你的两个问题。如果希望有一个更干净的vars文件,还可以指定
    队列大小最小值
    队列大小最大值

    编辑: 为了更好地解释我在评论中的意思:

    你有两种方法(我能想到)来解决这个问题:

    第一:使用一个单独的文件,其中包含非默认队列的值。这可能更干净,但您必须将所有队列保留在原始var文件中:

    # file vars/original_file.yml
    queues: 
      - queue1
      - entities
    
    # file vars/specific.yml
    queue_with_specific_metrics:
        queue1: {}
        entities:
           warn: 1000
           crit: 15000
    
    第二:根据需要编辑原始文件以包含特定值

    queues:
       queue1: {}
       entities:
            warn: 1000
            crit: 2000
    
    在任何一种情况下,您都可以更改模板以获取值或指定默认值:

    # case 1
    check_command check_graphite_data!{{ queue_with_specific_metrics[queue_name]['warn'] | default(1000) }}!{{ queue_with_specific_metrics[queue_name]['crit'] | default(800) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value}
    
    check_command check_graphite_data!{{ queues[queue_name]['warn'] | default(1000) }}!{{ queues[queue_name]['crit'] | default(800) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value}
    

    角色//defaults/中的变量可以被任何上层变量(在/vars、group_vars、host_vars和inventory vars中的变量)覆盖

    因此,如果您定义了一个变量
    队列大小
    ,那么在默认情况下,您可以在组/主机变量文件中覆盖它

    # file: roles/nagios/deaults/main.yml
    queue_size: "1000!15000"
    
    # file: host_vars/host1.yml
    queue_size: "2000!25000"
    
    # file: host_vars/host2.yml
    queue_size: "1000!5000"
    
    # file: roles/nagios/templates/check.j2
          define service {
                use                     rabbit-critical-service         ; Name of service template to use
                service_description     RabbitMQ {{ queue_name }} queue size
                check_command                   check_graphite_data!{{ queue_size }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
                host_name               {{ rabbitmq_server }}
                notifications_enabled   1
                servicegroups           rabbitmq
        }
    
    这应该能回答你的两个问题。如果希望有一个更干净的vars文件,还可以指定
    队列大小最小值
    队列大小最大值

    编辑: 为了更好地解释我在评论中的意思:

    你有两种方法(我能想到)来解决这个问题:

    第一:使用一个单独的文件,其中包含非默认队列的值。这可能更干净,但您必须将所有队列保留在原始var文件中:

    # file vars/original_file.yml
    queues: 
      - queue1
      - entities
    
    # file vars/specific.yml
    queue_with_specific_metrics:
        queue1: {}
        entities:
           warn: 1000
           crit: 15000
    
    第二:根据需要编辑原始文件以包含特定值

    queues:
       queue1: {}
       entities:
            warn: 1000
            crit: 2000
    
    在任何一种情况下,您都可以更改模板以获取值或指定默认值:

    # case 1
    check_command check_graphite_data!{{ queue_with_specific_metrics[queue_name]['warn'] | default(1000) }}!{{ queue_with_specific_metrics[queue_name]['crit'] | default(800) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value}
    
    check_command check_graphite_data!{{ queues[queue_name]['warn'] | default(1000) }}!{{ queues[queue_name]['crit'] | default(800) }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value}
    

    以下是我为完成任务所做的步骤:

    nagios/defaults/main.yml
    中,我添加了:

    nagios_queue_size_default_values:
      warn: 1000
      crit: 15000
    nagios_queue_size_override_values:
      entities_prod_whatever_2:
        warn: 600
        crit: 900
    
    然后,在
    rabbitmq.cfg.j2
    中,我将check命令更改为以下命令:

    check_command     check_graphite_data!{{ nagios_queue_size_override_values.get(queue_name, nagios_queue_size_default_values).warn }}!{{ nagios_queue_size_override_values.get(queue_name, nagios_queue_size_default_values).crit }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
    

    现在运行playbook会根据需要创建模板。

    以下是我为完成任务所做的步骤:

    nagios/defaults/main.yml
    中,我添加了:

    nagios_queue_size_default_values:
      warn: 1000
      crit: 15000
    nagios_queue_size_override_values:
      entities_prod_whatever_2:
        warn: 600
        crit: 900
    
    然后,在
    rabbitmq.cfg.j2
    中,我将check命令更改为以下命令:

    check_command     check_graphite_data!{{ nagios_queue_size_override_values.get(queue_name, nagios_queue_size_default_values).warn }}!{{ nagios_queue_size_override_values.get(queue_name, nagios_queue_size_default_values).crit }}!rabbitmq._.rabbitmq_messages.{{ queue_name }}.value
    

    现在运行playbook会根据需要创建模板。

    我想我还是不明白您想要实现什么。为什么要“如果存在特殊队列”?我想举一个例子,说明当这个“不同”队列存在时,应该有什么不同或应该发生什么。请检查编辑#2,再次感谢!您可以完全按照您所说的做,但可以使用
    队列\u和\u特定的\u度量[queue]['warn']|默认值(1000)
    (假设“queue”是您从循环中获得的队列名称)。如果您没有在队列中定义“队列”和特定的度量,那么这也应该有效。您可以详细说明您的答案并给出解释吗?那太好了!用精化更新了答案@ItaiI think我仍然不明白你想要实现什么。为什么要“如果存在特殊队列”?我想这是一个不同的例子