The Azure API action is a universal executor that enables you to call any Azure REST API 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
This action allows you to execute any operation documented in the Azure REST API reference. Simply provide the API path, HTTP method, and request body - the action handles authentication and manages long-running operations automatically.
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. |
clientSecret | Required | String | Must be passed as a secret. An Azure Service Principal clientSecret. See how to register an Azure app. |
tenantId | Required | String | The Azure tenant identifier, can be passed as a secret. |
urlPath | Required | String | The URL path for the Azure API request. |
method | Required | String | One of [ |
body | Optional | Map | An optional body as a JSON map to pass when needed, typically used with |
Output Field | Type | Description |
|---|---|---|
success | Boolean |
|
errorMessage | String | Failure reason as message. |
response | Object |
each api has different response for example Usages - List - REST API (Azure Virtual Networks) |
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: GET network usages
- 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
- 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-demoExample: Complete ResourceGroup and VM creation
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 }}