Ansible - 检查是否存在多个目录 - 如果是,则在每个目录上运行脚本 - 如何?

时间:2016-12-29 17:44:25

标签: ansible ansible-playbook

我正在为我们的网络服务创建部署手册。每个Web服务都在其自己的目录中,例如:

/webapps/service-one/
/webapps/service-two/
/webapps/service-three/

我想查看服务目录是否存在,如果存在,我想运行一个shell脚本来优雅地停止服务。目前,我可以使用ignore_errors: yes完成此步骤。

- name: Stop services
  with_items: services_to_stop
  shell: "/webapps/scripts/stopService.sh {{item}}"
  ignore_errors: yes

虽然这样可行,但如果其中一个目录不存在或者第一次部署服务,则输出非常混乱。我实际上想要其中一个:

这:

- name: Stop services
  with_items: services_to_stop
  shell: "/webapps/scripts/stopService.sh {{item}}"
  when: shell: [ -d /webapps/{{item}} ] 

或者这个:

- name: Stop services
  with_items: services_to_stop
  shell: "/webapps/scripts/stopService.sh {{item}}"
  stat: 
    path: /webapps/{{item}}
  register: path
  when: path.stat.exists == True

2 个答案:

答案 0 :(得分:4)

我先收集事实,然后只做必要的事情。

 - name: Check existing services
   stat:
     path: "/tmp/{{ item }}"
   with_items: "{{ services_to_stop }}"
   register: services_stat

 - name: Stop existing services
   with_items: "{{ services_stat.results | selectattr('stat.exists') | map(attribute='item') | list }}"
   shell: "/webapps/scripts/stopService.sh {{ item }}"

另请注意,with_items中的裸变量自Ansible 2.2起不起作用,因此您应该对它们进行模板化。

答案 1 :(得分:1)

这样您就可以在列表变量dir_names中获取现有目录名称列表(使用recurse: no只读取webapps下的第一级别):

---

- hosts: localhost
  connection: local
  vars:
    dir_names: []

  tasks:
    - find:
        paths: "/webapps"
        file_type: directory
        recurse: no
      register: tmp_dirs
    - set_fact:  dir_names="{{ dir_names+ [item['path']] }}"
      no_log: True
      with_items:
        - "{{ tmp_dirs['files'] }}"

    - debug: var=dir_names

然后,您可以通过with_items在“停止服务”任务中使用dir_names。看起来你打算只使用“webapps”下的目录名称,所以你可能想使用| basename jinja2过滤器来实现它,所以像这样:

- name: Stop services
  with_items: "{{ dir_names }}"
  shell: "/webapps/scripts/stopService.sh {{item | basename }}"