Repository: ansible/ansible

Issue:
azure_rm_networkinterface module does not associate existing network security group when creating new NIC
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
Always add information AFTER of these html comments.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
<!---
Insert below this comment the name of the module, plugin, task or feature.
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path
-->
azure_rm_networkinterface

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.5.0
  config file = /home/user/git/ansible-playbooks/ansible.cfg
  configured module search path = [u'/home/user/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.13 (default, Nov 24 2017, 17:33:09) [GCC 6.3.0 20170516]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->
DEFAULT_HOST_LIST(/home/user/git/ansible-playbooks/ansible.cfg) = [u'/home/user/git/ansible-playbooks/ansible/inventory']

##### 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.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
Debian GNU/Linux 9.4 ("Stretch")

##### SUMMARY
<!--- Explain the problem briefly -->
When I create a network-interface that should be used with an already existing Network Security Group (NSG), it never uses the existing NSG, but instead creates a new one with default values and the same name as the networkinterface, which is the default behavior if no NSG is provided as a parameter.

##### 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.
-->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
---
- name: Create VLAN, subnets, Public IPs and NICs for an Azure VM
  hosts: localhost
  connection: local
  tasks:
  - name: Create resource group
    azure_rm_resourcegroup:
      name: testRG
      location: westeurope

  - name: Create a virtual network
    azure_rm_virtualnetwork:
      name: testVNET
      resource_group: testRG
      address_prefixes_cidr:
          - "192.0.0.0/24"

  - name: Create VLAN subnet
    azure_rm_subnet:
      name: "testSUBNET"
      virtual_network_name: "testVNET"
      resource_group: "testRG"
      address_prefix_cidr: "192.0.0.0/28"

  - name: Create network security group (firewall rules)
    azure_rm_securitygroup:
      resource_group: "testRG"
      name: "testNSG"
      state: present
      purge_rules: yes
      rules:
        - name: 'AllowSSH'
          protocol: Tcp
          source_adress_prefix: '*'
          destination_port_range: 22
          access: Allow
          priority: 1000
          direction: Inbound

  - name: Create public IP address
    azure_rm_publicipaddress:
      name: "testVM_ip"
      resource_group: "testRG"
      allocation_method: Static
 
  - name: Create virtual network interface card
    azure_rm_networkinterface:
      name: "testVM_nic"
      resource_group: "testRG"
      virtual_network_name: "testVNET"
      subnet_name: "testSUBNET"
      security_group_name: "testNSG" # this parameter seems to be ignored
      ip_configurations:
        - name: "testVM_ip"
          public_ip_address_name: "testVM_ip"
          primary: True
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
This is what I have in my resource group “testRG” as a result of above operations vs. what I would expect

Resource Type  | Resource Name  | Expected | Status
----------------|-----------------|----------|---------------------------------
virtual network | testVNET | yes | OK
subnet  | testSUBNET | yes | OK
nsg | testNSG | yes | OK
nsg | testVM_nic | no | unwanted
public IP | testVM_ip | yes | OK
virtual NIC | testVM_nic | yes | Points to wrong NSG (testVM_nic)

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
also see table above.
Here is the verbatim output (Azure subscription ID has been replace with '*****'):
```
ansible-playbook 2.5.0
  config file = /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible.cfg
  configured module search path = [u'/home/user/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 2.7.13 (default, Nov 24 2017, 17:33:09) [GCC 6.3.0 20170516]
Using /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible.cfg as config file
setting up inventory plugins
Parsed /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible/inventory/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /usr/local/lib/python2.7/dist-packages/ansible/plugins/callback/default.pyc

PLAYBOOK: bugreport.yml *********************************************************************************************************************************************************************************************************************************************************
1 plays in ansible/playbooks/bugreport.yml

PLAY [Create VLAN, subnets, Public IPs and NICs for an Azure VM] ****************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************************************************
task path: /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible/playbooks/bugreport.yml:2
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/system/setup.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: user
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/user/.ansible/tmp/ansible-tmp-1523879011.44-237037382102053 `" && echo ansible-tmp-1523879011.44-237037382102053="` echo /home/user/.ansible/tmp/ansible-tmp-1523879011.44-237037382102053 `" ) && sleep 0'
<localhost> PUT /home/user/.ansible/tmp/ansible-local-3312Wir4T3/tmptT0TAJ TO /home/user/.ansible/tmp/ansible-tmp-1523879011.44-237037382102053/setup.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-tmp-1523879011.44-237037382102053/ /home/user/.ansible/tmp/ansible-tmp-1523879011.44-237037382102053/setup.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1523879011.44-237037382102053/setup.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-tmp-1523879011.44-237037382102053/ > /dev/null 2>&1 && sleep 0'
ok: [localhost]
META: ran handlers

TASK [Create resource group] ****************************************************************************************************************************************************************************************************************************************************
task path: /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible/playbooks/bugreport.yml:6
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/cloud/azure/azure_rm_resourcegroup.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: user
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/user/.ansible/tmp/ansible-tmp-1523879011.9-102289128857512 `" && echo ansible-tmp-1523879011.9-102289128857512="` echo /home/user/.ansible/tmp/ansible-tmp-1523879011.9-102289128857512 `" ) && sleep 0'
<localhost> PUT /home/user/.ansible/tmp/ansible-local-3312Wir4T3/tmpiHWBSW TO /home/user/.ansible/tmp/ansible-tmp-1523879011.9-102289128857512/azure_rm_resourcegroup.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-tmp-1523879011.9-102289128857512/ /home/user/.ansible/tmp/ansible-tmp-1523879011.9-102289128857512/azure_rm_resourcegroup.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1523879011.9-102289128857512/azure_rm_resourcegroup.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-tmp-1523879011.9-102289128857512/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true, 
    "contains_resources": false, 
    "invocation": {
        "module_args": {
            "ad_user": null, 
            "api_profile": "latest", 
            "append_tags": true, 
            "auth_source": null, 
            "cert_validation_mode": null, 
            "client_id": null, 
            "cloud_environment": null, 
            "force": false, 
            "location": "westeurope", 
            "name": "testRG", 
            "password": null, 
            "profile": null, 
            "secret": null, 
            "state": "present", 
            "subscription_id": null, 
            "tags": null, 
            "tenant": null
        }
    }, 
    "state": {
        "id": "/subscriptions/*****/resourceGroups/testRG", 
        "location": "westeurope", 
        "name": "testRG", 
        "provisioning_state": "Succeeded", 
        "tags": null
    }
}

TASK [Create a virtual network] *************************************************************************************************************************************************************************************************************************************************
task path: /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible/playbooks/bugreport.yml:11
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/cloud/azure/azure_rm_virtualnetwork.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: user
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/user/.ansible/tmp/ansible-tmp-1523879014.35-104418366999151 `" && echo ansible-tmp-1523879014.35-104418366999151="` echo /home/user/.ansible/tmp/ansible-tmp-1523879014.35-104418366999151 `" ) && sleep 0'
<localhost> PUT /home/user/.ansible/tmp/ansible-local-3312Wir4T3/tmp9QF7uv TO /home/user/.ansible/tmp/ansible-tmp-1523879014.35-104418366999151/azure_rm_virtualnetwork.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-tmp-1523879014.35-104418366999151/ /home/user/.ansible/tmp/ansible-tmp-1523879014.35-104418366999151/azure_rm_virtualnetwork.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1523879014.35-104418366999151/azure_rm_virtualnetwork.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-tmp-1523879014.35-104418366999151/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true, 
    "check_mode": false, 
    "invocation": {
        "module_args": {
            "ad_user": null, 
            "address_prefixes_cidr": [
                "192.0.0.0/24"
            ], 
            "api_profile": "latest", 
            "append_tags": true, 
            "auth_source": null, 
            "cert_validation_mode": null, 
            "client_id": null, 
            "cloud_environment": null, 
            "dns_servers": null, 
            "location": null, 
            "name": "testVNET", 
            "password": null, 
            "profile": null, 
            "purge_address_prefixes": false, 
            "purge_dns_servers": false, 
            "resource_group": "testRG", 
            "secret": null, 
            "state": "present", 
            "subscription_id": null, 
            "tags": null, 
            "tenant": null
        }
    }, 
    "state": {
        "address_prefixes": [
            "192.0.0.0/24"
        ], 
        "etag": "W/\"f56f2ab0-287e-4f17-9302-d518ae456681\"", 
        "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/virtualNetworks/testVNET", 
        "location": "westeurope", 
        "name": "testVNET", 
        "provisioning_state": "Succeeded", 
        "tags": null, 
        "type": "Microsoft.Network/virtualNetworks"
    }
}

