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
kind
field describes the Azure resource type to be ingested into Port. Thekind
field should be set to the Azure resource type as it appears in the resource guide. e.g. The resource type for theStorage Account
could be found here as well with the resource object structure.resources:
- kind: Microsoft.Storage/storageAccounts
selector:
... -
The
selector
field 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
query
field 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
apiVersion
field is the Azure API version to use to fetch the resource. This field is required for all resources. For example, the API versions for thestorageAccount
resource was found in the Storage Account Rest APIapiVersion: "2023-01-01"
- The
-
The
port
field 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
entity
field describes the Port entity to be created from the Azure resource.-
The
mappings
field describes the mapping between the Azure resource and the Port entity.-
The
identifier
field describes the Azure resource identifier. This field is required for all resources.mappings:
identifier: .id -
The
title
field describes the Azure resource title. This field is required for all resources.mappings:
title: .name -
The
blueprint
field describes the Port blueprint to be used to create the Port entity. This field is required for all resources.mappings:
blueprint: '"azureStorageAccount"' -
The
properties
field describes the Azure resource properties to be mapped to the Portmappings:
identifier: .id
title: .name
blueprint: '"azureStorageAccount"'
properties:
location: .location
provisioningState: .properties.provisioningState
-
-
-