<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">ec2_group</p>
<h5 dir="auto">ANSIBLE VERSION</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible 2.2.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides"><pre class="notranslate"><code class="notranslate">ansible 2.2.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
</code></pre></div>
<p dir="auto">(but code review suggests that later versions likely also susceptible)</p>
<h5 dir="auto">CONFIGURATION</h5>
<p dir="auto">n/a</p>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">n/a</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">A playbook using an <code class="notranslate">ec2_group</code> module with a rule whose <code class="notranslate">cidr_ip</code> value has any host bits set will execute successfully at most once, but will fail to execute thereafter.</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="- hosts: localhost
  tasks:
  - name: Test case
    ec2_group:
      description: Test SG
      name: Test SG
      region: us-east-1
      rules: [{proto: all, cidr_ip: '10.0.0.1/8'}]
      rules_egress: [{proto: all, cidr_ip: '0.0.0.0/0'}]
      vpc_id: FIXME
  connection: local
  become: false
  gather_facts: false"><pre class="notranslate">- <span class="pl-ent">hosts</span>: <span class="pl-s">localhost</span>
  <span class="pl-ent">tasks</span>:
  - <span class="pl-ent">name</span>: <span class="pl-s">Test case</span>
    <span class="pl-ent">ec2_group</span>:
      <span class="pl-ent">description</span>: <span class="pl-s">Test SG</span>
      <span class="pl-ent">name</span>: <span class="pl-s">Test SG</span>
      <span class="pl-ent">region</span>: <span class="pl-s">us-east-1</span>
      <span class="pl-ent">rules</span>: <span class="pl-s">[{proto: all, cidr_ip: '10.0.0.1/8'}]</span>
      <span class="pl-ent">rules_egress</span>: <span class="pl-s">[{proto: all, cidr_ip: '0.0.0.0/0'}]</span>
      <span class="pl-ent">vpc_id</span>: <span class="pl-s">FIXME</span>
  <span class="pl-ent">connection</span>: <span class="pl-s">local</span>
  <span class="pl-ent">become</span>: <span class="pl-c1">false</span>
  <span class="pl-ent">gather_facts</span>: <span class="pl-c1">false</span></pre></div>
<p dir="auto">(replace <code class="notranslate">vpc_id</code>, and maybe <code class="notranslate">region</code>, as applicable)</p>
<h5 dir="auto">EXPECTED RESULTS</h5>
<p dir="auto"><em>Preferably</em> the rule's validation should fail entirely every time.</p>
<p dir="auto">Alternatively, the CIDR could be sanitized by Ansible at run-time <em>before</em> it compares the configured rules with the ones currently active in AWS.</p>
<h5 dir="auto">ACTUAL RESULTS</h5>
<p dir="auto">Initial run executes fine; the rule is created on the security group, however the CIDR is masked so that only the network bits are set (ie 10.0.0.0/8). Thus what shows up in AWS is slightly different than what the user requested, but it works (at least for the first time).</p>
<p dir="auto">Subsequent runs, however, will all fail with this error:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Traceback (most recent call last):
  File &quot;/tmp/ansible_y6BGXK/ansible_module_ec2_group.py&quot;, line 478, in &lt;module&gt;
    main()
  File &quot;/tmp/ansible_y6BGXK/ansible_module_ec2_group.py&quot;, line 373, in main
    group.authorize(rule['proto'], rule['from_port'], rule['to_port'], thisip, grantGroup)
  File &quot;/usr/lib/python2.7/dist-packages/boto/ec2/securitygroup.py&quot;, line 203, in authorize
    dry_run=dry_run)
  File &quot;/usr/lib/python2.7/dist-packages/boto/ec2/connection.py&quot;, line 3192, in authorize_security_group
    params, verb='POST')
  File &quot;/usr/lib/python2.7/dist-packages/boto/connection.py&quot;, line 1223, in get_status
    raise self.ResponseError(response.status, response.reason, body)
boto.exception.EC2ResponseError: EC2ResponseError: 400 Bad Request
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;Response&gt;&lt;Errors&gt;&lt;Error&gt;&lt;Code&gt;InvalidPermission.Duplicate&lt;/Code&gt;&lt;Message&gt;the specified rule &quot;peer: 10.0.0.0/8, ALL, ALLOW&quot; already exists&lt;/Message&gt;&lt;/Error&gt;&lt;/Errors&gt;&lt;RequestID&gt;963c0e1b-bcdb-4ab3-815a-89c7ce1b2204&lt;/RequestID&gt;&lt;/Response&gt;

