使用Ansible定义每个角色的`become = yes'

时间:2016-08-27 16:05:22

标签: ansible

在使用Ansible的系统配置中,我不想在每个任务中指定become=yes,因此我在项目主目录中创建了以下 ansible.cfg ,并自动安装了Ansible以root身份运行所有内容:

[privilege_escalation]
become = True

但随着项目的不断发展,一些新角色不应该以root身份运行。我想知道是否有可能在角色中有一些指令,该角色中的所有任务都应该以root身份运行(例如,在vars /中运行),而不是全局 ansible.cfg 上面的解决方案!

5 个答案:

答案 0 :(得分:43)

我找到了一个解决方案,虽然我认为Ansible团队应该实施更好的解决方案。将 main.yml 重命名为 tasks.yml ,然后将以下内容写入 main.yml

---
- { include: tasks.yml, become: yes }

另一个解决方案是直接在 site.yml 中传递参数,但问题的主要思想是在其他项目中重用该角色而不忘记它需要root:

---
- hosts: localhost
  roles:
    - { role: name, become: yes }

答案 1 :(得分:23)

您还可以将任务包装在一个块中,并将become: yes放在块上。因此,在roles/role_name/tasks/main.yml内,你会这样做:

- block:

  - name: Tasks go here as normal
    ...

  become: yes

这将以root身份运行块内的所有任务。 Ansible的块here的更多细节。

答案 2 :(得分:5)

这并不是一个根本不同的答案,而是对已经说过的内容进行了重新格式化。对我来说,看起来最短,最干净且最喜欢YAML:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript">
        function myFunction() {
            var abc, obj, i, j;
            abc = {
                "cars": [
                    '{"model":"Sentra", "doors":4, "lol":["hi","hello","hahahaha"]}',
                    '{"model":"Maxima", "doors":4,"lol":["hi","hello","hahahaha"]}',
                    '{"model":"Skyline", "doors":2,"lol":["hi","hello","hahahaha"]}'
                ]
            }
            var obj = JSON.parse(abc);
            var theader = "<tr><th>Title</th><th>Author</th><th>year</th></tr>";
            document.getElementById("dtable").appendChild(theader);
            var x;
            for (i = 0; i < abc.cars.length; i++) {
                x += "<tr><td>" + obj.cars[i].model + "</td><td>" + obj.cars[i].doors + "</td><td>" + obj.cars[i].lol[0] + "</td></tr>";
                document.getElementById("dtable").appendChild(x);
            }
        };
    </script>
</head>
<body>
    <div class="container" ,id="dsjson">
        <button type="button" onclick="myFunction()">display json</button>
        <br><br>
        <table id="dtable"></table>
    </div>
</body>
</html>

角色1将以root用户身份运行,而角色2将不会。

答案 3 :(得分:2)

有一种方法可以满足您的要求,但您需要小心使用它,因为Ansible在运行任何任务之前会评估大多数变量。如果您使用此技巧,则必须确保始终如一地使用它,否则您可能无意中使用了become您不想要的地方。

在引擎盖下,Ansible使用变量ansible_become来确定是否使用变为该任务。在您的角色中,您可以创建defaults/main.yml并设置ansible_become: [true/false]这将导致整个角色接受该值,除非被更高优先级定义覆盖(对于理解variable precedence很重要)< / p>

关键&#34;陷阱&#34;这是因为如果你使用一个定义了它的角色,它将影响游戏中在它下面调用的所有其他角色,除非它们也定义了它。

示例:

默认情况下,

role_default_become_trueansible_become: true定义为true 默认情况下,role_default_become_falseansible_become: false定义为true role_no_default没有默认ansible_become

---
- name: test1
  hosts: localhost
  connection: local
  roles:
  - role_default_become_true
  - role_default_become_false
  - role_no_default

- name: test2
  hosts: localhost
  connection: local
  roles:
  - role_default_become_false
  - role_default_become_true
  - role_no_default

- name: test3
  hosts: localhost
  connection: local
  roles:
  - role_default_become_false
  - role_default_become_true
  - { role: role_no_default, become: false }

在test1中,role_no_default将运行而不会变为,因为前一个角色将其定义为false,并且它没有自己的定义。

在test2中,role_no_default将与ran一起运行,因为前一个角色将其定义为true,并且它没有自己的定义。

在test3中,role_no_default将在没有变为的情况下运行,因为它有自己的定义。

答案 4 :(得分:2)

Ansible documentation for 2.4中,您可以找到一种定义连接变量的方法,例如ansible_becomeansible_user。它们被定义为常规变量。下面是一个片段。

第一个角色prepare_user使用没有提升权限的root用户连接到hosts。第二个角色register使用通过hosts设置的remote_user连接到ansible.cfg(在defined order中查找;按“以下顺序”搜索)。

---
- hosts: all
  name: Prepare VMs for cluster
  roles:
    - role: prepare_user
      vars:
        - ansible_become: false
        - ansible_user: root

    - role: register
...