provisioners/ansible: don't read/write known_hosts

Like Vagrant's default SSH behaviors (e.g ssh or ssh-config commands),
the Ansible provisioner should by default not modify or read the user
known host file (e.g. ~/.ssh/known_hosts).

Given that `UserKnownHostsFile=/dev/null` SSH option is usually combined
with `StrictHostKeyChecking=no`, it seems quite reasonable to bind the
activation/disactivation of both options to `host_key_checking`
provisioner attribute.

For the records, a discussion held in Ansible-Development mailing list
clearly confirmed that there is no short-term plan to adapt Ansible to
offer an extra option or change the behavior of
ANSIBLE_HOST_KEY_CHECKING. For this reason, the current implementation
seems reasonable and should be stable on the long run.

Close #3900

Related References:

- https://groups.google.com/forum/#!msg/ansible-devel/iuoZs1oImNs/6xrj5oa1CmoJ
- https://github.com/ansible/ansible/issues/9442
This commit is contained in:
Gilles Cornu 2014-11-30 06:55:21 +01:00
parent 178942cf27
commit f96636587a
4 changed files with 18 additions and 5 deletions

View File

@ -95,6 +95,8 @@ BUG FIXES:
- providers/virtualbox: Show more descriptive error if VirtualBox is
reporting an empty version. [GH-4657]
- provisioners/ansible: Force `ssh` (OpenSSH) connection by default [GH-3396]
- provisioners/ansible: Don't use or modify `~/.ssh/known_hosts` file by default,
similarly to native vagrant commands [GH-3900]
- provisioners/docker: Get GPG key over SSL. [GH-4597]
- provisioners/docker: Search for docker binary in multiple places. [GH-4580]
- provisioners/salt: Highstate works properly with a master. [GH-4471]

View File

@ -183,9 +183,14 @@ module VagrantPlugins
@ansible_ssh_args ||= get_ansible_ssh_args
end
# Use ANSIBLE_SSH_ARGS to pass some OpenSSH options that are not wrapped by
# an ad-hoc Ansible option. Last update corresponds to Ansible 1.8
def get_ansible_ssh_args
ssh_options = []
# Don't access user's known_hosts file, except when host_key_checking is enabled.
ssh_options << "-o UserKnownHostsFile=/dev/null" unless config.host_key_checking
# Multiple Private Keys
@ssh_info[:private_key_path].drop(1).each do |key|
ssh_options << "-o IdentityFile=#{key}"

View File

@ -63,7 +63,7 @@ VF
#
def self.it_should_set_arguments_and_environment_variables(
expected_args_count = 6, expected_vars_count = 3, expected_host_key_checking = false, expected_transport_mode = "ssh")
expected_args_count = 6, expected_vars_count = 4, expected_host_key_checking = false, expected_transport_mode = "ssh")
it "sets implicit arguments in a specific order" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args|
@ -101,6 +101,12 @@ VF
it "exports environment variables" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args|
cmd_opts = args.last
if expected_host_key_checking
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to be_nil unless config.raw_arguments
else
expect(cmd_opts[:env]['ANSIBLE_SSH_ARGS']).to include("-o UserKnownHostsFile=/dev/null")
end
expect(cmd_opts[:env]['ANSIBLE_FORCE_COLOR']).to eql("true")
expect(cmd_opts[:env]['ANSIBLE_HOST_KEY_CHECKING']).to eql(expected_host_key_checking.to_s)
expect(cmd_opts[:env]['PYTHONUNBUFFERED']).to eql(1)
@ -305,7 +311,7 @@ VF
"--new-arg=yeah"]
end
it_should_set_arguments_and_environment_variables 17, 3, false, "paramiko"
it_should_set_arguments_and_environment_variables 17, 4, false, "paramiko"
it "sets all raw arguments" do
expect(Vagrant::Util::Subprocess).to receive(:execute).with { |*args|
@ -459,7 +465,7 @@ VF
it "shows the ansible-playbook command" do
expect(machine.env.ui).to receive(:detail).with { |full_command|
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} playbook.yml")
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} playbook.yml")
}
end
end
@ -474,7 +480,7 @@ VF
it "shows the ansible-playbook command" do
expect(machine.env.ui).to receive(:detail).with { |full_command|
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} -v playbook.yml")
expect(full_command).to eq("PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/path/to/my/key --user=testuser --connection=ssh --limit='machine1' --inventory-file=#{generated_inventory_dir} -v playbook.yml")
}
end
end

View File

@ -198,7 +198,7 @@ by the sudo command.
* `ansible.start_at_task` can be set to a string corresponding to the task name where the playbook provision will start.
* `ansible.raw_arguments` can be set to an array of strings corresponding to a list of `ansible-playbook` arguments (e.g. `['--check', '-M /my/modules']`). It is an *unsafe wildcard* that can be used to apply Ansible options that are not (yet) supported by this Vagrant provisioner. As of Vagrant 1.7, `raw_arguments` has the highest priority and its values can potentially override or break other Vagrant settings.
* `ansible.raw_ssh_args` can be set to an array of strings corresponding to a list of OpenSSH client parameters (e.g. `['-o ControlMaster=no']`). It is an *unsafe wildcard* that can be used to pass additional SSH settings to Ansible via `ANSIBLE_SSH_ARGS` environment variable.
* `ansible.host_key_checking` can be set to `true` which will enable host key checking. As Vagrant 1.5, the default value is `false`, to avoid connection problems when creating new virtual machines.
* `ansible.host_key_checking` can be set to `true` which will enable host key checking. As of Vagrant 1.5, the default value is `false` and as of Vagrant 1.7 the user kownn host file (e.g. `~/.ssh/known_hosts`) is no longer read nor modified. In other words: by default, the Ansible provisioner behaves the same as Vagrant native commands (e.g `vagrant ssh`).
## Tips and Tricks