---
title: Execute an Azure API
source: https://docs.newrelic.com/docs/workflow-automation/setup-and-configure/actions-catalog/azure/azure-execute-api
---

The Azure API action is a universal executor that enables you to call any [Azure REST API](https://learn.microsoft.com/en-us/rest/api/azure/) directly from your workflows. This action provides a flexible way to integrate with Azure services without needing dedicated actions for each Azure operation.

## Execute an Azure API [#azure-execute-api]

This action allows you to execute any operation documented in the [Azure REST API reference](https://learn.microsoft.com/en-us/rest/api/azure/). Simply provide the API path, HTTP method, and request body - the action handles authentication and manages long-running operations automatically.

### Inputs

| Input Field    | Optionality | Type   | Description                                                                                                                                                                                                 |
| -------------- | ----------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clientId`     | Required    | String | Must be passed as a secret. An Azure Service Principal clientID. See how to [register an Azure app.](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/api/register-app-for-token?tabs=portal)     |
| `clientSecret` | Required    | String | Must be passed as a secret. An Azure Service Principal clientSecret. See how to [register an Azure app.](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/api/register-app-for-token?tabs=portal) |
| `tenantId`     | Required    | String | The Azure tenant identifier, can be passed as a secret.                                                                                                                                                     |
| `urlPath`      | Required    | String | The URL path for the [Azure API request](https://learn.microsoft.com/en-us/rest/api/azure/).                                                                                                                |
| `method`       | Required    | String | One of [`"GET", "POST", "PUT", "DELETE", "PATCH"`]                                                                                                                                                          |
| `body`         | Optional    | Map    | An optional body as a JSON map to pass when needed, typically used with `PUT`, `PATCH` and `POST` methods. Secret references are allowed.                                                                   |

### Outputs

| Output Field        | Type    | Description                                                                                                                                                                                                                                                                                                  |
| ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `success`           | Boolean | `success: true | false`                                                                                                                                                                                                                                                                                      |
| `errorMessage`      | String  | Failure reason as message.                                                                                                                                                                                                                                                                                   |
| `response`          | Object  | `<azure api body response>` each api has different response for example [Usages - List - REST API (Azure Virtual Networks)](https://learn.microsoft.com/en-us/rest/api/virtualnetwork/usages/list?view=rest-virtualnetwork-2025-05-01&viewFallbackFrom=rest-virtualnetwork-2025-03-01&tabs=HTTP#list-usages) |
| `asyncResponseUrl`  | String  | Optional for long running operation. The URL to poll for status.                                                                                                                                                                                                                                             |
| `finalResponseUrl`  | String  | Optional for long running operation. This URL returns the final result once the operation completes.                                                                                                                                                                                                         |
| `retryAfterSeconds` | Integer | Optional for long running operation. How long to wait before polling the async URL.                                                                                                                                                                                                                          |
| `eTag`              | String  | Optional. Used for concurrency control when updating a resource to avoid overwriting someone else's changes.                                                                                                                                                                                                 |

### Example

#### Example: GET network usages

```yaml
  - name: getNetworkUsage
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ :secrets:my-client-id }}
      clientSecret: ${{ :secrets:my-client-secret }}
      tenantId: ${{ :secrets:my-tenant-id }}
      urlPath: "subscriptions/c6f367b2-d6af-41f5-a9e3-3828fbd97241/providers/Microsoft.Network/locations/westus/usages?api-version=2025-03-01"
      method: "GET"
      selectors:
        - name: firstResponseValue
          expression: ".response.value[0] | tostring"
```

#### Example: Create ResourceGroup

```yaml
  - name: createResourceGroup
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ :secrets:my-client-id }}
      clientSecret: ${{ :secrets:my-client-secret }}
      tenantId: ${{ :secrets:my-tenant-id }}
      urlPath: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourcegroups/${{ .workflowInputs.resourceGroupName }}?api-version=2021-04-01"
      method: "PUT"
      body:
        location: ${{ .workflowInputs.location }}
        tags:
          environment: test
          createdBy: my-demo
```

#### Example: Complete ResourceGroup and VM creation

```yaml
name: azure-execute-api-create-vm

workflowInputs:
  clientId:
    type: String
    defaultValue: "${{ :secrets:my-client-id }}"
  clientSecret:
    type: String
    defaultValue: "${{ :secrets:my-client-secret }}"
  tenantId:
    type: String
    defaultValue: "${{ :secrets:my-tenant-id }}"
  subscriptionId:
    type: String
  resourceGroupName:
    type: String
  location:
    type: String
    defaultValue: "eastus2"
  vnetName:
    type: String
    defaultValue: "test-vnet"
  subnetName:
    type: String
    defaultValue: "test-subnet"
  nsgName:
    type: String
    defaultValue: "test-nsg"
  publicIpName:
    type: String
    defaultValue: "test-public-ip"
  nicName:
    type: String
    defaultValue: "test-nic"
  vmName:
    type: String
    defaultValue: "my-demo-vm"
  adminUsername:
    type: String
    defaultValue: "azureuser"
  sshPublicKey:
    type: String
    defaultValue: "${{ :secrets:my-ssh-public-key }}"

steps:
  # Step 1: Create Resource Group
  - name: createResourceGroup
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourcegroups/${{ .workflowInputs.resourceGroupName }}?api-version=2021-04-01"
      method: "PUT"
      body:
        location: ${{ .workflowInputs.location }}
        tags:
          environment: test
          createdBy: my-demo
    next: checkResourceGroupAsync

  - name: checkResourceGroupAsync
    type: switch
    switch:
      - condition: ${{ (.steps.createResourceGroup.outputs.asyncResponseUrl // .steps.createResourceGroup.outputs.finalResponseUrl // "") != "" }}
        next: waitBeforePollResourceGroup
    next: createVirtualNetwork

  - name: waitBeforePollResourceGroup
    type: wait
    seconds: ${{ .steps.createResourceGroup.outputs.retryAfterSeconds // 5 }}
    next: pollResourceGroup

  - name: pollResourceGroup
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: ${{ .steps.createResourceGroup.outputs.asyncResponseUrl // .steps.createResourceGroup.outputs.finalResponseUrl }}
      method: "GET"
    next: checkResourceGroupStatus

  - name: checkResourceGroupStatus
    type: switch
    switch:
      - condition: ${{ .steps.pollResourceGroup.outputs.response.status == "Succeeded" }}
        next: createVirtualNetwork
      - condition: ${{ .steps.pollResourceGroup.outputs.response.status == "Failed" }}
        next: logResult
    next: waitBeforePollResourceGroup

  # Step 2: Create Virtual Network
  - name: createVirtualNetwork
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Network/virtualNetworks/${{ .workflowInputs.vnetName }}?api-version=2023-09-01"
      method: "PUT"
      body:
        location: ${{ .workflowInputs.location }}
        properties:
          addressSpace:
            addressPrefixes:
              - "10.0.0.0/24"
    next: checkVirtualNetworkAsync

  - name: checkVirtualNetworkAsync
    type: switch
    switch:
      - condition: ${{ (.steps.createVirtualNetwork.outputs.asyncResponseUrl // .steps.createVirtualNetwork.outputs.finalResponseUrl // "") != "" }}
        next: waitBeforePollVirtualNetwork
    next: createSubnet

  - name: waitBeforePollVirtualNetwork
    type: wait
    seconds: ${{ .steps.createVirtualNetwork.outputs.retryAfterSeconds // 5 }}
    next: pollVirtualNetwork

  - name: pollVirtualNetwork
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: ${{ .steps.createVirtualNetwork.outputs.asyncResponseUrl // .steps.createVirtualNetwork.outputs.finalResponseUrl }}
      method: "GET"
    next: checkVirtualNetworkStatus

  - name: checkVirtualNetworkStatus
    type: switch
    switch:
      - condition: ${{ .steps.pollVirtualNetwork.outputs.response.status == "Succeeded" }}
        next: createSubnet
      - condition: ${{ .steps.pollVirtualNetwork.outputs.response.status == "Failed" }}
        next: logResult
    next: waitBeforePollVirtualNetwork

  # Step 3: Create Subnet
  - name: createSubnet
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Network/virtualNetworks/${{ .workflowInputs.vnetName }}/subnets/${{ .workflowInputs.subnetName }}?api-version=2023-09-01"
      method: "PUT"
      body:
        properties:
          addressPrefix: "10.0.0.0/28"
    next: checkSubnetAsync

  - name: checkSubnetAsync
    type: switch
    switch:
      - condition: ${{ (.steps.createSubnet.outputs.asyncResponseUrl // .steps.createSubnet.outputs.finalResponseUrl // "") != "" }}
        next: waitBeforePollSubnet
    next: createNetworkSecurityGroup

  - name: waitBeforePollSubnet
    type: wait
    seconds: ${{ .steps.createSubnet.outputs.retryAfterSeconds // 5 }}
    next: pollSubnet

  - name: pollSubnet
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: ${{ .steps.createSubnet.outputs.asyncResponseUrl // .steps.createSubnet.outputs.finalResponseUrl }}
      method: "GET"
    next: checkSubnetStatus

  - name: checkSubnetStatus
    type: switch
    switch:
      - condition: ${{ .steps.pollSubnet.outputs.response.status == "Succeeded" }}
        next: createNetworkSecurityGroup
      - condition: ${{ .steps.pollSubnet.outputs.response.status == "Failed" }}
        next: logResult
    next: waitBeforePollSubnet

  # Step 4: Create Network Security Group with SSH access
  - name: createNetworkSecurityGroup
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Network/networkSecurityGroups/${{ .workflowInputs.nsgName }}?api-version=2023-09-01"
      method: "PUT"
      body:
        location: ${{ .workflowInputs.location }}
        properties:
          securityRules:
            - name: "Allow-SSH"
              properties:
                protocol: "Tcp"
                sourcePortRange: "*"
                destinationPortRange: "22"
                sourceAddressPrefix: "*"
                destinationAddressPrefix: "*"
                access: "Allow"
                priority: 100
                direction: "Inbound"
        tags:
          environment: test
          createdBy: my-demo
    next: checkNetworkSecurityGroupAsync

  - name: checkNetworkSecurityGroupAsync
    type: switch
    switch:
      - condition: ${{ (.steps.createNetworkSecurityGroup.outputs.asyncResponseUrl // .steps.createNetworkSecurityGroup.outputs.finalResponseUrl // "") != "" }}
        next: waitBeforePollNetworkSecurityGroup
    next: createPublicIP

  - name: waitBeforePollNetworkSecurityGroup
    type: wait
    seconds: ${{ .steps.createNetworkSecurityGroup.outputs.retryAfterSeconds // 5 }}
    next: pollNetworkSecurityGroup

  - name: pollNetworkSecurityGroup
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: ${{ .steps.createNetworkSecurityGroup.outputs.asyncResponseUrl // .steps.createNetworkSecurityGroup.outputs.finalResponseUrl }}
      method: "GET"
    next: checkNetworkSecurityGroupStatus

  - name: checkNetworkSecurityGroupStatus
    type: switch
    switch:
      - condition: ${{ .steps.pollNetworkSecurityGroup.outputs.response.status == "Succeeded" }}
        next: createPublicIP
      - condition: ${{ .steps.pollNetworkSecurityGroup.outputs.response.status == "Failed" }}
        next: logResult
    next: waitBeforePollNetworkSecurityGroup

  # Step 5: Create Public IP Address
  - name: createPublicIP
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Network/publicIPAddresses/${{ .workflowInputs.publicIpName }}?api-version=2023-09-01"
      method: "PUT"
      body:
        location: ${{ .workflowInputs.location }}
        sku:
          name: "Standard"
        properties:
          publicIPAllocationMethod: "Static"
          publicIPAddressVersion: "IPv4"
        tags:
          environment: test
          createdBy: my-demo
    next: checkPublicIPAsync

  - name: checkPublicIPAsync
    type: switch
    switch:
      - condition: ${{ (.steps.createPublicIP.outputs.asyncResponseUrl // .steps.createPublicIP.outputs.finalResponseUrl // "") != "" }}
        next: waitBeforePollPublicIP
    next: createNetworkInterface

  - name: waitBeforePollPublicIP
    type: wait
    seconds: ${{ .steps.createPublicIP.outputs.retryAfterSeconds // 5 }}
    next: pollPublicIP

  - name: pollPublicIP
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: ${{ .steps.createPublicIP.outputs.asyncResponseUrl // .steps.createPublicIP.outputs.finalResponseUrl }}
      method: "GET"
    next: checkPublicIPStatus

  - name: checkPublicIPStatus
    type: switch
    switch:
      - condition: ${{ .steps.pollPublicIP.outputs.response.status == "Succeeded" }}
        next: createNetworkInterface
      - condition: ${{ .steps.pollPublicIP.outputs.response.status == "Failed" }}
        next: logResult
    next: waitBeforePollPublicIP

  # Step 6: Create Network Interface with Public IP and NSG
  - name: createNetworkInterface
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Network/networkInterfaces/${{ .workflowInputs.nicName }}?api-version=2023-09-01"
      method: "PUT"
      body:
        location: ${{ .workflowInputs.location }}
        properties:
          networkSecurityGroup:
            id: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Network/networkSecurityGroups/${{ .workflowInputs.nsgName }}"
          ipConfigurations:
            - name: "${{ .workflowInputs.nicName }}-ipconfig1"
              properties:
                privateIPAllocationMethod: "Dynamic"
                subnet:
                  id: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Network/virtualNetworks/${{ .workflowInputs.vnetName }}/subnets/${{ .workflowInputs.subnetName }}"
                publicIPAddress:
                  id: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Network/publicIPAddresses/${{ .workflowInputs.publicIpName }}"
    next: checkNetworkInterfaceAsync

  - name: checkNetworkInterfaceAsync
    type: switch
    switch:
      - condition: ${{ (.steps.createNetworkInterface.outputs.asyncResponseUrl // .steps.createNetworkInterface.outputs.finalResponseUrl // "") != "" }}
        next: waitBeforePollNetworkInterface
    next: createVirtualMachine

  - name: waitBeforePollNetworkInterface
    type: wait
    seconds: ${{ .steps.createNetworkInterface.outputs.retryAfterSeconds // 5 }}
    next: pollNetworkInterface

  - name: pollNetworkInterface
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: ${{ .steps.createNetworkInterface.outputs.asyncResponseUrl // .steps.createNetworkInterface.outputs.finalResponseUrl }}
      method: "GET"
    next: checkNetworkInterfaceStatus

  - name: checkNetworkInterfaceStatus
    type: switch
    switch:
      - condition: ${{ .steps.pollNetworkInterface.outputs.response.status == "Succeeded" }}
        next: createVirtualMachine
      - condition: ${{ .steps.pollNetworkInterface.outputs.response.status == "Failed" }}
        next: logResult
    next: waitBeforePollNetworkInterface

  # Step 7: Create Virtual Machine
  - name: createVirtualMachine
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Compute/virtualMachines/${{ .workflowInputs.vmName }}?api-version=2023-09-01"
      method: "PUT"
      body:
        location: ${{ .workflowInputs.location }}
        properties:
          hardwareProfile:
            vmSize: "Standard_B2ts_v2"
          storageProfile:
            imageReference:
              publisher: "Canonical"
              offer: "0001-com-ubuntu-server-jammy"
              sku: "22_04-lts-gen2"
              version: "latest"
            osDisk:
              name: "${{ .workflowInputs.vmName }}-osdisk"
              createOption: "FromImage"
              managedDisk:
                storageAccountType: "Standard_LRS"
              diskSizeGB: 30
          osProfile:
            computerName: ${{ .workflowInputs.vmName }}
            adminUsername: ${{ .workflowInputs.adminUsername }}
            linuxConfiguration:
              disablePasswordAuthentication: true
              ssh:
                publicKeys:
                  - path: "/home/${{ .workflowInputs.adminUsername }}/.ssh/authorized_keys"
                    keyData: ${{ .workflowInputs.sshPublicKey }}
          networkProfile:
            networkInterfaces:
              - id: "/subscriptions/${{ .workflowInputs.subscriptionId }}/resourceGroups/${{ .workflowInputs.resourceGroupName }}/providers/Microsoft.Network/networkInterfaces/${{ .workflowInputs.nicName }}"
                properties:
                  primary: true
        tags:
          environment: test
          createdBy: my-demo
    next: checkVirtualMachineAsync

  - name: checkVirtualMachineAsync
    type: switch
    switch:
      - condition: ${{ (.steps.createVirtualMachine.outputs.asyncResponseUrl // .steps.createVirtualMachine.outputs.finalResponseUrl // "") != "" }}
        next: waitBeforePollVirtualMachine
    next: logResult

  - name: waitBeforePollVirtualMachine
    type: wait
    seconds: ${{ .steps.createVirtualMachine.outputs.retryAfterSeconds // 5 }}
    next: pollVirtualMachine

  - name: pollVirtualMachine
    type: action
    action: azure.execute.api
    version: 1
    inputs:
      clientId: ${{ .workflowInputs.clientId }}
      clientSecret: ${{ .workflowInputs.clientSecret }}
      tenantId: ${{ .workflowInputs.tenantId }}
      urlPath: ${{ .steps.createVirtualMachine.outputs.asyncResponseUrl // .steps.createVirtualMachine.outputs.finalResponseUrl }}
      method: "GET"
    next: checkVirtualMachineStatus

  - name: checkVirtualMachineStatus
    type: switch
    switch:
      - condition: ${{ .steps.pollVirtualMachine.outputs.response.status == "Succeeded" }}
        next: logResult
      - condition: ${{ .steps.pollVirtualMachine.outputs.response.status == "Failed" }}
        next: logResult
    next: waitBeforePollVirtualMachine

  # Step 8: Log Results
  - name: logResult
    type: action
    action: newrelic.ingest.sendLogs
    version: 1
    inputs:
      logs:
        - message: "Azure VM Creation Complete"
          attributes:
            resourceGroupSuccess: ${{ .steps.createResourceGroup.outputs.success }}
            vnetSuccess: ${{ .steps.createVirtualNetwork.outputs.success }}
            subnetSuccess: ${{ .steps.createSubnet.outputs.success }}
            nsgSuccess: ${{ .steps.createNetworkSecurityGroup.outputs.success }}
            publicIpSuccess: ${{ .steps.createPublicIP.outputs.success }}
            nicSuccess: ${{ .steps.createNetworkInterface.outputs.success }}
            vmSuccess: ${{ .steps.createVirtualMachine.outputs.success }}
            resourceGroupName: ${{ .workflowInputs.resourceGroupName }}
            vmName: ${{ .workflowInputs.vmName }}
            location: ${{ .workflowInputs.location }}
            vmSize: ${{ .steps.createVirtualMachine.outputs.response.properties.hardwareProfile.vmSize // "N/A" }}
            provisioningState: ${{ .steps.createVirtualMachine.outputs.response.properties.provisioningState // "N/A" }}
            vmTags: ${{ .steps.createVirtualMachine.outputs.response.tags // {} | tostring }}
```
