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  ```