New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
pas256 opened this Issue Oct 22, 2013 · 21 comments

Comments

Projects
None yet
@pas256
Contributor

pas256 commented Oct 22, 2013

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

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

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

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.

@kelseyhightower

This comment has been minimized.

Collaborator

kelseyhightower commented Oct 22, 2013

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

@pas256

This comment has been minimized.

Contributor

pas256 commented Nov 26, 2013

@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.

@strcrzy

This comment has been minimized.

Contributor

strcrzy commented Jan 22, 2014

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.

@pas256

This comment has been minimized.

Contributor

pas256 commented Jan 22, 2014

@strcrzy you legend! Thank you

@jgornick

This comment has been minimized.

Contributor

jgornick commented Apr 4, 2014

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

@coop

This comment has been minimized.

coop commented May 1, 2014

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"
  ]
}
@coop

This comment has been minimized.

coop commented May 1, 2014

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?

@strcrzy

This comment has been minimized.

Contributor

strcrzy commented May 2, 2014

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.

@elithrar

This comment has been minimized.

elithrar commented Aug 14, 2014

@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.

@coop

This comment has been minimized.

coop commented Aug 14, 2014

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

@emalloy

This comment has been minimized.

emalloy commented Nov 24, 2014

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.

@iknite

This comment has been minimized.

iknite commented Jan 14, 2015

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

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

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

@philbert

This comment has been minimized.

philbert commented Jul 23, 2015

Yes please! I want this!

@jvasallo

This comment has been minimized.

Contributor

jvasallo commented Aug 24, 2015

+1

1 similar comment
@nicolai86

This comment has been minimized.

nicolai86 commented Sep 7, 2015

+1

@bschwind

This comment has been minimized.

bschwind commented Oct 6, 2015

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):

{
    "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"
            ]
        }
    ]
}

ansible-vault-password.py:

#!/usr/bin/env python

import os
print os.environ['VAULT_PASSWORD']

And a snippet from the output:

amazon-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]

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

@rickard-von-essen

This comment has been minimized.

Collaborator

rickard-von-essen commented Mar 4, 2016

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

@jaytaylor

This comment has been minimized.

jaytaylor commented Mar 11, 2016

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

@bschwind

This comment has been minimized.

bschwind commented Mar 11, 2016

@jaytaylor Glad I could help!

bascht added a commit to yakshed/vm that referenced this issue Jun 28, 2016

@fewknow

This comment has been minimized.

fewknow commented Jan 4, 2017

@bschwind how are you getting the ansible-vault-password.py script on the box? Is this something that is part of your base image before you run the ansible provisioner?

@rickard-von-essen

This comment has been minimized.

Collaborator

rickard-von-essen commented Jan 4, 2017

Please only use GitHub Issues for reporting bugs and feature requests. Do not ask for general help here. Use IRC #packer-tool on Freenode or the mailing list for that.

See https://www.packer.io/community/

If you are describing a bug or a feature request please reopen and try to add some more details to make it clearer.

@hashicorp hashicorp locked and limited conversation to collaborators Jan 4, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.