Azure VMware Solutions REST API - part 2: az rest
Overview
After a discovery of Azure VMware Solution REST API through the Postman collection in part 1, we will use some of the fundamentals API calls through az rest
, a useful subset of the Azure Command-Line Interface.
Compared to Postman, I consider az rest
an easier way to discover Azure REST API in a blog post as it doesn't require to post screenshots or long code samples to narrate the exploration. But of course, you could use the AVS Postman collection to achieve the same purpose or any other REST client tool (httpie, curl etc.): this is the great power of REST APIs.
Preparation
A big benefit of using az rest
to manage an Azure product, like Azure VMware Solution, through its REST API is that the tool already manages the authentication or provide a simple way to connect to your tenant and to execute request without manually providing authentication tokens.
Login
If you have not already logged-in to your tenant, you can follow the next steps:
1az login
2
3# Or, if you manage multiple tenants, you can add the --tenant parameter to login to it:
4az login --tenant xxxxxxxxxxx.onmicrosoft.com
By default, this command will open a web browser asking you to connect to your azure tenant. Once logged-in your browser, you can close the tab and the CLI will successfully be connected.
If your terminal session cannot connect to a web browser (if you use a remote session like SSH for example), you can use:
1az login --use-device-code
2# To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code ********** to authenticate.
After opening the provided link and used the token, your CLI should be connected.
You can check your connection information with:
1az account show --output table
2
3EnvironmentName HomeTenantId IsDefault Name State TenantId
4----------------- ------------------------------------ ----------- ---------------------------- ------- ------------------------------------
5AzureCloud ********-****-****-****-************ True Azure VMware Solutions Tests Enabled ********-****-****-****-************
Subscription
If you use multiple subscriptions (it is recommended!), you can select to one hosting your AVS:
1# List available subscriptions
2az account subscription list --output table
3
4# Select one subscription
5az account set --subscription ********-****-****-****-************
SDDC base URI
To achieve quick and successfully REST requests on a specific resource, it could be useful to get its base URI and to store it in an environment variable.
For an AVS resource, this base URI is built like:
https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCEGROUP_NAME}/providers/Microsoft.AVS/privateClouds/${SDDC_NAME}
With the following components:
https://management.azure.com
: The Azure REST API domain endpoint/subscriptions/${SUBSCRIPTION_ID}
resourceGroups/${RESOURCEGROUP_NAME}
/providers/Microsoft.AVS
: A pointer to the AVS resources provider/privateClouds/${SDDC_NAME}
With the following commands, you can easily populate an AVS base URI:
1export SUBSCRIPTION_ID="********-****-****-****-************"
2export RESOURCEGROUP_NAME="resourceGroupName"
3export SDDC_NAME="AVS-Tests"
4export SDDC_BASE_URI="https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCEGROUP_NAME}/providers/Microsoft.AVS/privateClouds/${SDDC_NAME}"
API version
When using Azure API, you need to specify the API version you want to use. For AVS, I currently use version 2021-12-01 (the last version currently available):
1export API_VERSION="api-version=2021-12-01"
AVS endpoints and credentials management
When you need to connect to an AVS system, you need two mandatory information:
- The endpoints name
- The credentials to use
The endpoints can be retrieved from (Doc.):
1# The global information about the AVS deployment:
2az rest -m get -u "${SDDC_BASE_URI}?${API_VERSION}"
3
4# A filtered result from the previous request:
5az rest -m get -u "${SDDC_BASE_URI}?${API_VERSION}" | jq ".properties.endpoints"
6{
7 "hcxCloudManager": "https://10.100.100.9/",
8 "nsxtManager": "https://10.100.100.3/",
9 "vcsa": "https://10.100.100.2/"
10}
And credentials (Doc.):
1az rest -m post -u "${SDDC_BASE_URI}/listAdminCredentials?${API_VERSION}"
2{
3 "nsxtPassword": "***************",
4 "nsxtUsername": "admin",
5 "vcenterPassword": "***************",
6 "vcenterUsername": "cloudadmin@vsphere.local"
7}
Please note that you must use the
post
HTTP method to get credentials.
With this information, you can now connect to your AVS instance.
AVS network management
Some parts of an AVS workload management can be made through the Azure API and portal (in replacement or addition to the VMware products API or UI).
NSX-T Tier1 gateway
When dealing with NSX-T based networks, the Tier1 gateway (T1 GW) is an important element to consider.
In a vast majority of scenarios (including the AVS deployment model), the T1 GW is considered the first router component, accessible from a workload to communicate with network items out of its subnet.
By default, a first T1 GW is deployed with AVS and you can retrieve details about it by using (Doc.):
1az rest -m get -u "${SDDC_BASE_URI}/workloadNetworks/default/gateways?${API_VERSION}"
Note: Only a
get
method is available as you cannot Create, Update or Delete T1 gateways through the Azure API/UI: actions on T1 GW are only available from NSX-T itself (including creating new GWs).
DHCP service
It is possible to rely on the T1 GW to provide DHCP leases within network segment. The DHCP service can run as a server or a relay from another server.
The simpliest role to configure is the server one:
1# Prepare data for the request
2server_name="DHCPServer"
3body=$(cat <<EOF
4{
5 "properties": {
6 "displayName": "${DHCPServer}",
7 "revision": 0,
8 "dhcpType": "SERVER",
9 "serverAddress": "10.100.104.1/24",
10 "leaseTime":null
11 }
12}
13EOF
14)
15
16# Create the DHCP service
17az rest -m put -u "${SDDC_BASE_URI}/workloadNetworks/default/dhcpConfigurations/${DHCPServer}?${API_VERSION}" --body "${body}"
NSX-T Segments
For example, you can Create, Read, Update or Delete (C.R.U.D.) NSX-T segments with the Azure API:
1# Prepare data for the request
2segment_name="VM-tests-109" # Name of segment to create
3t1_gw_name="TNTXX-T1" # T1 GW name
4body=$(cat <<EOF
5{
6 "properties": {
7 "displayName": "${segment_name}",
8 "connectedGateway": "${t1_gw_name}",
9 "subnet": {
10 "dhcpRanges": [
11 "10.100.109.10-10.100.109.100"
12 ],
13 "gatewayAddress": "10.100.109.1/24"
14 },
15 "revision": 0
16 }
17}
18EOF
19)
20
21# Create segment
22az rest -m put -u "${SDDC_BASE_URI}/workloadNetworks/default/segments/${segment_name}?${API_VERSION}" --body "${body}"
23
24# Get the new segment
25az rest -m get -u "${SDDC_BASE_URI}/workloadNetworks/default/segments/${segment_name}?${API_VERSION}"
26
27# Output
28{
29 "id": "/subscriptions/********-****-****-****-************/resourceGroups/resourceGroupName/providers/Microsoft.AVS/privateClouds/AVS-Tests/workloadNetworks/default/segments/VM-tests-109",
30 "name": "VM-tests-109",
31 "properties": {
32 "connectedGateway": "TNTXX-T1",
33 "displayName": "VM-tests-109",
34 "provisioningState": "Fulfilled",
35 "revision": 0,
36 "status": "IN_PROGRESS",
37 "subnet": {
38 "dhcpRanges": [
39 "10.100.109.10-10.100.109.100"
40 ],
41 "gatewayAddress": "10.100.109.1/24"
42 }
43 },
44 "resourceGroup": "resourceGroupName",
45 "type": "Microsoft.AVS/privateClouds/workloadNetworks/segments"
46}
AVS interconnectivity management
When your AVS instance is deployed, you will certainly need to connect it with external components like other Azure Resources, jump servers, on-premises resources etc.
I will not cover all the available AVS interconnectivity solutions in this post but here is a list of supported ones:
In this post, we will see how-to setup an ExpressRoute circuit.
ExpressRoute
The first information to collect is the ExpressRoute ID or Circuit ID:
1az rest -m get -u "${SDDC_BASE_URI}?${API_VERSION}" | jq ".properties.circuit"
2
3# Output
4{
5 "expressRouteID": "/subscriptions/********-****-****-****-************/resourceGroups/resourceGroupName/providers/Microsoft.Network/expressRouteCircuits/tntxx-cust-p02-westeurope-er",
6 "expressRoutePrivatePeeringID": "/subscriptions/********-****-****-****-************/resourceGroups/resourceGroupName/providers/Microsoft.Network/expressRouteCircuits/tntxx-cust-p02-westeurope-er/peerings/AzurePrivatePeering",
7 "primarySubnet": "10.100.100.232/30",
8 "secondarySubnet": "10.100.100.236/30"
9}
We keep only the expressRouteID
information to create a new ExpressRoute authorization key:
1connection_name="expressroute-test" # name the future authorization key
2sddc_er_id=$(az rest -m get -u "${SDDC_BASE_URI}?${API_VERSION}" | jq ".properties.circuit.expressRouteID") # store the expressRouteID
3body=$(cat <<EOF
4{
5 "properties": {
6 "expressRouteId": ${sddc_er_id}
7 }
8}
9EOF
10)
11
12az rest -m put -u "${SDDC_BASE_URI}/authorizations/${connection_name}?${API_VERSION}" --body "${body}"
13
14# Output
15{
16 "id": "/subscriptions/********-****-****-****-************/resourceGroups/resourceGroupName/providers/Microsoft.AVS/privateClouds/AVS-CSU-FR-LRI/authorizations/expressroute-test",
17 "name": "expressroute-test",
18 "properties": {
19 "expressRouteAuthorizationId": "/subscriptions/********-****-****-****-************/resourceGroups/tntxx-cust-p02-westeurope/providers/Microsoft.Network/expressRouteCircuits/tntxx-cust-p02-westeurope-er/authorizations/avs_resource_expressroute-test",
20 "expressRouteAuthorizationKey": "d502f9cb-91a2-4069-a474-7363e723bccc",
21 "expressRouteId": "/subscriptions/********-****-****-****-************/resourceGroups/tntxx-cust-p02-westeurope/providers/Microsoft.Network/expressRouteCircuits/tntxx-cust-p02-westeurope-er",
22 "provisioningState": "Succeeded"
23 },
24 "resourceGroup": "AVS-CSU-FR-LRI",
25 "type": "Microsoft.AVS/privateClouds/authorizations"
26}
This will provide you with an authorization key: expressRouteAuthorizationKey
to be used to create a new connection from an expressRoute compatible component, like a Virtual network gateway:
Conclusion
As you may understand from the AVS API reference or the AVS Postman collection, this post is not a complete coverage of the AVS REST API capabilities but an example of what you can do with it and the az rest
CLI tool.
To simplify the above commands, I did not mention any header like Accept
or Content-Type
as we used the default type of data when dealing with requests and answers: application/json
.
Using API with az rest
is a very easy way to manage automation of an AVS deployed instance with an imperative approach. A declarative approach may be preferred to managed large AVS workloads with production and self-remediation requirements and I will try to cover it in a future (not-yet-planned) post.
Credits
Title photo by Joshua Reddekopp on Unsplash