Mapping Extra Resources
As you've probably looked at the Resource Templates page, you've noticed that the Azure Exporter supports many Azure resources, but not all of them are documented in the Resource Templates page.
This page will help you understand what kind of Azure resources are supported by the Azure integration and how to map them into Port.
Is the resource supported by the Azure Exporter?โ
The Azure Exporter relies on the Base Azure Resource to have a List API by subscription to get all the resources of a specific type.
If it is a resource that is not documented in the Resource Templates page, you can map it to Port by following these steps:
- Find the resource in the Azure REST API reference.
- If it's a base resource (in the format of
Microsoft.<Provider>/<resourceName>) can be found in the type example response and in the API URL
- If it has a List API by subscription it will be supported by the Azure Exporter.
- If it's an extension resource (in the format of
Microsoft.<Provider>/<resourceName>/<extensionName>) such asMicrosoft.Storage/storageAccounts/blobServices/containers.- Then, if the base resource is supported by the Azure Exporter, the extension resource will be supported as well.
Mapping the resource to Portโ
After you've found the resource in the Azure REST API reference and you've confirmed that it is supported by the Azure Exporter, you can map it to Port by following these steps:
Blueprintโ
Create a Port blueprint definition for the resource. The blueprint definition is based on the resource API response in the Azure REST API reference.
Azure Storage Account Rest API Response Example
{
"value": [
{
"id": "/subscriptions/{subscription-id}/resourceGroups/res2627/providers/Microsoft.Storage/storageAccounts/sto1125",
"kind": "Storage",
"location": "eastus",
"name": "sto1125",
"properties": {
"isHnsEnabled": true,
"creationTime": "2017-05-24T13:28:53.4540398Z",
"primaryEndpoints": {
"web": "https://sto1125.web.core.windows.net/",
"dfs": "https://sto1125.dfs.core.windows.net/",
"blob": "https://sto1125.blob.core.windows.net/",
"file": "https://sto1125.file.core.windows.net/",
"queue": "https://sto1125.queue.core.windows.net/",
"table": "https://sto1125.table.core.windows.net/",
"microsoftEndpoints": {
"web": "https://sto1125-microsoftrouting.web.core.windows.net/",
"dfs": "https://sto1125-microsoftrouting.dfs.core.windows.net/",
"blob": "https://sto1125-microsoftrouting.blob.core.windows.net/",
"file": "https://sto1125-microsoftrouting.file.core.windows.net/",
"queue": "https://sto1125-microsoftrouting.queue.core.windows.net/",
"table": "https://sto1125-microsoftrouting.table.core.windows.net/"
},
"internetEndpoints": {
"web": "https://sto1125-internetrouting.web.core.windows.net/",
"dfs": "https://sto1125-internetrouting.dfs.core.windows.net/",
"blob": "https://sto1125-internetrouting.blob.core.windows.net/",
"file": "https://sto1125-internetrouting.file.core.windows.net/"
}
},
"primaryLocation": "eastus",
"provisioningState": "Succeeded",
"routingPreference": {
"routingChoice": "MicrosoftRouting",
"publishMicrosoftEndpoints": true,
"publishInternetEndpoints": true
},
"encryption": {
"services": {
"file": {
"keyType": "Account",
"enabled": true,
"lastEnabledTime": "2019-12-11T20:49:31.7036140Z"
},
"blob": {
"keyType": "Account",
"enabled": true,
"lastEnabledTime": "2019-12-11T20:49:31.7036140Z"
}
},
"keySource": "Microsoft.Storage"
},
"secondaryLocation": "centraluseuap",
"statusOfPrimary": "available",
"statusOfSecondary": "available",
"supportsHttpsTrafficOnly": false
},
"sku": {
"name": "Standard_GRS",
"tier": "Standard"
},
"tags": {
"key1": "value1",
"key2": "value2"
},
"type": "Microsoft.Storage/storageAccounts"
}
]
}
Based on the API response, you can create a Port blueprint definition for the resource.
Storage Account Blueprint
{
"identifier": "azureStorageAccount",
"description": "This blueprint represents an Azure Storage Account in our software catalog",
"title": "Storage Account",
"icon": "Azure",
"schema": {
"properties": {
"location": {
"title": "Location",
"type": "string"
},
"provisioningState": {
"title": "Provisioning State",
"type": "string",
"enum": ["Creating", "ResolvingDNS", "Succeeded"]
},
"creationTime": {
"title": "Creation Time",
"type": "string",
"format": "date-time"
},
"isHnsEnabled": {
"title": "Is HNS Enabled",
"type": "boolean",
"default": false
},
"fileEncryptionEnabled": {
"title": "File Encryption Enabled",
"type": "boolean"
},
"blobEncryptionEnabled": {
"title": "Blob Encryption Enabled",
"type": "boolean"
},
"primaryLocation": {
"title": "Primary Location",
"type": "string"
},
"secondaryLocation": {
"title": "Secondary Location",
"type": "string"
},
"statusOfPrimary": {
"title": "Status of Primary",
"type": "string",
"enum": ["available", "unavailable"],
"enumColors": {
"unavailable": "red",
"available": "green"
}
},
"statusOfSecondary": {
"title": "Status of Secondary",
"type": "string",
"enum": ["available", "unavailable"],
"enumColors": {
"unavailable": "red",
"available": "green"
}
},
"tags": {
"title": "Tags",
"type": "object"
},
"allowBlobPublicAccess": {
"title": "Allow Blob Public Access",
"type": "boolean"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"resourceGroup": {
"target": "azureResourceGroup",
"title": "Resource Group",
"required": false,
"many": false
}
}
}
Integration configurationโ
Create an integration configuration for the resource. The integration configuration is a YAML file that describes the ETL process to load data into the developer portal.
Mapping configuration for Storage Account and Storage Container
resources:
- kind: Microsoft.Storage/storageAccounts
selector:
query: "true"
# azure resource api version to query
apiVersion: "2023-01-01"
port:
entity:
mappings:
# lowercase only the resourceGroups namespace and name to align how azure API returns the resource group reference
identifier: '.id | split("/") | .[3] |= ascii_downcase |.[4] |= ascii_downcase | join("/")'
title: .name
blueprint: '"azureStorageAccount"'
properties:
location: .location
provisioningState: .properties.provisioningState
creationTime: .properties.creationTime
isHnsEnabled: .properties.isHnsEnabled
fileEncryptionEnabled: .properties.encryption.services.file.enabled
blobEncryptionEnabled: .properties.encryption.services.blob.enabled
primaryLocation: .properties.primaryLocation
secondaryLocation: .properties.secondaryLocation
statusOfPrimary: .properties.statusOfPrimary
statusOfSecondary: .properties.statusOfSecondary
allowBlobPublicAccess: .properties.allowBlobPublicAccess
tags: .tags
relations:
# resolve resource group id from storage account id
resourceGroup: '.id | split("/") | .[3] |= ascii_downcase |.[4] |= ascii_downcase | .[:5] |join("/")'
- kind: Microsoft.Storage/storageAccounts/blobServices/containers
selector:
query: "true"
# azure resource api version to query
apiVersion: "2023-01-01"
port:
entity:
mappings:
identifier: '.id | split("/") | .[3] |= ascii_downcase |.[4] |= ascii_downcase | join("/")'
title: .name
blueprint: '"azureStorageContainer"'
properties:
publicAccess: .properties.publicAccess
hasImmutabilityPolicy: .properties.hasImmutabilityPolicy
hasLegalHold: .properties.hasLegalHold
deleted: .properties.deleted
deletedTime: .properties.deletedTime
remainingRetentionDays: .properties.remainingRetentionDays
leaseStatus: .properties.leaseStatus
leaseState: .properties.leaseState
defaultEncryptionScope: .properties.defaultEncryptionScope
version: .properties.version
relations:
# resolve storage account id from container id
storageAccount: '.id | split("/") | .[3] |= ascii_downcase | .[4] |= ascii_downcase | .[:-4] | join("/")'
The integration configuration structureโ
-
The
kindfield describes the Azure resource type to be ingested into Port. Thekindfield should be set to the Azure resource type as it appears in the resource guide. e.g. The resource type for theStorage Accountcould be found here as well with the resource object structure.resources:
- kind: Microsoft.Storage/storageAccounts
selector:
... -
The
selectorfield describes the Azure resource selection criteria.resources:
- kind: Microsoft.Storage/storageAccounts
selector:
query: "true" # JQ boolean expression. If evaluated to false - this object will be skipped.
apiVersion: "2023-01-01" # Azure API version to use to fetch the resource
port:- The
queryfield is a JQ boolean query, if evaluated tofalse- the resource will be skipped. Example use case - skip syncing resources that are not in a specific region.query: .location == "eastus2" - The
apiVersionfield is the Azure API version to use to fetch the resource. This field is required for all resources. For example, the API versions for thestorageAccountresource was found in the Storage Account Rest APIapiVersion: "2023-01-01"
- The
-
The
portfield describes the Port entity to be created from the Azure resource.resources:
- kind: Microsoft.Storage/storageAccounts
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
apiVersion: "2023-01-01" # Azure API version to use to fetch the resource
port:
entity:
mappings: # Mappings between one Azure object to a Port entity. Each value is a JQ query.
identifier: .id
title: .name
blueprint: '"azureStorageAccount"'
properties:
location: .location
provisioningState: .properties.provisioningState-
The
entityfield describes the Port entity to be created from the Azure resource.-
The
mappingsfield describes the mapping between the Azure resource and the Port entity.-
The
identifierfield describes the Azure resource identifier. This field is required for all resources.mappings:
identifier: .id -
The
titlefield describes the Azure resource title. This field is required for all resources.mappings:
title: .name -
The
blueprintfield describes the Port blueprint to be used to create the Port entity. This field is required for all resources.mappings:
blueprint: '"azureStorageAccount"' -
The
propertiesfield describes the Azure resource properties to be mapped to the Portmappings:
identifier: .id
title: .name
blueprint: '"azureStorageAccount"'
properties:
location: .location
provisioningState: .properties.provisioningState
-
-
-