Load ansible.cfg in each playbook dir - ansible

I'm looking for a solution to load local ansible.cfg at root playbook_dir.
This is my architeture folder of playbooks:
ansible
├── deploy_manager
│ ├── ansible.cfg
│ ├── deploy_manager.yml
│ ├── environments
│ │ ├── demo
│ │ │ ├── group_vars
│ │ │ │ └── demo.yml
│ │ │ ├── inventory.yml
│ │ │ └── vars
│ │ │ └── vault.yml
│ │ ├── int
│ │ │ ├── group_vars
│ │ │ │ └── int.yml
│ │ │ ├── inventory.yml
│ │ │ └── vars
│ │ │ └── vault.yml
│ │ └── prod
│ │ ├── group_vars
│ │ │ └── prod.yml
│ │ ├── inventory.yml
│ │ └── vars
│ │ └── vault.yml
│ ├── README.md
│ └── roles
│ ├── create_instance
│ │ └── tasks
│ │ └── main.yml
When I execute the playbook with ansible-playbook cli, I have an ansible.cfg in current dir so ansible.cfg is loaded.
When I execute the playbook from AWX, the project is in tmp/cev039fj/awx_1900_tw78u5vh/project.
There is no ansible.cfg in /tmp/ cev039fj/awx_1900_tw78u5vh so it's the /etc/ansible/ansible.cfg which is loaded.
I have an ansible.cfg in each playbook directory with different params so how could I setup the ANSIBLE_CONFIG path to playbook dir ansible.cfg when a playbook is launched by AWX ?
I did some tests unsuccessful with ANSIBLE_CONFIG setup.
Have you any ideas ?
Thanks
EDIT:
I have open an issue to awx github https://github.com/ansible/awx/issues/10398
This is a limitation of AWX which loads ansible config to root project only because the playbook is executed at root of the project.
Usually, I execute playbook in current directory playbook that's why I have no problem with my specific ansible.cfg.
I made two proposals to resolve this problem, I will post the final point here when it will be finished

Okay, I know that ansible-runner won't respect your callback_plugins setting here. It tries to respect the user settings for callback plugins, and append its own to the end of the list.
https://github.com/ansible/ansible-runner/blob/4926a6afda13e768f55010f46509d2888e83e9a7/ansible_runner/config/_base.py#L242
But the issue is that you didn't set the env var ANSIBLE_CALLBACK_PLUGINS. You set the config file setting for the same thing. To combine with that, it would have to read the config file. It doesn't.
However, AWX does read the config file in cases, so that it doesn't clobber the user settings. This is the wrong place to do it. That needs to be moved into ansible-runner so that it can take responsibility for properly over-riding existing user settings. Or else, Ansible core needs to add some syntax to denote "existing values of a list-valued setting".
There is 1 other way we could fix this - we could put the ansible-runner callback plugin in a collection in an expected location. See ansible/ansible-runner#482. This avoids the need for ansible-runner to change the ANSIBLE_CALLBACK_PLUGINS setting at all and it just references the standard out callback plugin. However, it would still need to set the ANSIBLE_STDOUT_CALLBACK setting.
You are also setting the stdout callback setting. This doesn't make a lot of sense to me. There can only be 1 standard out callback plugin, because that's what dictates what gets written to standard out. I toyed with ideas for layering them, but they would step on each other's toes. Instead, I think you should consider doing your plugin as a "normal" callback plugin instead of a stdout callback plugin. If you do this, you can still enable it by changing the AWX_TASK_ENV setting without ansible-runner clobbering it. You can't do that with the config file - and that's our bug.

Related

Share common configuration items among hydra config groups

