New ansible user
Here is my playbook.
---
- name: Creating Local User Account on RHEL Systems.
hosts: hapansible05
become: true
vars:
passwd: WSXcde1234
tasks:
- name: Creating Local User
user:
name: svc_cldscp
password: "{{ passwd | password_hash('sha512') }}"
comment: svc_cldscp-ServiceAcct
shell: /bin/bash
Keep getting this message on RHEL server
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
PLAY [Creating Local User Account on RHEL Systems.] ********************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************
ok: [hapansible05]
TASK [Creating Local User] ***********************************************************************************************************************************
****fatal: [hapansible05]: FAILED! => {"changed": false, "msg": "usermod: user 'svc_cldscp' does not exist in /etc/passwd\n", "name": "svc_cldscp", "rc": 6}******
PLAY RECAP *************************************************************************************************************************************************
hapansible05 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
A working practice example for creating and configuring local users via user module with a filter for Hashing and encrypting strings and passwords is
---
- name: Create local user account on RHEL System
hosts: rhel.example.com
become: true
vars:
pwd: "WSXcde1234"
tasks:
- name: Create and configure user in local system
user:
name: "svc_cldscp"
password: "{{ pwd | password_hash('sha512') }}"
system: false # Defaults to no
createhome: true # Defaults to yes
uid: '1234' #
group: '1234' # Need to exist before
shell: /bin/bash # Defaults to /bin/bash
comment: "Service Account"
state: present
Related
This is my code:
---
- hosts: localhost
gather_facts: no
vars_prompt:
- name: server
prompt: "What is the hostname/ip you want to execute at?"
private: no
tasks:
- add_host:
name: "{{ server }}"
groups: dynamic_hosts
with_items: "{{ server.split(',') }}"
#### Dynamic Host
- hosts: dynamic_hosts
gather_facts: no
tasks:
- name: "Running task id"
command: id
and this is the behaviour:
What is the hostname you want to execute at?: 10.0.0.2, 10.0.0.3
PLAY [localhost] *******************************************************************************************************************************************************************************************************************
TASK [add_host] ********************************************************************************************************************************************************************************************************************
changed: [localhost] => (item= 10.0.0.2)
changed: [localhost] => (item= 10.0.0.3)
PLAY [dynamic_hosts] ***************************************************************************************************************************************************************************************************************
TASK [Running task id] ********************************************************************************************************************************************
fatal: [10.0.0.2, 10.0.0.3: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname 10.0.0.2, 10.0.0.3: Name or service not known\r\n", "unreachable": true}
to retry, use: --limit #/home/user/playbook.yaml
PLAY RECAP *************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=1 unreachable=0 failed=0
10.0.0.2, 10.0.0.3 : ok=0 changed=0 unreachable=1 failed=0
So the input of multiple hosts is working properly but when I try to call the group in hosts basically it tries to "ssh 10.0.0.2, 10.0.0.3" and naturally it fails.
What am I missing here?
What I want to do is prompt the user for the hosts he wants to execute at, input
and then just execute the tasks to each host. I do not want to make use of an inventory file.
Is it possible? Thank you in advance
Working code:
---
- hosts: localhost
gather_facts: no
vars_prompt:
- name: server
prompt: "What is the hostname/ip you want to execute at?"
private: no
tasks:
- add_host:
name: "{{ item }}"
groups: dynamic_hosts
with_items: "{{ server.split(',') }}"
#### Dynamic Host
- hosts: dynamic_hosts
gather_facts: no
tasks:
- name: "Running task id"
command: id
thank you
I am trying to create new users and groups using Ansible playbook. Below is my folder structure.
tree
.
├── create-users.yaml
└── ubuntu
create-users.yaml playbook contains create user and group tasks. Note, I am not having any group (admin_group) and users (Rajini, Kamal) in my target machine, instead they will be created when running the playbook.
---
- name: Create Users & Groups
hosts: target1
gather_facts: false
tasks:
- name: Create Users Task
user:
name: "{{ item }}"
state: present
password: "{{ 'default_user_password' | password_hash('sha512','A512') }}"
shell: /bin/bash
groups: "{{ admin_group }}"
loop:
- Rajini
- Kamal
I have another file called ubuntu to pick group name and password. When running the playbook I am getting below error.
ansible-playbook --vault-id #prompt create-users.yaml -K
BECOME password:
Vault password (default):
PLAY [Create Users & Groups] *****************************************************************************************************************************************************************
TASK [Create Users Task] *********************************************************************************************************************************************************************
fatal: [target1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'admin_group' is undefined\n\nThe error appears to be in '/home/osboxes/Ansible_Project/web_deployment/Ansible/groups_vars/create-users.yaml': line 6, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: Create Users Task\n ^ here\n"}
PLAY RECAP ***********************************************************************************************************************************************************************************
target1 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
admin_group: admin
default_user_password: Password1
Can somebody please help me on this?
Updating Output after getting help from user Moon.
ansible-playbook --vault-id #prompt create-users.yaml -K
BECOME password:
Vault password (default):
PLAY [Create Users & Groups] *****************************************************************************************************************************************************************
TASK [Create Users Task] *********************************************************************************************************************************************************************
changed: [target1] => (item=Rajini)
changed: [target1] => (item=Kamal)
PLAY RECAP ***********************************************************************************************************************************************************************************
target1 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ssh Kamal#192.168.0.1
Kamal#192.168.0.1's password:
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 5.0.0-23-generic x86_64)
Kamal#Ansible_Target1:~$ id
uid=1005(Kamal) gid=1001(admin) groups=1001(admin)
Couple of things:
To use variables from ubuntu file you need specify the vars file in playbook.
To use default_user_password as a variable, remove the quotes '
If you want admin as the users primary group then use group attribute instead. groups on the other hand takes a list and add the users to the listed groups.
And, if the group isn't created yet on the target machine then first create the group using group module.
Playbook after the above changes.
---
- name: Create Users & Groups
hosts: target1
gather_facts: false
vars_files: ubuntu
tasks:
- name: Create group
group:
name: "{{ admin_group }}"
state: present
- name: Create Users Task
user:
name: "{{ item }}"
state: present
password: "{{ default_user_password | password_hash('sha512','A512') }}"
shell: /bin/bash
group: "{{ admin_group }}"
loop:
- Rajini
- Kamal
This will help you make your playbook more dynamic:
create a secret.yml file for storing user password using below command:
ansible-vault create secret.yml
#sample:
user_password: mypass#155
create userlist.yml to specify the list of user and their department:
vim userlist.yml
#sample:
##user matching job role mentioned in create-user.yml playbook will be created
- users:
- name: "user1"
job: "developer"
- name: "user2"
job: "devops"
- name: "user3"
job: "developer"
Now create your playbook as follows:
vim user-create.yml
- hosts: appserver1
vars_files:
- secret.yml
- userlist.yml
tasks:
- name: "create group"
group:
name: "{{ item }}"
loop:
- "dev"
- "devops"
- name: "create user when Job=developer from userlist.yml file with password from secret.yml file and add to secondary group 'dev' "
user:
name: "{{ item['name'] }}"
password: "{{ user_password | password_hash('sha512') }}"
update_password: on_create
groups: "dev"
append: yes
loop: "{{ users }}"
when: "item['job'] == 'developer'"
- name: "create user when Job=devops from userlist.yml file with password from secret.yml file and add to secondary group 'devops' "
user:
name: "{{ item['name'] }}"
password: "{{ user_password | password_hash('sha512') }}"
update_password: on_create
groups: "devops"
append: yes
loop: "{{ users }}"
when: "item['job'] == 'devops'"
Run the playbook
ansible-playbook -i inventory user-create.yml --ask-vault-pass
Things to remember
If you do not specify the update_password: on_create option, Ansible re-sets the user password every time the playbook is run: if the user has changed the password since the last time the playbook was run, Ansible re-sets password.
There are several computers on the network, on each of them you need to create a user with a specific login and password.
I create users like this:
vars_prompt:
- name: "user_name"
prompt: "User name"
private: no
- name: "user_password"
prompt: "Enter a password for the user"
private: yes
encrypt: "md5_crypt"
confirm: yes
salt_size: 7
tasks:
- name: "add new user"
user:
name: "{{user_name}}"
password: "{{user_password}}"
shell: /bin/bash
Since there are many computers I don’t want to run a playbook a huge number of times. Ideally, I would like to implement the input of the list of hosts (computers) and the list of users. Password, in principle, you can do the same everywhere.
Loop the task
tasks:
- name: "add new user"
user:
name: "{{ item.user_name }}"
password: "{{ item.user_password }}"
shell: /bin/bash
loop: "{{ my_users }}"
and put the variable(s) my_users to host_vars
my_users:
- user_name: user1
user_password: password1
- user_name: user2
user_password: password2
Put common users to group_vars.
See Variable precedence: Where should I put a variable?
Use Ansible Vault to encrypt the passwords.
Here is an example of what you can try. Adapt to your needs.
Note: if the list of users is different for each host, just execute the playbook several times. Implementing this as a promptable play in ansible will just be a total pain and merely unusable.
In the example below, test1 and test2 are pointing to 2 docker containers I added in my demo_inventory.yml.
all:
hosts:
test1:
ansible_connection: docker
test2:
ansible_connection: docker
The hosts you enter will need to be correctly known by ansible for this to work.
This is the demo playbook test.yml
---
- name: Gather needed information
hosts: localhost
vars_prompt:
- name: hosts_entry
prompt: Enter comma separated list of hosts to target
private: false
- name: users_entry
prompt: Enter comma separated list of users to create
private: false
- name: user_password
prompt: Enter initial password applied to all users
encrypt: md5_crypt
confirm: true
salt_size: 7
tasks:
- name: Create a dynamic whatever_group with entered hosts
add_host:
name: "{{ item | trim }}"
groups:
- whatever_group
loop: "{{ hosts_entry.split(',') }}"
- name: Create a list of host for later reuse. Will be scoped to localhost
set_fact:
users_list: "{{ users_entry.split(',') }}"
- name: Store password for later reuse as vars_prompt are limited to play
set_fact:
user_password: "{{ user_password }}"
- name: Do the actual work
hosts: whatever_group
tasks:
- name: Make sure users are present
user:
name: "{{ item | trim }}"
password: "{{ hostvars['localhost'].user_password }}"
shell: /bin/bash
loop: "{{ hostvars['localhost'].users_list }}"
I created a play on localhost to gather the info from vars_prompt. In this play, I used add_host to create a whatever_group dynamically. Note the use of split to create list from a string with comma seperated elements in the input and of trim to remove the leading/trailing spaces (if user entered them). Since vars_prompt are limited in scope to the current play, I also used set_fact to get the users list and the password for future use.
On the next play, I target the whatever_group and run the user task. Note that since set_fact used previously scoped the variables to localhost, we have to use the hostvars magic variable to get the relevant information for the user loop and the password.
Here is the example run
$ ansible-playbook -i demo_inventory.yml test.yml
Enter comma separated list of hosts to target: test1, test2
Enter comma separated list of users to create: user1, user2, user3
Enter initial password applied to all users:
confirm Enter initial password applied to all users:
PLAY [Gather needed information] ***************************************************************
TASK [Gathering Facts] *************************************************************************
ok: [localhost]
TASK [Create a dynamic whatever_group with entered hosts] **************************************
changed: [localhost] => (item=test1)
changed: [localhost] => (item= test2)
TASK [Create a list of host for later reuse. Will be scoped to localhost] **********************
ok: [localhost]
TASK [Store password for later reuse as vars_prompt are limited to play] ***********************
ok: [localhost]
PLAY [Do the actual work] **********************************************************************
TASK [Gathering Facts] *************************************************************************
ok: [test1]
ok: [test2]
TASK [Make sure users are present] *************************************************************
changed: [test2] => (item=user1)
changed: [test1] => (item=user1)
changed: [test2] => (item= user2)
changed: [test1] => (item= user2)
changed: [test2] => (item= user3)
changed: [test1] => (item= user3)
PLAY RECAP *************************************************************************************
localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
I've got a simple ansible playbook that works fine on most ios devices. It fails on some of my 3850 switches with what looks like a timeout when doing a "show conf". How do I specify a longer, non-default timeout for command completion with the ios_command module (and presumably also ios_config)?
Useful details:
Playbook:
---
- hosts: ios_devices
gather_facts: no
connection: local
tasks:
- name: OBTAIN LOGIN CREDENTIALS
include_vars: secrets.yaml
- name: DEFINE PROVIDER
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: "{{ creds['username'] }}"
password: "{{ creds['password'] }}"
- name: LIST NAME SERVERS
ios_command:
provider: "{{ provider }}"
commands: "show run | inc name-server"
register: dns_servers
- debug: var=dns_servers.stdout_lines
successful run:
$ ansible-playbook listnameserver.yaml -i inventory/onehost
PLAY [ios_devices] *****************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] ****************************************************************************************************
ok: [iosdevice1.example.com]
TASK [DEFINE PROVIDER] *************************************************************************************************************
ok: [iosdevice1.example.com]
TASK [LIST NAME SERVERS] ***********************************************************************************************************
ok: [iosdevice1.example.com]
TASK [debug] ***********************************************************************************************************************
ok: [iosdevice1.example.com] => {
"dns_servers.stdout_lines": [
[
"ip name-server 10.1.1.166",
"ip name-server 10.1.1.168"
]
]
}
PLAY RECAP *************************************************************************************************************************
iosdevice1.example.com : ok=4 changed=0 unreachable=0 failed=0
unsuccessful run:
$ ansible-playbook listnameserver.yaml -i inventory/onehost
PLAY [ios_devices] *****************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] ****************************************************************************************************
ok: [iosdevice2.example.com]
TASK [DEFINE PROVIDER] *************************************************************************************************************
ok: [iosdevice2.example.com]
TASK [LIST NAME SERVERS] ***********************************************************************************************************
fatal: [iosdevice2.example.com]: FAILED! => {"changed": false, "msg": "timeout trying to send command: show run | inc name-server", "rc": 1}
to retry, use: --limit #/home/sample/ansible-playbooks/listnameserver.retry
PLAY RECAP *************************************************************************************************************************
iosdevice2.example.com : ok=2 changed=0 unreachable=0 failed=1
The default timeout is 10 seconds if the request takes longer than this ios_command will fail.
You can add the timeout as a key in the provider variable, like this:
- name: DEFINE PROVIDER
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: "{{ creds['username'] }}"
password: "{{ creds['password'] }}"
timeout: 30
If you've already got a timeout value in provider here's a handy way to update only that key in the variable.
- name: Update existing provider timeout key
set_fact:
provider: "{{ provider | combine( {'timeout': '180'} ) }}"
I have the following playbook example.yml:
- hosts: all
remote_user: administrator
become: yes
tasks:
- name: Put resolv.conf
template:
src: /home/user/resolv.conf.j2
dest: /etc/resolv.conf
backup: yes
mode: 0644
when: variable_name == "string"
The purpose is to update the resolv.conf by a customized one.
For executing it I am running:
ansible-playbook example.yml -k -u administrator --become --ask-become-pass --limit server_name -e variable_name='string'
However I get the following error:
SSH password:
SUDO password[defaults to SSH password]:
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [server_name]
TASK [Put resolv.conf] *******************************************************
fatal: [server_name]: FAILED! => {"changed": true, "failed": true, "msg": "unsupported parameter for module: when"}
to retry, use: --limit #/home/user/playbooks/example.retry
PLAY RECAP *********************************************************************
server_name : ok=1 changed=0 unreachable=0 failed=1
I have tried with different syntax by applying "()" to the variable, change between double and single commas, etc. But always the same error.
If I don't use both, variable and when condition, the task is succesfully completed.
Where is the problem?
Mind the padding!
- hosts: all
remote_user: administrator
become: yes
tasks:
- name: Put resolv.conf
template:
src: /home/user/resolv.conf.j2
dest: /etc/resolv.conf
backup: yes
mode: 0644
when: variable_name == "string"
when is a task property, not template's parameter.