在Ansible中,是否可以根据剧本定义身份验证方法?

Inf*_*ian 8 authentication passwords ssh-keys ansible ansible-playbook

TL; DR:是否可以使用一个ansible-playbook命令链接两个剧本,其中一个剧本是密码认证而另一个剧本是密钥认证?(参见上一节的实际目的).

建立:

我有两本剧本,第二部是include第一部.

PlaybookA.yml

---
- name: PlaybookA # requires password authentication
  hosts: sub.domain.ext
  remote_user: root
  roles:
    - { role: role1, sudo: yes }
...
Run Code Online (Sandbox Code Playgroud)

PlaybookB.yml

---
- name: Run PlaybookA
  include: PlaybookA.yml

- name: PlaybookB # requires ssh-key authentication
  hosts: sub.domain.ext
  remote_user: ansible
  roles:
    - { role: role2, sudo: yes }
...
Run Code Online (Sandbox Code Playgroud)

要求:

  1. 仅执行一个命令.
  2. 使用密码验证为PlaybookA.
  3. 对PlaybookB使用ssh-key auth.

问题1:

在Ansible(版本1.9.4或更低版本)中是否可以执行一个ansible-playbook命令,该命令将使用ssh-key身份验证成功运行PlaybookB,但是当PlaybookB包含PlaybookA时,使用密码身份验证运行PlaybookA?

问题2:

如果Ansible 1.9.4或更低版本无法做到这一点,那么这可能是2.0.0+吗?

价值说明:

  1. Ansible提供--ask-pass(或-k)作为启用密码验证的命令行开关.
  2. Ansible提供ask_pass了一个变量但似乎只能在其中设置ansible.cfg(我无法将其设置为Playbook变量以达到所需效果).
  3. 尝试ask_pass在剧本中设置指令会产生以下结果:ERROR: ask_pass is not a legal parameter of an Ansible Play.如果此参数是合法的,它将提供一种方法来指示每个剧本级别的ansible,使用什么身份验证方法.

目的/现实世界:

我正在尝试使用Ansible创建一个配置管理工作流程,该工作流程非常简单,其他工作人员将能够学习/适应它(并希望通常使用Ansible进行CM和编排).

对于任何新建的机器(VM或物理),我打算让我们立即运行两个剧本.PlaybookA(如上所示)负责使用正确的默认用户登录(通常取决于基础设施[aws,vsphere,none等]).进入后,它的工作非常有限:

  1. 为ansible创建标准化用户以运行为(并安装其ssh-key).
  2. 删除可能存在的所有非root用户(vm基础结构的工件等).
  3. 禁用root访问权限.
  4. 禁用密码验证(仅从此时开始使用ssh-key).

根据vm基础结构(或缺少基础结构),默认用户或默认身份验证方法可以不同.为了采用Ansible的目标,我试图让同事们保持极其简单,所以我想尽可能地自动化这种流量控制.

一旦PlaybookA锁定了vm并设置了标准化用户,PlaybookB就会使用该标准化用户执行所有其他必要的操作,以使我们的vm达到必要的工具和实用程序基线等.

任何提示,提示,建议将不胜感激.

小智 6

我今天一直面临同样的问题.这里有两个想法可以帮到你:你可以在你的剧本中使用vars_prompt来代替--ask-pass使用set_fact来设置密码:


- name: "set password for the play"

  set_fact: ansible_ssh_pass="{{ my_pass }}"
Run Code Online (Sandbox Code Playgroud)

您可以将密码存储在文件中,或者提示输入密码,如下例所示.在我的示例中,正在创建的sshd配置将禁止密码登录,但是使用ansible默认值,即使我"忘记"创建authorized_key,您仍会惊讶于第二个剧本仍将被执行(!).这是因为ansible使用ssh的ControlPersist选项,并且只是保持单个任务之间的连接打开.你可以在ansible.cfg中关闭它

示例手册:


- name: "MAKE BARE: Run preparatory steps on a newly acquired server"
  hosts: blankee

  tasks:
    - name: "set password for the play"
      set_fact: ansible_ssh_pass="{{ my_pass }}"

    - name: "Create directory {{ pathsts }}/registry/ansible-init"
      file: name="{{ pathsts }}/registry/ansible-init" state=directory owner=root group=www-data mode=770

    - name: "copy sshd config file"
      copy:
        src:    'roles/newhost/files/sshd_config'
        dest:   '/etc/ssh/sshd_config'
        owner:  'root'
        group:  'root'
        mode:   '0644'


    - name: "Check syntax of sshd configuration"
      shell: sshd -t
      register: result
      changed_when: false
      failed_when: "result.rc != 0"

    - name: "Restart SSHD and enable Service to start at boot"
      service: name=sshd state=restarted
      changed_when: false

  vars:
    my_pass2: foobar

  vars_prompt:
    - name: "my_pass"
      prompt: "########## Enter PWD:\n "



- name: "Second run: This should authenticate w/out password:"
  hosts: blankee

  tasks:

    - name: "Create directory {{ pathsts }}/registry/ansible-init"
      file: name="{{ pathsts }}/registry/ansible-init22" state=directory owner=root group=www-data mode=770
Run Code Online (Sandbox Code Playgroud)


nik*_*lia 0

我不知道如何更改剧中的身份验证方法。我想我更喜欢运行两个不同的剧本作为 Jenkins 工作或类似的工作,但我可以想到一个纯粹的 Ansible 解决方法:您可以让 ansible 将 shell 命令作为本地操作运行,然后运行命令执行第一个剧本中的第二个剧本。这是一个粗略的概念证明:

---
- hosts: all
  vars_files:
    - vars.yml
  tasks:
    - debug: msg="Run your first role here."

    - name: Then call Ansible to run the second playbook.
      local_action: shell ansible-playbook -i ~/workspace/hosts ~/workspace/second_playbook.yml
      register: playbook_results

    - debug: var=playbook_results.stdout_lines
Run Code Online (Sandbox Code Playgroud)

这是输出:

GATHERING FACTS *************************************************************** 
ok: [vagrantbox]

TASK: [debug msg="Run your first role here."] ********************************* 
ok: [vagrantbox] => {
    "msg": "Run your first role here."
}

TASK: [Then call Ansible to run the second playbook.] ************************* 
changed: [vagrantbox -> 127.0.0.1]

TASK: [debug var=playbook_results.stdout_lines] ******************************* 
ok: [vagrantbox] => {
    "var": {
        "playbook_results.stdout_lines": [
            "", 
            "PLAY [Proof of concept] ******************************************************* ", 
            "", 
            "GATHERING FACTS *************************************************************** ", 
            "ok: [vagrantbox]", 
            "", 
            "TASK: [debug msg=\"This playbook was called from another playbook!\"] *********** ", 
            "ok: [vagrantbox] => {", 
            "    \"msg\": \"This playbook was called from another playbook!\"", 
            "}", 
            "", 
            "PLAY RECAP ******************************************************************** ", 
            "vagrantbox                 : ok=2    changed=0    unreachable=0    failed=0   "
        ]
    }
}

PLAY RECAP ******************************************************************** 
vagrantbox                 : ok=4    changed=1    unreachable=0    failed=0   
Run Code Online (Sandbox Code Playgroud)