Repository: ansible/ansible

Issue:
vars_prompt does not display variable's value in prompt message
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
vars_prompt 

##### ANSIBLE VERSION
```
ansible 2.4.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/tora5/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/python27/lib/python2.7/site-packages/ansible
  executable location = /opt/python27/bin/ansible
  python version = 2.7.14 (default, Nov  9 2017, 03:10:36) [GCC 4.4.7 20120313 (Red Hat 4.4.7-18)]
```

##### CONFIGURATION
PERSISTENT_CONNECT_TIMEOUT(/etc/ansible/ansible.cfg) = 30

##### OS / ENVIRONMENT
2.6.32-642.4.2.el6.x86_64 GNU/Linux

##### SUMMARY
Variables defined in playbook or read via extra-vars are not displayed in vars_prompt's prompt. Instead {{ var_name }} is displayed

##### STEPS TO REPRODUCE
1. define a variable: var1=x
2. create a prompt that contains var1's value : "value of var1 is {{ var1 }}"

```yaml
vars: 
    var1: "test_value"

vars_prompt:
    - name: "confirmation"
      prompt: "Value of var1 is {{ var1 }}"
```

##### EXPECTED RESULTS
prompt displays 
Value of var1 is test_value

##### ACTUAL RESULTS
prompt displays
```
Value of var1 is {{ var1 }}
```



Discussion:
The `prompt` value is not currently templated. It _may_ be possible to do this, but could easily turn into a chicken/egg scenario.

`vars_prompt` happens very early on because the variables supplied at the prompt are most likely required in the play.

I'll see what it would take to do this, though.

Resolving patch:
diff --git a/lib/ansible/executor/playbook_executor.py b/lib/ansible/executor/playbook_executor.py
--- a/lib/ansible/executor/playbook_executor.py
+++ b/lib/ansible/executor/playbook_executor.py
@@ -68,7 +68,6 @@ def __init__(self, playbooks, inventory, variable_manager, loader, options, pass
         check_for_controlpersist(C.ANSIBLE_SSH_EXECUTABLE)
 
     def run(self):
-
         '''
         Run the given playbook, based on the settings in the play which
         may limit the runs to serialized groups, etc.
@@ -103,8 +102,16 @@ def run(self):
                     # clear any filters which may have been applied to the inventory
                     self._inventory.remove_restriction()
 
+                    # Create a temporary copy of the play here, so we can run post_validate
+                    # on it without the templating changes affecting the original object.
+                    # Doing this before vars_prompt to allow for using variables in prompt.
+                    all_vars = self._variable_manager.get_vars(play=play)
+                    templar = Templar(loader=self._loader, variables=all_vars)
+                    new_play = play.copy()
+                    new_play.post_validate(templar)
+
                     if play.vars_prompt:
-                        for var in play.vars_prompt:
+                        for var in new_play.vars_prompt:
                             vname = var['name']
                             prompt = var.get("prompt", vname)
                             default = var.get("default", None)
@@ -121,12 +128,10 @@ def run(self):
                                 else:  # we are either in --list-<option> or syntax check
                                     play.vars[vname] = default
 
-                    # Create a temporary copy of the play here, so we can run post_validate
-                    # on it without the templating changes affecting the original object.
-                    all_vars = self._variable_manager.get_vars(play=play)
-                    templar = Templar(loader=self._loader, variables=all_vars)
-                    new_play = play.copy()
-                    new_play.post_validate(templar)
+                        # Post validating again in case variables were entered in the prompt.
+                        all_vars = self._variable_manager.get_vars(play=play)
+                        templar = Templar(loader=self._loader, variables=all_vars)
+                        new_play.post_validate(templar)
 
                     if self._options.syntax:
                         continue


Test patch: