From 0c6e6ba637fe9454dd20f046170158c3e4873bce Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Tue, 3 Jul 2018 11:12:12 -0400 Subject: [PATCH 1/3] Update Ansible provisioner docs for WinRM --- .../source/docs/provisioners/ansible.html.md | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index cac00ab60..82047070d 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -192,7 +192,8 @@ Building within a chroot (e.g. `amazon-chroot`) requires changing the Ansible co ### winrm communicator -Windows builds require a custom Ansible connection plugin and a particular configuration. Assuming a directory named `connection_plugins` is next to the playbook and contains a file named `packer.py` whose contents is +Windows builds require a custom Ansible connection plugin and a particular configuration. Assuming a directory named `connection_plugins` is next to the playbook and contains a file named `packer.py` which implements +the connection plugin. On versions of Ansible before 2.4.x, the following works as the connection plugin ``` python from __future__ import (absolute_import, division, print_function) @@ -213,6 +214,43 @@ class Connection(SSHConnection): super(Connection, self).__init__(*args, **kwargs) ``` +Newer versions of Ansible require all plugins to have a documentation string. You will need to copy +the `options` from the `DOCUMENTATION` string from the [ssh.py Ansible connection plugin](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py) +of the Ansible version you are using and add it to packer.py similar to as follows + +``` python +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.connection.ssh import Connection as SSHConnection + +DOCUMENTATION = ''' + connection: packer + short_description: ssh based connections for powershell via packer + description: + - This connection plugin allows ansible to communicate to the target packer + machines via ssh based connections for powershell. + author: Packer + version_added: na + options: + **** Copy the options from + https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py + for the version of Ansible you are using **** +''' + +class Connection(SSHConnection): + ''' ssh based connections for powershell via packer''' + + transport = 'packer' + has_pipelining = True + become_methods = [] + allow_executable = False + module_implementation_preferences = ('.ps1', '') + + def __init__(self, *args, **kwargs): + super(Connection, self).__init__(*args, **kwargs) +``` + This template should build a Windows Server 2012 image on Google Cloud Platform: ``` json From 4cfa49596a907e8e0373f7d01caa9be0cf7f68e6 Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Tue, 10 Jul 2018 17:10:53 -0400 Subject: [PATCH 2/3] Add ansible connection plugin examples --- .../ansible/connection-plugin/2.4.x/packer.py | 186 +++++++++++++++ .../ansible/connection-plugin/2.5.x/packer.py | 204 ++++++++++++++++ .../ansible/connection-plugin/2.6.x/packer.py | 218 ++++++++++++++++++ 3 files changed, 608 insertions(+) create mode 100644 examples/ansible/connection-plugin/2.4.x/packer.py create mode 100644 examples/ansible/connection-plugin/2.5.x/packer.py create mode 100644 examples/ansible/connection-plugin/2.6.x/packer.py diff --git a/examples/ansible/connection-plugin/2.4.x/packer.py b/examples/ansible/connection-plugin/2.4.x/packer.py new file mode 100644 index 000000000..ea4210d32 --- /dev/null +++ b/examples/ansible/connection-plugin/2.4.x/packer.py @@ -0,0 +1,186 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.connection.ssh import Connection as SSHConnection + +DOCUMENTATION = ''' + connection: packer + short_description: ssh based connections for powershell via packer + description: + - This connection plugin allows ansible to communicate to the target packer machines via ssh based connections for powershell. + author: Packer Community + version_added: na + options: + host: + description: Hostname/ip to connect to. + default: inventory_hostname + vars: + - name: ansible_host + - name: ansible_ssh_host + host_key_checking: + #constant: HOST_KEY_CHECKING + description: Determines if ssh should check host keys + type: boolean + ini: + - section: defaults + key: 'host_key_checking' + env: + - name: ANSIBLE_HOST_KEY_CHECKING + password: + description: Authentication password for the C(remote_user). Can be supplied as CLI option. + vars: + - name: ansible_password + - name: ansible_ssh_pass + ssh_args: + description: Arguments to pass to all ssh cli tools + default: '-C -o ControlMaster=auto -o ControlPersist=60s' + ini: + - section: 'ssh_connection' + key: 'ssh_args' + env: + - name: ANSIBLE_SSH_ARGS + ssh_common_args: + description: Common extra args for all ssh CLI tools + vars: + - name: ansible_ssh_common_args + ssh_executable: + default: ssh + description: + - This defines the location of the ssh binary. It defaults to `ssh` which will use the first ssh binary available in $PATH. + - This option is usually not required, it might be useful when access to system ssh is restricted, + or when using ssh wrappers to connect to remote hosts. + env: [{name: ANSIBLE_SSH_EXECUTABLE}] + ini: + - {key: ssh_executable, section: ssh_connection} + yaml: {key: ssh_connection.ssh_executable} + #const: ANSIBLE_SSH_EXECUTABLE + version_added: "2.2" + scp_extra_args: + description: Extra exclusive to the 'scp' CLI + vars: + - name: ansible_scp_extra_args + sftp_extra_args: + description: Extra exclusive to the 'sftp' CLI + vars: + - name: ansible_sftp_extra_args + ssh_extra_args: + description: Extra exclusive to the 'ssh' CLI + vars: + - name: ansible_ssh_extra_args + retries: + # constant: ANSIBLE_SSH_RETRIES + description: Number of attempts to connect. + default: 3 + type: integer + env: + - name: ANSIBLE_SSH_RETRIES + ini: + - section: connection + key: retries + - section: ssh_connection + key: retries + port: + description: Remote port to connect to. + type: int + default: 22 + ini: + - section: defaults + key: remote_port + env: + - name: ANSIBLE_REMOTE_PORT + vars: + - name: ansible_port + - name: ansible_ssh_port + remote_user: + description: + - User name with which to login to the remote server, normally set by the remote_user keyword. + - If no user is supplied, Ansible will let the ssh client binary choose the user as it normally + ini: + - section: defaults + key: remote_user + env: + - name: ANSIBLE_REMOTE_USER + vars: + - name: ansible_user + - name: ansible_ssh_user + pipelining: + default: ANSIBLE_PIPELINING + description: + - Pipelining reduces the number of SSH operations required to execute a module on the remote server, + by executing many Ansible modules without actual file transfer. + - This can result in a very significant performance improvement when enabled. + - However this conflicts with privilege escalation (become). + For example, when using sudo operations you must first disable 'requiretty' in the sudoers file for the target hosts, + which is why this feature is disabled by default. + env: + - name: ANSIBLE_PIPELINING + #- name: ANSIBLE_SSH_PIPELINING + ini: + - section: defaults + key: pipelining + #- section: ssh_connection + # key: pipelining + type: boolean + vars: + - name: ansible_pipelining + - name: ansible_ssh_pipelining + private_key_file: + description: + - Path to private key file to use for authentication + ini: + - section: defaults + key: private_key_file + env: + - name: ANSIBLE_PRIVATE_KEY_FILE + vars: + - name: ansible_private_key_file + - name: ansible_ssh_private_key_file + control_path: + default: null + description: + - This is the location to save ssh's ControlPath sockets, it uses ssh's variable substitution. + - Since 2.3, if null, ansible will generate a unique hash. Use `%(directory)s` to indicate where to use the control dir path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH + ini: + - key: control_path + section: ssh_connection + control_path_dir: + default: ~/.ansible/cp + description: + - This sets the directory to use for ssh control path if the control path setting is null. + - Also, provides the `%(directory)s` variable for the control path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH_DIR + ini: + - section: ssh_connection + key: control_path_dir + sftp_batch_mode: + default: True + description: 'TODO: write it' + env: [{name: ANSIBLE_SFTP_BATCH_MODE}] + ini: + - {key: sftp_batch_mode, section: ssh_connection} + type: boolean + scp_if_ssh: + default: smart + description: + - "Prefered method to use when transfering files over ssh" + - When set to smart, Ansible will try them until one succeeds or they all fail + - If set to True, it will force 'scp', if False it will use 'sftp' + env: [{name: ANSIBLE_SCP_IF_SSH}] + ini: + - {key: scp_if_ssh, section: ssh_connection} +''' + +class Connection(SSHConnection): + ''' ssh based connections for powershell via packer''' + + transport = 'packer' + has_pipelining = True + become_methods = [] + allow_executable = False + module_implementation_preferences = ('.ps1', '') + + def __init__(self, *args, **kwargs): + super(Connection, self).__init__(*args, **kwargs) \ No newline at end of file diff --git a/examples/ansible/connection-plugin/2.5.x/packer.py b/examples/ansible/connection-plugin/2.5.x/packer.py new file mode 100644 index 000000000..e133aeea4 --- /dev/null +++ b/examples/ansible/connection-plugin/2.5.x/packer.py @@ -0,0 +1,204 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.connection.ssh import Connection as SSHConnection + +DOCUMENTATION = ''' + connection: packer + short_description: ssh based connections for powershell via packer + description: + - This connection plugin allows ansible to communicate to the target packer machines via ssh based connections for powershell. + author: Packer Community + version_added: na + options: + host: + description: Hostname/ip to connect to. + default: inventory_hostname + vars: + - name: ansible_host + - name: ansible_ssh_host + host_key_checking: + description: Determines if ssh should check host keys + type: boolean + ini: + - section: defaults + key: 'host_key_checking' + - section: ssh_connection + key: 'host_key_checking' + version_added: '2.5' + env: + - name: ANSIBLE_HOST_KEY_CHECKING + - name: ANSIBLE_SSH_HOST_KEY_CHECKING + version_added: '2.5' + vars: + - name: ansible_host_key_checking + version_added: '2.5' + - name: ansible_ssh_host_key_checking + version_added: '2.5' + password: + description: Authentication password for the C(remote_user). Can be supplied as CLI option. + vars: + - name: ansible_password + - name: ansible_ssh_pass + ssh_args: + description: Arguments to pass to all ssh cli tools + default: '-C -o ControlMaster=auto -o ControlPersist=60s' + ini: + - section: 'ssh_connection' + key: 'ssh_args' + env: + - name: ANSIBLE_SSH_ARGS + ssh_common_args: + description: Common extra args for all ssh CLI tools + vars: + - name: ansible_ssh_common_args + ssh_executable: + default: ssh + description: + - This defines the location of the ssh binary. It defaults to `ssh` which will use the first ssh binary available in $PATH. + - This option is usually not required, it might be useful when access to system ssh is restricted, + or when using ssh wrappers to connect to remote hosts. + env: [{name: ANSIBLE_SSH_EXECUTABLE}] + ini: + - {key: ssh_executable, section: ssh_connection} + yaml: {key: ssh_connection.ssh_executable} + #const: ANSIBLE_SSH_EXECUTABLE + version_added: "2.2" + scp_extra_args: + description: Extra exclusive to the 'scp' CLI + vars: + - name: ansible_scp_extra_args + sftp_extra_args: + description: Extra exclusive to the 'sftp' CLI + vars: + - name: ansible_sftp_extra_args + ssh_extra_args: + description: Extra exclusive to the 'ssh' CLI + vars: + - name: ansible_ssh_extra_args + retries: + # constant: ANSIBLE_SSH_RETRIES + description: Number of attempts to connect. + default: 3 + type: integer + env: + - name: ANSIBLE_SSH_RETRIES + ini: + - section: connection + key: retries + - section: ssh_connection + key: retries + port: + description: Remote port to connect to. + type: int + default: 22 + ini: + - section: defaults + key: remote_port + env: + - name: ANSIBLE_REMOTE_PORT + vars: + - name: ansible_port + - name: ansible_ssh_port + remote_user: + description: + - User name with which to login to the remote server, normally set by the remote_user keyword. + - If no user is supplied, Ansible will let the ssh client binary choose the user as it normally + ini: + - section: defaults + key: remote_user + env: + - name: ANSIBLE_REMOTE_USER + vars: + - name: ansible_user + - name: ansible_ssh_user + pipelining: + default: ANSIBLE_PIPELINING + description: + - Pipelining reduces the number of SSH operations required to execute a module on the remote server, + by executing many Ansible modules without actual file transfer. + - This can result in a very significant performance improvement when enabled. + - However this conflicts with privilege escalation (become). + For example, when using sudo operations you must first disable 'requiretty' in the sudoers file for the target hosts, + which is why this feature is disabled by default. + env: + - name: ANSIBLE_PIPELINING + #- name: ANSIBLE_SSH_PIPELINING + ini: + - section: defaults + key: pipelining + #- section: ssh_connection + # key: pipelining + type: boolean + vars: + - name: ansible_pipelining + - name: ansible_ssh_pipelining + private_key_file: + description: + - Path to private key file to use for authentication + ini: + - section: defaults + key: private_key_file + env: + - name: ANSIBLE_PRIVATE_KEY_FILE + vars: + - name: ansible_private_key_file + - name: ansible_ssh_private_key_file + control_path: + default: null + description: + - This is the location to save ssh's ControlPath sockets, it uses ssh's variable substitution. + - Since 2.3, if null, ansible will generate a unique hash. Use `%(directory)s` to indicate where to use the control dir path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH + ini: + - key: control_path + section: ssh_connection + control_path_dir: + default: ~/.ansible/cp + description: + - This sets the directory to use for ssh control path if the control path setting is null. + - Also, provides the `%(directory)s` variable for the control path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH_DIR + ini: + - section: ssh_connection + key: control_path_dir + sftp_batch_mode: + default: True + description: 'TODO: write it' + env: [{name: ANSIBLE_SFTP_BATCH_MODE}] + ini: + - {key: sftp_batch_mode, section: ssh_connection} + type: boolean + scp_if_ssh: + default: smart + description: + - "Prefered method to use when transfering files over ssh" + - When set to smart, Ansible will try them until one succeeds or they all fail + - If set to True, it will force 'scp', if False it will use 'sftp' + env: [{name: ANSIBLE_SCP_IF_SSH}] + ini: + - {key: scp_if_ssh, section: ssh_connection} + use_tty: + version_added: '2.5' + default: True + description: add -tt to ssh commands to force tty allocation + env: [{name: ANSIBLE_SSH_USETTY}] + ini: + - {key: usetty, section: ssh_connection} + type: boolean + yaml: {key: connection.usetty} +''' + +class Connection(SSHConnection): + ''' ssh based connections for powershell via packer''' + + transport = 'packer' + has_pipelining = True + become_methods = [] + allow_executable = False + module_implementation_preferences = ('.ps1', '') + + def __init__(self, *args, **kwargs): + super(Connection, self).__init__(*args, **kwargs) \ No newline at end of file diff --git a/examples/ansible/connection-plugin/2.6.x/packer.py b/examples/ansible/connection-plugin/2.6.x/packer.py new file mode 100644 index 000000000..8ef8c0548 --- /dev/null +++ b/examples/ansible/connection-plugin/2.6.x/packer.py @@ -0,0 +1,218 @@ +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.connection.ssh import Connection as SSHConnection + +DOCUMENTATION = ''' + connection: packer + short_description: ssh based connections for powershell via packer + description: + - This connection plugin allows ansible to communicate to the target packer machines via ssh based connections for powershell. + author: Packer Community + version_added: na + options: + host: + description: Hostname/ip to connect to. + default: inventory_hostname + vars: + - name: ansible_host + - name: ansible_ssh_host + host_key_checking: + description: Determines if ssh should check host keys + type: boolean + ini: + - section: defaults + key: 'host_key_checking' + - section: ssh_connection + key: 'host_key_checking' + version_added: '2.5' + env: + - name: ANSIBLE_HOST_KEY_CHECKING + - name: ANSIBLE_SSH_HOST_KEY_CHECKING + version_added: '2.5' + vars: + - name: ansible_host_key_checking + version_added: '2.5' + - name: ansible_ssh_host_key_checking + version_added: '2.5' + password: + description: Authentication password for the C(remote_user). Can be supplied as CLI option. + vars: + - name: ansible_password + - name: ansible_ssh_pass + ssh_args: + description: Arguments to pass to all ssh cli tools + default: '-C -o ControlMaster=auto -o ControlPersist=60s' + ini: + - section: 'ssh_connection' + key: 'ssh_args' + env: + - name: ANSIBLE_SSH_ARGS + ssh_common_args: + description: Common extra args for all ssh CLI tools + vars: + - name: ansible_ssh_common_args + ssh_executable: + default: ssh + description: + - This defines the location of the ssh binary. It defaults to ``ssh`` which will use the first ssh binary available in $PATH. + - This option is usually not required, it might be useful when access to system ssh is restricted, + or when using ssh wrappers to connect to remote hosts. + env: [{name: ANSIBLE_SSH_EXECUTABLE}] + ini: + - {key: ssh_executable, section: ssh_connection} + #const: ANSIBLE_SSH_EXECUTABLE + version_added: "2.2" + sftp_executable: + default: sftp + description: + - This defines the location of the sftp binary. It defaults to ``sftp`` which will use the first binary available in $PATH. + env: [{name: ANSIBLE_SFTP_EXECUTABLE}] + ini: + - {key: sftp_executable, section: ssh_connection} + version_added: "2.6" + scp_executable: + default: scp + description: + - This defines the location of the scp binary. It defaults to `scp` which will use the first binary available in $PATH. + env: [{name: ANSIBLE_SCP_EXECUTABLE}] + ini: + - {key: scp_executable, section: ssh_connection} + version_added: "2.6" + scp_extra_args: + description: Extra exclusive to the ``scp`` CLI + vars: + - name: ansible_scp_extra_args + sftp_extra_args: + description: Extra exclusive to the ``sftp`` CLI + vars: + - name: ansible_sftp_extra_args + ssh_extra_args: + description: Extra exclusive to the 'ssh' CLI + vars: + - name: ansible_ssh_extra_args + retries: + # constant: ANSIBLE_SSH_RETRIES + description: Number of attempts to connect. + default: 3 + type: integer + env: + - name: ANSIBLE_SSH_RETRIES + ini: + - section: connection + key: retries + - section: ssh_connection + key: retries + port: + description: Remote port to connect to. + type: int + default: 22 + ini: + - section: defaults + key: remote_port + env: + - name: ANSIBLE_REMOTE_PORT + vars: + - name: ansible_port + - name: ansible_ssh_port + remote_user: + description: + - User name with which to login to the remote server, normally set by the remote_user keyword. + - If no user is supplied, Ansible will let the ssh client binary choose the user as it normally + ini: + - section: defaults + key: remote_user + env: + - name: ANSIBLE_REMOTE_USER + vars: + - name: ansible_user + - name: ansible_ssh_user + pipelining: + default: ANSIBLE_PIPELINING + description: + - Pipelining reduces the number of SSH operations required to execute a module on the remote server, + by executing many Ansible modules without actual file transfer. + - This can result in a very significant performance improvement when enabled. + - However this conflicts with privilege escalation (become). + For example, when using sudo operations you must first disable 'requiretty' in the sudoers file for the target hosts, + which is why this feature is disabled by default. + env: + - name: ANSIBLE_PIPELINING + #- name: ANSIBLE_SSH_PIPELINING + ini: + - section: defaults + key: pipelining + #- section: ssh_connection + # key: pipelining + type: boolean + vars: + - name: ansible_pipelining + - name: ansible_ssh_pipelining + private_key_file: + description: + - Path to private key file to use for authentication + ini: + - section: defaults + key: private_key_file + env: + - name: ANSIBLE_PRIVATE_KEY_FILE + vars: + - name: ansible_private_key_file + - name: ansible_ssh_private_key_file + control_path: + description: + - This is the location to save ssh's ControlPath sockets, it uses ssh's variable substitution. + - Since 2.3, if null, ansible will generate a unique hash. Use `%(directory)s` to indicate where to use the control dir path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH + ini: + - key: control_path + section: ssh_connection + control_path_dir: + default: ~/.ansible/cp + description: + - This sets the directory to use for ssh control path if the control path setting is null. + - Also, provides the `%(directory)s` variable for the control path setting. + env: + - name: ANSIBLE_SSH_CONTROL_PATH_DIR + ini: + - section: ssh_connection + key: control_path_dir + sftp_batch_mode: + default: 'yes' + description: 'TODO: write it' + env: [{name: ANSIBLE_SFTP_BATCH_MODE}] + ini: + - {key: sftp_batch_mode, section: ssh_connection} + type: bool + scp_if_ssh: + default: smart + description: + - "Prefered method to use when transfering files over ssh" + - When set to smart, Ansible will try them until one succeeds or they all fail + - If set to True, it will force 'scp', if False it will use 'sftp' + env: [{name: ANSIBLE_SCP_IF_SSH}] + ini: + - {key: scp_if_ssh, section: ssh_connection} + use_tty: + version_added: '2.5' + default: 'yes' + description: add -tt to ssh commands to force tty allocation + env: [{name: ANSIBLE_SSH_USETTY}] + ini: + - {key: usetty, section: ssh_connection} + type: bool + yaml: {key: connection.usetty} +''' + +class Connection(SSHConnection): + ''' ssh based connections for powershell via packer''' + + transport = 'packer' + has_pipelining = True + become_methods = [] + allow_executable = False + module_implementation_preferences = ('.ps1', '') + + def __init__(self, *args, **kwargs): + super(Connection, self).__init__(*args, **kwargs) \ No newline at end of file From 37cb3ec055d3b77907e9a83d955cdb5a62085957 Mon Sep 17 00:00:00 2001 From: Adam Robinson Date: Tue, 10 Jul 2018 17:15:22 -0400 Subject: [PATCH 3/3] clarify ansible connection plugin creation and link to working examples --- website/source/docs/provisioners/ansible.html.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/website/source/docs/provisioners/ansible.html.md b/website/source/docs/provisioners/ansible.html.md index 82047070d..26047458d 100644 --- a/website/source/docs/provisioners/ansible.html.md +++ b/website/source/docs/provisioners/ansible.html.md @@ -214,9 +214,12 @@ class Connection(SSHConnection): super(Connection, self).__init__(*args, **kwargs) ``` -Newer versions of Ansible require all plugins to have a documentation string. You will need to copy -the `options` from the `DOCUMENTATION` string from the [ssh.py Ansible connection plugin](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py) -of the Ansible version you are using and add it to packer.py similar to as follows +Newer versions of Ansible require all plugins to have a documentation string. You can see if there is a +plugin available for the version of Ansible you are using [here](https://github.com/hashicorp/packer/tree/master/examples/ansible/connection-plugin). + +To create the plugin yourself, you will need to copy all of the `options` from the `DOCUMENTATION` string +from the [ssh.py Ansible connection plugin](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py) +of the Ansible version you are using and add it to a packer.py file similar to as follows ``` python from __future__ import (absolute_import, division, print_function) @@ -233,7 +236,7 @@ DOCUMENTATION = ''' author: Packer version_added: na options: - **** Copy the options from + **** Copy ALL the options from https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py for the version of Ansible you are using **** '''