Deploying AWS infra with CloudFormation and provisioning application in same playbook

101 views
Skip to first unread message

Juris

unread,
Dec 7, 2015, 11:15:02 AM12/7/15
to Ansible Project
Hi,

I am having hard time figuring out idiomatic way of doing AWS infrastructure deployment and application e.g. EC2 instance provisioning in one go in same playbook. The problem being accessing EC2 host in the next play after AWS infrastructure creation. The example playbook is as follows:

---
- name: Deploy cloud infrastructure
  hosts: localhost
  connection: local
  gather_facts: False
  vars:
    aws_region: "us-east-1"
    ssh_key_name: "MyAwsKey"
    stack_name: "test-stack"

  tasks:
    - name: Create a sample stack
      cloudformation:
        stack_name: "{{ stack_name }}"
        state: "present"
        region: "us-east-1"
        disable_rollback: true
        template: "files/simple.template"
        template_parameters:
          KeyName: "{{ ssh_key_name }}"
      register: cf

    - name: Output EC2 IP
      debug: var=cf.stack_outputs.PublicIP

# Try to install something to EC2
- name: Provision application
  hosts: "{{ hostvars.localhost.cf.stack_outputs.PublicIP }}"
  remote_user: "ubuntu"
  sudo: yes

  tasks:
    - name: Just a test command
      command: uptime
      register: out
    - debug: var=out.stdout

And output:

ok: [localhost] => {
    "var": {
        "cf.stack_outputs.PublicIP": "XXX.XXX.XXX.XXX"
    }
}

PLAY [Provision application] **************************************************
skipping: no hosts matched


My naive assumption was that consecutive play "Provision application" would reference EC2 instance with hosts directive via registered variable e.g. hostvars.localhost.cf.stack_outputs.PublicIP which apparently does not work like I imagined.

So, the question is - what is the right way to approach this problem? I bet I am missing something. I would prefer just one playbook that does both cloud infrastructure deployment and server/application provisioning.

Thanks!
Juris

James Martin

unread,
Dec 7, 2015, 11:47:14 AM12/7/15
to Ansible Project
I would tag the instances in your CF template, then reference those tagged hosts by the inventory groups that are created with the ec2.py dynamic inventory script.  If you do this in two separate ansible-playbook runs, you won't need to do anything special, the inventory will reflect the newly tagged instances. If you are doing this within the same play or playbook, you'll need to update the inventory in memory, you can do that  (in Ansible 2.0) with:

- meta: refresh_inventory

Juris

unread,
Dec 7, 2015, 2:01:12 PM12/7/15
to Ansible Project
James,

I stumbled across ec2.py dynamic inventory and immediately got bit the issue no refresh of dynamic inventory if executed from the same playbook. If I go with the approach of separating cloud infrastructure deployment and application provisioning into a separate  playbooks then this problem can be avoided and I probably can stick with suggested approach of tagging resources in CF template.

I am just wondering how more experienced engineers approach this problem, what are the good practices?

Thanks,
Juris

Stephen Granger

unread,
Dec 7, 2015, 2:37:07 PM12/7/15
to ansible...@googlegroups.com
Maybe you just need to add the host (cf.stack_outputs.PublicIP) to a group as per the example here using the add_host module, this will add it to your inventory temporarily

    - name: create some ec2 instances
      ec2: ....
      register: ec2

    - name: Add new instance to host group
      add_host: hostname={{ item.public_ip }} groupname=launched
      with_items: ec2.instances
...

I've used something like this and then include the same roles I would call for a deployment on the host in the same playbook, just a different play.

hosts: launched

  roles::
    - my_role

There are other examples on the ec2 page, it's been update a lot since I last looked at it.

If you want to reuse the same playbooks tag your instances and just mention the tag and group name to later use the ec2.py inventory to manage the instance. (I've used a tag called AnsibleGroup)

hosts: launched:tag_AnsibleGroup_launched

launched would be a really esoteric group name to use, I'm just trying to fit in with your example.

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/dcbe4f72-86c6-4e16-8f94-55b68e625727%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Steve
Reply all
Reply to author
Forward
0 new messages