Search code examples
ansibleansible-inventory

Accessing Ansible Inventory


I am trying to model different environments (local, development, sandbox) under two regions. For each environment, I have defined properties for that environment (such as rest_api_port: '8080') that I need to refer to in my playbook.

Given the below, how can I run my Ansible playbook against the local environment only in ewest?

I have tried the following but it seems like it tries to run against all hosts in euwest:

ansible-playbook playbook.yaml --inventory inventory.yaml --limit="euwest:local"

---
euwest:
  hosts:
    local:
      ansible_connection: local
      rest_api_host: 127.0.0.1
      rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
      rest_api_port: '8080'
      rest_api_timeout: '60'
      rest_api_username: admin
    development:
      ansible_connection: local
      rest_api_host: dev.messaging.cloud
      rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
      rest_api_port: '943'
      rest_api_timeout: '60'
      rest_api_username: dev-admin
    sandbox:
      ansible_connection: local
      rest_api_host: sand.messaging.cloud
      rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
      rest_api_port: '9443'
      rest_api_timeout: '60'
      rest_api_username: sand-admin
apsouth:
  hosts:
    local:
      ansible_connection: local
      rest_api_host: 127.0.0.1
      rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
      rest_api_port: '8081'
      rest_api_timeout: '60'
      rest_api_username: admin
    development:
      ansible_connection: local
      rest_api_host: dev2.messaging.cloud
      rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
      rest_api_port: '9091'
      rest_api_timeout: '60'
      rest_api_username: dev-admin
    sandbox:
      ansible_connection: local
      rest_api_host: sand2.messaging.cloud
      rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
      rest_api_port: '443'
      rest_api_timeout: '60'
      rest_api_username: sand-admin

Solution

  • A host in Ansible is identified only by name. If you list the same hostname in multiple groups, you still only have a single host: it's just a member of multiple groups.

    That is, if I have:

    euwest:
      hosts:
        development:
    apsouth:
      hosts:
        development:
    

    Then I have just put the single host development in two hostgroups (euwest and apsouth).


    For what you're trying to do, your best option is probably to use multiple inventory files. Create euwest.yaml with:

    all:
      hosts:
        local:
          ansible_connection: local
          rest_api_host: 127.0.0.1
          rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
          rest_api_port: '8080'
          rest_api_timeout: '60'
          rest_api_username: admin
        development:
          ansible_connection: local
          rest_api_host: dev.messaging.cloud
          rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
          rest_api_port: '943'
          rest_api_timeout: '60'
          rest_api_username: dev-admin
        sandbox:
          ansible_connection: local
          rest_api_host: sand.messaging.cloud
          rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
          rest_api_port: '9443'
          rest_api_timeout: '60'
          rest_api_username: sand-admin
    

    And apsouth.yaml with:

    all:
      hosts:
        local:
          ansible_connection: local
          rest_api_host: 127.0.0.1
          rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
          rest_api_port: '8081'
          rest_api_timeout: '60'
          rest_api_username: admin
        development:
          ansible_connection: local
          rest_api_host: dev2.messaging.cloud
          rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
          rest_api_port: '9091'
          rest_api_timeout: '60'
          rest_api_username: dev-admin
        sandbox:
          ansible_connection: local
          rest_api_host: sand2.messaging.cloud
          rest_api_password: "{{ lookup('env', 'REST_API_PASSWORD') }}"
          rest_api_port: '443'
          rest_api_timeout: '60'
          rest_api_username: sand-admin
    

    And then pick which one to use at runtime with the -i option:

    ansible-playbook -i apsouth.yaml playbook.yaml
    

    If I need to restrict the playbook to only run against local in euwest, can I just pass --limit="local" ?

    Sure. The --limit option limits execution to a specific host or group. Nothing we've done here changes that behavior.

    Will the properties of each host be seamlessly available to me in my playbook role? E.g. In my playbook, host: "{{ rest_api_host }}"

    Also yes :). Again, nothing we've done here changes the behavior; the only difference is that now we have two inventory files, so each host is part of only a single hostgroup rather than being part of two host groups.