How to get the creation timestamp of an Azure resource
Introduction
There are situations where we would like to know when a resource was created in an Azure subscription.
Unfortunately the Properties
blade of a resource doesn't reveal the creation timestamp from within the Azure Portal.
The same situation applies when we try to apply our Azure PowerShell
or Azure CLI
kata. For example the following commands wont give us
the required information.
C:\> Get-AzResource -Name nic-1
Name : nic-1
ResourceGroupName : rg-virtual-machines
ResourceType : Microsoft.Network/networkInterfaces
Location : westeurope
ResourceId : /subscriptions/{subscription}/resourceGroups/rg-virtual-machines/providers/Microsoft.Network/networkInterfaces/nic-1
Tags :
Naa, not helpful... What properties are there?
C:\> Get-AzResource -Name nic-1 | get-member
TypeName: Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResource
Name MemberType Definition
---- ---------- ----------
[...]
CreatedTime Property System.Nullable[datetime] CreatedTime {get;set;}
[...]
Interessting. There is a member called CreatedTime
, let's inspect that one.
C:\> (Get-AzResource -Name nic-1).CreatedTime
C:\>
Hm seems to be empty 😪 Okay, how about expanding the query?
C:\> (Get-AzResource -Name nic-1 -ExpandProperties).CreatedTime
C:\>
Nope, still no luck. How about Azure CLI
?
$ az resource show \
--name nic-1 \
--resource-group rg-virtual-machines \
--resource-type Microsoft.Network/networkInterfaces \
--output jsonc \
--query createdTime
$
And again, nothing! 😫 Okay there MUST be a way to get to that piece of information.
Let's see what happens if query the Azure REST API manually which is available at https://management.azure.com
. Let's get to it.
Edit & TLDR
I have just found a way which is ways more comfortable than the instructions given below.
The key here is the the magic az rest
command, which allows us to send custom requests and handles all of the authentication & authorization stuff for use.
az rest \
--method GET \
--url "https://management.azure.com/subscriptions/{subscription-id}/resources" \
--url-parameters api-version=2020-06-01 \$expand=createdTime \$select=name,createdTime
Querying the Azure REST API
Steps involved
- Create a service principal
- Request an access token
- Use that token to request data from API
Create a service principal
Run the following command to create a service principal and make a note of the output. We are going to need that SP to request an access token from the token endpoit, that we later can use to request data from the management API.
As we are only going to need a read-only access there is no need to give the contributor
role to that SP (which is the default, if the --role
parameter is ommited).
az ad sp create-for-rbac --name postman --role reader
{
"appId": "{app-guid}",
"displayName": "postman",
"name": "http://postman",
"password": "auto-generated-password",
"tenant": "{tenant-guid}"
}
Request an access token
POST https://login.microsoftonline.com/{tenantId}/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id={appId}&
client_secret={password}&
resource=https://management.azure.com/
This is going to give us an access token.
{
"token_type": "Bearer",
"expires_in": "3599",
"ext_expires_in": "3599",
"expires_on": "1604357538",
"not_before": "1604353638",
"resource": "https://management.azure.com/",
"access_token": "eyJ0eXAi[...]"
}
As a side note, we are using the OAuth 2.0 Client Credentials Flow here.
Request property
Now that we have an access token we can call the list action and set the authorization key in the header.
Please note, that using the Get or Get By Id methods wont work, as it doesn't allow the use of the
$expand
parameter that is required to retrieve thecreatedTime
property!
GET https://management.azure.com/subscriptions/{subscriptionId}/resources
Authorization: Bearer eyJ0eXAi[...]
api-version=2020-06-01&
$filter=name eq 'nic-1'&
$expand=createdTime&
$select=name,createdTime
Finally! 🙄
{
"value": [
{
"id": "/subscriptions/{subscriptionId}/resourceGroups/rg-virtual-machines/providers/Microsoft.Network/networkInterfaces/nic-1",
"name": "nic-1",
"type": "Microsoft.Network/networkInterfaces",
"location": "westeurope",
"createdTime": "2020-10-30T21:24:04.4488198Z",
"tags": {}
}
]
}
Conclusion
That was pretty time consuming 😫 It seems that the Get
and Get By Id
methods of the Azure REST API are getting used behind the scenes when using Get-AzResource
or az resource
, which doesn't allow the usage of the $expand
parameter.
Maybe I find some spare time in the future and wrap this into a script.