以 root 身份使用密码连接到新服务器的简单 ansible 示例
Simple ansible example that connects to new server as root with password
我想提供一个新的 vps。通常这样做的方式:1) 尝试以非根用户身份手动登录,以及 2) 如果失败则执行配置。
但是我无法连接。 我什至不能以 root 身份登录。(我可以从 shell ssh,所以密码是正确的。)
主持人:
[server]
42.42.42.42
playbook.yml:
---
- hosts: all
vars:
ROOT_PASSWORD: foo
gather_facts: no
tasks:
- name: set root password
set_fact: ansible_password={{ ROOT_PASSWORD }}
- name: try login with password
local_action: "command ssh -q -o BatchMode=yes -o ConnectTimeout=3 root@{{ inventory_hostname }} 'echo ok'"
ignore_errors: true
changed_when: false
# more stuff here...
我尝试了以下方法,但都无法连接:
我将密码存储在上面的变量中
我使用 ansible-playbook -k playbook.yml
提示输入密码
我把密码移到了库存文件
[服务器]
42.42.42.42 ansible_user=root ansible_password=foo
我添加了 ssh 标志 -o PreferredAuthentications=password
以强制密码验证
但是上面的none连接。我总是得到错误
root@42.42.42.42: Permission denied (publickey,password).
如果我删除 -o BatchMode=yes
然后它会提示我输入密码,然后连接。但这会阻止自动化,我们的想法是在没有用户干预的情况下执行此操作。
我做错了什么?
这是一个新的 vps,还没有任何设置 - 所以我正在寻找 使用 root 和密码连接的剧本的最简单示例。
你很接近。变量是 ansible_ssh_password
,而不是 ansible_ssh_pass
。名称中带有 _ssh
的变量是旧名称,因此您可以改用 ansible_user
和 ansible_password
。
如果我有这样的库存:
[server]
example ansible_host=192.168.122.148 ansible_user=root ansible_password=secret
然后我可以运行这个命令成功:
$ ansible all -i hosts -m ping
example | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
如果上面的临时命令工作正常,那么 playbook 也应该工作正常。例如,仍然假设上述库存,我可以使用以下剧本:
---
- hosts: all
gather_facts: false
tasks:
- ping:
我可以这样称呼它:
$ ansible-playbook playbook.yml -i hosts
PLAY [all] ***************************************************************************
TASK [ping] **************************************************************************
ok: [example]
PLAY RECAP ***************************************************************************
example : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
...一切正常。
尝试使用 --ask-become-pass
ansible-playbook -k playbook.yml --ask-become-pass
这样就不是硬编码了。
此外,在剧本中您可以调用:
---
- hosts: all
become: true
gather_facts: no
到目前为止我看到的所有 SO 答案和博客文章都建议按照我展示的方式进行操作。
但是在这上面花了很多时间之后,我不相信它可以那样工作,所以我不明白为什么总是推荐它。我注意到 ansible 已经多次更改 API,也许这种方法已经过时了!
所以我想出了一个替代方案,使用 sshpass
:
主机:
[server]
42.42.42.42
playbook.yml:
---
- hosts: all
vars:
ROOT_PASSWORD: foo
gather_facts: no
tasks:
- name: try login with password (using out-of-band ssh connection)
local_action: command sshpass -p {{ ROOT_PASSWORD }} ssh -q -o ConnectTimeout=3 root@{{ inventory_hostname }} 'echo ok'
ignore_errors: true
register: exists_user
- name: ping if above succeeded (using in-band ssh connection)
remote_user: root
block:
- name: set root ssh password
set_fact:
ansible_password: "{{ ROOT_PASSWORD }}"
- name: ping
ping:
data: pong
when: exists_user is success
这只是一个微小的概念证明。
实际用例是尝试与非 root 用户连接,如果失败,则配置服务器。以上就是这样一个剧本的起点。
与@larsks 的优秀替代方案不同,它不假设 python 安装在远程,并在 sshpass
.
的协助下执行带外 ssh 连接测试
我想提供一个新的 vps。通常这样做的方式:1) 尝试以非根用户身份手动登录,以及 2) 如果失败则执行配置。
但是我无法连接。 我什至不能以 root 身份登录。(我可以从 shell ssh,所以密码是正确的。)
主持人:
[server]
42.42.42.42
playbook.yml:
---
- hosts: all
vars:
ROOT_PASSWORD: foo
gather_facts: no
tasks:
- name: set root password
set_fact: ansible_password={{ ROOT_PASSWORD }}
- name: try login with password
local_action: "command ssh -q -o BatchMode=yes -o ConnectTimeout=3 root@{{ inventory_hostname }} 'echo ok'"
ignore_errors: true
changed_when: false
# more stuff here...
我尝试了以下方法,但都无法连接:
我将密码存储在上面的变量中
我使用
ansible-playbook -k playbook.yml
提示输入密码
我把密码移到了库存文件
[服务器]
42.42.42.42 ansible_user=root ansible_password=foo我添加了 ssh 标志
-o PreferredAuthentications=password
以强制密码验证
但是上面的none连接。我总是得到错误
root@42.42.42.42: Permission denied (publickey,password).
如果我删除 -o BatchMode=yes
然后它会提示我输入密码,然后连接。但这会阻止自动化,我们的想法是在没有用户干预的情况下执行此操作。
我做错了什么?
这是一个新的 vps,还没有任何设置 - 所以我正在寻找 使用 root 和密码连接的剧本的最简单示例。
你很接近。变量是 ansible_ssh_password
,而不是 ansible_ssh_pass
。名称中带有 _ssh
的变量是旧名称,因此您可以改用 ansible_user
和 ansible_password
。
如果我有这样的库存:
[server]
example ansible_host=192.168.122.148 ansible_user=root ansible_password=secret
然后我可以运行这个命令成功:
$ ansible all -i hosts -m ping
example | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
如果上面的临时命令工作正常,那么 playbook 也应该工作正常。例如,仍然假设上述库存,我可以使用以下剧本:
---
- hosts: all
gather_facts: false
tasks:
- ping:
我可以这样称呼它:
$ ansible-playbook playbook.yml -i hosts
PLAY [all] ***************************************************************************
TASK [ping] **************************************************************************
ok: [example]
PLAY RECAP ***************************************************************************
example : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
...一切正常。
尝试使用 --ask-become-pass
ansible-playbook -k playbook.yml --ask-become-pass
这样就不是硬编码了。
此外,在剧本中您可以调用:
---
- hosts: all
become: true
gather_facts: no
到目前为止我看到的所有 SO 答案和博客文章都建议按照我展示的方式进行操作。
但是在这上面花了很多时间之后,我不相信它可以那样工作,所以我不明白为什么总是推荐它。我注意到 ansible 已经多次更改 API,也许这种方法已经过时了!
所以我想出了一个替代方案,使用 sshpass
:
主机:
[server]
42.42.42.42
playbook.yml:
---
- hosts: all
vars:
ROOT_PASSWORD: foo
gather_facts: no
tasks:
- name: try login with password (using out-of-band ssh connection)
local_action: command sshpass -p {{ ROOT_PASSWORD }} ssh -q -o ConnectTimeout=3 root@{{ inventory_hostname }} 'echo ok'
ignore_errors: true
register: exists_user
- name: ping if above succeeded (using in-band ssh connection)
remote_user: root
block:
- name: set root ssh password
set_fact:
ansible_password: "{{ ROOT_PASSWORD }}"
- name: ping
ping:
data: pong
when: exists_user is success
这只是一个微小的概念证明。
实际用例是尝试与非 root 用户连接,如果失败,则配置服务器。以上就是这样一个剧本的起点。
与@larsks 的优秀替代方案不同,它不假设 python 安装在远程,并在 sshpass
.