fatal: [localhost]: FAILED! =&gt; {
    &quot;changed&quot;: false, 
    &quot;failed&quot;: true, 
    &quot;invocation&quot;: {
        &quot;module_name&quot;: &quot;ec2_group&quot;
    }, 
    &quot;module_stderr&quot;: &quot;Traceback (most recent call last):\n  File \&quot;/tmp/ansible_y6BGXK/ansible_module_ec2_group.py\&quot;, line 478, in &lt;module&gt;\n    main()\n  File \&quot;/tmp/ansible_y6BGXK/ansible_module_ec2_group.py\&quot;, line 373, in main\n    group.authorize(rule['proto'], rule['from_port'], rule['to_port'], thisip, grantGroup)\n  File \&quot;/usr/lib/python2.7/dist-packages/boto/ec2/securitygroup.py\&quot;, line 203, in authorize\n    dry_run=dry_run)\n  File \&quot;/usr/lib/python2.7/dist-packages/boto/ec2/connection.py\&quot;, line 3192, in authorize_security_group\n    params, verb='POST')\n  File \&quot;/usr/lib/python2.7/dist-packages/boto/connection.py\&quot;, line 1223, in get_status\n    raise self.ResponseError(response.status, response.reason, body)\nboto.exception.EC2ResponseError: EC2ResponseError: 400 Bad Request\n&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;UTF-8\&quot;?&gt;\n&lt;Response&gt;&lt;Errors&gt;&lt;Error&gt;&lt;Code&gt;InvalidPermission.Duplicate&lt;/Code&gt;&lt;Message&gt;the specified rule \&quot;peer: 10.0.0.0/8, ALL, ALLOW\&quot; already exists&lt;/Message&gt;&lt;/Error&gt;&lt;/Errors&gt;&lt;RequestID&gt;963c0e1b-bcdb-4ab3-815a-89c7ce1b2204&lt;/RequestID&gt;&lt;/Response&gt;\n&quot;, 
    &quot;module_stdout&quot;: &quot;&quot;, 
    &quot;msg&quot;: &quot;MODULE FAILURE&quot;
}"><pre lang="An" class="notranslate"><code class="notranslate">Traceback (most recent call last):
  File "/tmp/ansible_y6BGXK/ansible_module_ec2_group.py", line 478, in &lt;module&gt;
    main()
  File "/tmp/ansible_y6BGXK/ansible_module_ec2_group.py", line 373, in main
    group.authorize(rule['proto'], rule['from_port'], rule['to_port'], thisip, grantGroup)
  File "/usr/lib/python2.7/dist-packages/boto/ec2/securitygroup.py", line 203, in authorize
    dry_run=dry_run)
  File "/usr/lib/python2.7/dist-packages/boto/ec2/connection.py", line 3192, in authorize_security_group
    params, verb='POST')
  File "/usr/lib/python2.7/dist-packages/boto/connection.py", line 1223, in get_status
    raise self.ResponseError(response.status, response.reason, body)
boto.exception.EC2ResponseError: EC2ResponseError: 400 Bad Request
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;Response&gt;&lt;Errors&gt;&lt;Error&gt;&lt;Code&gt;InvalidPermission.Duplicate&lt;/Code&gt;&lt;Message&gt;the specified rule "peer: 10.0.0.0/8, ALL, ALLOW" already exists&lt;/Message&gt;&lt;/Error&gt;&lt;/Errors&gt;&lt;RequestID&gt;963c0e1b-bcdb-4ab3-815a-89c7ce1b2204&lt;/RequestID&gt;&lt;/Response&gt;

