Jay Taylor's notes

back to listing index

Add a way to pass extra variables to ansible-local provisioner · Issue #555 · mitchellh/packer

[web search]
Original source (github.com)
Tags: ansible packer build-pipeline github.com
Clipped on: 2016-03-10

Skip to content

Add a way to pass extra variables to ansible-local provisioner #555

Closed
pas256 opened this Issue on Oct 22, 2013 · 18 comments

Milestone

No milestone

Assignee

No one assigned

Notifications

You’re receiving notifications because you commented.

15 participants

Image (Asset 2/30) alt= pas256 Image (Asset 3/30) alt= kelseyhightower Image (Asset 4/30) alt= strcrzy Image (Asset 5/30) alt= jgornick Image (Asset 6/30) alt= coop Image (Asset 7/30) alt= elithrar Image (Asset 8/30) alt= lv0 Image (Asset 9/30) alt= iknite Image (Asset 10/30) alt= philbert Image (Asset 11/30) alt= jvasallo Image (Asset 12/30) alt= nicolai86 Image (Asset 13/30) alt= bschwind Image (Asset 14/30) alt= rickard-von-essen Image (Asset 15/30) alt= jaytaylor Image (Asset 16/30) alt= sethvargo
Image (Asset 17/30) alt=

This is for @kelseyhightower and the  ansible-local  provisioner:

 ansible-playbook  has an option to pass extra variables along from the command line:

normal-e EXTRA_VARS, --extra-vars=EXTRA_VARS
                    set additional variables as key=value or YAML/JSON
normal

When using the  amazon-chroot  builder, it is important to not start any services (e.g. Apache) inside the chroot environment so that the volume can be unmounted correctly. I write my playbooks so that they can be run on both running instances, as well as to build AMIs, and I do that as a flag I pass in a AMI creation time. Right now, there is no way for me to pass that flag to the  ansible-local  provisioner.

Please let me know if there is anything else you need.

Image (Asset 18/30) alt=
Collaborator

@pas256 Thanks for requesting this. I have some ideas on how to make this work, expect a pull request for review soon.

Image (Asset 19/30) alt=

@kelseyhightower Have you made any progress on this? I have done an episode on using Aminator and the Ansible Provisioner here, and would like to do one on Packer for comparison, but need this in place before I can use my playbooks.

Image (Asset 20/30) alt=

i just needed this, so i submitted #842 which will let you pass in arbitrary arguments in to ansible-playbook.
this should resolve this issue as well, if i understand what you're asking for correctly.

Image (Asset 21/30) alt=

@strcrzy you legend! Thank you

Image (Asset 22/30) alt=

@kelseyhightower Should probably close this issue out since it's no longer valid.

Image (Asset 23/30) alt=

I think there was a bug in #842 that still exists in master that doesn't allow you to pass through the extra variables. In master the extra variables are passed in just before the  -c  flag without a prefix. I believe this needs to be changed to:

extraArgs := ""
if len(p.config.ExtraArguments) > 0 {
    extraArgs = " --extra-vars " + strings.Join(p.config.ExtraArguments, " ")
}
command := fmt.Sprintf("cd %s && %s %s%s -c local -i %s",
     p.config.StagingDir, p.config.Command, playbook, extraArgs, inventory)

The important part here is the  --extra-vars  prefix before setting the variables. Given the implementation in master I see the following error:

amazon-ebs: Executing Ansible: ansible-playbook /tmp/packer-provisioner-ansible-local/solo.yml APP=tango REVISION=70c11781cfb3a3b6022924be2b8e487ca9c131f5 -c local -i "127.0.0.1,"
    amazon-ebs: ERROR: the playbook: APP=tango could not be found

with the following packer config:

{
  "type": "ansible-local",
  "playbook_file": "ansible/solo.yml",
  "role_paths": [
    "ansible/roles/solo"
  ],
  "extra_arguments": [
    "APP={{user `app`}}",
    "REVISION={{user `revision`}}"
  ]
}

I couldn't find a test for this functionality in  master  which is probably why it has gone unnoticed. I'll submit a pull request for the required functionality but I don't know enough about go to write a failing test, I'd appreciate any help with that.

For the time being you can work around this problem by adjusting the  command  used to run  ansible-playbook :

{
  "type": "ansible-local",
  "playbook_file": "ansible/solo.yml",
  "command": "APP={{user `app`}} REVISION={{user `revision`}} ansible-playbook",
  "role_paths": [
    "ansible/roles/solo"
  ]
}
Image (Asset 24/30) alt=

Thinking about it more I might have misunderstood the usage of  extra_arguments  because I could also solve my problem without modifying  command  with the following:

{
  "type": "ansible-local",
  "playbook_file": "ansible/solo.yml",
  "role_paths": [
    "ansible/roles/solo"
  ],
  "extra_arguments": [
    "--extra-vars"
    "APP={{user `app`}}",
    "REVISION={{user `revision`}}"
  ]
}

This approach also allows you to pass  --ask-vault-pass  or any of the arguments listed in  ansible-playbook --help  without packer having to support each and every one of them. I think I was mislead by the original request around  --extra-vars  and my lack of understanding.

I think some solid examples in the documentation would help with this. Are the examples on github so I can contribute?

Image (Asset 25/30) alt=

 extra_arguments  is for passing additional command line arguments to ansible, beyond the ones already passed in by packer.

