skip to Main Content

I have the following (simplified) play:

- hosts: testing

  roles:
     - nginx
  vars_files:
     - config.yml
  environment:
    http_proxy: http://proxy.example.com:8080

Now, when I run my code, I can read process.env.http_proxy. I would however like to be able to set other environment variables dynamically under environment. For example, in my config.yml I have the following:

application_variables:
  - key: "NODE_ENV"
    value: "production"
  - key: "PORT"
    value: "3000"

How would I get the values from application_variables to be dynamically created under environment? I’ve tried a few different solutions I found out there to no avail.

2

Answers


  1. You can feed the environment parameter from a templated Jinja expression, in your case:

    environment: "{{ application_variables | items2dict }}"
    

    Then you have the choice to:

    • either add the HTTP proxy variable to your application_variables list:
      application_variables:
        - key: http_proxy
          value: http://proxy.example.com:8080
        - key: NODE_ENV
          value: production
        - key: PORT
          value: 3000
      
    • or combine the dictionary created from the application_variables with a variable defined at the in your playbook:
      - hosts: testing
      
        environment: >-
          {{ 
            default_env | combine(
              application_variables | items2dict
            )
          }}
        vars:
          default_env:
            http_proxy: http://proxy.example.com:8080
      

    As an example, the playbook:

    - hosts: localhost
      gather_facts: true
    
      environment: >-
        {{ 
          default_env | combine(
            application_variables | items2dict
          ) 
        }}
      vars_files: config.yml
      vars:
        default_env:
          http_proxy: http://proxy.example.com:8080
    
      tasks:
        - debug:
            msg:
              http_proxy: "{{ ansible_facts.env.http_proxy }}"
              NODE_ENV: "{{ ansible_facts.env.NODE_ENV }}"
    

    Would give you:

    ok: [localhost] => 
      msg:
        NODE_ENV: production
        http_proxy: http://proxy.example.com:8080
    
    Login or Signup to reply.
  2. Combine the environment

      env_static:
        http_proxy: http://proxy.example.com:8080
      env_dynamic: "{{ application_variables | items2dict }}"
      env: "{{ env_static | combine(env_dynamic) }}"
    

    gives

      env:
        NODE_ENV: production
        PORT: '3000'
        http_proxy: http://proxy.example.com:8080
    

    Import the role

        - import_role:
            name: nginx
          environment: "{{ env }}"
    

    For example, given the simplified role

    shell> cat roles/nginx/tasks/main.yml 
    - command: echo $NODE_ENV $PORT $http_proxy
      register: out
    - debug:
        var: out.stdout
    

    gives

      out.stdout: production 3000 http://proxy.example.com:8080
    

    Example of a complete playbook for testing

    - hosts: test
    
      vars_files:
        - config.yml
    
      vars:
    
        env_static:
          http_proxy: http://proxy.example.com:8080
        env_dynamic: "{{ application_variables | items2dict }}"
        env: "{{ env_static | combine(env_dynamic) }}"
    
      tasks:
    
        - debug:
            var: env
    
        - import_role:
            name: nginx
          environment: "{{ env }}"
    

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search