I need to add a host from the user's input. Now I'm trying to use the ansible in-memory inventory
, add_host
module and prompt
to add the target host to execute the remaining tasks. This is the content of my playbook:
Deploy.yml
- name: Adding the host server hosts: localhost - vars_prompt: - name: "Server IP" prompt: "Server" private: no - name: "Username (default: Ubuntu)" prompt: "User" default: "Ubuntu" private: no - name: "Password" prompt: "Passwd" private: yes encrypt: "sha512_crypt" - name: "Identity file path" prompt: "IdFile" private: no when: Passwd is undefined tasks: - name: Add host server add_host: name: "{{ Server }}" ansible_ssh_user: "{{ User }}" ansible_ssh_private_key_file: "{{ IdFile }}" when: IdFile is defined - name: Add host server add_host: name: "{{ Server }}" ansible_ssh_user: "{{ User }}" ansible_ssh_pass: "{{ Passwd }}" when: Passwd is defined - hosts: "{{ Server }}" tasks: - name: Copy the script file to the server copy: src: script.sh dest: "{{ ansible_env.HOME }}/folder/" mode: 755 force: yes attr: - +x
When I run this playbook with this command $ ansible-playbook Deploy.yml
, The output is:
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Adding the host server] ***********************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************
ok: [localhost]
Server: <server-ip>
User [Ubuntu]:
Passwd:
IdFile: <path/to/id/file>
ERROR! the field 'hosts' is required but was not set
I don't know why it throws this error:
ERROR! the field 'hosts' is required but was not set
How can I do what I need to do?
It still not working. This is the content of my playbook:
Deploy.yml
- name: Adding the host server hosts: localhost vars_prompt: - name: "Server" prompt: "Server IP" private: no - name: "User" prompt: "Username" default: "Ubuntu" private: no - name: "Passwd" prompt: "Password" private: yes encrypt: "sha512_crypt" - name: "IdFile" prompt: "Identity file path" private: no when: Passwd is undefined tasks: - name: Add host server add_host: name: "{{ Server }}" ansible_ssh_user: "{{ User }}" ansible_ssh_private_key_file: "{{ IdFile }}" when: IdFile is defined - name: Add host server add_host: name: "{{ Server }}" ansible_ssh_user: "{{ User }}" ansible_ssh_pass: "{{ Passwd }}" when: IdFile is undefined - hosts: "{{ Server }}" tasks: - name: Copy the script file to the server copy: src: script.sh dest: "{{ ansible_env.HOME }}/folder/" mode: 755 force: yes attr: - +x
When I run this playbook with this command $ ansible-playbook Deploy.yml
, The output is:
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Adding the host server] ***********************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************
ok: [localhost]
Server IP: <server-ip>
Username [Ubuntu]:
Password:
Identity file path: <path/to/id/file>
ERROR! the field 'hosts' is required but was not set
I don't know why it throws this error:
ERROR! The field 'hosts' has an invalid value, which includes an undefined variable. The error was: 'Server' is undefined
Here is a flowchart of how the playbook should works:
+------------------+ +---------------+ +-----------------+ |Use ansible to run| |Get host IP fom| |Get ssh User from| | this playbook +---->+ user's input +---->+ user's input | +------------------+ +---------------+ +--------+--------+ | v +------------+--------+ |Get ssh password from| | user's input | +------------+--------+ | v +---------------+ ************************* |Add a host with| Yes | Did the user inputted | v----------+ password +<---+| a password? | +----------------+ +---------------+ ***************+********* ||Run some tasks|| |No ||in recently || v ||added host || +---------------+ +------------+--------+ +----------------+ |Add a host with| |Get ssh identity file| ^----------+ identity file +<------+ from user's input | +---------------+ +---------------------+
Ok I've updated my answer to suit the changes in your question, with the original answer left for historic reasons.
To solve the substitution error you are seeing, which results in an empty host list in your second play, I would instead use an inventory group.
There are also two other syntax errors in the second play
0700
)Here is an updated playbook:
- name: Adding the host server
hosts: localhost
vars_prompt:
- name: "Server"
prompt: "Server IP"
private: no
- name: "User"
prompt: "Username"
default: "Ubuntu"
private: no
- name: "Passwd"
prompt: "Password"
private: yes
encrypt: "sha512_crypt"
- name: "IdFile"
prompt: "Identity file path"
private: no
when: Passwd is undefined
tasks:
- name: Add host server
add_host:
name: "{{ Server }}"
ansible_ssh_user: "{{ User }}"
ansible_ssh_private_key_file: "{{ IdFile }}"
group: added_hosts
when: IdFile is defined
- name: Add host server
add_host:
name: "{{ Server }}"
ansible_ssh_user: "{{ User }}"
ansible_ssh_pass: "{{ Passwd }}"
group: added_hosts
when: IdFile is undefined
- hosts: added_hosts
tasks:
- name: Copy the script file to the server
copy:
src: script.sh
dest: "{{ ansible_env.HOME }}/folder/"
mode: 0755
force: yes
=== OLD ANSWER ===
User input is stored in the whatever variable you are using for the name
attribute in each of the variable prompts.
You need to switch around your name
and prompt
values under vars_prompt
There are also YAML formatting issues
For example:
- vars_prompt:
- name: "Server IP"
prompt: "Server"
private: no
should be:
vars_prompt:
- name: "server"
prompt: "Server IP"
private: no
Then you can refer to the {{ server }}
variable in your tasks