TASK [Create VLAN subnet] *******************************************************************************************************************************************************************************************************************************************************
task path: /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible/playbooks/bugreport.yml:18
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/cloud/azure/azure_rm_subnet.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: user
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/user/.ansible/tmp/ansible-tmp-1523879032.38-132612978103782 `" && echo ansible-tmp-1523879032.38-132612978103782="` echo /home/user/.ansible/tmp/ansible-tmp-1523879032.38-132612978103782 `" ) && sleep 0'
<localhost> PUT /home/user/.ansible/tmp/ansible-local-3312Wir4T3/tmplLOTaF TO /home/user/.ansible/tmp/ansible-tmp-1523879032.38-132612978103782/azure_rm_subnet.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-tmp-1523879032.38-132612978103782/ /home/user/.ansible/tmp/ansible-tmp-1523879032.38-132612978103782/azure_rm_subnet.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1523879032.38-132612978103782/azure_rm_subnet.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-tmp-1523879032.38-132612978103782/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true, 
    "invocation": {
        "module_args": {
            "ad_user": null, 
            "address_prefix_cidr": "192.0.0.0/28", 
            "api_profile": "latest", 
            "append_tags": true, 
            "auth_source": null, 
            "cert_validation_mode": null, 
            "client_id": null, 
            "cloud_environment": null, 
            "name": "testSUBNET", 
            "password": null, 
            "profile": null, 
            "resource_group": "testRG", 
            "secret": null, 
            "security_group_name": null, 
            "state": "present", 
            "subscription_id": null, 
            "tags": null, 
            "tenant": null, 
            "virtual_network_name": "testVNET"
        }
    }, 
    "state": {
        "address_prefix": "192.0.0.0/28", 
        "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/virtualNetworks/testVNET/subnets/testSUBNET", 
        "name": "testSUBNET", 
        "network_security_group": {}, 
        "provisioning_state": "Succeeded"
    }
}

TASK [Create network security group (firewall rules)] ***************************************************************************************************************************************************************************************************************************
task path: /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible/playbooks/bugreport.yml:25
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/cloud/azure/azure_rm_securitygroup.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: user
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/user/.ansible/tmp/ansible-tmp-1523879038.03-119496553013227 `" && echo ansible-tmp-1523879038.03-119496553013227="` echo /home/user/.ansible/tmp/ansible-tmp-1523879038.03-119496553013227 `" ) && sleep 0'
<localhost> PUT /home/user/.ansible/tmp/ansible-local-3312Wir4T3/tmpCBozVO TO /home/user/.ansible/tmp/ansible-tmp-1523879038.03-119496553013227/azure_rm_securitygroup.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-tmp-1523879038.03-119496553013227/ /home/user/.ansible/tmp/ansible-tmp-1523879038.03-119496553013227/azure_rm_securitygroup.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1523879038.03-119496553013227/azure_rm_securitygroup.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-tmp-1523879038.03-119496553013227/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true, 
    "invocation": {
        "module_args": {
            "ad_user": null, 
            "api_profile": "latest", 
            "append_tags": true, 
            "auth_source": null, 
            "cert_validation_mode": null, 
            "client_id": null, 
            "cloud_environment": null, 
            "default_rules": null, 
            "location": null, 
            "name": "testNSG", 
            "password": null, 
            "profile": null, 
            "purge_default_rules": false, 
            "purge_rules": true, 
            "resource_group": "testRG", 
            "rules": [
                {
                    "access": "Allow", 
                    "destination_address_prefix": "*", 
                    "destination_port_range": 22, 
                    "direction": "Inbound", 
                    "name": "AllowSSH", 
                    "priority": 1000, 
                    "protocol": "Tcp", 
                    "source_address_prefix": "*", 
                    "source_adress_prefix": "*", 
                    "source_port_range": "*"
                }
            ], 
            "secret": null, 
            "state": "present", 
            "subscription_id": null, 
            "tags": null, 
            "tenant": null
        }
    }, 
    "state": {
        "default_rules": [
            {
                "access": "Allow", 
                "description": "Allow inbound traffic from all VMs in VNET", 
                "destination_address_prefix": "VirtualNetwork", 
                "destination_port_range": "*", 
                "direction": "Inbound", 
                "etag": "W/\"46701d1a-caf8-4372-a308-14804c5af399\"", 
                "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkSecurityGroups/testNSG/defaultSecurityRules/AllowVnetInBound", 
                "name": "AllowVnetInBound", 
                "priority": 65000, 
                "protocol": "*", 
                "provisioning_state": "Succeeded", 
                "source_address_prefix": "VirtualNetwork", 
                "source_port_range": "*"
            }, 
            {
                "access": "Allow", 
                "description": "Allow inbound traffic from azure load balancer", 
                "destination_address_prefix": "*", 
                "destination_port_range": "*", 
                "direction": "Inbound", 
                "etag": "W/\"46701d1a-caf8-4372-a308-14804c5af399\"", 
                "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkSecurityGroups/testNSG/defaultSecurityRules/AllowAzureLoadBalancerInBound", 
                "name": "AllowAzureLoadBalancerInBound", 
                "priority": 65001, 
                "protocol": "*", 
                "provisioning_state": "Succeeded", 
                "source_address_prefix": "AzureLoadBalancer", 
                "source_port_range": "*"
            }, 
            {
                "access": "Deny", 
                "description": "Deny all inbound traffic", 
                "destination_address_prefix": "*", 
                "destination_port_range": "*", 
                "direction": "Inbound", 
                "etag": "W/\"46701d1a-caf8-4372-a308-14804c5af399\"", 
                "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkSecurityGroups/testNSG/defaultSecurityRules/DenyAllInBound", 
                "name": "DenyAllInBound", 
                "priority": 65500, 
                "protocol": "*", 
                "provisioning_state": "Succeeded", 
                "source_address_prefix": "*", 
                "source_port_range": "*"
            }, 
            {
                "access": "Allow", 
                "description": "Allow outbound traffic from all VMs to all VMs in VNET", 
                "destination_address_prefix": "VirtualNetwork", 
                "destination_port_range": "*", 
                "direction": "Outbound", 
                "etag": "W/\"46701d1a-caf8-4372-a308-14804c5af399\"", 
                "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkSecurityGroups/testNSG/defaultSecurityRules/AllowVnetOutBound", 
                "name": "AllowVnetOutBound", 
                "priority": 65000, 
                "protocol": "*", 
                "provisioning_state": "Succeeded", 
                "source_address_prefix": "VirtualNetwork", 
                "source_port_range": "*"
            }, 
            {
                "access": "Allow", 
                "description": "Allow outbound traffic from all VMs to Internet", 
                "destination_address_prefix": "Internet", 
                "destination_port_range": "*", 
                "direction": "Outbound", 
                "etag": "W/\"46701d1a-caf8-4372-a308-14804c5af399\"", 
                "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkSecurityGroups/testNSG/defaultSecurityRules/AllowInternetOutBound", 
                "name": "AllowInternetOutBound", 
                "priority": 65001, 
                "protocol": "*", 
                "provisioning_state": "Succeeded", 
                "source_address_prefix": "*", 
                "source_port_range": "*"
            }, 
            {
                "access": "Deny", 
                "description": "Deny all outbound traffic", 
                "destination_address_prefix": "*", 
                "destination_port_range": "*", 
                "direction": "Outbound", 
                "etag": "W/\"46701d1a-caf8-4372-a308-14804c5af399\"", 
                "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkSecurityGroups/testNSG/defaultSecurityRules/DenyAllOutBound", 
                "name": "DenyAllOutBound", 
                "priority": 65500, 
                "protocol": "*", 
                "provisioning_state": "Succeeded", 
                "source_address_prefix": "*", 
                "source_port_range": "*"
            }
        ], 
        "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkSecurityGroups/testNSG", 
        "location": "westeurope", 
        "name": "testNSG", 
        "network_interfaces": [], 
        "rules": [
            {
                "access": "Allow", 
                "description": null, 
                "destination_address_prefix": "*", 
                "destination_port_range": "22", 
                "direction": "Inbound", 
                "etag": "W/\"46701d1a-caf8-4372-a308-14804c5af399\"", 
                "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkSecurityGroups/testNSG/securityRules/AllowSSH", 
                "name": "AllowSSH", 
                "priority": 1000, 
                "protocol": "Tcp", 
                "provisioning_state": "Succeeded", 
                "source_address_prefix": "*", 
                "source_port_range": "*"
            }
        ], 
        "subnets": [], 
        "tags": {}, 
        "type": "Microsoft.Network/networkSecurityGroups"
    }
}

TASK [Create public IP address] *************************************************************************************************************************************************************************************************************************************************
task path: /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible/playbooks/bugreport.yml:40
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/cloud/azure/azure_rm_publicipaddress.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: user
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/user/.ansible/tmp/ansible-tmp-1523879051.92-63839946526101 `" && echo ansible-tmp-1523879051.92-63839946526101="` echo /home/user/.ansible/tmp/ansible-tmp-1523879051.92-63839946526101 `" ) && sleep 0'
<localhost> PUT /home/user/.ansible/tmp/ansible-local-3312Wir4T3/tmpAoBACJ TO /home/user/.ansible/tmp/ansible-tmp-1523879051.92-63839946526101/azure_rm_publicipaddress.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-tmp-1523879051.92-63839946526101/ /home/user/.ansible/tmp/ansible-tmp-1523879051.92-63839946526101/azure_rm_publicipaddress.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1523879051.92-63839946526101/azure_rm_publicipaddress.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-tmp-1523879051.92-63839946526101/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true, 
    "invocation": {
        "module_args": {
            "ad_user": null, 
            "allocation_method": "Static", 
            "api_profile": "latest", 
            "append_tags": true, 
            "auth_source": null, 
            "cert_validation_mode": null, 
            "client_id": null, 
            "cloud_environment": null, 
            "domain_name": null, 
            "location": null, 
            "name": "testVM_ip", 
            "password": null, 
            "profile": null, 
            "resource_group": "testRG", 
            "secret": null, 
            "state": "present", 
            "subscription_id": null, 
            "tags": null, 
            "tenant": null
        }
    }, 
    "state": {
        "dns_settings": {}, 
        "etag": "W/\"07a50e76-fe54-44e5-8670-7f80f6081e1b\"", 
        "idle_timeout_in_minutes": 4, 
        "ip_address": "51.144.118.152", 
        "location": "westeurope", 
        "name": "testVM_ip", 
        "provisioning_state": "Succeeded", 
        "public_ip_allocation_method": "Static", 
        "tags": null, 
        "type": "Microsoft.Network/publicIPAddresses"
    }
}

TASK [Create virtual network interface card] ************************************************************************************************************************************************************************************************************************************
task path: /home/user/git/cloud/devops/manage/ansible-playbook-repos/IMS-ansible-playbooks/ansible/playbooks/bugreport.yml:46
Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/cloud/azure/azure_rm_networkinterface.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: user
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/user/.ansible/tmp/ansible-tmp-1523879057.8-8583585535719 `" && echo ansible-tmp-1523879057.8-8583585535719="` echo /home/user/.ansible/tmp/ansible-tmp-1523879057.8-8583585535719 `" ) && sleep 0'
<localhost> PUT /home/user/.ansible/tmp/ansible-local-3312Wir4T3/tmpfpLfME TO /home/user/.ansible/tmp/ansible-tmp-1523879057.8-8583585535719/azure_rm_networkinterface.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-tmp-1523879057.8-8583585535719/ /home/user/.ansible/tmp/ansible-tmp-1523879057.8-8583585535719/azure_rm_networkinterface.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /home/user/.ansible/tmp/ansible-tmp-1523879057.8-8583585535719/azure_rm_networkinterface.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-tmp-1523879057.8-8583585535719/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true, 
    "invocation": {
        "module_args": {
            "ad_user": null, 
            "api_profile": "latest", 
            "append_tags": true, 
            "auth_source": null, 
            "cert_validation_mode": null, 
            "client_id": null, 
            "cloud_environment": null, 
            "ip_configurations": [
                {
                    "name": "testVM_ip", 
                    "primary": true, 
                    "private_ip_address": null, 
                    "private_ip_allocation_method": "Dynamic", 
                    "public_ip_address_name": "testVM_ip", 
                    "public_ip_allocation_method": "Dynamic"
                }
            ], 
            "location": null, 
            "name": "testVM_nic", 
            "open_ports": null, 
            "os_type": "Linux", 
            "password": null, 
            "private_ip_address": null, 
            "private_ip_allocation_method": "Dynamic", 
            "profile": null, 
            "public_ip": true, 
            "public_ip_address_name": null, 
            "public_ip_allocation_method": "Dynamic", 
            "resource_group": "testRG", 
            "secret": null, 
            "security_group_name": "testNSG", 
            "state": "present", 
            "subnet_name": "testSUBNET", 
            "subscription_id": null, 
            "tags": null, 
            "tenant": null, 
            "virtual_network_name": "testVNET"
        }
    }, 
    "state": {
        "dns_settings": {
            "applied_dns_servers": [], 
            "dns_servers": [], 
            "internal_dns_name_label": null, 
            "internal_fqdn": null
        }, 
        "enable_ip_forwarding": false, 
        "etag": "W/\"ff4e5079-d8cf-4cfa-ab9a-ba2e9bfc3e92\"", 
        "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkInterfaces/testVM_nic", 
        "ip_configuration": {
            "name": "testVM_ip", 
            "primary": true, 
            "private_ip_address": "192.0.0.4", 
            "private_ip_allocation_method": "Dynamic", 
            "public_ip_address": {
                "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/publicIPAddresses/testVM_ip", 
                "name": "testVM_ip", 
                "public_ip_allocation_method": null
            }, 
            "subnet": {
                "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/virtualNetworks/testVNET/subnets/testSUBNET", 
                "name": "testSUBNET", 
                "resource_group": "testRG", 
                "virtual_network_name": "testVNET"
            }
        }, 
        "ip_configurations": [
            {
                "name": "testVM_ip", 
                "primary": true, 
                "private_ip_address": "192.0.0.4", 
                "private_ip_allocation_method": "Dynamic", 
                "public_ip_address": {
                    "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/publicIPAddresses/testVM_ip", 
                    "name": "testVM_ip", 
                    "public_ip_allocation_method": null
                }, 
                "subnet": {
                    "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/virtualNetworks/testVNET/subnets/testSUBNET", 
                    "name": "testSUBNET", 
                    "resource_group": "testRG", 
                    "virtual_network_name": "testVNET"
                }
            }
        ], 
        "location": "westeurope", 
        "mac_address": null, 
        "name": "testVM_nic", 
        "network_security_group": {
            "id": "/subscriptions/*****/resourceGroups/testRG/providers/Microsoft.Network/networkSecurityGroups/testVM_nic", 
            "name": "testVM_nic"
        }, 
        "provisioning_state": "Succeeded", 
        "tags": null, 
        "type": "Microsoft.Network/networkInterfaces"
    }
}
META: ran handlers
META: ran handlers

PLAY RECAP **********************************************************************************************************************************************************************************************************************************************************************
localhost               : ok=7    changed=6    unreachable=0    failed=0   


```



Discussion:

Resolving patch:
diff --git a/lib/ansible/module_utils/azure_rm_common.py b/lib/ansible/module_utils/azure_rm_common.py
--- a/lib/ansible/module_utils/azure_rm_common.py
+++ b/lib/ansible/module_utils/azure_rm_common.py
@@ -814,8 +814,15 @@ def create_default_securitygroup(self, resource_group, location, security_group_
                 priority += 1
                 rule_name = "Rule_{0}".format(priority)
                 parameters.security_rules.append(
-                    self.network_models.SecurityRule('Tcp', '*', '*', 'Allow', 'Inbound', source_port_range='*',
-                                                     destination_port_range=str(port), priority=priority, name=rule_name)
+                    self.network_models.SecurityRule(protocol='Tcp',
+                                                     source_address_prefix='*',
+                                                     destination_address_prefix='*',
+                                                     access='Allow',
+                                                     direction='Inbound',
+                                                     source_port_range='*',
+                                                     destination_port_range=str(port),
+                                                     priority=priority,
+                                                     name=rule_name)
                 )
 
         self.log('Creating default security group {0}'.format(security_group_name))
diff --git a/lib/ansible/modules/cloud/azure/azure_rm_networkinterface.py b/lib/ansible/modules/cloud/azure/azure_rm_networkinterface.py
--- a/lib/ansible/modules/cloud/azure/azure_rm_networkinterface.py
+++ b/lib/ansible/modules/cloud/azure/azure_rm_networkinterface.py
@@ -2,6 +2,7 @@
 #
 # Copyright (c) 2016 Matt Davis, <mdavis@ansible.com>
 #                    Chris Houseknecht, <house@redhat.com>
+#                    Yuwei ZHou, <yuwzho@microsoft.com>
 #
 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
 
@@ -174,6 +175,7 @@
 author:
     - "Chris Houseknecht (@chouseknecht)"
     - "Matt Davis (@nitzmahone)"
+    - "Yuwei Zhou (@yuwzho)"
 '''
 
 EXAMPLES = '''
@@ -266,7 +268,8 @@
                 "id": "/subscriptions/XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX/resourceGroups/Testing/providers/Microsoft.Network/publicIPAddresses/publicip001",
                 "name": "publicip001"
             },
-            "subnet": {}
+            "subnet": {},
+            "load_balancer_backend_address_pools": []
         }],
         "location": "eastus2",
         "mac_address": null,
@@ -340,16 +343,6 @@ def nic_to_dict(nic):
     )
 
 
-def construct_ip_configuration_set(raw):
-    configurations = [str(dict(
-        private_ip_allocation_method=to_native(item.get('private_ip_allocation_method')),
-        public_ip_address_name=(to_native(item.get('public_ip_address').get('name'))
-                                if item.get('public_ip_address') else to_native(item.get('public_ip_address_name'))),
-        primary=item.get('primary'),
-        name=to_native(item.get('name'))
-    )) for item in raw]
-    return set(configurations)
-
 ip_configuration_spec = dict(
     name=dict(type='str', required=True),
     private_ip_address=dict(type='str'),
@@ -438,6 +431,9 @@ def exec_module(self, **kwargs):
         if virtual_network_resource_group is None:
             virtual_network_resource_group = self.resource_group
 
+        # if not set the security group name, use nic name for default
+        self.security_group_name = self.security_group_name or self.name
+
         if self.state == 'present' and not self.ip_configurations:
             # construct the ip_configurations array for compatiable
             self.deprecate('Setting ip_configuration flatten is deprecated and will be removed.'
@@ -448,7 +444,8 @@ def exec_module(self, **kwargs):
                     private_ip_allocation_method=self.private_ip_allocation_method,
                     public_ip_address_name=self.public_ip_address_name if self.public_ip else None,
                     public_ip_allocation_method=self.public_ip_allocation_method,
-                    name='default'
+                    name='default',
+                    primary=True
                 )
             ]
 
@@ -468,11 +465,10 @@ def exec_module(self, **kwargs):
                 if update_tags:
                     changed = True
 
-                if self.security_group_name:
-                    nsg = self.get_security_group(self.security_group_name)
-                    if nsg and results['network_security_group'].get('id') != nsg.id:
-                        self.log("CHANGED: network interface {0} network security group".format(self.name))
-                        changed = True
+                nsg = self.get_security_group(self.security_group_name)
+                if nsg and results.get('network_security_group') and results['network_security_group'].get('id') != nsg.id:
+                    self.log("CHANGED: network interface {0} network security group".format(self.name))
+                    changed = True
 
                 if results['ip_configurations'][0]['subnet']['virtual_network_name'] != virtual_network_name:
                     self.log("CHANGED: network interface {0} virtual network name".format(self.name))
@@ -490,8 +486,8 @@ def exec_module(self, **kwargs):
                 # construct two set with the same structure and then compare
                 # the list should contains:
                 # name, private_ip_address, public_ip_address_name, private_ip_allocation_method, subnet_name
-                ip_configuration_result = construct_ip_configuration_set(results['ip_configurations'])
-                ip_configuration_request = construct_ip_configuration_set(self.ip_configurations)
+                ip_configuration_result = self.construct_ip_configuration_set(results['ip_configurations'])
+                ip_configuration_request = self.construct_ip_configuration_set(self.ip_configurations)
                 if ip_configuration_result != ip_configuration_request:
                     self.log("CHANGED: network interface {0} ip configurations".format(self.name))
                     changed = True
@@ -531,7 +527,11 @@ def exec_module(self, **kwargs):
                     ) for ip_config in self.ip_configurations
                 ]
 
-                nsg = nsg or self.create_default_securitygroup(self.resource_group, self.location, self.name, self.os_type, self.open_ports)
+                nsg = self.create_default_securitygroup(self.resource_group,
+                                                        self.location,
+                                                        self.security_group_name,
+                                                        self.os_type,
+                                                        self.open_ports)
                 self.log('Creating or updating network interface {0}'.format(self.name))
                 nic = self.network_models.NetworkInterface(
                     id=results['id'] if results else None,
@@ -598,6 +598,16 @@ def get_security_group(self, name):
         except Exception as exc:
             return None
 
+    def construct_ip_configuration_set(self, raw):
+        configurations = [str(dict(
+            private_ip_allocation_method=to_native(item.get('private_ip_allocation_method')),
+            public_ip_address_name=(to_native(item.get('public_ip_address').get('name'))
+                                    if item.get('public_ip_address') else to_native(item.get('public_ip_address_name'))),
+            primary=item.get('primary'),
+            name=to_native(item.get('name'))
+        )) for item in raw]
+        return set(configurations)
+
 
 def main():
     AzureRMNetworkInterface()


Test patch:
diff --git a/test/integration/targets/azure_rm_networkinterface/tasks/main.yml b/test/integration/targets/azure_rm_networkinterface/tasks/main.yml
--- a/test/integration/targets/azure_rm_networkinterface/tasks/main.yml
+++ b/test/integration/targets/azure_rm_networkinterface/tasks/main.yml
@@ -12,6 +12,11 @@
       address_prefix: "10.10.0.0/24"
       virtual_network: testnic001
 
+- name: create public ip
+  azure_rm_publicipaddress:
+    name: ansiblepip3
+    resource_group: '{{ resource_group }}'
+
 - name: Create NIC (check mode)
   azure_rm_networkinterface:
       resource_group: "{{ resource_group }}"
@@ -40,6 +45,22 @@
       security_group: testnic001
   register: output
 
+- name: Create NIC using virtual_network_resource_group parameter (idempotent)
+  azure_rm_networkinterface:
+      resource_group: "{{ resource_group }}"
+      name: testnic001rg
+      virtual_network: testnic001
+      virtual_network_resource_group: "{{ resource_group_secondary }}"
+      subnet: testnic001
+      public_ip_name: testnic001
+      public_ip_allocation_method: Static
+      security_group: testnic001
+  register: output
+
+- assert:
+    that:
+      - not output.changed
+
 - name: Delete NIC
   azure_rm_networkinterface:
       resource_group: "{{ resource_group }}"
@@ -139,8 +160,8 @@
       virtual_network: "{{ vn.state.id }}"
       subnet: testnic001
       ip_configurations:
-        - name: ipconfig-add
-          public_ip_name: testnic002
+        - name: ipconfig1
+          public_ip_name: testnic003
         - name: default
           public_ip_name: testnic001
           public_ip_allocation_method: Static
@@ -156,7 +177,6 @@
   azure_rm_networkinterface:
       resource_group: "{{ resource_group }}"
       name: testnic001noip
-      security_group: testnic001
       virtual_network: "{{ vn.state.id }}"
       subnet: testnic001
       ip_configurations:
@@ -183,8 +203,11 @@
 - name: Delete the NIC
   azure_rm_networkinterface:
       resource_group: "{{ resource_group }}"
-      name: testnic001
+      name: "{{ item }}"
       state: absent
+  with_items:
+    - testnic001
+    - testnic001noip
   register: output
 
 - assert: