title: using variables in ansible hosts targetting in playbook
body: <p>I am trying to write a very flexible playbook that targets hosts based on environment they are in. I am using as many variables as possible, so the playbook can be reused for other projects/environments with minimal changes.</p>
  
  <p>I have a single application.yml </p>
  
  <pre><code>---
  - name: Prepare app-server for "The app"
    hosts: "{{'env'}}_super_app"
    vars:
    vars_files:
    - "environments/{{env}}.yml"
    sudo: yes
    tasks:
      - command: echo {{env}}
    roles:
      - common
      - nginx
      - php5-fpm
      - nodejs
      - newrelic
      - users
      - composer
  
  - name: Install and configure mysql for "The super app"
    hosts:
    - "{{env}}_super_db"
    vars:
    vars_files:
    - "environments/{{env}}.yml"
    sudo: yes
    roles:
      - common
      - mysql
      - newrelic
  </code></pre>
  
  <p>Here is the playbook directory structure:</p>
  
  <pre><code>├── environments
  │   ├── prod.yml       &lt;&lt; environment specific vars
  │   ├── stag.yml       &lt;&lt; environment specific vars
  │   └── uat.yml        &lt;&lt; environment specific vars
  ├── roles
  │   ├── common
  │   ├── composer
  │   ├── mysql
  │   ├── newrelic
  │   ├── nginx
  │   ├── nodejs
  │   ├── php5-fpm
  │   └── users
  ├── users
  │   └── testo.yml
  ├── prod              &lt;&lt; inventory file for production
  ├── README.md
  ├── application.yml   &lt;&lt; application playbook
  ├── stag              &lt;&lt; inventory file for staging
  ├── uat               &lt;&lt; inventory file for uat
  </code></pre>
  
  <p>Here are the contents of the uat inventory file:</p>
  
  <pre><code>[uat_super_app]
  10.10.10.4
  [uat_super_db]
  10.10.10.5
  </code></pre>
  
  <p>When I run my playbook, I pass the environment as an extra variable:</p>
  
  <pre><code>ansible-playbook -K -i uat application.yml -e="env=uat" --check
  </code></pre>
  
  <p>The idea being:
  If {{env}} is set to uat, then the environments/uat.yml vars will be used, AND hosts [uat_super_app] will be targeted based on {{env}}_super_app.</p>
  
  <p>If I or anyone makes a mistake and tries to run the uat vars against a production inventory, the hosts will not match, and ansible will not run the playbook.</p>
  
  <pre><code>ansible-playbook -K -i prod application.yml -e="env=uat" --check
  </code></pre>
  
  <p>This playbook works when I do not use variables in hosts targeting.
  The problem is that no hosts match either way:</p>
  
  <pre><code>ansible-playbook -K -i uat application.yml -e="env=uat" --check -vvvv
  
  SUDO password: 
  PLAY [Prepare app-server for "The app"] ******************************* 
  skipping: no hosts matched
  
  PLAY [Install and configure mysql for "The app"] ********************** 
  skipping: no hosts matched
  
  PLAY RECAP ******************************************************************** 
  </code></pre>