How to pass variables to the ansible provisioner in Packer? - ansible

When using vanilla Ansible playbooks, I have a number of inventories that encapsulate various configurations via the setting of variables; these work as expected. I now wish to use one or more playbooks from the Packer Ansible plugin to perform the same steps.
At present, I have resorted to passing arguments via the "--extra-vars" directive; for a limited number of variables, this is acceptable. However, I would prefer to be able to reference the existing inventory file which contains the set of variables I wish to use.
Is this possible?

Yes, you can specify the inventory file containing the variables in the Packer Ansible provisioner:
provisioner "ansible" {
inventory_file = "${path.root}/path/to/inventory"
}
More information is available in the documentation.
However, this can also become tricky since Packer normally generates an inventory file with an entry for the instance being provisioned. You may have difficulties adapting the host entry for the instance being provisioned to the existing inventory file. It may be easier to use the inventory directory instead:
provisioner "ansible" {
inventory_directory = "${path.root}/path/to/inventory_dir"
}
In that situation, Packer will still generate the guaranteed accurate inventory file for you, but host_vars and group_vars from the existing inventory files will still be available from the directory.

Related

how to not display skipped hosts/tasks?

I have many playbooks and I don't have access the where Ansible is installed. I can write my playbooks locally on my laptop then I push them to a repo and I can run them via Jenkins. I can't control or change e.g. ansible.cfg or so. Is there a way to manipulate the ansible default stdout callback plugin per playbook without accessing the ansible host itself?
Actually it is, you can use Environmental variable for this: check documentation
ANSIBLE_DISPLAY_SKIPPED_HOSTS=yes ansible-playbook main.yml
But for obvious reasons (It's deprecated) it's better to use the ansible.cfg option for this.
[defaults]
display_skipped_hosts = False

Getting a python warning when running playbook EC2 inventory

I am really new to Ansible and I hate getting warnings when I run a playbook. This environment is being used for my education.
Environment:
AWS EC2
4 Ubuntu 20
3 Amazon Linux2 hosts
Inventory
using the dynamic inventory script
playbook
just runs a simple ping against all hosts. I wanted to test the inventory
warning
[WARNING]: Platform linux on host XXXXXX.amazonaws.com is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change the
meaning of that path. See https://docs.ansible.com/ansible-core/2.11/reference_appendices/interpreter_discovery.html for more information.
Things I have tried
updated all sym links on hosts to point to the python3 version
adding the line "ansible_python_interpreter = /usr/bin/python" to "/etc/ansible/ansible.cfg"
I am relying on that cfg file
I would like to know how to solve this. since I am not running a static inventory, I didn't think that I could specific an interpreter on a per host or group of hosts. While the playbook runs, it seems that something is not configured correctly and I would like to get that sorted. This is only present on the Amazon Linux instances. the Ubuntu instances are fine.
Michael
Thank you. I did find another route that work though I am sure that you suggest would also work.
I was using the wrong configuration entry. I was using
ansible_python_interpreter = /usr/bin/python
when I should have been using
interpreter_python = /usr/bin/python
on each host I made sure that /usr/bin/python sym link was pointing and the correct version.
according to the documentation
for individual hosts and groups, use the ansible_python_interpreter inventory variable
globally, use the interpreter_python key in the [defaults] section of ansible.cfg
Regards, Michael.
You can edit your ansible.cfg and set auto_silent mode:
interpreter_python=auto_silent
Check reference here:
https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html

How to get current inventory from Ansible module?

I'm developing custom Ansible module to control Vagrant controlled multiple VM nodes on multiple VM servers following guide https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html. As far as I understand, Ansible iterates over all specified target hosts and executes run_module on them, allowing to module.run_command on each host.
But I need some info from inventory file. For example if VM server is passed to Ansible command then I need to get IPs of VM nodes on that server and I could do it using info from inventory file. How could I get full inventory data from Ansible module Python code?
Found answer by myself and posted it as a part of answer to related question https://stackoverflow.com/a/59877713/1927853

how to deploy different conf in different server without repeat the task each time

hy folks
I have to deploy configurations on several servers but they are different on each of them. I was wondering if with ansible it was possible to make a loop or I would pass in parameter the names of the servers. And when this match it deploys the configuration on the server?
There are multiple ways you can approach this, depending on your envirmonment:
If you have a seperate file for each host you could name them something like "hostname.application.conf". Then you can use a simple copy to deploy the configs:
- copy:
src: "/path/to/configs/{{ansible_hostname}}.application.conf
dest: path/to/application/folder/application.conf
The variable "ansible_hostname" is automatically generated by ansible and contains the hostname of the currently targeted host. If you have multiple applications you can loop over them with someting like this:
- copy
src: "/path/to/configs/{{ansible_hostname}}.{{item.name}}.conf
dest: "{{item.path}}{{item.name}}.conf
...
loop:
- { name: 'appl1', path: '/path/to/application/folder/' }
- ...
If you have one configuration that needs to be modified and copied to the other hosts, you can look into templating: https://docs.ansible.com/ansible/latest/modules/template_module.html
I woud Strongly recommend to use a Jinja2 template as the configuration file so Ansible can set the vars as described in group or host files.
https://docs.ansible.com/ansible/latest/modules/template_module.html
Role based Ansible Playbook
Will work based on the following behaviors, for each role ‘x’:
If roles/x/tasks/main.yml exists, tasks listed therein will be added to the play.
If roles/x/handlers/main.yml exists, handlers listed therein will be added to the play.
If roles/x/vars/main.yml exists, variables listed therein will be added to the play.
If roles/x/defaults/main.yml exists, variables listed therein will be added to the play.
If roles/x/meta/main.yml exists, any role dependencies listed therein will be added to the list of roles
Any copy, script, template or include tasks (in the role) can reference files in roles/x/{files,templates,tasks}/ (dir depends on task) without having to path them relatively or absolutely.

Generate VMs based on Ansible Inventory prior to playbook run

So I'm looking at creating a generic wrapper around the ansible-playbook command.
What I'd like to do is spin up a number of VMs (Vagrant or docker), based on the inventory supplied.
I'd use these VMs locally for automated testing using molecule, as well as manual function testing.
Crucially the number of machines in the inventory could change, so these need created prior to the run.
Any thoughts?
Cheers,
Stuart
You could use a tool like Terraform to run your docker images, and then export the inventory from Terraform to Ansible using something like terraform-inventory.
I think there's also an Ansible provisioner for Terraform.

Resources