如果存在复杂对象,则有条件地设置值

时间:2017-10-25 20:21:54

标签: ansible

在我的ansible角色中,我最终包含一个运行cloudformation模块的任务,然后注册堆栈输出

- name: a cloudformation template
  cloudformation:
    stack_name: mystack
    state: present
    template: someTemplate.yml
    template_parameters:
      SomeParameter: someValue
  register: my_stack

由于此任务可能会或可能不会运行,my_stack将为空或者看起来像:

my_stack:
  stack_outputs:
    var1: something
    var2: something_else
    var3: etc

我想在my_stack.stack_outputs中将其中一个变量包含在另一个任务中如果定义了它,否则使用空字符串(''

我已尝试在另一个cloudformation中有条件地添加my_stack.stack_outputs.var1(如果已定义),否则为''但会收到错误

任务是:

- name: another cloudformation template
  cloudformation:
    stack_name: my_new_stack
    state: present
    template: someOtherTemplate.yml
    template_parameters:
      SomeOtherParameter: "{{ (my_stack.stack_outputs.var1 is defined) | ternary(my_stack.stack_outputs.var1, '') }}"

如果原始任务(mystack)已运行,则此方法有效,但如果没有,则在第二个任务的ternary部分出现错误

"The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'stack_outputs'

如果原始SomeOtherParameter从未运行,如何将mystack设置为空字符串,如果mystack 运行,则如何正确设置?

1 个答案:

答案 0 :(得分:1)

编辑:更好的解决方案:使用Jinja2 default过滤器:

((my_stack | default({})).stack_outputs | default({})).var1 | default('')

首先我们检查my_stack是否存在;如果不是,我们使用{}。然后我们检查那个东西是stack_outputs是否存在;在我们正在查看{}.stack_outputs的情况下,这将是一个显而易见的否定,而在它是my_stack的情况下,它将是。var1。再次对my_stack重复。

你需要进一步测试它。如果您可以相信(my_stack is defined) 只是未设置或具有完整价值,那么您可以这样做

(my_stack is defined and my_stack.stack_outputs is defined and my_stack.stack_outputs.var1 is defined)

否则,您需要执行类似

的操作
my_stack

操作员短路意味着如果my_stack.stack_output不存在,则不会尝试访问my_stack.stack_outputs.var1。同样,如果不存在,则不会继续尝试访问 def fetch_entity_from_ES(self,func): @wraps(func) def ES_wrapper(*args): entity_type = args[0] entity_id = args[1] search_service_utility = ElasticSearchUtilities(self.config) entity = search_service_utility.fetch_entity_from_ES(entity_type, entity_id) if not entity: return func(*args) return entity return ES_wrapper