过去两天我一直在试图解决这个问题,但毫无进展
我想要做的是从我的家庭服务器(Centos7)运行 ansible playbooks 来配置 AWS 中私有子网上的 AWS linux(centos7)服务器。
如果我运行:
sshpass -p "PASSWORD" ssh -i "/aws_ssh/KEY_PAIR.pem" -o "StrictHostKeyChecking=no" -t ansibleuser@PUBLICBASTIONHOSTIP 'sshpass -p "PASSWORD" ssh -i "/aws_ssh/KEY_PAIR.pem" -o "StrictHostKeyChecking=no" ansibleuser@PRIVATEHOSTIP'
我可以从家里连接到私有子网上的 AWS 服务器
/etc/ansible/hosts
[webservers:vars]
ansible_user=ec2-user
ansible_become=yes
ansible_become_method=sudo
ansible_become_pass='PASSWORD'
ansible_ssh_common_args: '-o ProxyCommand="ssh ssh -i /aws_ssh/_KEY_PAIR.pem -t -W %h:%p -q ec2-user@IPADDRESS"'
[webservers]
10.150.2.15
10.150.4.15
test.yml
---
- name: This sets up an httpd webserver
hosts: webservers
tasks:
- name: example
command: hostname
我想要实现的目标是当我运行时:
[ec2-user@terraform playbook]$ ansible-playbook test.yml -vvvv
ansible-playbook 2.9.6
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/ec2-user/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Parsed /etc/ansible/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /usr/lib/python2.7/site-packages/ansible/plugins/callback/default.pyc
PLAYBOOK: test.yml **************************************************************************************************************************************************************************************************************************
Positional arguments: test.yml
become_method: sudo
inventory: (u'/etc/ansible/hosts',)
forks: 5
tags: (u'all',)
verbosity: 4
connection: smart
timeout: 10
1 plays in test.yml
PLAY [This sets up an httpd webserver] ******************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
task path: /playbook/test.yml:2
<10.150.2.15> ESTABLISH SSH CONNECTION FOR USER: ec2-user
<10.150.2.15> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ec2-user"' -o ConnectTimeout=10 -o ControlPath=/home/ec2-user/.ansible/cp/f72ac484f5 10.150.2.15 '/bin/sh -c '"'"'echo ~ec2-user && sleep 0'"'"''
<10.150.4.15> ESTABLISH SSH CONNECTION FOR USER: ec2-user
<10.150.4.15> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ec2-user"' -o ConnectTimeout=10 -o ControlPath=/home/ec2-user/.ansible/cp/a6bd87bb6f 10.150.4.15 '/bin/sh -c '"'"'echo ~ec2-user && sleep 0'"'"''
<10.150.2.15> (255, '', 'OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 58: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: Control socket "/home/ec2-user/.ansible/cp/f72ac484f5" does not exist\r\ndebug2: resolving "10.150.2.15" port 22\r\ndebug2: ssh_connect_direct: needpriv 0\r\ndebug1: Connecting to 10.150.2.15 [10.150.2.15] port 22.\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug1: connect to address 10.150.2.15 port 22: Connection timed out\r\nssh: connect to host 10.150.2.15 port 22: Connection timed out\r\n')
fatal: [10.150.2.15]: UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 58: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: Control socket \"/home/ec2-user/.ansible/cp/f72ac484f5\" does not exist\r\ndebug2: resolving \"10.150.2.15\" port 22\r\ndebug2: ssh_connect_direct: needpriv 0\r\ndebug1: Connecting to 10.150.2.15 [10.150.2.15] port 22.\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug1: connect to address 10.150.2.15 port 22: Connection timed out\r\nssh: connect to host 10.150.2.15 port 22: Connection timed out",
"unreachable": true
}
<10.150.4.15> (255, '', 'OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 58: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: Control socket "/home/ec2-user/.ansible/cp/a6bd87bb6f" does not exist\r\ndebug2: resolving "10.150.4.15" port 22\r\ndebug2: ssh_connect_direct: needpriv 0\r\ndebug1: Connecting to 10.150.4.15 [10.150.4.15] port 22.\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug1: connect to address 10.150.4.15 port 22: Connection timed out\r\nssh: connect to host 10.150.4.15 port 22: Connection timed out\r\n')
fatal: [10.150.4.15]: UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 58: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug1: Control socket \"/home/ec2-user/.ansible/cp/a6bd87bb6f\" does not exist\r\ndebug2: resolving \"10.150.4.15\" port 22\r\ndebug2: ssh_connect_direct: needpriv 0\r\ndebug1: Connecting to 10.150.4.15 [10.150.4.15] port 22.\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug1: connect to address 10.150.4.15 port 22: Connection timed out\r\nssh: connect to host 10.150.4.15 port 22: Connection timed out",
"unreachable": true
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************
10.150.2.15 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
10.150.4.15 : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0
我究竟做错了什么?
我不想做的是登录堡垒主机然后运行 ansible 命令。
答案1
这可以通过巧妙使用 Ansible 参数来实现。首先创建一个清单文件,其中包含您可以针对其运行单个任务/游戏的主机组。这些组中至少有一个应该是您的 Bastion,另一个在您的私有子网中。
记录 Bastion 的 IP 地址,并在 Play 中创建一个新的 Jinja2 变量,该变量针对私有子网中的服务器。之后,在 Playbook 中创建一个新的 Play,将一个vars
选项传递给引用此变量的私有子网主机组等。
- hosts: private_subnet
vars:
- ansible_ssh_user: "example"
- ansible_ssh_common_args: >
-o ProxyCommand="ssh -W %h:%p -q {{ ansible_ssh_user }}@{{ bastion_ip }}" \
-o ServerAliveInterval=5 \
-o StrictHostKeyChecking=no
tasks:
- name: example
debug:
msg: Hello World from {{ inventory_hostname }}!
您应该能够按照此操作执行任何您想要的任务,并且 Ansible 将通过 Bastion 传输所有流量。
我已经成功做到了几次。一个很好的改进是使用执行 AWS EC2 API 调用的角色自动发现 Bastion 服务器的 IP 地址,而不是手动创建和操作变量bastion_ip
。