In a playbook, I am using a role this way:
- { role: project, project_name: "{{project_name}}" }
And in the "project" role, I actually have a dependency that wants to use the project_name variable of the "project" role:
---
dependencies:
- {
role: users,
users: [
{
name: "{{project_name}}",
home: "/home/{{project_name}}",
shell: "/bin/bash",
group: "{{project_name}}",
}
]
}
But I get an error:
recursive loop detected in template string: {{project_name}}
Is changing the name of the "project_name" variable the only solution?
Thanks
External variables are inherited into roles automatically, so project_name: "{{ project_name }}" isn't necessary. Change your role declaration to:
- project
... and the {{ project_name }} variable will be available within your role as-is.
Related
I am new to ansible.
I have 2 variable files one is global and another is environment specific.
Here is the global one in global/group_var/all.yaml folder:
rel:
deployment:
webui:
dockerName: "rel"
dockerTag: "Dev_{{ travis.build_number }}"
And the specific one is in develop/group_var/all.yaml folder
docker:
registery: "xxxx"
is there any way I can import global/group_var/all.yaml to develop/group_var/all.yaml
import global/group_var/all.yaml
docker:
registery: "xxxx"
so develop/group_var/all.yaml becomes:
rel:
deployment:
webui:
dockerName: "rel"
docker:
registery: "xxxx"
dockerTag: "Dev_1111"
Thanks
It's possible to read the global variables into a dictionary. For example
$ cat develop/group_var/all.yaml
global: "{{ lookup('file', 'global/group_var/all.yaml')|from_yaml }}"
docker:
registery: "xxxx"
the playbook
- hosts: localhost
tasks:
- include_vars: develop/group_var/all.yaml
- debug:
var: global
- debug:
var: docker
gives
"global": {
"rel": {
"deployment": {
"webui": {
"dockerName": "rel"
}
}
}
}
"docker": {
"registery": "xxxx"
}
Let's say I have a single playbook with some roles for the installation of an appserver and I like to apply the same playbook on both production and testing servers.
Both production and testing servers have the same list of roles, with the exception of one, that only should be applied on production servers.
Is it possible to specify somehow that this role will only be applied to production servers using the same playbook?
For example, if the playbook is:
---
- hosts: appserver
roles:
- { role: mail, tags: ["mail"] }
- { role: firewall, tags: ["firewall"] }
- { role: webserver, tags: ["webserver"] }
- { role: cache, tags: ["cache"] }
and I have two inventories: one for production and one for testing.
When I run the playbook using the testing inventory, I don't want the role 'firewall' to be executed.
My idea is do something like setting a variable in the 'production' inventory and use something like 'if <var> is set, then execute role 'firewall'' ... I don't know if this is possible, and if it is, how to do it?
You can define a variable, for example production_environment, in your inventory files, assign true or false value and use a when conditional in the playbook:
---
- hosts: appserver
roles:
- { role: mail, tags: ["mail"] }
- { role: firewall, tags: ["firewall"], when: production_environment }
- { role: webserver, tags: ["webserver"] }
- { role: cache, tags: ["cache"] }
Or you can access inventory_file variable directly. For example if you use -i production:
---
- hosts: appserver
roles:
- { role: mail, tags: ["mail"] }
- { role: firewall, tags: ["firewall"], when: inventory_file == "production" }
- { role: webserver, tags: ["webserver"] }
- { role: cache, tags: ["cache"] }
Which way you go is an administrative decision. The second method uses less steps, but requires the inventory file name to be "hardcoded" in the playbook.
Why don't you just use inventory groups?
Make two inventories:
testing:
[application]
my-dev-server
production:
[application]
company-prod-server
[firewall]
company-prod-server
And change your playbook as follows:
---
- hosts: firewall
roles:
- { role: firewall, tags: ["firewall"] }
- hosts: application
roles:
- { role: mail, tags: ["mail"] }
- { role: webserver, tags: ["webserver"] }
- { role: cache, tags: ["cache"] }
- { role: firewall, tags: ["firewall"], when: MyVar }
See Applying ‘when’ to roles and includes.
I have a playbook like that, with one role per client.
- hosts: hosting
roles:
- { role: client1, tags: ['client1'] }
- { role: client2, tags: ['client2'] }
And on each role, I have a dependency on nginx for example.
/roles/client1/meta/main.yml
dependencies:
- nginx
I would like to not launch the nginx role when it is not necessary. So I have added the nginx tag to the dependency.
/roles/client1/meta/main.yml
dependencies:
- { role: nginx, tags: ['system'] }
But when I launch the playbook with the tag client1, the nginx role is executed.
Is there a solution to avoid that ?
I know a can "export" the dependency on the playbook, it works good, but it's not a nice solution I think.
- hosts: hosting
roles:
- { role: nginx, tags: ['system'] }
- { role: client1, tags: ['client1'] }
- { role: client2, tags: ['client2'] }
Tags do not override each other but are cummulative. Your dependency now has the tags client1 and system.
But that already is enough. Just tell Ansible to skip the system tag when calling your playbook:
ansible-playbook ... --tags client1 --skip-tags system
top_level_main.yml
roles:
- { role: deploy_nds }
roles/deploy_nds/vars/main.yml
artifact_url: urlsomething
roles/deploy_nds/meta/main.yml
dependencies:
- {role: download_artifact, url: artifact_url }
roles/download_artifactory/tasks/main.yml
- name: download artifact from jfrog
get_url:
url: "{{ url }}"
dest: /var/tmp
I tried using variable name as "{{ artifact_url }}" but still it does not work as expect. Can someone please help?
I have explicitly included vars file of perticular role in playbook then it worked.
vars_files:
- roles/deploy_nds/vars/main.yml
roles:
- { role: deploy_nds }
My playbook runs a list of roles:
roles:
- common
- postgres
- nginx
- supervisord
- { role: deploy_app, app_name: myapp }
- { role: deploy_app, app_name: otherapp }
I have another role, celery, that I only want to run when the app named myapp is created using deploy_app. I was thinking I should pass a parameter into the role like this:
- { role: deploy_app, app_name: myapp, celery: yes }
Then within my deploy_app role, I would use a when conditional:
- name: create celery worker for application
<RUN ROLE HERE>
when: '{{ celery }}' == 'yes'
How can I conditionally run a role from within a task list?
I think ansible depenencies would help here. Just create a
/meta/main.yml inside your role with the following:
---
dependencies:
- { role: celery, tags: ["sometag"], when: "celery == 'yes'" }
I would suggest to not call from within a playbook and either use a condition in your entry books
- { role: celery, tags: ["sometag"], when: "celery == 'yes'" }
or simply convert it into a group of tasks in a file and do a conditional import
Hope that helps.