How to assign a value to variable dictionary from another dictionary variable - ansible

Hi I have a template in ansible yaml file:
env:
"{{ env }}"
this value is assigned when I executed:
ansible-playbook template.yaml --extra-vars vars.yaml
vars.yml has:
env:
CONSUL_HOST: 'x.x.x.x:8500'
SERVICE_NAME: 'backoffice-fe'
that works fine , now I want to add another variable in the template.yaml with the value of CONSUL_HOST
I tried without lucky:
env:
"{{ env }}"
NEW_VAR: env.CONSULT_HOST
I need to do this in template.yaml because it is used for a lot of modules , I don't want to modify all the modules because there are more than 100!
that is possible?
thanks in advance!

Related

Using gitlab-ci vars inside an ansible playbook

I want to set a remote environment inside a docker container using an Ansible playbook. This playbook will run from gitlab-ci with variables I set in in the Gitlab CI/CD confituration. How can I acheive that?
Here is the template I want to use. How do I set the user_id and password from the CI/CD variables?
tasks:
- name: Run XYZ Container
docker_container:
name: XYZ
restart_policy: on-failure
image: xxxxxxxxxxx
container_default_behavior: "compatibility"
env:
USER_ID= $USER_ID
PASSWORD= $PASSWORD
Since gitlab-ci variables are just environment variables inside your job, and since your ansible controller runs inside that job, you can use the env lookup to read them from the controller.
Please note that:
the docker_container module's env parameter expects a dict and not a new line separated string of bash like env vars definition like in your example.
as a security measure, you should either check that the vars are defined prior to using them (with an assert or fail task) or use a default value in case they're not. My example uses a default value. For more on providing default value, you can see the ansible documentation (and the original jinja2 documentation to understand that d is a an alias to default)
tasks:
- name: Run XYZ Container
docker_container:
name: XYZ
restart_policy: on-failure
image: xxxxxxxxxxx
container_default_behavior: "compatibility"
env:
USER_ID: "{{ lookup('env', 'USER_ID') | d('defaultuser', true) }}"
PASSWORD: "{{ lookup('env', 'PASSWORD') | d('defaultpass', true) }}"
i wanted to use the CI_JOB_TOKEN so i used:
tasks:
- include_role: role_name
vars:
ci_job_token: "{{ lookup('env', 'CI_JOB_TOKEN') }}"

Conditionals with custom variables

In my playbook i have tasks that use the hostname of a server and extrapolate data to set location and environment based on that. But some servers have unique names and I'm not sure how to set variables on those. I'd prefer not to use ansible facts since i would like to share the playbook with a team. One way I was thinking is to do what's listed below but i'm running into issues. Could someone please guide me.
Create vars_file inventory
---
customservers
customhostname1:
env: test
location: hawaii
customhostname2:
env: prod
location: alaska
In Playbook.
---
task
tasks:
- name: set hostname
shell: echo "customhostname1"
register: my_hostname
- name: setting env var
set_fact:
env: "{{ item.value.env }}"
when: my_hostname == "{{ item.key }}"
with_dict: "{{ customservers }}"
- name: outputing env var
debug:
msg: the output is {{ env }}
Expected output should be test.
Thank you.
In my playbook i have tasks that use the hostname of a server and
extrapolate data to set location and environment based on that.
Bad Idea.
But some servers have unique names and I'm not sure how to set variables on those
And that is why.
The second Bad Idea is to have TEST and PROD in the same inventory. That's just begging for a disaster. They should be two completely separate inventories, though perhaps under the same parent directory:
inventories/
inventories/test/
inventories/test/hosts
inventories/test/host_vars/
inventories/test/host_vars/customhostname1.yml
inventories/prod/
inventories/prod/hosts
inventories/prod/host_vars/
inventories/prod/host_vars/customhostname2.yml
So inventories/prod/hosts could look like this (I prefer the ini format):
[customservers]
customhostname2 location=hawaii
Or:
[customservers]
customhostname2
[customhostname2:vars]
location=hawaii
But in any case, DO NOT combine test and prod inventories.
If you still need that env variable, you can either put it in group_vars/all.yml or right in the hosts file like so:
[all:vars]
env=prod

