github.com/raghuse92/packer@v1.3.2/website/source/docs/provisioners/ansible.html.md (about) 1 --- 2 description: | 3 The ansible Packer provisioner allows Ansible playbooks to be run to 4 provision the machine. 5 layout: docs 6 page_title: 'Ansible - Provisioners' 7 sidebar_current: 'docs-provisioners-ansible-remote' 8 --- 9 10 # Ansible Provisioner 11 12 Type: `ansible` 13 14 The `ansible` Packer provisioner runs Ansible playbooks. It dynamically creates 15 an Ansible inventory file configured to use SSH, runs an SSH server, executes 16 `ansible-playbook`, and marshals Ansible plays through the SSH server to the 17 machine being provisioned by Packer. 18 19 -> **Note:**: Any `remote_user` defined in tasks will be ignored. Packer will 20 always connect with the user given in the json config for this provisioner. 21 22 ## Basic Example 23 24 This is a fully functional template that will provision an image on 25 DigitalOcean. Replace the mock `api_token` value with your own. 26 27 ``` json 28 { 29 "provisioners": [ 30 { 31 "type": "ansible", 32 "playbook_file": "./playbook.yml" 33 } 34 ], 35 36 "builders": [ 37 { 38 "type": "digitalocean", 39 "api_token": "6a561151587389c7cf8faa2d83e94150a4202da0e2bad34dd2bf236018ffaeeb", 40 "image": "ubuntu-14-04-x64", 41 "region": "sfo1" 42 } 43 ] 44 } 45 ``` 46 47 ## Configuration Reference 48 49 Required Parameters: 50 51 - `playbook_file` - The playbook to be run by Ansible. 52 53 Optional Parameters: 54 55 - `ansible_env_vars` (array of strings) - Environment variables to set before 56 running Ansible. 57 Usage example: 58 59 ``` json 60 { 61 "ansible_env_vars": [ "ANSIBLE_HOST_KEY_CHECKING=False", "ANSIBLE_SSH_ARGS='-o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s'", "ANSIBLE_NOCOLOR=True" ] 62 } 63 ``` 64 If you are running a Windows build on AWS, Azure or Google Compute and would 65 like to access the auto-generated password that Packer uses to connect to a 66 Windows instance via WinRM, you can use the template variable 67 {{.WinRMPassword}} in this option. 68 For example: 69 70 ```json 71 "ansible_env_vars": [ "WINRM_PASSWORD={{.WinRMPassword}}" ], 72 ``` 73 74 - `command` (string) - The command to invoke ansible. 75 Defaults to `ansible-playbook`. 76 77 - `empty_groups` (array of strings) - The groups which should be present in 78 inventory file but remain empty. 79 80 - `extra_arguments` (array of strings) - Extra arguments to pass to Ansible. 81 These arguments *will not* be passed through a shell and arguments should 82 not be quoted. Usage example: 83 84 ```json 85 { 86 "extra_arguments": [ "--extra-vars", "Region={{user `Region`}} Stage={{user `Stage`}}" ] 87 } 88 ``` 89 90 If you are running a Windows build on AWS, Azure or Google Compute and would 91 like to access the auto-generated password that Packer uses to connect to a 92 Windows instance via WinRM, you can use the template variable 93 {{.WinRMPassword}} in this option. 94 For example: 95 96 ```json 97 "extra_arguments": [ 98 "--extra-vars", "winrm_password={{ .WinRMPassword }}" 99 ] 100 ``` 101 102 - `groups` (array of strings) - The groups into which the Ansible host 103 should be placed. When unspecified, the host is not associated with any 104 groups. 105 106 - `inventory_file` (string) - The inventory file to use during provisioning. 107 When unspecified, Packer will create a temporary inventory file and will 108 use the `host_alias`. 109 110 - `host_alias` (string) - The alias by which the Ansible host should be known. 111 Defaults to `default`. This setting is ignored when using a custom inventory 112 file. 113 114 - `inventory_directory` (string) - The directory in which to place the 115 temporary generated Ansible inventory file. By default, this is the 116 system-specific temporary file location. The fully-qualified name of this 117 temporary file will be passed to the `-i` argument of the `ansible` command 118 when this provisioner runs ansible. Specify this if you have an existing 119 inventory directory with `host_vars` `group_vars` that you would like to use 120 in the playbook that this provisioner will run. 121 122 - `local_port` (string) - The port on which to attempt to listen for SSH 123 connections. This value is a starting point. The provisioner will attempt 124 listen for SSH connections on the first available of ten ports, starting at 125 `local_port`. A system-chosen port is used when `local_port` is missing or 126 empty. 127 128 - `sftp_command` (string) - The command to run on the machine being provisioned 129 by Packer to handle the SFTP protocol that Ansible will use to transfer 130 files. The command should read and write on stdin and stdout, respectively. 131 Defaults to `/usr/lib/sftp-server -e`. 132 133 - `skip_version_check` (boolean) - Check if ansible is installed prior to running. 134 Set this to `true`, for example, if you're going to install ansible during 135 the packer run. 136 137 - `ssh_host_key_file` (string) - The SSH key that will be used to run the SSH 138 server on the host machine to forward commands to the target machine. Ansible 139 connects to this server and will validate the identity of the server using 140 the system known\_hosts. The default behavior is to generate and use a 141 onetime key. Host key checking is disabled via the 142 `ANSIBLE_HOST_KEY_CHECKING` environment variable if the key is generated. 143 144 - `ssh_authorized_key_file` (string) - The SSH public key of the Ansible 145 `ssh_user`. The default behavior is to generate and use a onetime key. If 146 this key is generated, the corresponding private key is passed to 147 `ansible-playbook` with the `--private-key` option. 148 149 - `user` (string) - The `ansible_user` to use. Defaults to the user running 150 packer. 151 152 ## Default Extra Variables 153 154 In addition to being able to specify extra arguments using the 155 `extra_arguments` configuration, the provisioner automatically defines certain 156 commonly useful Ansible variables: 157 158 - `packer_build_name` is set to the name of the build that Packer is running. 159 This is most useful when Packer is making multiple builds and you want to 160 distinguish them slightly when using a common playbook. 161 162 - `packer_builder_type` is the type of the builder that was used to create the 163 machine that the script is running on. This is useful if you want to run 164 only certain parts of the playbook on systems built with certain builders. 165 166 - `packer_http_addr` If using a builder that provides an http server for file 167 transfer (such as hyperv, parallels, qemu, virtualbox, and vmware), this 168 will be set to the address. You can use this address in your provisioner to 169 download large files over http. This may be useful if you're experiencing 170 slower speeds using the default file provisioner. A file provisioner using 171 the `winrm` communicator may experience these types of difficulties. 172 173 ## Debugging 174 175 To debug underlying issues with Ansible, add `"-vvvv"` to `"extra_arguments"` to enable verbose logging. 176 177 ```json 178 { 179 "extra_arguments": [ "-vvvv" ] 180 } 181 ``` 182 183 ## Limitations 184 185 ### Redhat / CentOS 186 187 Redhat / CentOS builds have been known to fail with the following error due to `sftp_command`, which should be set to `/usr/libexec/openssh/sftp-server -e`: 188 189 ``` text 190 ==> virtualbox-ovf: starting sftp subsystem 191 virtualbox-ovf: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh", "unreachable": true} 192 ``` 193 194 ### chroot communicator 195 196 Building within a chroot (e.g. `amazon-chroot`) requires changing the Ansible connection to chroot. 197 198 ```json 199 { 200 "builders": [ 201 { 202 "type": "amazon-chroot", 203 "mount_path": "/mnt/packer-amazon-chroot", 204 "region": "us-east-1", 205 "source_ami": "ami-123456" 206 } 207 ], 208 "provisioners": [ 209 { 210 "type": "ansible", 211 "extra_arguments": [ 212 "--connection=chroot", 213 "--inventory-file=/mnt/packer-amazon-chroot," 214 ], 215 "playbook_file": "main.yml" 216 } 217 ] 218 } 219 ``` 220 221 ### winrm communicator 222 223 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 224 the connection plugin. On versions of Ansible before 2.4.x, the following works as the connection plugin 225 226 ``` python 227 from __future__ import (absolute_import, division, print_function) 228 __metaclass__ = type 229 230 from ansible.plugins.connection.ssh import Connection as SSHConnection 231 232 class Connection(SSHConnection): 233 ''' ssh based connections for powershell via packer''' 234 235 transport = 'packer' 236 has_pipelining = True 237 become_methods = [] 238 allow_executable = False 239 module_implementation_preferences = ('.ps1', '') 240 241 def __init__(self, *args, **kwargs): 242 super(Connection, self).__init__(*args, **kwargs) 243 ``` 244 245 Newer versions of Ansible require all plugins to have a documentation string. You can see if there is a 246 plugin available for the version of Ansible you are using [here](https://github.com/hashicorp/packer/tree/master/examples/ansible/connection-plugin). 247 248 To create the plugin yourself, you will need to copy all of the `options` from the `DOCUMENTATION` string 249 from the [ssh.py Ansible connection plugin](https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py) 250 of the Ansible version you are using and add it to a packer.py file similar to as follows 251 252 ``` python 253 from __future__ import (absolute_import, division, print_function) 254 __metaclass__ = type 255 256 from ansible.plugins.connection.ssh import Connection as SSHConnection 257 258 DOCUMENTATION = ''' 259 connection: packer 260 short_description: ssh based connections for powershell via packer 261 description: 262 - This connection plugin allows ansible to communicate to the target packer 263 machines via ssh based connections for powershell. 264 author: Packer 265 version_added: na 266 options: 267 **** Copy ALL the options from 268 https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py 269 for the version of Ansible you are using **** 270 ''' 271 272 class Connection(SSHConnection): 273 ''' ssh based connections for powershell via packer''' 274 275 transport = 'packer' 276 has_pipelining = True 277 become_methods = [] 278 allow_executable = False 279 module_implementation_preferences = ('.ps1', '') 280 281 def __init__(self, *args, **kwargs): 282 super(Connection, self).__init__(*args, **kwargs) 283 ``` 284 285 This template should build a Windows Server 2012 image on Google Cloud Platform: 286 287 ``` json 288 { 289 "variables": {}, 290 "provisioners": [ 291 { 292 "type": "ansible", 293 "playbook_file": "./win-playbook.yml", 294 "extra_arguments": [ 295 "--connection", "packer", 296 "--extra-vars", "ansible_shell_type=powershell ansible_shell_executable=None" 297 ] 298 } 299 ], 300 "builders": [ 301 { 302 "type": "googlecompute", 303 "account_file": "{{user `account_file`}}", 304 "project_id": "{{user `project_id`}}", 305 "source_image": "windows-server-2012-r2-dc-v20160916", 306 "communicator": "winrm", 307 "zone": "us-central1-a", 308 "disk_size": 50, 309 "winrm_username": "packer", 310 "winrm_use_ssl": true, 311 "winrm_insecure": true, 312 "metadata": { 313 "sysprep-specialize-script-cmd": "winrm set winrm/config/service/auth @{Basic=\"true\"}" 314 } 315 } 316 ] 317 } 318 ``` 319 320 ### Post i/o timeout errors 321 If you see `unknown error: Post http://<ip>:<port>/wsman:dial tcp <ip>:<port>: i/o timeout` errors while provisioning a Windows machine, try setting Ansible to copy files over [ssh instead of sftp](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#envvar-ANSIBLE_SCP_IF_SSH). 322 323 ### Too many SSH keys 324 325 SSH servers only allow you to attempt to authenticate a certain number of times. All of your loaded keys will be tried before the dynamically generated key. If you have too many SSH keys loaded in your `ssh-agent`, the Ansible provisioner may fail authentication with a message similar to this: 326 327 ```console 328 googlecompute: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '[127.0.0.1]:62684' (RSA) to the list of known hosts.\r\nReceived disconnect from 127.0.0.1 port 62684:2: too many authentication failures\r\nAuthentication failed.\r\n", "unreachable": true} 329 ``` 330 331 To unload all keys from your `ssh-agent`, run: 332 333 ```console 334 $ ssh-add -D 335 ``` 336 337 ### Become: yes 338 339 We recommend against running Packer as root; if you do then you won't be able to successfully run your ansible playbook as root; `become: yes` will fail.