如何在ansible playbook中只运行一项任务?

Posted

技术标签:

【中文标题】如何在ansible playbook中只运行一项任务?【英文标题】:How to run only one task in ansible playbook? 【发布时间】:2014-07-19 15:48:53 【问题描述】:

有没有办法在 ansible playbook 中只运行一个任务?

例如,roles/hadoop_primary/tasks/hadoop_master.yml。我有"start hadoop job tracker services" 任务。我可以只运行那一项任务吗?

hadoop_master.yml 文件:

# Playbook for  Hadoop master servers

- name: Install the namenode and jobtracker packages
  apt: name=item force=yes state=latest
  with_items: 
   - hadoop-0.20-mapreduce-jobtracker
   - hadoop-hdfs-namenode
   - hadoop-doc
   - hue-plugins

- name: start hadoop jobtracker services
  service: name=hadoop-0.20-mapreduce-jobtracker state=started
  tags:
   debug

【问题讨论】:

【参考方案1】:

你熟悉handlers吗?我想这就是你要找的。将重启从hadoop_master.yml移动到roles/hadoop_primary/handlers/main.yml

- name: start hadoop jobtracker services
  service: name=hadoop-0.20-mapreduce-jobtracker state=started

现在在hadoop_master.yml 中调用使用notify

- name: Install the namenode and jobtracker packages
  apt: name=item force=yes state=latest
  with_items: 
   - hadoop-0.20-mapreduce-jobtracker
   - hadoop-hdfs-namenode
   - hadoop-doc
   - hue-plugins
  notify: start hadoop jobtracker services

【讨论】:

【参考方案2】:

您应该按照https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html 中的说明使用tags:


如果您有一个大型 playbook,那么能够在不运行整个 playbook 的情况下运行配置的特定部分可能会很有用。

出于这个原因,plays 和 tasks 都支持“tags:”属性。

例子:

tasks:

    - yum: name= item  state=installed
      with_items:
         - httpd
         - memcached
      tags:
         - packages

    - template: src=templates/src.j2 dest=/etc/foo.conf
      tags:
         - configuration

如果您只想运行很长的剧本中的“配置”和“包”部分,您可以这样做:

ansible-playbook example.yml --tags "configuration,packages"

另一方面,如果您想在没有特定任务的情况下运行剧本,您可以这样做:

ansible-playbook example.yml --skip-tags "notification"

您也可以将标签应用于角色:

roles:
  -  role: webserver, port: 5000, tags: [ 'web', 'foo' ] 

您还可以标记基本的包含语句:

- include: foo.yml tags=web,foo

这两者都具有在包含语句中标记每个任务的功能。

【讨论】:

看看这个答案:***.com/a/52888274/2834918。此处接受的答案在 google 中弹出,duckduckgo 位于顶部,但隐藏了 ansible 2.7 引入的较新界面。 我建议不要使用--tags。问题是ansible-playbook 不会失败,如果你打错了标签,而且从 IRC 上告诉我的内容来看,没有办法让它失败。这意味着在重构剧本时很容易引入难以发现的错误。我个人决定将剧本拆分为较小的剧本,因此ansible-playbook 将在给定的剧本中运行所有内容。不是我喜欢的东西,但是哦,好吧…… “根据我在 irc 上被告知的内容”几乎不是质量参考来源。也许您想链接到一些已发表的文章或讨论这些问题的帖子? @Mxx 当然,文档是否被视为优质来源?在这种情况下,只需输入man ansible-playbook 并搜索“tags”关键字。您只会找到选择/跳过/列出标签的选项。没有办法让它失败。 @Hi-Angel,我上面的回答链接到官方文档页面。【参考方案3】:

有一种方法,虽然不是很优雅:

    ansible-playbook roles/hadoop_primary/tasks/hadoop_master.yml --step --start-at-task='start hadoop jobtracker services' 你会得到一个提示:Perform task: start hadoop jobtracker services (y/n/c) 回复y 你会得到下一个提示,按Ctrl-C

【讨论】:

将它与--check-vvv 选项结合起来也非常有用。它实际上不会执行命令,但会给出非常详细的输出结果。【参考方案4】:

