在 Ansible 1.9 中 运行 时指定 SSH 配置文件
Specify SSH configuration file at run time in Ansible 1.9
我正在管理两个配置不同的服务器环境。我通过在命令行上指定不同的 SSH 配置来访问这两个环境,因为我需要为 SSH 指定不同的 User
、ProxyCommand
和其他选项列表。
例如
ssh oldserver.example.org -F config_legacy
ssh newserver.example.org -F config
为了在我的服务器上配置和维护状态,我一直在使用 Ansible(版本 1.9.0.1),它读取 SSH 配置文件,该文件由其 ansible.cfg
中的一行指定:
...
ssh_args = -F some_configuration_file
...
ansible.cfg
是 loaded a number of ways:
def load_config_file():
''' Load Config File order(first found is used): ENV, CWD, HOME, /etc/ansible '''
p = configparser.ConfigParser()
path0 = os.getenv("ANSIBLE_CONFIG", None)
if path0 is not None:
path0 = os.path.expanduser(path0)
path1 = os.getcwd() + "/ansible.cfg"
path2 = os.path.expanduser("~/.ansible.cfg")
path3 = "/etc/ansible/ansible.cfg"
for path in [path0, path1, path2, path3]:
if path is not None and os.path.exists(path):
try:
p.read(path)
except configparser.Error as e:
print("Error reading config file: \n{0}".format(e))
sys.exit(1)
return p
return None
我可以使用此行为在每个命令加载完全不同的 ansible.cfg 之前设置一个环境变量,但这看起来很乱,因为我只需要 fiddle ssh_args。不幸的是,Ansible 没有公开命令开关来指定 SSH 配置。
我不想维护对 Ansible 的任何修改我不想包装对 ansible
或 ansible-playbook
命令的所有调用。为了保留 Ansible 命令的行为,我相信我的选择是:
- a)
ssh_args = -F <<config_file>>
的目标是一个打开的脚本
- b) 使
p.read(path)
的目标成为一个脚本,该脚本被扩展以生成有效的 ansible.cfg
- c) 只需维护不同的 ansible.cfg 文件,并利用 Ansible 按照环境变量 cwd 的顺序选择该文件的事实。
选项 C 是我认为实现此目的的唯一方法。你可以让你的 default/most-used ansible.cfg 成为在 cwd ansible.cfg 中读取的那个,然后可选地 setting/unsetting 一个环境变量指向指定 ssh_args = -F config_legacy
行 (ANSIBLE_SSH_ARGS
).
之所以需要执行 ansible.cfg 而不是仅仅传递带有 SSH 选项的 envvar,是因为 Ansible 不遵守 ssh 配置文件中的 User
设置——它已经决定了谁它想要 运行 作为命令的开始。
动态清单 (ec2.py
) 文件是出于维护原因修改更改的非常糟糕的地方,这就是为什么通常会看到 --user=REMOTE_USER
标志,再加上设置 ANSIBLE_SSH_ARGS="-F some_ssh_config"
环境变量,为 Ansible 存储库的临时用户提供难看的命令。
例如
ANSIBLE_SSH_ARGS="-F other_ssh_config" ansible-playbook playbooks/why_i_am_doing_this.yml -u ubuntu
v.
ansible-playbook playbooks/why_i_am_doing_this.yml -F other_ansible.cfg
选项 A 不起作用,因为根据上面的 p.read()
,文件被一次性打开以加载到 Python,这并不重要,因为如果文件可以任意决定打开为脚本,我们将生活在一个非常可怕的世界中。
从系统的角度来看,ansible.cfg
加载是这样的:
$ sudo dtruss -a ansible ......
74947/0x11eadf: 312284 3 2 stat64("/Users/tfisher/code/ansible/ansible.cfg[=12=]", 0x7FFF55D936C0, 0x7FD70207EA00) = 0 0
74947/0x11eadf: 312308 19 17 open_nocancel("/Users/tfisher/code/ansible/ansible.cfg[=12=]", 0x0, 0x1B6) = 5 0
74947/0x11eadf: 312316 3 1 read_nocancel(0x5, "# ansible.cfg \n#\n# Config-file load order is:\n# envvar ANSIBLE_CONFIG\n# `pwd`/ansible.cfg\n# ~/.ansible.cfg\n# /etc/ansible/ansible.cfg\n\n# Some unmodified settings are left as comments to encourage research/suggest modific", 0x1000) = 3477 0
74947/0x11eadf: 312308 19 17 open_nocancel("/Users/tfisher/code/ansible/ansible.cfg[=12=]", 0x0, 0x1B6) = 5 0
选项 B 不起作用的原因与 A 不起作用的原因相同——即使您创建了一个具有适当 read/readline/readlines 签名的模拟 Python 文件对象,该文件仍在打开只读,不执行。
如果这是 OpenSSH 的正确存储库,config file is specified like so:
#define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config"
/* Read systemwide configuration file after user config. */
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
host, host_arg, &options,
post_canon ? SSHCONF_POSTCANON : 0);
and read here with an fopen,这没有给 "file as a script" 恶作剧留下空间。
另一个选项是将环境变量 ANSIBLE_SSH_ARGS
设置为您希望 Ansible 传递给 ssh 命令的参数。
我正在管理两个配置不同的服务器环境。我通过在命令行上指定不同的 SSH 配置来访问这两个环境,因为我需要为 SSH 指定不同的 User
、ProxyCommand
和其他选项列表。
例如
ssh oldserver.example.org -F config_legacy
ssh newserver.example.org -F config
为了在我的服务器上配置和维护状态,我一直在使用 Ansible(版本 1.9.0.1),它读取 SSH 配置文件,该文件由其 ansible.cfg
中的一行指定:
...
ssh_args = -F some_configuration_file
...
ansible.cfg
是 loaded a number of ways:
def load_config_file():
''' Load Config File order(first found is used): ENV, CWD, HOME, /etc/ansible '''
p = configparser.ConfigParser()
path0 = os.getenv("ANSIBLE_CONFIG", None)
if path0 is not None:
path0 = os.path.expanduser(path0)
path1 = os.getcwd() + "/ansible.cfg"
path2 = os.path.expanduser("~/.ansible.cfg")
path3 = "/etc/ansible/ansible.cfg"
for path in [path0, path1, path2, path3]:
if path is not None and os.path.exists(path):
try:
p.read(path)
except configparser.Error as e:
print("Error reading config file: \n{0}".format(e))
sys.exit(1)
return p
return None
我可以使用此行为在每个命令加载完全不同的 ansible.cfg 之前设置一个环境变量,但这看起来很乱,因为我只需要 fiddle ssh_args。不幸的是,Ansible 没有公开命令开关来指定 SSH 配置。
我不想维护对 Ansible 的任何修改我不想包装对 ansible
或 ansible-playbook
命令的所有调用。为了保留 Ansible 命令的行为,我相信我的选择是:
- a)
ssh_args = -F <<config_file>>
的目标是一个打开的脚本 - b) 使
p.read(path)
的目标成为一个脚本,该脚本被扩展以生成有效的 ansible.cfg - c) 只需维护不同的 ansible.cfg 文件,并利用 Ansible 按照环境变量 cwd 的顺序选择该文件的事实。
选项 C 是我认为实现此目的的唯一方法。你可以让你的 default/most-used ansible.cfg 成为在 cwd ansible.cfg 中读取的那个,然后可选地 setting/unsetting 一个环境变量指向指定 ssh_args = -F config_legacy
行 (ANSIBLE_SSH_ARGS
).
之所以需要执行 ansible.cfg 而不是仅仅传递带有 SSH 选项的 envvar,是因为 Ansible 不遵守 ssh 配置文件中的 User
设置——它已经决定了谁它想要 运行 作为命令的开始。
动态清单 (ec2.py
) 文件是出于维护原因修改更改的非常糟糕的地方,这就是为什么通常会看到 --user=REMOTE_USER
标志,再加上设置 ANSIBLE_SSH_ARGS="-F some_ssh_config"
环境变量,为 Ansible 存储库的临时用户提供难看的命令。
例如
ANSIBLE_SSH_ARGS="-F other_ssh_config" ansible-playbook playbooks/why_i_am_doing_this.yml -u ubuntu
v.
ansible-playbook playbooks/why_i_am_doing_this.yml -F other_ansible.cfg
选项 A 不起作用,因为根据上面的 p.read()
,文件被一次性打开以加载到 Python,这并不重要,因为如果文件可以任意决定打开为脚本,我们将生活在一个非常可怕的世界中。
从系统的角度来看,ansible.cfg
加载是这样的:
$ sudo dtruss -a ansible ......
74947/0x11eadf: 312284 3 2 stat64("/Users/tfisher/code/ansible/ansible.cfg[=12=]", 0x7FFF55D936C0, 0x7FD70207EA00) = 0 0
74947/0x11eadf: 312308 19 17 open_nocancel("/Users/tfisher/code/ansible/ansible.cfg[=12=]", 0x0, 0x1B6) = 5 0
74947/0x11eadf: 312316 3 1 read_nocancel(0x5, "# ansible.cfg \n#\n# Config-file load order is:\n# envvar ANSIBLE_CONFIG\n# `pwd`/ansible.cfg\n# ~/.ansible.cfg\n# /etc/ansible/ansible.cfg\n\n# Some unmodified settings are left as comments to encourage research/suggest modific", 0x1000) = 3477 0
74947/0x11eadf: 312308 19 17 open_nocancel("/Users/tfisher/code/ansible/ansible.cfg[=12=]", 0x0, 0x1B6) = 5 0
选项 B 不起作用的原因与 A 不起作用的原因相同——即使您创建了一个具有适当 read/readline/readlines 签名的模拟 Python 文件对象,该文件仍在打开只读,不执行。
如果这是 OpenSSH 的正确存储库,config file is specified like so:
#define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config"
/* Read systemwide configuration file after user config. */
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
host, host_arg, &options,
post_canon ? SSHCONF_POSTCANON : 0);
and read here with an fopen,这没有给 "file as a script" 恶作剧留下空间。
另一个选项是将环境变量 ANSIBLE_SSH_ARGS
设置为您希望 Ansible 传递给 ssh 命令的参数。