Search code examples
provisioningrackspaceansible

Ansible Playbook to Provision and Save Hosts for Later


I'm trying to make some Ansible playbooks that will provision an environment (n databases, m web servers, etc.) and save those hosts for later so I can run deployments against them. The best I can come up with is https://gist.github.com/geowa4/7686681 (copied below). This works in that it creates machines for the various server types and saves them to the hosts file. My deployment scripts, for which I will use the newly generated hosts file, ensure that the correct packages are installed and configured correctly before deploying the source code. Is this the only way to accomplish provisioning and deployment with Ansible? What if I want to dynamically add a new web server to the mix? Do I have to manually edit the static hosts file? So far, with the dynamic inventory script for Rackspace, it just lists a whole bunch of servers with no way to group them by type. If I could get that, I'd be ecstatic.

hosts.j2:

[a]
{% for a in a_provision.instances %}
{{ a.rax_accessipv4 }}
{% endfor %}

[b]
{% for b in b_provision.instances %}
{{ b.rax_accessipv4 }}
{% endfor %}

main.yml:

---
- name: a - build request
  local_action:
    module: rax
    username: username
    api_key: key
    name: test-a
    count: 1
    flavor: 3
    image: a-image-id
    files:
      /root/.ssh/authorized_keys: ~/.ssh/id_rsa.pub
    state: present
    wait: yes
    wait_timeout: 1000
    networks:
    - private
    - public
  register: a_provision

- name: b - build request
  local_action:
    module: rax
    username: username
    api_key: key
    name: test-b
    flavor: 5
    image: b-image-id
    files:
      /root/.ssh/authorized_keys: ~/.ssh/id_rsa.pub
    state: present
    wait: yes
    wait_timeout: 1000
    networks:
    - private
    - public
  register: b_provision

- name: add new nodes to hosts configuration
  template: 'src=hosts.j2 dest=provisioned_hosts'

Solution

  • The Rackspace module and dynamic inventory in recent versions of Ansible (I'm using 1.4.1) do let you group servers!

    The rax module accepts a "group" parameter that's stored in the created server's metadata, which the Rackspace dynamic inventory plugin will then extract to create Ansible groups, so subsequent plays can use the group names that you've specified.

    However, it looks like the inventory is only queried at the start of the play. To work with your newly launched servers within the same run, you'll need to use the add-host module to add them to the inventory at runtime:

    - name: build webservers
      local_action:
        module: rax
        name: webserver
        group: webservers
        exact_count: true
        credentials: ~/.rackspace_cloud_credentials
        flavor: 2
        image: df27d481-63a5-40ca-8920-3d132ed643d9
        files:
          /root/.ssh/authorized_keys: ~/.ssh/id_rsa.pub
        state: present
        disk_config: manual
        wait: yes
        wait_timeout: 10000
      register: webserversvar
    
    - name: add newly provisioned webservers to a group
      local_action: add_host hostname={{ item.accessIPv4 }} groupname=webservers
      with_items: webserversvar.instances
    
    - name: build databases
      local_action:
        module: rax
        name: database
        group: databases
        exact_count: true
        credentials: ~/.rackspace_cloud_credentials
        flavor: 2
        image: df27d481-63a5-40ca-8920-3d132ed643d9
        files:
          /root/.ssh/authorized_keys: ~/.ssh/id_rsa.pub
        state: present
        disk_config: manual
        wait: yes
        wait_timeout: 10000
      register: databasesvar
    
    - name: add newly provisioned databases to a group
      local_action: add_host hostname={{ item.accessIPv4 }} groupname=databases
      with_items: databasesvar.instances
    

    There's a writeup about doing this on AWS which covers a lot of the same high-level concepts, even though the provider is different.