42

I have my directory structure as this

.
├── README.md
├── play.yml
└── roles
    ├── bootstrap_server
    │   └── tasks
    │       └── main.yml
    ├── create_new_user
    │   └── tasks
    │       └── main.yml
    ├── update
    │   └── tasks
    │       └── main.yml
    └── vimserver
        ├── files
        │   └── vimrc_server
        └── tasks
            └── main.yml

When I create a user under the role create_new_user, I was hardcoding the username as

---
- name: Creating a user named username on the specified web server.
  user: 
    name: username
    state: present
    shell: /bin/bash
    groups: admin
    generate_ssh_key: yes
    ssh_key_bits: 2048
    ssh_key_file: .ssh/id_rsa
    
- name: Copy .ssh/id_rsa from host box to the remote box for user username
  become: true
  copy: 
    src: ~/.ssh/id_rsa.pub
    dest: /home/usernmame/.ssh/authorized_keys
    mode: 0600
    owner: username
    group: username

One way of solving this may be to create a var/main.yml and put the username there. But I wanted something through which I can specify the username at play.yml level. As I am also using the username in the role vimrcserver.

I am calling the roles using play.yml

---
- hosts: testdroplets
  roles:
    - update
    - bootstrap_server
    - create_new_user
    - vimserver

Would a template work here in this case?
Couldn't find much from those other question:

β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
Tasdik Rahman
  • 2,160
  • 1
  • 25
  • 37

6 Answers6

57

I got it working by using this playbook:

---
- hosts: testdroplets
  roles:
    - update
    - bootstrap_server
    - role: create_new_user
      username: username
    - role: vimserver
      username: username

Docs: http://docs.ansible.com/ansible/playbooks_roles.html#roles


Here is another option, with a directory structure like

.
├── README.md
├── ansible.cfg
├── play.yml
└── roles
    ├── bootstrap_server
    │   └── tasks
    │       └── main.yml
    ├── create_new_user
    │   ├── defaults
    │   │   └── main.yml
    │   └── tasks
    │       └── main.yml
    ├── update
    │   └── tasks
    │       └── main.yml
    └── vimserver
        ├── defaults
        │   └── main.yml
        ├── files
        │   └── vimrc_server
        └── tasks
            └── main.yml

Where I am creating a defaults/main.yml file inside the roles where I need the usage of {{username}}

If someone is interested in the code: https://github.com/tasdikrahman/ansible-bootstrap-server

β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
Tasdik Rahman
  • 2,160
  • 1
  • 25
  • 37
15

You should be able to put username in a vars entry in play.yml.

Variables can also be split out into separate files.

Here is an example which shows both options:

- hosts: all
  vars:
    favcolor: blue
  vars_files:
    - /vars/external_vars.yml

  tasks:

  - name: this is just a placeholder
    command: /bin/echo foo

https://docs.ansible.com/ansible/playbooks_variables.html#variable-file-separation

Ansible seems to delight in having different ways to do the same thing, without having either a nice comprehensive reference, or a rationale discussing the full implications of each different approach :). If you didn't remember the above was possible (I'd completely forgotten vars_files), the easiest option to find from the documentation might have been a third way, which is the most sophisticated one.

There's a prominent recommendation for ansible-examples. You can see a group_vars directory, with files which automatically provide values for hosts according to their groups, including the magic all group. The group_vars directory can be placed in the same directory as the playbook.

https://github.com/ansible/ansible-examples/tree/master/lamp_simple

sourcejedi
  • 3,051
  • 2
  • 24
  • 42
14

Maybe this is what you want?

---
- hosts: testdroplets
  roles:
    - update
    - bootstrap_server
    - { role: create_new_user, username: 'foobar' }
    - vimserver

https://docs.ansible.com/ansible/2.5/user_guide/playbooks_reuse_roles.html#using-roles

Richard Urban
  • 339
  • 3
  • 7
8

If you use include_role, variables can be passed like below.

- hosts: all_hosts
  tasks:
    - include_role:
        name: "path/to/role"
      vars:
        var1: "var2_value"
        var2: "var2_value"
    
Lahiru Chandima
  • 22,324
  • 22
  • 103
  • 179
  • Best answer. It is the option which gives you full control and more flexibility. – Richard Gomes Sep 28 '21 at 19:42
  • Pay attention: `default(omit)` doesn't work as expected when used inside the vars block. It will not skip that single line, instead it passes the omit placeholder string down to the imported role. To workaround this you can set role variables with `set_facts` before including the role. – Florin Hillebrand Oct 23 '21 at 06:33
  • Returns `did not find expected '-' indicator` message, pointing a the `vars:` operator. – Gergely Lukacsy Jul 10 '23 at 15:03
5

Can't you just pass the variable from the command line with the -e parameter? So you can specifiy the variable even before execution. This also results in the strongest variable declaration which always takes precendence (see Variable precendence).

If you want to place it inside your playbook I suggest defining the username with the set_fact directive in the playbook. This variable is then available in all roles and included playbooks as well. Something like:

---
- hosts: testdroplets
  pre_tasks:
    - set_fact:
        username: my_username
  roles:
    - update
    - bootstrap_server
    - create_new_user
    - vimserver
David Oliver
  • 2,424
  • 1
  • 24
  • 37
L. Tischler
  • 344
  • 1
  • 5
-3

It is all here: http://docs.ansible.com/ansible/playbooks_variables.html

while there are already some good answers, but I wanted to add mine because I've done this exact thing.

Here is the role I wrote: https://github.com/jmalacho/ansible-examples/tree/master/roles/users

And, I use hash_merge=true, and ansible's group_vars to make a dictionary of users: keys,groups so that adding a new user by host or by environment, and re-running is easy.

I also wrote up how my team uses group variables for environments once like this: "https://www.coveros.com/ansible-environment-design/"

Jon Malachowski
  • 256
  • 1
  • 7
  • 9
    Maybe you can include an example of passing variables to roles in your post itself? – mdornfe1 Jul 05 '17 at 15:47
  • The link above is no longer valid. It's been moved to here: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html – Kreempuff Mar 02 '21 at 14:13