How can I use a wildcard to include multiple files for using environment variables in Ansible?

I am trying to do a custom install of openedx and I have a bunch of .yml files with environment variables in them inside paths that looks like this
playbooks/roles/<component-name>/defaults/main.yml
Then, while running a playbook that installs all such components, I'm using a command like this
ansible-playbook ./openedx_native.yml -e"#roles/<component-name-1>/defaults/main.yml" -e"#roles/<component-name-2>/defaults/main.yml"
Now I want to be able to use the main.yml files from all components and there are about 20-25 of them, so I'm looking for a way to include them using a wildcard, something like this
ansible-playbook ./openedx_native.yml -e"#roles/*/defaults/main.yml"
This, of course, doesn't work and Ansible throws an error like this
ERROR! the file_name
'/var/tmp/configuration/playbooks/roles/*/defaults/main.yml' does not
exist, or is not readable
How do I achieve this? Please help!
An option would be to find the files and include_vars.
tasks:
- command: "sh -c 'find {{ playbook_dir }}/roles/*/defaults/main.yml'"
register: result
- include_vars:
file: "{{ item }}"
loop: "{{ result.stdout_lines }}"
If you have flexibility to change & re-arrange environment variables and its values in /group/all.yaml like environments:
- { name: ‘development’, profile: 'small' }
- { name: ‘staging’, profile: ‘medium’ }
- { name: ‘production’, profile: ‘complex’ }
And then you can use this variable for any task say for example you want to create folder with environment name
- name: create folders for Environment
file:
path: "{{ target }}/{{ item.name }}"
state: directory
mode: 0755
with_items: "{{ environments }}"

Dynamically building variable names in Ansible

I have a playbook that will iterate over a set of hosts in different environments, "dev", and "prod". The environment that a host is in will change the other variables that it has. For example, this is in my vars/main.yml file:
---
folder_list_DEV: ["folder-1", "folder-2", "folder-3"]
folder_list_PROD: ["folder-1", "folder-2"]
The intention in my example is to create a series of folders on the target system, depending on which environment it is in. The code that I would like to work, but does not, looks like this:
- name: Create folders
file:
path: "/{{ item }}"
state: present
with_items: "{{ folder_list_env }}
"env" is set on execution of the playbook (-e "env=DEV").
How can I reference this "folder_list_*" variable based on value of the "env" variable?
"{{ vars['folder_list_' + env] }}"

ansible playbook role variable

fairly new to ansible.
having following role e.g.: my-role - i have trouble overriding the default variables from the playbook
follwing files:
my-role/tasks/main.yml
my-role/defaults/main.yml
sample-playbook.yml
my-role/tasks/main.yml
- name: "Add Test User"
user: name={{ my_config_test_user }} comment="{{ my_config_test_user }}" group={{ my_config_test_user }}
my-role/defaults/main.yml
my_config_test_user: "test"
playbook:
- name: TestCase
hosts: all
remote_user: root
vars:
my_config_test_user: "override"
roles:
- my-role
in the task the value of my_config_test_user stays test instead of my expected result override
any hints?
regards
In the current version of Ansible order of precedence says that the value of my_config_test_user should be override not test so I think you probably have a typo somewhere. Maybe the variable is not spelled correctly?
I suggest removing defaults/main.yml temporarily to ensure that you do not get an undefined variable error. I would also suggest using the debug module to check the value of the variable in your tasks/main.yml
- debug: var={{ my_config_test_user }}
For reference here is the order of precedence (starting with the greatest) in the current version of Ansible:
Vars set on the command line -e foo=set_on_cmd_line
Vars set in the vars_files: block in the play
Vars set in the vars: block in the play
Vars set in host_vars/
Vars set in group_vars/
Role default vars roles/.../defaults/main.yml

Resources