github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/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. Note, this means that any `remote_user` 18 defined in tasks will be ignored. Packer will always connect with the user 19 given in the json config. 20 21 ## Basic Example 22 23 This is a fully functional template that will provision an image on 24 DigitalOcean. Replace the mock `api_token` value with your own. 25 26 ``` json 27 { 28 "provisioners": [ 29 { 30 "type": "ansible", 31 "playbook_file": "./playbook.yml" 32 } 33 ], 34 35 "builders": [ 36 { 37 "type": "digitalocean", 38 "api_token": "6a561151587389c7cf8faa2d83e94150a4202da0e2bad34dd2bf236018ffaeeb", 39 "image": "ubuntu-14-04-x64", 40 "region": "sfo1" 41 } 42 ] 43 } 44 ``` 45 46 ## Configuration Reference 47 48 Required Parameters: 49 50 - `playbook_file` - The playbook to be run by Ansible. 51 52 Optional Parameters: 53 54 - `ansible_env_vars` (array of strings) - Environment variables to set before 55 running Ansible. 56 Usage example: 57 58 ``` json 59 { 60 "ansible_env_vars": [ "ANSIBLE_HOST_KEY_CHECKING=False", "ANSIBLE_SSH_ARGS='-o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s'", "ANSIBLE_NOCOLOR=True" ] 61 } 62 ``` 63 64 - `command` (string) - The command to invoke ansible. 65 Defaults to `ansible-playbook`. 66 67 - `empty_groups` (array of strings) - The groups which should be present in 68 inventory file but remain empty. 69 70 - `extra_arguments` (array of strings) - Extra arguments to pass to Ansible. 71 These arguments *will not* be passed through a shell and arguments should 72 not be quoted. Usage example: 73 74 ``` json 75 { 76 "extra_arguments": [ "--extra-vars", "Region={{user `Region`}} Stage={{user `Stage`}}" ] 77 } 78 ``` 79 80 - `groups` (array of strings) - The groups into which the Ansible host 81 should be placed. When unspecified, the host is not associated with any 82 groups. 83 84 - `host_alias` (string) - The alias by which the Ansible host should be known. 85 Defaults to `default`. 86 87 - `inventory_directory` (string) - The directory in which to place the 88 temporary generated Ansible inventory file. By default, this is the 89 system-specific temporary file location. The fully-qualified name of this 90 temporary file will be passed to the `-i` argument of the `ansible` command 91 when this provisioner runs ansible. Specify this if you have an existing 92 inventory directory with `host_vars` `group_vars` that you would like to use 93 in the playbook that this provisioner will run. 94 95 - `local_port` (string) - The port on which to attempt to listen for SSH 96 connections. This value is a starting point. The provisioner will attempt 97 listen for SSH connections on the first available of ten ports, starting at 98 `local_port`. A system-chosen port is used when `local_port` is missing or 99 empty. 100 101 - `sftp_command` (string) - The command to run on the machine being provisioned 102 by Packer to handle the SFTP protocol that Ansible will use to transfer 103 files. The command should read and write on stdin and stdout, respectively. 104 Defaults to `/usr/lib/sftp-server -e`. 105 106 - `skip_version_check` (bool) - Check if ansible is installed prior to running. 107 Set this to `true`, for example, if you're going to install ansible during 108 the packer run. 109 110 - `ssh_host_key_file` (string) - The SSH key that will be used to run the SSH 111 server on the host machine to forward commands to the target machine. Ansible 112 connects to this server and will validate the identity of the server using 113 the system known\_hosts. The default behavior is to generate and use a 114 onetime key. Host key checking is disabled via the 115 `ANSIBLE_HOST_KEY_CHECKING` environment variable if the key is generated. 116 117 - `ssh_authorized_key_file` (string) - The SSH public key of the Ansible 118 `ssh_user`. The default behavior is to generate and use a onetime key. If 119 this key is generated, the corresponding private key is passed to 120 `ansible-playbook` with the `--private-key` option. 121 122 - `user` (string) - The `ansible_user` to use. Defaults to the user running 123 packer. 124 125 ## Default Extra Variables 126 127 In addition to being able to specify extra arguments using the 128 `extra_arguments` configuration, the provisioner automatically defines certain 129 commonly useful Ansible variables: 130 131 - `packer_build_name` is set to the name of the build that Packer is running. 132 This is most useful when Packer is making multiple builds and you want to 133 distinguish them slightly when using a common playbook. 134 135 - `packer_builder_type` is the type of the builder that was used to create the 136 machine that the script is running on. This is useful if you want to run 137 only certain parts of the playbook on systems built with certain builders. 138 139 ## Debugging 140 141 To debug underlying issues with Ansible, add `"-vvvv"` to `"extra_arguments"` to enable verbose logging. 142 143 ``` json 144 { 145 "extra_arguments": [ "-vvvv" ] 146 } 147 ``` 148 149 ## Limitations 150 151 ### Redhat / CentOS 152 153 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`: 154 155 ``` text 156 ==> virtualbox-ovf: starting sftp subsystem 157 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} 158 ``` 159 160 ### chroot communicator 161 162 Building within a chroot (e.g. `amazon-chroot`) requires changing the Ansible connection to chroot. 163 164 ``` json 165 { 166 "builders": [ 167 { 168 "type": "amazon-chroot", 169 "mount_path": "/mnt/packer-amazon-chroot", 170 "region": "us-east-1", 171 "source_ami": "ami-123456" 172 } 173 ], 174 "provisioners": [ 175 { 176 "type": "ansible", 177 "extra_arguments": [ 178 "--connection=chroot", 179 "--inventory-file=/mnt/packer-amazon-chroot," 180 ], 181 "playbook_file": "main.yml" 182 } 183 ] 184 } 185 ``` 186 187 ### winrm communicator 188 189 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 190 191 ``` python 192 from __future__ import (absolute_import, division, print_function) 193 __metaclass__ = type 194 195 from ansible.plugins.connection.ssh import Connection as SSHConnection 196 197 class Connection(SSHConnection): 198 ''' ssh based connections for powershell via packer''' 199 200 transport = 'packer' 201 has_pipelining = True 202 become_methods = [] 203 allow_executable = False 204 module_implementation_preferences = ('.ps1', '') 205 206 def __init__(self, *args, **kwargs): 207 super(Connection, self).__init__(*args, **kwargs) 208 ``` 209 210 This template should build a Windows Server 2012 image on Google Cloud Platform: 211 212 ``` json 213 { 214 "variables": {}, 215 "provisioners": [ 216 { 217 "type": "ansible", 218 "playbook_file": "./win-playbook.yml", 219 "extra_arguments": [ 220 "--connection", "packer", 221 "--extra-vars", "ansible_shell_type=powershell ansible_shell_executable=None" 222 ] 223 } 224 ], 225 "builders": [ 226 { 227 "type": "googlecompute", 228 "account_file": "{{user `account_file`}}", 229 "project_id": "{{user `project_id`}}", 230 "source_image": "windows-server-2012-r2-dc-v20160916", 231 "communicator": "winrm", 232 "zone": "us-central1-a", 233 "disk_size": 50, 234 "winrm_username": "packer", 235 "winrm_use_ssl": true, 236 "winrm_insecure": true, 237 "metadata": { 238 "sysprep-specialize-script-cmd": "winrm set winrm/config/service/auth @{Basic=\"true\"}" 239 } 240 } 241 ] 242 } 243 ``` 244 245 ### Too many SSH keys 246 247 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: 248 249 ```console 250 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} 251 ``` 252 253 To unload all keys from your `ssh-agent`, run: 254 255 ```console 256 $ ssh-add -D 257 ```