fatal: [localhost]: FAILED! =&gt; {
    "changed": false, 
    "failed": true, 
    "invocation": {
        "module_name": "ec2_group"
    }, 
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_y6BGXK/ansible_module_ec2_group.py\", line 478, in &lt;module&gt;\n    main()\n  File \"/tmp/ansible_y6BGXK/ansible_module_ec2_group.py\", line 373, in main\n    group.authorize(rule['proto'], rule['from_port'], rule['to_port'], thisip, grantGroup)\n  File \"/usr/lib/python2.7/dist-packages/boto/ec2/securitygroup.py\", line 203, in authorize\n    dry_run=dry_run)\n  File \"/usr/lib/python2.7/dist-packages/boto/ec2/connection.py\", line 3192, in authorize_security_group\n    params, verb='POST')\n  File \"/usr/lib/python2.7/dist-packages/boto/connection.py\", line 1223, in get_status\n    raise self.ResponseError(response.status, response.reason, body)\nboto.exception.EC2ResponseError: EC2ResponseError: 400 Bad Request\n&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\n&lt;Response&gt;&lt;Errors&gt;&lt;Error&gt;&lt;Code&gt;InvalidPermission.Duplicate&lt;/Code&gt;&lt;Message&gt;the specified rule \"peer: 10.0.0.0/8, ALL, ALLOW\" already exists&lt;/Message&gt;&lt;/Error&gt;&lt;/Errors&gt;&lt;RequestID&gt;963c0e1b-bcdb-4ab3-815a-89c7ce1b2204&lt;/RequestID&gt;&lt;/Response&gt;\n", 
    "module_stdout": "", 
    "msg": "MODULE FAILURE"
}
</code></pre></div>
<h5 dir="auto">Issue Type: Bug Report</h5>
<h5 dir="auto">Component: core</h5>
<h5 dir="auto">Ansible Version:</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible 2.0.0.2
  config file =
  configured module search path = Default w/o overrides"><pre class="notranslate"><code class="notranslate">ansible 2.0.0.2
  config file =
  configured module search path = Default w/o overrides
</code></pre></div>
<h5 dir="auto">Ansible Configuration:</h5>
<p dir="auto">n/a</p>
<h5 dir="auto">Environment:</h5>
<p dir="auto">python==2.7.10<br>
osx==10.10.5</p>
<h5 dir="auto">Summary:</h5>
<p dir="auto">Role dependencies are run more than once.</p>
<h5 dir="auto">Steps To Reproduce:</h5>
<p dir="auto">here are my files:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# inventory
localhost"><pre class="notranslate"><code class="notranslate"># inventory
localhost
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# play.yml

---
- name: dependency test with role tags
  hosts: localhost
  connection: local

  roles:
    - role: base
      tags:
        - always

    - role: feature
      tags:
        - always"><pre class="notranslate"><code class="notranslate"># play.yml

---
- name: dependency test with role tags
  hosts: localhost
  connection: local

  roles:
    - role: base
      tags:
        - always

    - role: feature
      tags:
        - always
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# roles/base/meta/main.yml

---
allow_duplicates: no"><pre class="notranslate"><code class="notranslate"># roles/base/meta/main.yml

---
allow_duplicates: no
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# roles/base/tasks/main.yml

---
- name: base role
  debug:
    msg: base role"><pre class="notranslate"><code class="notranslate"># roles/base/tasks/main.yml

---
- name: base role
  debug:
    msg: base role
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# roles/feature/meta/main.yml

---
allow_duplicates: no
dependencies:
  - role: base
    tags:
      - always"><pre class="notranslate"><code class="notranslate"># roles/feature/meta/main.yml

---
allow_duplicates: no
dependencies:
  - role: base
    tags:
      - always
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# roles/feature/tasks/main.yml

---
- name: feature role
  debug:
    msg: feature role"><pre class="notranslate"><code class="notranslate"># roles/feature/tasks/main.yml

---
- name: feature role
  debug:
    msg: feature role
</code></pre></div>
<p dir="auto">I call it with:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible-playbook -i inventory play.yml --list-tasks"><pre class="notranslate"><code class="notranslate">ansible-playbook -i inventory play.yml --list-tasks
</code></pre></div>
<h5 dir="auto">Expected Results:</h5>
<p dir="auto">The base role is executed once.</p>
<p dir="auto">Using ansible==1.9.4 the play works as expected:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="playbook: play.yml

  play #1 (dependency test with role tags): TAGS: []
    base role   TAGS: [always]
    feature role    TAGS: [always]"><pre class="notranslate"><code class="notranslate">playbook: play.yml

  play #1 (dependency test with role tags): TAGS: []
    base role   TAGS: [always]
    feature role    TAGS: [always]
</code></pre></div>
<h5 dir="auto">Actual Results:</h5>
<p dir="auto">The base role is executed twice.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="playbook: play.yml

  play #1 (localhost): dependency test with role tags   TAGS: []
    tasks:
      base : base role  TAGS: [always]
      base : base role  TAGS: [always]
      feature : feature role    TAGS: [always]"><pre class="notranslate"><code class="notranslate">playbook: play.yml

  play #1 (localhost): dependency test with role tags   TAGS: []
    tasks:
      base : base role  TAGS: [always]
      base : base role  TAGS: [always]
      feature : feature role    TAGS: [always]
</code></pre></div>