Repository: ansible/ansible

Issue:
ec2_asg fails to run when there is no instance in the Auto Scaling group
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
ec2_asg

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.3.0 (devel e98c0a3009) last updated 2017/01/04 10:41:06 (GMT -700)
  config file = 
  configured module search path = Default w/o overrides
```


##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
-->
N/A

##### SUMMARY
<!--- Explain the problem briefly -->

If there is no Instances running in the auto-scaling group, running ec2_asg fails: 

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->
- Have an ec2 Auto Scaling group running with at least one machine.
- Change the number of instances to 0
- When all the instances in our asg are terminated, re-run the ec2_asg task


<!--- Paste example playbooks or commands between quotes below -->
```yaml
- ec2_asg:
    name: "server autoscaling group"
    launch_config_name: "server-launch-config"
    health_check_period: 60
    health_check_type: EC2
    desired_capacity: 0
    min_size: 0
    max_size: 1
    region: "{{aws_region}}"
    replace_all_instances: yes
    vpc_zone_identifier: "{{autoscaling_subnet_ids}}"
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->

ec2_asg runs and update (or not) the asg config

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
TASK [ec2 : ec2_asg] ***************************************************************************************************************************************************************************************
task path: /../servers.yml
An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
  File "/var/folders/y2/l4g6_6zn03s1mh34lkz1czjm0000gn/T/ansible_lJMEl4/ansible_module_ec2_asg.py", line 928, in <module>
    main()
  File "/var/folders/y2/l4g6_6zn03s1mh34lkz1czjm0000gn/T/ansible_lJMEl4/ansible_module_ec2_asg.py", line 922, in main
    replace_changed, asg_properties=replace(connection, module)
  File "/var/folders/y2/l4g6_6zn03s1mh34lkz1czjm0000gn/T/ansible_lJMEl4/ansible_module_ec2_asg.py", line 646, in replace
    instances = props['instances']
KeyError: 'instances'

fatal: [localhost]: FAILED! => {
    "changed": false,
    "failed": true,
    "invocation": {
        "module_name": "ec2_asg"
    },
    "module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/y2/l4g6_6zn03s1mh34lkz1czjm0000gn/T/ansible_lJMEl4/ansible_module_ec2_asg.py\", line 928, in <module>\n    main()\n  File \"/var/folders/y2/l4g6_6zn03s1mh34lkz1czjm0000gn/T/ansible_lJMEl4/ansible_module_ec2_asg.py\", line 922, in main\n    replace_changed, asg_properties=replace(connection, module)\n  File \"/var/folders/y2/l4g6_6zn03s1mh34lkz1czjm0000gn/T/ansible_lJMEl4/ansible_module_ec2_asg.py\", line 646, in replace\n    instances = props['instances']\nKeyError: 'instances'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 1
}
```



Discussion:

Resolving patch:
diff --git a/lib/ansible/modules/cloud/amazon/ec2_asg.py b/lib/ansible/modules/cloud/amazon/ec2_asg.py
--- a/lib/ansible/modules/cloud/amazon/ec2_asg.py
+++ b/lib/ansible/modules/cloud/amazon/ec2_asg.py
@@ -306,6 +306,8 @@ def get_properties(autoscaling_group):
                 properties['terminating_instances'] += 1
             if i.lifecycle_state == 'Pending':
                 properties['pending_instances'] += 1
+    else:
+        properties['instances'] = []
     properties['instance_facts'] = instance_facts
     properties['load_balancers'] = autoscaling_group.load_balancers
 
@@ -644,7 +646,7 @@ def replace(connection, module):
     instances = props['instances']
     if replace_instances:
         instances = replace_instances
-        
+
     #check if min_size/max_size/desired capacity have been specified and if not use ASG values
     if min_size is None:
         min_size = as_group.min_size
@@ -674,7 +676,7 @@ def replace(connection, module):
     if not old_instances:
         changed = False
         return(changed, props)
-      
+
     # set temporary settings and wait for them to be reached
     # This should get overwritten if the number of instances left is less than the batch size.
 


Test patch: