如果标记为在 ansible 中使用,可能相当于 chef 的是什么?

What could be the possible equivalent of chef if tagged to be used in ansible?

寻找解决方案来解决 Ansible 中 Chef 的 if-tagged 用法。标签是在 chef 服务器中使用 knife 命令创建的,并且可以在 recipe if-tagged 中调用。

在 ansible 中执行此操作的等效方法是什么?

因此,在下面的代码中,如果节点标记为 prod,它会从食谱中选取 prod 模板并复制到节点的目标路径。

if tagged?('prod')
  template '/etc/prod.yml' do
  source 'prod.erb'
  action :create
end
else
template '/etc/qa.yml' do
  source 'qa.erb'
  action :create
  end
end

不确定 "how" 你 define/tag 你的主机是否是生产主机。但这里有一个使用主机命名约定的示例。

  - set_fact: myenv="prod"
    when: ( ansible_hostname | search("-p$")) or ( ansible_hostname | search("-prod$") )

这会分析目标服务器的主机名,如果主机名以 -p 或 -prod 结尾,则会创建一个名为 myenv 且值为 prod 的变量(事实)。您当然也可以使用其他 ansible 变量或检查现有文件或配置设置等的目标。

然后您可以使用 copy 模块:

  - name: Copy PROD config on PROD hosts
    copy: src=/srv/ansible/configs/prod.yml dest=/etc/prod.yml owner=root group=root mode=0644
    when: myenv == "prod"

  - name: Copy QA config on non-PROD hosts
    copy: src=/srv/ansible/configs/qa.yml dest=/etc/qa.yml owner=root group=root mode=0644
    when: myenv is undefined

注意我添加了 when: myenv is undefined 是因为上面的 set_fact 仅在主机名查找与 prod 命名约定匹配时定义了 myenv 变量。对于所有其他主机,这不适用,对于 ansible,在这种情况下未设置变量。您也可以在定义 qa 主机的地方创建第二个 set_fact。在这种情况下,您可以将 "Copy QA.." 任务的 when 条件调整为 when: myenv is undefined or myenv != "prod".

或者使用一个固定的事实变量(在这种情况下没有不同的环境),更简单但不太动态:

  - set_fact: myprod=yes
    when: ( ansible_hostname | search("-p$")) or ( ansible_hostname | search("-prod$") )

  - name: Copy PROD config on PROD hosts
    copy: src=/srv/ansible/configs/prod.yml dest=/etc/prod.yml owner=root group=root mode=0644
    when: myprod is defined

  - name: Copy QA config on all other hosts
    copy: src=/srv/ansible/configs/qa.yml dest=/etc/qa.yml owner=root group=root mode=0644
    when: myprod is undefined

您可以尝试使用 Ansible 中的组功能。 例如,定义您的库存文件如下

[all_hosts:children]
prod
qa

[prod]
prod_hostname

[qa]
qa_hostname

在您的剧本中,您可以为各个任务编写如下条件:

when: inventory_hostname in groups.prod 用于执行产品特定任务

when: inventory_hostname in groups.qa 用于执行产品特定任务

做,确保你应该访问 inventory_hostname 的方式,因为语法不同,你可能必须在某些版本的 ansbile 中使用 {{inventory_hostname}} .