我希望能够将角色用作任务集合,这样,在我的剧本中,我可以选择要运行的任务子集。不幸的是,剧本只能将它们全部加载,然后您必须使用 cmdline 上的--tags 选项来选择要运行的任务。这样做的问题是,所有任务都会运行,除非您记得设置--tags--skip-tags

不过,我已经使用when: 子句设置了一些任务,该子句仅在设置了 var 时才会触发。

例如

# role/stuff/tasks/main.yml
- name: do stuff
  when: stuff|default(false)

现在,这个任务默认不会触发,但前提是我设置了stuff=true

$ ansible-playbook -e '"stuff":true'

或在剧本中:

roles:
- "role":"stuff", "stuff":true

【讨论】:

我只是一个新手,我听到你在说什么......但我会探讨你为什么不愿意让整个剧本运行。一个适当的 Ansible 游戏通常是幂等的,如果满足状态标准,它将收集事实并且“什么都不做”。我承认我也有这种担忧,因为我的大部分剧本都是“做点什么”而不是“检查这是否是状态,如果需要就做点什么”。前者只能运行一次,或者有监督,而后者可以随时运行,不会造成任何危害。 我通常将它用于调试任务。通常,我不希望调试信息运行,但有时我会这样做。不过,看看其他回复,现在可能有更好的方法来做到这一点。 是的,有。具体来说,现在有选择地运行戏剧的一种方法是“标记”戏剧。可能还有其他方法来限制游戏;我还在学习... 至少在我的情况下,不运行整个 playbook 的原因是因为 1) 非常长,2) 可能针对大约 400 个主机运行。这需要一段时间。我大量使用-t-l--start-at-task,因为有时我需要快速拿出一些东西,或者我只是不想看着我的终端滚动一个小时。【参考方案5】:

带有 Ansible 2.2 的 FWIW 可以使用 include_role:

剧本test.yml:

- name: test
  hosts:
    - 127.0.0.1
  connection: local
  tasks:
    - include_role:
        name: test
        tasks_from: other

然后在roles/test/tasks/other.yml:

- name: say something else
  shell: echo "I'm the other guy"

并使用:ansible-playbook test.yml 调用剧本以获取:

TASK [test : say something else] *************
changed: [127.0.0.1]

【讨论】:

【参考方案6】:

这可以使用标签轻松完成

标签示例定义如下:

---
hosts: localhost
tasks:
 - name: Creating s3Bucket
   s3_bucket:
        name: ansiblebucket1234567890
   tags: 
       - createbucket

 - name: Simple PUT operation
   aws_s3:
       bucket: ansiblebucket1234567890
       object: /my/desired/key.txt
       src: /etc/ansible/myfile.txt
       mode: put
   tags:
      - putfile

 - name: Create an empty bucket
   aws_s3:
       bucket: ansiblebucket12345678901234
       mode: create
       permission: private
   tags:
       - emptybucket

要执行我们使用命令的标签

ansible-playbook creates3bucket.yml --tags "createbucket,putfile"

【讨论】:

这不起作用 - 错误!剧本必须是剧本列表,而不是 【参考方案7】:

在这里查看我的答案:Run only one task and handler from ansible playbook

可以运行单独的角色(来自roles/ dir):

ansible -i stage.yml -m include_role -a name=create-os-user localhost

和单独的任务文件:

ansible -i stage.yml -m include_tasks -a file=tasks/create-os-user.yml localhost

如果您将任务从角色外部化到根tasks/ 目录(通过import_tasks: ../../../tasks/create-os-user.yml 实现重用),您可以独立于剧本/角色运行它。

【讨论】:

以上是关于如何在ansible playbook中只运行一项任务?的主要内容,如果未能解决你的问题,请参考以下文章

markdown 如何在本地运行Ansible playbook

YAML基础语法-ansible使用ansible-playbook

如何在 python3.5 中以编程方式运行 ansible-playbook 时设置额外的变量?(Ansible 版本 - 2.8)

学习ansible playbook之前先了解下YAML语法

在Ansible中,如何在回调插件中访问提供给playbook的额外参数?

如何控制Ansible Playbook的执行顺序运行选定的剧本资源