Search code examples
ansibleansible-inventory

Using Ansible to run playbook from local computer for targeting environment-specific URLs


The problem I'm trying to solve with Ansible is to configure several Keycloak servers in different environments using the community.general.keycloak_role module.

My basic playbook looks like this and it already does what it is supposed to do. At least when running it locally against localhost:

- name: Configure Keycloak
  hosts: all
  vars_prompt:
    - name: auth_password
      prompt: Please enter Keycloak admin password
  module_defaults:
    community.general.keycloak_role:
      auth_keycloak_url: "{{ auth_keycloak_url }}"
      auth_realm: "{{ auth_realm }}"
      auth_username: "{{ auth_username }}"
      auth_password: "{{ auth_password }}"
      auth_client_id: "{{ auth_client_id }}"
      realm: "{{ realm }}"
  tasks:
    - name: Configure client roles
      community.general.keycloak_role:
        name: "{{ item }}"
        client_id: my-test-client
        state: present
      loop:
        - role_01
        - role_02
        - role_03

Now, I'd like to run this playbook for different environments, e.g. dev, staging, production with different URLs and credentials.

My first attempt was to create one inventory file per environment, each containing the hostname.

inventories/dev

keycloak-dev-server

inventories/staging

keycloak-staging-server

But this does not work because Ansible tries to actually connect to these machines, whereas I just want to run the playbook from my local computer targeting the environment. That's why my inventory files now only contain localhost ansible_connection=local as hostname and I configure the auth_keycloak_url specifically for each environment.

While it works, it "feels" as if this apporach is not correct in the sense that all inventory files only contain a local connection.


Solution

  • You're on the right track, but you need a separate set of variables for each environment. If you structure your project like this:

    .
    ├── inventories
    │   ├── dev
    │   │   ├── group_vars
    │   │   │   └── all.yaml
    │   │   └── hosts.yaml
    │   └── staging
    │       ├── group_vars
    │       │   └── all.yaml
    │       └── hosts.yaml
    └── playbook.yaml
    

    Then you can put the dev-specific environment variables in inventories/dev/group_vars/all.yaml and the staging-specific environment variables in inventories/staging/group_vars/all.yaml.

    Now you can run either:

    ansible-playbook playbook.yaml -i inventories/dev
    

    Or:

    ansible-playbook playbook.yaml -i inventories/staging
    

    And get the appropriate configuration.


    You can find a runnable example here.