Repository: ansible/ansible

Issue:
ec2 creates new instance if instance not running when using exact_count
From @moorereason on 2015-02-28T01:52:28Z
##### Issue Type:

Bug Report

##### Component Name:
ec2 module

##### Ansible Version:

1.8.2
##### Environment:

Red Hat 7
##### Summary:

When creating an ec2 instance with exact_count, the module creates new instances if the existing instance is not running.
##### Steps To Reproduce:

Given the following example playbook:

``` yaml
- hosts: localhost
  connection: local
  gather_facts: false
  tasks:
    - ec2:
        region: "{{ aws_region }}"
        instance_type: "{{ aws_instance_type }}"
        image: "{{ aws_image }}"
        vpc_subnet_id: "{{ aws_vpc_subnet_id }}"
        group: "{{ aws_group }}"
        key_name: "{{ aws_keypair }}"
        exact_count: 1
        count_tag:
          Name: "{{ item.hostname }}"
          Role: "{{ item.role }}"
          Env: "{{ item.env }}"
        instance_tags:
          Name: "{{ item.hostname }}"
          Role: "{{ item.role }}"
          Env: "{{ item.env }}"
        volumes:
          - device_name: /dev/sda1
            volume_size: 10
            device_type: gp2 
        wait: yes
        wait_timeout: 500
      with_items: aws_launch
```

Run the playbook twice, stopping the instance before the second run.
##### Expected Results:

I expect the second run to return OK without creating a new instance.
##### Actual Results:

Module creates a second instance.

Copied from original issue: ansible/ansible-modules-core#871

ec2 creates new instance if instance not running when using exact_count
From @moorereason on 2015-02-28T01:52:28Z
##### Issue Type:

Bug Report

##### Component Name:
ec2 module

##### Ansible Version:

1.8.2
##### Environment:

Red Hat 7
##### Summary:

When creating an ec2 instance with exact_count, the module creates new instances if the existing instance is not running.
##### Steps To Reproduce:

Given the following example playbook:

``` yaml
- hosts: localhost
  connection: local
  gather_facts: false
  tasks:
    - ec2:
        region: "{{ aws_region }}"
        instance_type: "{{ aws_instance_type }}"
        image: "{{ aws_image }}"
        vpc_subnet_id: "{{ aws_vpc_subnet_id }}"
        group: "{{ aws_group }}"
        key_name: "{{ aws_keypair }}"
        exact_count: 1
        count_tag:
          Name: "{{ item.hostname }}"
          Role: "{{ item.role }}"
          Env: "{{ item.env }}"
        instance_tags:
          Name: "{{ item.hostname }}"
          Role: "{{ item.role }}"
          Env: "{{ item.env }}"
        volumes:
          - device_name: /dev/sda1
            volume_size: 10
            device_type: gp2 
        wait: yes
        wait_timeout: 500
      with_items: aws_launch
```

Run the playbook twice, stopping the instance before the second run.
##### Expected Results:

I expect the second run to return OK without creating a new instance.
##### Actual Results:

Module creates a second instance.

Copied from original issue: ansible/ansible-modules-core#871



Discussion:
From @moorereason on 2015-02-28T01:52:28Z

Just wanted to report that I upgraded to 1.8.4, and I'm seeing the same behavior.

From @echiu64 on 2015-02-28T01:52:28Z

I'm wondering if it has something to do with the ec2 inventory cache? 

From @bennojoy on 2015-02-28T01:52:28Z

@moorereason  @echiu64  can you please try #1484

From @mspiegle on 2015-02-28T01:52:28Z

I have confirmed this still happens on 2.1.0.0

@ansibot Greetings! Thanks for taking the time to open this issue. In order for the community to handle your issue effectively, we need a bit more information. 

Here are the items we could not find in your description:
- component name

Please set the description of this issue with this template:
https://raw.githubusercontent.com/ansible/ansible/devel/.github/ISSUE_TEMPLATE.md

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: issue_missing_data --->
cc @lwade @tgerla
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
From @moorereason on 2015-02-28T01:52:28Z

Just wanted to report that I upgraded to 1.8.4, and I'm seeing the same behavior.

From @echiu64 on 2015-02-28T01:52:28Z

I'm wondering if it has something to do with the ec2 inventory cache? 

From @bennojoy on 2015-02-28T01:52:28Z

@moorereason  @echiu64  can you please try #1484

From @mspiegle on 2015-02-28T01:52:28Z

I have confirmed this still happens on 2.1.0.0

@ansibot Greetings! Thanks for taking the time to open this issue. In order for the community to handle your issue effectively, we need a bit more information. 

Here are the items we could not find in your description:
- component name

Please set the description of this issue with this template:
https://raw.githubusercontent.com/ansible/ansible/devel/.github/ISSUE_TEMPLATE.md

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: issue_missing_data --->
cc @lwade @tgerla
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/cloud/amazon/ec2.py b/lib/ansible/modules/cloud/amazon/ec2.py
--- a/lib/ansible/modules/cloud/amazon/ec2.py
+++ b/lib/ansible/modules/cloud/amazon/ec2.py
@@ -639,13 +639,18 @@
 
 def find_running_instances_by_count_tag(module, ec2, vpc, count_tag, zone=None):
 
-    # get reservations for instances that match tag(s) and are running
-    reservations = get_reservations(module, ec2, vpc, tags=count_tag, state="running", zone=zone)
+    # get reservations for instances that match tag(s) and are in the desired state
+    state = module.params.get('state')
+    if state not in ['running', 'stopped']:
+        state = None
+    reservations = get_reservations(module, ec2, vpc, tags=count_tag, state=state, zone=zone)
 
     instances = []
     for res in reservations:
         if hasattr(res, 'instances'):
             for inst in res.instances:
+                if inst.state == 'terminated':
+                    continue
                 instances.append(inst)
 
     return reservations, instances


Test patch: