ansible-collections / azure

Development area for Azure Collections
https://galaxy.ansible.com/azure/azcollection
GNU General Public License v3.0
247 stars 330 forks source link

azure_rm_azurefirewall does not generate private ip address when creating new firewall #1750

Closed DII-dsward closed 2 weeks ago

DII-dsward commented 4 weeks ago
SUMMARY

New Azure Firewall deployment with Ansible does not generate a private Ip address and provisioning state shows as failed.

ISSUE TYPE
COMPONENT NAME

azure.azcollection.azure_rm_azurefirewall

ANSIBLE VERSION
core 2.15.12
COLLECTION VERSION
2.7.0 - certified collection
CONFIGURATION
ANSIBLE_FORCE_COLOR(env: ANSIBLE_FORCE_COLOR) = True
COLLECTIONS_PATHS(env: ANSIBLE_COLLECTIONS_PATH) = ['/runner/requirements_collections', '/root/.ansible/collections', '/usr/share/ansible/collections']
CONFIG_FILE() = /etc/ansible/ansible.cfg
DEFAULT_CALLBACK_PLUGIN_PATH(env: ANSIBLE_CALLBACK_PLUGINS) = ['/runner/artifacts/16883/callback']
DEFAULT_JINJA2_NATIVE(env: ANSIBLE_JINJA2_NATIVE) = True
DEFAULT_ROLES_PATH(env: ANSIBLE_ROLES_PATH) = ['/runner/requirements_roles', '/root/.ansible/roles', '/usr/share/ansible/roles', '/etc/ansible/roles']
DEFAULT_STDOUT_CALLBACK(env: ANSIBLE_STDOUT_CALLBACK) = awx_display
HOST_KEY_CHECKING(env: ANSIBLE_HOST_KEY_CHECKING) = False
INVENTORY_UNPARSED_IS_FAILED(env: ANSIBLE_INVENTORY_UNPARSED_FAILED) = True
RETRY_FILES_ENABLED(env: ANSIBLE_RETRY_FILES_ENABLED) = False
OS / ENVIRONMENT
Firewall SKU: Standard
STEPS TO REPRODUCE

From AAP

# 3. Create or update the Azure Firewall using the correct VNet with 'AzureFirewallSubnet'
- name: Create or update the Azure Firewall
  azure.azcollection.azure_rm_azurefirewall:
    resource_group: "VnetRSG"
    name: "AZFWUSC1"
    location: "southcentralus"
    ip_configurations:
      - name: "FirewallInternetEgress"
        public_ip_address:
          id: "{{ available_public_ip.id }}"
        subnet:
          id: "/subscriptions/{{ subscription_id }}/resourceGroups/VnetRSG/providers/Microsoft.Network/virtualNetworks/VNETUSC1/subnets/AzureFirewallSubnet"
    state: "present"
EXPECTED RESULTS

Azure firewall should use an Ip on the AzureFirewallSubnet Ip range and provisioning should reflect succeeded.

ACTUAL RESULTS

Azure firewall does deploy but it does not have a private Ip address and the provisioning state shows as failed. Azure vnet shows the firewall object without a private Ip address as well.

Fred-sun commented 3 weeks ago

@DII-dsward I test locally, the resource will be created successfully, and configure the corresponding 'private_id', can you try according to the following script?

- name: Create virtual network
  azure_rm_virtualnetwork:
    name: "{{ virtual_network_name }}"
    address_prefixes_cidr:
      - 10.1.0.0/16
      - 172.100.0.0/16
    dns_servers:
      - 127.0.0.1
      - 127.0.0.3
    tags:
      testing: testing
      delete: on-exit
    resource_group: "{{ resource_group }}"

- name: Create subnet
  azure_rm_subnet:
    name: "{{ subnet_name }}"
    virtual_network_name: "{{ virtual_network_name }}"
    resource_group: "{{ resource_group }}"
    address_prefix_cidr: "10.1.0.0/24"

- name: Create public IP address
  azure_rm_publicipaddress:
    resource_group: "{{ resource_group }}"
    allocation_method: Static
    name: "{{ public_ipaddress_name }}"
    sku: Standard
  register: pip_output

- name: Create Azure Firewall
  azure_rm_azurefirewall:
    resource_group: '{{ resource_group }}'
    name: '{{ azure_firewall_name }}'
    ip_configurations:
      - subnet:
          virtual_network_name: "{{ virtual_network_name }}"
          name: "{{ subnet_name }}"
        public_ip_address:
          name: "{{ public_ipaddress_name }}"
        name: azureFirewallIpConfiguration
  register: output

- name: Get info of the Azure Firewall
  azure_rm_azurefirewall_info:
    resource_group: '{{ resource_group }}'
    name: '{{ azure_firewall_name }}'
  register: output
- name: Print the azure firewall facts
  debug:
      var: output

    "output": {
        "changed": false,
        "failed": false,
        "firewalls": {
            "etag": "W/\"55f620c1-d4c4-4a77-ab34-a3dc7e3d6bec\"",
            "id": "/subscriptions/xxx/resourceGroups/v-xisuRG01/providers/Microsoft.Network/azureFirewalls/myFirewall",
            "ip_configurations": [
                {
                    "etag": "W/\"55f620c1-d4c4-4a77-ab34-a3dc7e3d6bec\"",
                    "id": "/subscriptions/xxx/resourceGroups/v-xisuRG01/providers/Microsoft.Network/azureFirewalls/myFirewall/azureFirewallIpConfigurations/azureFirewallIpConfiguration",
                    "name": "azureFirewallIpConfiguration",
                    "properties": {
                        "privateIPAddress": "10.1.0.4",
                        "privateIPAllocationMethod": "Dynamic",
                        "provisioningState": "Succeeded",
                        "publicIPAddress": {
                            "id": "/subscriptions/xxx/resourceGroups/v-xisuRG01/providers/Microsoft.Network/publicIPAddresses/myPublicIpAddress"
                        },
                        "subnet": {
                            "id": "/subscriptions/xxx/resourceGroups/v-xisuRG01/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/AzureFirewallSubnet"
                        }
                    },
                    "type": "Microsoft.Network/azureFirewalls/azureFirewallIpConfigurations"
                }
            ],
            "location": "eastus",
            "name": "myFirewall",
            "nat_rule_collections": [],
            "network_rule_collections": [],
            "provisioning_state": "Succeeded",
            "tags": null
        }
    }
}
Fred-sun commented 3 weeks ago

@DII-dsward Your creation failure should be due to the fact that your subnet, public IP address and azure firewall are not in the same region. Thank you!

DII-dsward commented 3 weeks ago

I have switched from using id to name as you suggested. These deployments don't show up under the resource group deployments list, so I cannot provide any output from Azure. When this deploys and provisioning shows as failed, there is a migrate to firewall policy button. If I click through that it also fails because the firewall has a provisioning state of failed. But it does then provide an output from azure in the deployment list of the resource group showing this:

{
  "code": "InternalServerError",
  "message": "An error occurred.",
  "details": []
}

Here is the playbook

  # 1. Create or update the public IP if none is available
  - name: Create public IP if none is available
    azure.azcollection.azure_rm_publicipaddress:
      resource_group: "VnetRSG"
      name: "PIP-AZFWUSC1-1"
      location: "southcentralus"
      allocation_method: "Static"
      sku: "Standard"
      state: "present"
    register: new_public_ip

  # 2. Create or update the Azure Firewall using names instead of IDs
  - name: Create or update the Azure Firewall
    azure.azcollection.azure_rm_azurefirewall:
      resource_group: "VnetRSG"
      name: "AZFWUSC1"
      location: "southcentralus"
      ip_configurations:
        - name: "azureFirewallIpConfiguration"
          public_ip_address:
            name: "{{ new_public_ip.name }}"
          subnet:
            virtual_network_name: "FW_VNET"
            name: "AzureFirewallSubnet"
      state: "present"

Here is the ansible output

{
  "changed": true,
  "id": "/subscriptions/<omitted>/resourceGroups/VnetRSG/providers/Microsoft.Network/azureFirewalls/AZFWUSC1",
  "invocation": {
    "module_args": {
      "resource_group": "VnetRSG",
      "name": "AZFWUSC1",
      "location": " southcentralus \n",
      "ip_configurations": [
        {
          "name": "azureFirewallIpConfiguration",
          "public_ip_address": {
            "name": "PIP-AZFWUSC1-1"
          },
          "subnet": {
            "virtual_network_name": "FW_VNET",
            "name": "AzureFirewallSubnet"
          }
        }
      ],
      "state": "present",
      "auth_source": "auto",
      "cloud_environment": "AzureCloud",
      "api_profile": "latest",
      "disable_instance_discovery": false,
      "append_tags": true,
      "profile": null,
      "subscription_id": null,
      "client_id": null,
      "secret": null,
      "tenant": null,
      "ad_user": null,
      "password": null,
      "cert_validation_mode": null,
      "adfs_authority_url": null,
      "log_mode": null,
      "log_path": null,
      "x509_certificate_path": null,
      "thumbprint": null,
      "tags": null,
      "application_rule_collections": null,
      "nat_rule_collections": null,
      "network_rule_collections": null
    }
  },
  "_ansible_no_log": false
}

Should I be using azure.azcollection.azure_rm_firewallpolicy to deploy these firewalls instead?

Fred-sun commented 3 weeks ago

@DII-dsward I have not been able to simulate the error you encountered, so I am not sure whether the connection (--) solves the problem you encountered, you can refer to the following way to try, thank you!


![aure_fireawll](https://github.com/user-attachments/assets/acc6f9c3-89fa-404e-a10e-4c490f081bb1)
DII-dsward commented 3 weeks ago

Adding the user defined route in the screenshot below doesn’t help unfortunately. I can deploy this azure firewall manually via the azure marketplace just fine. Ansible’s account has the same rights I do but fails every time. The manual deployment takes 10 minutes. The ansible deployment completes in less than 2 minutes. I will go ahead and open a support ticket and reference this github issue.

DII-dsward commented 2 weeks ago

The issue was identified. 'location' is not a valid parameter. Removing 'location' from the azure.azcollection.azure_rm_azurefirewall task deployed the firewall as intended. Thanks all for your help.

p3ck commented 2 weeks ago

The documentation and module includes location so we should remove that if it's not a valid option.

Fred-sun commented 2 weeks ago

@p3ck This parameter 'location' cannot be removed because the default location is the same as the resource group. However, you can use this parameter to configure the region that is different from the resource group, but same with the virtual network, the public IP address location. It can deploy success. Thank you!!


sample as:
- name: Create a resource group
  azure_rm_resourcegroup:
    name: "{{ resource_group }}"
    location: westus

- name: Define random variable
  ansible.builtin.set_fact:
    virtual_network_name: myVirtualNetwork
    subnet_name: AzureFirewallSubnet
    rpfx: test01

- name: Create virtual network
  azure_rm_virtualnetwork:
    resource_group: "{{ resource_group }}"
    name: "{{ virtual_network_name }}"
    address_prefixes_cidr:
      - 10.1.0.0/16
      - 172.100.0.0/16

- name: Create a subnet
  azure_rm_subnet:
    resource_group: "{{ resource_group }}"
    name: "{{ subnet_name }}"
    virtual_network_name: "{{ virtual_network_name }}"
    address_prefix_cidr: "10.1.0.0/24"

- name: Create public IP if none is available
  azure.azcollection.azure_rm_publicipaddress:
    resource_group: "{{ resource_group }}"
    name: "PIP-AZFWUSC1-2"
    location: "eastus"
    allocation_method: "Static"
    sku: "Standard"
    state: "present"
  register: new_public_ip

- name: Create or update the Azure Firewall
  azure.azcollection.azure_rm_azurefirewall:
    resource_group: "{{ resource_group }}"
    name: "AZFWUSC1"
    location: eastus
    ip_configurations:
      - name: "azureFirewallIpConfiguration"
        public_ip_address:
          name: "{{ new_public_ip.state.name }}"
        subnet:
          virtual_network_name: "{{ virtual_network_name }}"
          name: "{{ subnet_name }}"
    state: "present"