How to write host-specific configuration information to a host I spin up using ec2

40 views
Skip to first unread message

ch...@subtlety.com

unread,
Apr 28, 2015, 1:53:14 PM4/28/15
to ansible...@googlegroups.com
I've got a playbook that looks like this:

---
-  name: Launch Instances
   hosts: localhost
   gather_facts: no
   vars:
      aws_instance_type: m3.medium
      aws_image: ami-cb214ae3
      aws_region: us-east-1
      machines:
         - name: db
           script: basic

        - name: db2
          script: basic

         - name: cache
           script: complicated

   tasks:
    - name: Launch instance
      ec2:
         key_name: development
         instance_type: "{{ aws_instance_type }}"
         image: "{{ aws_image }}"
         wait: true
         region: "{{ aws_region }}"
         group: ansible-default
         instance_tags:
            cluster: "{{ tag }}"
            controller: ansible
            role: "{{ item.name }}"


      register: ec2
      with_items: machines


    - name: Add new instance to host group
      add_host: hostname={{ item[1].public_ip }} groups=launched
      with_subelements:
        - ec2.results
        - instances


    - name: Wait for SSH to come up
      wait_for: host={{ item[1].public_dns_name }} port=22 delay=60 timeout=300 state=started
      with_subelements:
        - ec2.results
        - instances


-  name: Run init scripts
   hosts: launched
   tasks:
    - name: Copy scripts
      copy:
         src: ../../build_scripts/scripts/
         dest: /opt/comp/scripts/
         force: yes
         mode: 0755


    - name: Execute script
      shell: /opt/comp/scripts/init/{{ script }}.sh


   The first play brings up two machines, and waits for them to be available. The second play loops over them, copying scripts and executing a specific one depending on the machine.

   The problem, obviously, is that the {{ script }} variable doesn't work. I need a way to associate the host I bring up with the script variable associated with it. I could use tags, but this has to ultimate support providers that don't use tags. I'd like to write a value into the local facts of the host after bringing up a machine, but the "copy" tag doesn't support arbitrary hosts the way "wait_for" does. It would be great if "add_host" allowed you to specify variables to associate with them, or "set_fact" allowed you to set a fact for an arbitrary host, but they don't seem to.
   What's the right way to do this?

-- Chris

ch...@subtlety.com

unread,
Apr 29, 2015, 11:15:39 AM4/29/15
to ansible...@googlegroups.com
Does anybody have any idea about the question below, or how to answer it? Is there a better place to ask for help?

Matt Davis

unread,
Apr 29, 2015, 1:34:39 PM4/29/15
to ansible...@googlegroups.com
Hi Chris,

The item you used to create the EC2 instance in the loop should be registered in the corresponding result object as "item". What about:

- name: Execute script
  shell: /opt/comp/scripts/init/{{ item[0].item.script }}.sh
  with_subelements:
    - ec2.results
    - instances 

There are other ways to address some of the issues you ran into (just for future reference):

- Try copy with delegate_to to drop custom facts (delegate_to will copy from the control machine to the delegated host).
- Fetch (and/or run) your scripts or dump custom facts during instance creation with ec2 user_data scripting

Good luck!

- Matt Davis
  Senior Solutions Architect @ Ansible
Reply all
Reply to author
Forward
0 new messages