it is not solely for passing extra variables to ansible.  --extra-vars  is an example of one of the  extra_arguments  that you could pass, but it is not the only one. for example, i pass  -vvv  in to get to the bottom of things sometimes.

sorry for the confusion, and thank you for offering to add examples. the docs for the ansible provisioner can be found here if you'd like to edit them.

Image (Asset 26/30) alt=

@coop Curious—how did you pass  --ask-vault-pass  to Packer? AFAIK, Ansible doesn't let you pass the password as an argument. It either prompts, or you use  --vault-password-file filename  instead. I'm trying to avoid using a file because I (obviously) don't want the key lying around on a machine.

Image (Asset 27/30) alt=

@elithrar I used  --vault-password-file  on a CI machine.

Image (Asset 28/30) alt=

Just fyi, this doesn't work unless you first xfer the vault-password-file to the image being provisioned in some shell preprovisioning step. I ended up just using git-crypt, as it's more transparent, and since i've already init'd git-crypt on my local repo, and packer is copying the files across using scp (or some equivalent), the files are already unencrypted, and get destroyed as part of the builtin post-provisioners

If anyone has a better way to do this, please speak up.

Image (Asset 29/30) alt=

Just a quick workaround, to read from stdin the password:

normal{
    "variables":{
            "pass": "{{env `ANSIBLE_VAULT_PASS`}}"
    },
    "builders": [...],
    "provisioners": [
        {
            "type": "ansible-local",
            "command": "echo '{{user `pass`}}' | ansible-playbook",
            "extra_arguments": "--vault-password-file=/bin/cat"
        }
    ]
}
normal

The only caveat is that it shows your password in your tty (so avoid eavesdroppers)

more info:
https://groups.google.com/forum/#!topic/ansible-devel/1vFc3y6Ogto

Yes please! I want this!

Kind of clunky, but here's a workaround to getting the vault password to ansible without displaying it in the TTY (using ubuntu 14.04 AMI):

normal{
    "variables": {
        "aws_access_key": "",
        "aws_secret_key": "",
        "vault_secret": "{{env `VAULT_PASSWORD`}}"
    },
    "builders": [{
        "type": "amazon-ebs",
        "access_key": "{{user `aws_access_key`}}",
        "secret_key": "{{user `aws_secret_key`}}",
        "region": "...",
        "source_ami": "ami-936d9d93",
        "instance_type": "t2.micro",
        "ssh_username": "ubuntu",
        "ami_name": "packer-example {{timestamp}}",
        "vpc_id": "...",
        "subnet_id": "..."
    }],
    "provisioners": [
        {
            "type": "shell",
            "inline": [
                "sleep 30",
                "sudo apt-add-repository ppa:ansible/ansible",
                "sudo apt-get update",
                "sudo apt-get -y install ansible",
                "echo \"export VAULT_PASSWORD=\"{{user `vault_secret`}}\"\" > ~/passwordExport"
            ]
        },
        {
            "type": "ansible-local",
            "command": "source ~/passwordExport && ansible-playbook",
            "playbook_file": "provision.yml",
            "playbook_dir": ".",
            "extra_arguments": [
                "--extra-vars \"deploy_env=dev\"",
                "--user=ubuntu",
                "--vault-password-file=ansible-vault-password.py"
            ]
        }
    ]
}
normal

ansible-vault-password.py:

normal#!/usr/bin/env python

import os
print os.environ['VAULT_PASSWORD']

normal

And a snippet from the output:

normalamazon-ebs: Setting up python-crypto (2.6.1-4build1) ...
    amazon-ebs: Setting up python-paramiko (1.10.1-1git1build1) ...
    amazon-ebs: Setting up python-httplib2 (0.8-2build1) ...
    amazon-ebs: Setting up sshpass (1.05-1) ...
    amazon-ebs: Setting up ansible (1.9.3-1ppa~trusty) ...
    amazon-ebs: Processing triggers for libc-bin (2.19-0ubuntu6.6) ...
    amazon-ebs: Processing triggers for python-support (1.0.15) ...
==> amazon-ebs: Provisioning with Ansible...
    amazon-ebs: Uploading Playbook directory to Ansible staging directory...
    amazon-ebs: Creating directory: /tmp/packer-provisioner-ansible-local
    amazon-ebs: Uploading main Playbook file...
    amazon-ebs: Uploading inventory file...
    amazon-ebs: Executing Ansible: cd /tmp/packer-provisioner-ansible-local && source ~/passwordExport && ansible-playbook /tmp/packer-provisioner-ansible-local/provision.yml --extra-vars "deploy_env=dev" --user=ubuntu --vault-password-file=ansible-vault-password.py -c local -i /tmp/packer-provisioner-ansible-local/packer-provisioner-ansible-local540716987
    amazon-ebs:
    amazon-ebs: PLAY [all] ********************************************************************
    amazon-ebs:
    amazon-ebs: GATHERING FACTS ***************************************************************
    amazon-ebs: ok: [127.0.0.1]
normal

It would probably also be wise to have a third shell provisioner which deletes the passwordExport file from the machine.

Collaborator

Closing this since this have been implemented a long time ago, see https://www.packer.io/docs/provisioners/ansible-local.html#extra_arguments

Pick your reaction

@bschwind Thanks for your example, it's a really helpful example and has more complete information than the documentation.

Attach files by dragging & dropping, selecting them, or pasting from the clipboard.