I have two sets of config groups, from which I need to select one config file each time.
the file structure looks like this:
conf
├── datasets
│ ├── A
│ │ ├── a1.yaml
│ │ └── a2.yaml
│ └── B
│ ├── b1.yaml
│ └── b2.yaml
└── config.yaml
I could choose dataset config with dataset=A/a1 or dataset=B/b1, etc.
Now suppose each config file in A or B has many items in common(that's why they are grouped in two subfolders).
The question is:
How could I specify these common items in A and B, without having to specify them in each config file under these folders?
The resulting file structure may look like this:
conf
├── datasets
│ ├── A
│ │ ├── a_common.yaml # common config items for a1 and a2
│ │ ├── a1.yaml
│ │ └── a2.yaml
│ └── B
│ ├── b_common.yaml # common config items for b1 and b2
│ ├── b1.yaml
│ └── b2.yaml
└── config.yaml
You can use a defaults list in the a1/a2/b1/b2 files:
# A/a1.yaml
defaults:
- a_common
... # a1 contents
References:
The tutorial on defaults lists
The reference page for defaults lists

Ansible not recognising variables not found under host_vars

Ι have the following inventory
[foo]
foosrv ansible_host=11.22.33.44
[bar]
barsrv ansible_host=44.11.22.33
[zoo]
zoosrv ansible_host=21.21.21.21
and the following file structure
.
├── ansible.cfg
├── files
│ └── aws.yaml
├── host_vars
│ ├── foosrv
│ │ ├── templates
│ │ │ └── repoConf.yaml.j2
│ │ └── vault
│ └── barsrv
│ ├── templates
│ │ └── repoConf.yaml.j2
│ └── vault
├── inventory
├── site.yaml
├── templates
│ ├── amend.py.j2
│ └── config.j2
└── vars
├── ansible_vars.yaml
└── vault
My problem is that any variables under ./vars/vault are not recognized by ansible.
Any hints about what might be the issue here?
Ansible doesn't automatically load variables from a vars directory.
You have several options for loading variables:
Ansible will load variables from a file (or directory) in host_vars matching the inventory hostname.
Ansible will load variables from a file (or directory) in group_vars matching the names of groups of which a host is a member.
You can use the include_vars task to explicitly load variables from a file.
If you want to load the variables for all hosts automatically, then place them in group_vars/all.yaml (or a subdirectory of group_vars/all).
Ansible will automatically detect (and decrypt, if you've provided a password) files that are vault encrypted.

Ansible group_vars referencing and loading another var file

Based on the following Ansible inventory directory tree:
inventories/region
├── staging
│ ├── group_vars
│ │ ├── all.yml
│ │
│ │── hosts.yml
│ └── site1
│ ├── group_vars
│ │ ├── all.yml
│ │
│ ├── hosts.yml
│
├── group_vars
│ └── all.yml
└── prod
├── group_vars
│ ├── all.yml
│── hosts.yml
├── site1
│ ├── group_vars
│ │ ├── all.yml
│── hosts.yml
└──site2
├── group_vars
│ ├── all.yml
│── hosts.yml
Is there a way for me to load vars from inventories/region/group_vars/all.yml and inventories/region/env/group_vars/all.yml inside inventories/region/env/siteX/group_vars/all.yml? I will be calling playbooks with the reference to the site-specific inventory files, such as inventories/region/prod/site2/group_vars/all.yml. I'm trying to avoid maintaining the same variables with the same values across multiple var files (group_vars/all.yml in this example) for each site and environment.
The value of the variables will change for different regions.
Thanks

Ansible ask for password to ansible vault from other group vars

I have problem with ansible.
I have couple of group_vars folders and in this folders there is files encrypted by ansible-vault with difference passwords between prod and test:
├── group_vars
│   ├── app1_prod
│   │   ├── application.yml <- Ancryptes by Ansible Vault prod pass
│   │   └── service.yml
│   ├── app1_test
│   │   ├── application.yml <- Ancryptes by Ansible Vault test pass
│   │   └── service.yml
│   ├── app2_prod
│   │   ├── application.yml <- Ancryptes by Ansible Vault prod pass
│   │   └── service.yml
│   └── app2_test
│   ├── application.yml <- Ancryptes by Ansible Vault test pass
│   └── service.yml
And my inventory file looks like:
[test_hosts]
test_host1
test_host2
[prod_hosts]
prod_host1
prod_host2
[app1_test:children]
test_hosts
[app2_test:children]
test_hosts
[app1_prod:children]
prod_hosts
[app2_prod:children]
prod_hosts
When I running playbook command:
ansible-playbook app1_playbook.yml -i ./inventory/hosts -l app1_test -u ssh_user -k --vault-password-file path_to_vault_key
I get error that saying the vault password is wrong for file and pointing for file in prod and from other group:
Decryption failed on ansible/group_vars/app1_prod/application.yml
I don't know how to fix this.
Personally, I think your inventory structure is a Bad Idea. I do not condone having PROD and TEST servers in the same inventory, and I see no good reason for it.
I would restructure your system like this:
├── prod
│ ├── ansible.cfg
│ ├── group_vars
│ │ ├── app1
│ │ │ ├── application.yml <- Ancryptes by Ansible Vault prod pass
│ │ │ └── service.yml
│ │ ├── app2
│ │ │ ├── application.yml <- Ancryptes by Ansible Vault prod pass
│ │ │ └── service.yml
├── test
│ ├── ansible.cfg
│ ├── group_vars
│ │ ├── app1
│ │ │ ├── application.yml <- Ancryptes by Ansible Vault prod pass
│ │ │ └── service.yml
│ │ ├── app2
│ │ │ ├── application.yml <- Ancryptes by Ansible Vault prod pass
│ │ │ └── service.yml
And, of course, there would be two host files:
PROD:
[hosts]
prod_host1
prod_host2
[app1:children]
hosts
[app2:children]
hosts
TEST:
[hosts]
test_host1
test_host2
[app1:children]
hosts
[app2:children]
hosts
Have an ansible.cfg file in each inventory directory with the lines:
inventory = .
vault_password_file = /path/to/vault_password_file
remote_user = ssh_user
ask_pass = True
(Best if you just copy /etc/ansible/ansible.cfg to the inventory directory and change what you need to change.)
Once you have that setup, you go into the prod or test directory, and execute the playbook from there. Of course, you will need to specify the path to the playbooks:
cd prod
ansible-playbook /path/to/playbooks/app_playbook.yml
cd test
ansible-playbook /path/to/playbooks/app_playbook.yml
Trust me, life is much easier with inventory separation.
Good luck!

Shell/terminal/bash command or script for copying list of files from one project to another

Let's say I have a project called my-project/ that lives in it's own directory and has the following file structure.
my-project/
.
├── src
│ ├── index.html
│ ├── main.js
│ ├── normalize.js
│ ├── routes
│ │ ├── index.js
│ │ └── Home
│ │ ├── index.js
│ │ └── assets
│ ├── static
│ ├── store
│ │ ├── createStore.js
│ │ └── reducers.js
│ └── styles
└── project.config.js
Now let's say I have a new project called my-new-project that also lives in it's own directory and has the same file structure as my-project but it contains an additional file called my-files-to-copy.txt
my-new-project/
.
├── src
│ ├── index.html
│ ├── main.js
│ ├── normalize.js
│ ├── routes
│ │ ├── index.js
│ │ └── Home
│ │ ├── index.js
│ │ └── assets
│ ├── static
│ ├── store
│ │ ├── createStore.js
│ │ └── reducers.js
│ └── styles
├── project.config.js
└── my-files-to-copy.txt # new file added to tree
my-new-project/ has the same file structure but different file contents than my-project/
Now let's say my-files-to-copy.txt contains a list of files I want to copy from my-project/ and write to the same path in my-new-project/ to overwrite the existing files in my-new-project/ at those locations.
my-files-to-copy.txt
src/main.js
src/routes/index.js
src/store/reducers.js
project.config.js
How can I accomplish this with a terminal/bash/shell command or script?
edit:
I think I might be able to do:
cp my-project/src/main.js my-new-project/src/main.js
cp my-project/src/routes/index.js my-new-project/src/routes/index.js
cp my-project/src/store/reducers.js my-new-project/src/store/reducers.js
cp my-project/project.config.js my-new-project/project.config.js
But as the number of files scales, this method will become less efficient. I was looking for a more efficient solution that would allow me to leverage the file that contains the list of files (or at least a script) without having to write a separate command for each one.
Assuming my-project and my-new-project are on the same directory:
xargs -i -a my-new-project/my-files-to-copy.txt cp my-project/{} my-new-project/{}

Resources