Ansible 如何配置Jinja配置文件以包含基于通用值的服务检查?
我公司的ansible配置为为为某些服务构建Nagios模板 例如: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
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 %}
我的问题是:
{% 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我仍然不明白你想要实现什么。为什么要“如果存在特殊队列”?我想这是一个不同的例子