Creating servers at Rackspace, host specification and where best to store group variables

Hi,

We use ansible to create servers at Rackspace. We rely on rax.py to provide the inventory of the current server configuration. Currently, the play that creates the required servers this looks like this:

- name: "Create infrastructure"
  hosts: localhost
  vars:
    network_name: "{{ target_environment }}"
  roles:
    - infrastructure

The infrastructure role that is called sets up a number of servers for each of our environments. Generally, each environment contains app servers, database servers and monitoring servers. Each of these server types have their own respective group. For example, to create the necessary app servers, the infrastructure role has a task as follows:

- name: App servers
  local_action:
    module: rax
    credentials: ~/.rackspace_cloud_credentials
    region: "{{ region }}"
    name: "{{ target_environment }}-{{ region }}-app-%02d"
    count: "{{ app_server_count }}"
    exact_count: yes
    group: "{{ target_environment }}_app_servers"
    meta:
        groups: "{{ target_environment }},app_servers,{{ target_environment }}_nrpe_servers"
        build_config: "core,monitoring"
    files:
        /root/.ssh/authorized_keys: "./ansible_key_{{ target_environment }}.pub"
    flavor: "{{ app_server_rackspace_flavor }}"
    image: "{{ debian8_image_id }}"
    state: present
    networks:
        - private
        - public
        - "{{ network_name }}"
    wait: yes
    wait_timeout: 900
  register: new_app_servers

The variable which specifies the flavour to use when the server is created, app_server_rackspace_flavor is set in group_vars/all. Additional configuration, such as the number of app servers to create in an environment and the target environment name is contained within a json file (named to reflect the environment it represents) and loaded in when the playbook is run using the --extra-vars command line option. For example, when creating the test environment, the command would look like this:

ansible-playbook ./create-infrastructure.yml -i ./inventories/ --extra-vars=“@test.json” --user=ansible --private-key=./ansible_key_test

I would like to change the infrastructure role so that the Rackspace flavor of the app servers can differ per environment. We want to use servers with increased performance in the production environment compared to those in the test environment.

When attempting to make these changes, I started to consider where to put the configuration for each of the groups. With the flavor variable already specified in group_vars/all, obviously group_vars was my first thought. The first problem that I encountered when I did that though was that in the play I provided above, the hosts specification uses localhost and so the relevant information was not picked up when the rax task ran. I changed the host specification of the play to {{ target_environment }}. The play correctly identified the environment that I was attempting to target, but because the group didn’t already exist at Rackspace, the play was skipped :frowning:

I’m sure this is a problem that others have encountered - be it using Rackspace or other cloud based providers. I wondered if those people would mind responding, either with suggested changes that I can make to how our servers are created so that I can refer to the group_vars values, or with examples of how they do their own server creation so that I can understand if there is a different strategy which I should consider employing.

Thanks!

Dan.