none
Azure Blueprints Published Through Restful API Fail But Publish fine Through the Portal RRS feed

  • Question

  • My code is below.

    My problem is that I can create & publish all Azure Blueprint content manually through the portal but when I try to publish it through the restful API as coded below, I get the following error:

    <#ERROR START#>

    Invoke-RestMethod : {
      "error": {
        "code": "InvalidSchema",
        "message": "Path:, Schema:#/definitions/ScriptArtifact, Error: JSON does not match all schemas from 'allOf'. Invalid schema indexes: 0."
      }
    }
    At line:2 char:13
    + $response = Invoke-RestMethod -Uri $restUriForAddingReaderRoleAssignm ...
    +             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
        + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

    <# ERROR END #>

    The code I ran is as follows (any sensitive data has been "XXX"-ed out):

    <# CODE START #>
    $tenantId = (az account show | convertFrom-Json).tenantId

    $azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
    $profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
    $token = $profileClient.AcquireAccessToken($tenantId)

    $authHeader = @{

        'Content-Type'='application/json'
        'Authorization'='Bearer ' + $token.AccessToken
    }

    $someJsonStringDefiningIntialBlueprintObject = '{

        "name": "DataStoreBluePrint",
        "location": "westeurope",
        "identity": {

            "type": "SystemAssigned"
        },
        
        "properties": {

            "description": "This blueprint sets role assignment on a target asset",
            "targetScope": "subscription",
            "blueprintId": "/subscriptions/xxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint",
            "locks": {

                "mode": "AllResourcesReadOnly",
                "excludedPrincipals": [

                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                ],

                "mode": "AllResourcesDoNotDelete",
                "excludedPrincipals": [

                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                ]

            },
            "parameters": {

    "readers": {

                    "type": "array",
                    "value": [
                    
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  
                    ],
                    "metadata": {

                        "description": "List of AAD object IDs that are assigned Reader role at the resource group"
                    }
                },
                "contributors": {

                    "type": "array",
                     "value": [
                    
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  
                    ],
                    "metadata": {

                        "description": "List of AAD object IDs that are assigned Contributor role at the resource group"
                    }
                },
                "owners": {

                    "type": "array",
                     "value": [
                    
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                    ],
                    "metadata": {

                        "description": "List of AAD object IDs that are assigned Owner role at the resource group"
                    }
                }
            },
            "resourceGroups": {
            
                "xx-xxxx-xxx-xxxxxxx-rg": {

                    "name": "xx-xxxx-xxx-xxxxxxx-rg",
                    "location": "westeurope"
                }
            }
        }
    }'

    # Not using management groups as we don't have the concept
    # In the below code, 'DatastoreBlueprint' is set up under the xxxxxxxxxxx subscription...
    $restUriForInitialisingBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForInitialisingBluePrint -Method Put -Body $someJsonStringDefiningIntialBlueprintObject -Headers $authHeader



    $someJsonStringDefiningContributor = '{

        "kind": "roleAssignment",
        "properties": {

            "resourceGroup": "xx-xxxx-xxx-xxxxxxxx-rg",
            "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
            "principalIds": [
                    
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
        }
    }'

    # In the below code, 'DatastoreBlueprint' has a roleAssignment added to it under the xxxxxxx subscription... 
    $restUriForAddingRoleContributorToBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/roleContributor?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingRoleContributorToBluePrint -Method Put -Body $someJsonStringDefiningContributor -Headers $authHeader



    $someJsonStringDefiningOwner = '{

        "kind": "roleAssignment",
        "properties": {

            "resourceGroup": "xx-xxxx-xxx-xxxxxxxx-rg",
            "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
            "principalIds": [
            
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
        }
    }'

    # In the below code, 'DataStoreBlueprint' has an Owner Role Assignment added to it under the xxxxxxxxxxxxx subscription...
    $restUriForAddingOwnerRoleAssignmentToBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/roleOwner?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingOwnerRoleAssignmentToBluePrint -Method Put -Body $someJsonStringDefiningOwner -Headers $authHeader



    $someJsonStringDefiningReader = '{

        "kind": "roleAssignment",
        "properties": {

            "resourceGroup": "xx-xxxx-xxx-xxxxxxx-rg",
            "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",
            "principalIds": [
            
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
        }
    }'

    # In the below code, 'DataStoreBlueprint' has a Reader Role Assignment added to it under the xxxxxxxxxxxxxx subscription...
    $restUriForAddingReaderToBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/roleReader?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingReaderToBluePrint -Method Put -Body $someJsonStringDefiningReader -Headers $authHeader



    $someJsonStringDefiningARMTemplate = '{

        "kind": "template",
        "properties": {

            "template": {

                "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                "contentVersion": "1.0.0.0",
                "parameters": {

                    "storageAccountType": {

                        "type": "string",

                        "defaultValue": "Standard_RAGRS",
                        "allowedValues": [
                            
                            "Standard_RAGRS",
                            "Standard_LRS",
                            "Standard_GRS",
                            "Standard_ZRS",
                            "Premium_LRS"
                        ],

                        "metadata": {

                            "description": "Storage Account type"
                        }
                    }
                },

                "variables": {

                    "storageAccountName": "xxxxxxxxxxxxxxxxxxxx"
                },

                "resources": [{

                    "type": "Microsoft.Storage/storageAccounts",
                    "name": "[variables(''storageAccountName'')]",
                    "apiVersion": "2019-04-01",
                    "location": "westeurope",
                    "sku": {

                        "name": "[parameters(''storageAccountType'')]"
                    },
                    "kind": "StorageV2",
                    "properties": {}
                }]
            },

            "resourceGroup": "xx-xxxx-xxx-xxxx-rg",
            "parameters": {

                "storageAccountType": {
                
                    "value": "[parameters(''storageAccountType'')]"
                }
            }
        }
    }'

    # In the below code, 'DataStoreBlueprint' has an ARM Template added to it under the XXXXXXXX subscription...
    $restUriForAddingARMTemplateToBluePrint = 'https://management.azure.com/subscriptions/XXXXXXXX/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/templateSA?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingARMTemplateToBluePrint -Method Put -Body $someJsonStringDefiningARMTemplate -Headers $authHeader


    # Add a policy assignment just so there is one...(it may stop the publish process from error-ing?...)
    $someJsonStringDefiningPolicyAssignmentForBlueprint = '{

        "kind": "policyAssignment",
        "properties": {

            "description": "This is just a dummy",
            "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/49c88fc8-6fd1-46fd-a676-f12d1d3a4c71",
            "parameters": {

                  "tagName": {
                    "value": "Platform"
                },
                "tagValue": {
                    "value": "Monkey Magic"
                }
            }
        }
    }'

    $restUriForAddingPolicyToBluePrint = 'https://management.azure.com/subscriptions/XXXXXXXXX/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/dummyPolicy?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingPolicyToBluePrint -Method Put -Body $someJsonStringDefiningPolicyAssignmentForBlueprint -Headers $authHeader



    # In the below code, 'DataStoreBlueprint' is published under the XXXXXXX subscription...
    $restUriForPublishingBluePrint = 'https://management.azure.com/subscriptions/XXXXXXXXX/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/versions/01?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingReaderRoleAssignmentToBluePrint -Method Put -Headers $authHeader

    <# CODE END #>

    Tuesday, July 23, 2019 5:23 PM

Answers

  • Hello IbbyRiz,

    Thanks for reaching out!

    So it looks like some required artifact parameters definitions are missing from the initial blueprint object. After going through all the code provided above, I tweaked some sections to include those and could get it to work. Defining the artifact parameters is necessary as stated in the Note in the REST API quickstart for Azure Blueprints:

    Also, the last line should have $restUriForPublishingBluePrint passed as the Uri instead of $restUriForAddingReaderRoleAssignmentToBluePrint for the publish operation.

    Here is what it now looks like:

    $tenantId = (az account show | convertFrom-Json).tenantId
    
    $azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
    $profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
    $token = $profileClient.AcquireAccessToken($tenantId)
    
    $authHeader = @{
    
        'Content-Type'='application/json'
        'Authorization'='Bearer ' + $token.AccessToken
    }
    
    $someJsonStringDefiningIntialBlueprintObject = '{
    
        "name": "DataStoreBluePrint",
        "location": "westeurope",
        "identity": {
    
            "type": "SystemAssigned"
        },
        
        "properties": {
    
            "description": "This blueprint sets role assignment on a target asset",
            "targetScope": "subscription",
            "blueprintId": "/subscriptions/xxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint",
            "locks": {
    
                "mode": "AllResourcesReadOnly",
                "excludedPrincipals": [
    
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                ],
    
                "mode": "AllResourcesDoNotDelete",
                "excludedPrincipals": [
    
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                ]
    
            },
            "parameters": {
    
                "storageAccountType": {
                    "type": "string",
                    "metadata": {
                        "displayName": "storage account type.",
                        "description": null
                    },
                    "value": "Standard_RAGRS"
                },
                "tagName": {
                    "type": "string",
                    "metadata": {
                        "displayName": "The name of the tag to provide the policy assignment.",
                        "description": null
                    }
                },
                "tagValue": {
                    "type": "string",
                    "metadata": {
                        "displayName": "The value of the tag to provide the policy assignment.",
                        "description": null
                    }
                },
    
                "readers": {
    
                    "type": "array",
                    "value": [
                    
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  
                    ],
                    "metadata": {
    
                        "description": "List of AAD object IDs that are assigned Reader role at the resource group"
                    }
                },
                "contributors": {
    
                    "type": "array",
                     "value": [
                    
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  
                    ],
                    "metadata": {
    
                        "description": "List of AAD object IDs that are assigned Contributor role at the resource group"
                    }
                },
                "owners": {
    
                    "type": "array",
                     "value": [
                    
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                    ],
                    "metadata": {
    
                        "description": "List of AAD object IDs that are assigned Owner role at the resource group"
                    }
                }
            },
            "resourceGroups": {
            
                "xx-xxxx-xxx-xxxxxxx-rg": {
    
                    "name": "xx-xxxx-xxx-xxxxxxx-rg",
                    "location": "westeurope"
                }
            }
        }
    }'
    
    # Not using management groups as we don't have the concept
    # In the below code, 'DatastoreBlueprint' is set up under the xxxxxxxxxxx subscription...
    $restUriForInitialisingBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForInitialisingBluePrint -Method Put -Body $someJsonStringDefiningIntialBlueprintObject -Headers $authHeader
    
    
    
    $someJsonStringDefiningContributor = '{
    
        "kind": "roleAssignment",
        "properties": {
    
            "resourceGroup": "xx-xxxx-xxx-xxxxxxxx-rg",
            "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
            "principalIds": [
                    
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
        }
    }'
    
    # In the below code, 'DatastoreBlueprint' has a roleAssignment added to it under the xxxxxxx subscription... 
    $restUriForAddingRoleContributorToBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/roleContributor?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingRoleContributorToBluePrint -Method Put -Body $someJsonStringDefiningContributor -Headers $authHeader
    
    
    
    $someJsonStringDefiningOwner = '{
    
        "kind": "roleAssignment",
        "properties": {
    
            "resourceGroup": "xx-xxxx-xxx-xxxxxxxx-rg",
            "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
            "principalIds": [
            
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
        }
    }'
    
    # In the below code, 'DataStoreBlueprint' has an Owner Role Assignment added to it under the xxxxxxxxxxxxx subscription...
    $restUriForAddingOwnerRoleAssignmentToBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/roleOwner?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingOwnerRoleAssignmentToBluePrint -Method Put -Body $someJsonStringDefiningOwner -Headers $authHeader
    
    
    
    $someJsonStringDefiningReader = '{
    
        "kind": "roleAssignment",
        "properties": {
    
            "resourceGroup": "xx-xxxx-xxx-xxxxxxx-rg",
            "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",
            "principalIds": [
            
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
        }
    }'
    
    # In the below code, 'DataStoreBlueprint' has a Reader Role Assignment added to it under the xxxxxxxxxxxxxx subscription...
    $restUriForAddingReaderToBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/roleReader?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingReaderToBluePrint -Method Put -Body $someJsonStringDefiningReader -Headers $authHeader
    
    
    
    $someJsonStringDefiningARMTemplate = '{
    
        "kind": "template",
        "properties": {
    
            "template": {
    
                "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                "contentVersion": "1.0.0.0",
                "parameters": {
    
                    "storageAccountType": {
    
                        "type": "string",
    
                        "defaultValue": "Standard_RAGRS",
                        "allowedValues": [
                            
                            "Standard_RAGRS",
                            "Standard_LRS",
                            "Standard_GRS",
                            "Standard_ZRS",
                            "Premium_LRS"
                        ],
    
                        "metadata": {
    
                            "description": "Storage Account type"
                        }
                    }
                },
    
                "variables": {
    
                    "storageAccountName": "xxxxxxxxxxxxxxxxxxxx"
                },
    
                "resources": [{
    
                    "type": "Microsoft.Storage/storageAccounts",
                    "name": "[variables(''storageAccountName'')]",
                    "apiVersion": "2019-04-01",
                    "location": "westeurope",
                    "sku": {
    
                        "name": "[parameters(''storageAccountType'')]"
                    },
                    "kind": "StorageV2",
                    "properties": {}
                }]
            },
    
            "resourceGroup": "xx-xxxx-xxx-xxxx-rg",
            "parameters": {
    
                "storageAccountType": {
                
                    "value": "[parameters(''storageAccountType'')]"
                }
            }
        }
    }'
    
    # In the below code, 'DataStoreBlueprint' has an ARM Template added to it under the XXXXXXXX subscription...
    $restUriForAddingARMTemplateToBluePrint = 'https://management.azure.com/subscriptions/XXXXXXXX/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/templateSA?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingARMTemplateToBluePrint -Method Put -Body $someJsonStringDefiningARMTemplate -Headers $authHeader
    
    
    # Add a policy assignment just so there is one...(it may stop the publish process from error-ing?...)
    $someJsonStringDefiningPolicyAssignmentForBlueprint = '{
    
        "kind": "policyAssignment",
        "properties": {
    
            "description": "This is just a dummy",
            "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/49c88fc8-6fd1-46fd-a676-f12d1d3a4c71",
            "parameters": {
    
                  "tagName": {
                    "value": "Platform"
                },
                "tagValue": {
                    "value": "Monkey Magic"
                }
            }
        }
    }'
    
    $restUriForAddingPolicyToBluePrint = 'https://management.azure.com/subscriptions/XXXXXXXXX/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/dummyPolicy?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingPolicyToBluePrint -Method Put -Body $someJsonStringDefiningPolicyAssignmentForBlueprint -Headers $authHeader
    
    
    
    # In the below code, 'DataStoreBlueprint' is published under the XXXXXXX subscription...
    $restUriForPublishingBluePrint = 'https://management.azure.com/subscriptions/XXXXXXXXX/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/versions/01?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForPublishingBluePrint -Method Put -Headers $authHeader

    Executing the above resulted in a blueprint that looks like this:

    Please give it a try and feel free to revert if you still see issues. Hope this helps!



    Saturday, July 27, 2019 4:36 PM
    Moderator

All replies

  • Hello IbbyRiz,

    Thanks for reaching out!

    So it looks like some required artifact parameters definitions are missing from the initial blueprint object. After going through all the code provided above, I tweaked some sections to include those and could get it to work. Defining the artifact parameters is necessary as stated in the Note in the REST API quickstart for Azure Blueprints:

    Also, the last line should have $restUriForPublishingBluePrint passed as the Uri instead of $restUriForAddingReaderRoleAssignmentToBluePrint for the publish operation.

    Here is what it now looks like:

    $tenantId = (az account show | convertFrom-Json).tenantId
    
    $azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
    $profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
    $token = $profileClient.AcquireAccessToken($tenantId)
    
    $authHeader = @{
    
        'Content-Type'='application/json'
        'Authorization'='Bearer ' + $token.AccessToken
    }
    
    $someJsonStringDefiningIntialBlueprintObject = '{
    
        "name": "DataStoreBluePrint",
        "location": "westeurope",
        "identity": {
    
            "type": "SystemAssigned"
        },
        
        "properties": {
    
            "description": "This blueprint sets role assignment on a target asset",
            "targetScope": "subscription",
            "blueprintId": "/subscriptions/xxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint",
            "locks": {
    
                "mode": "AllResourcesReadOnly",
                "excludedPrincipals": [
    
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                ],
    
                "mode": "AllResourcesDoNotDelete",
                "excludedPrincipals": [
    
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                ]
    
            },
            "parameters": {
    
                "storageAccountType": {
                    "type": "string",
                    "metadata": {
                        "displayName": "storage account type.",
                        "description": null
                    },
                    "value": "Standard_RAGRS"
                },
                "tagName": {
                    "type": "string",
                    "metadata": {
                        "displayName": "The name of the tag to provide the policy assignment.",
                        "description": null
                    }
                },
                "tagValue": {
                    "type": "string",
                    "metadata": {
                        "displayName": "The value of the tag to provide the policy assignment.",
                        "description": null
                    }
                },
    
                "readers": {
    
                    "type": "array",
                    "value": [
                    
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  
                    ],
                    "metadata": {
    
                        "description": "List of AAD object IDs that are assigned Reader role at the resource group"
                    }
                },
                "contributors": {
    
                    "type": "array",
                     "value": [
                    
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  
                    ],
                    "metadata": {
    
                        "description": "List of AAD object IDs that are assigned Contributor role at the resource group"
                    }
                },
                "owners": {
    
                    "type": "array",
                     "value": [
                    
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                    ],
                    "metadata": {
    
                        "description": "List of AAD object IDs that are assigned Owner role at the resource group"
                    }
                }
            },
            "resourceGroups": {
            
                "xx-xxxx-xxx-xxxxxxx-rg": {
    
                    "name": "xx-xxxx-xxx-xxxxxxx-rg",
                    "location": "westeurope"
                }
            }
        }
    }'
    
    # Not using management groups as we don't have the concept
    # In the below code, 'DatastoreBlueprint' is set up under the xxxxxxxxxxx subscription...
    $restUriForInitialisingBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForInitialisingBluePrint -Method Put -Body $someJsonStringDefiningIntialBlueprintObject -Headers $authHeader
    
    
    
    $someJsonStringDefiningContributor = '{
    
        "kind": "roleAssignment",
        "properties": {
    
            "resourceGroup": "xx-xxxx-xxx-xxxxxxxx-rg",
            "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
            "principalIds": [
                    
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
        }
    }'
    
    # In the below code, 'DatastoreBlueprint' has a roleAssignment added to it under the xxxxxxx subscription... 
    $restUriForAddingRoleContributorToBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/roleContributor?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingRoleContributorToBluePrint -Method Put -Body $someJsonStringDefiningContributor -Headers $authHeader
    
    
    
    $someJsonStringDefiningOwner = '{
    
        "kind": "roleAssignment",
        "properties": {
    
            "resourceGroup": "xx-xxxx-xxx-xxxxxxxx-rg",
            "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
            "principalIds": [
            
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
        }
    }'
    
    # In the below code, 'DataStoreBlueprint' has an Owner Role Assignment added to it under the xxxxxxxxxxxxx subscription...
    $restUriForAddingOwnerRoleAssignmentToBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/roleOwner?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingOwnerRoleAssignmentToBluePrint -Method Put -Body $someJsonStringDefiningOwner -Headers $authHeader
    
    
    
    $someJsonStringDefiningReader = '{
    
        "kind": "roleAssignment",
        "properties": {
    
            "resourceGroup": "xx-xxxx-xxx-xxxxxxx-rg",
            "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",
            "principalIds": [
            
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
        }
    }'
    
    # In the below code, 'DataStoreBlueprint' has a Reader Role Assignment added to it under the xxxxxxxxxxxxxx subscription...
    $restUriForAddingReaderToBluePrint = 'https://management.azure.com/subscriptions/xxxxxxxxxxxxxxxxxxxxxxxx/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/roleReader?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingReaderToBluePrint -Method Put -Body $someJsonStringDefiningReader -Headers $authHeader
    
    
    
    $someJsonStringDefiningARMTemplate = '{
    
        "kind": "template",
        "properties": {
    
            "template": {
    
                "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                "contentVersion": "1.0.0.0",
                "parameters": {
    
                    "storageAccountType": {
    
                        "type": "string",
    
                        "defaultValue": "Standard_RAGRS",
                        "allowedValues": [
                            
                            "Standard_RAGRS",
                            "Standard_LRS",
                            "Standard_GRS",
                            "Standard_ZRS",
                            "Premium_LRS"
                        ],
    
                        "metadata": {
    
                            "description": "Storage Account type"
                        }
                    }
                },
    
                "variables": {
    
                    "storageAccountName": "xxxxxxxxxxxxxxxxxxxx"
                },
    
                "resources": [{
    
                    "type": "Microsoft.Storage/storageAccounts",
                    "name": "[variables(''storageAccountName'')]",
                    "apiVersion": "2019-04-01",
                    "location": "westeurope",
                    "sku": {
    
                        "name": "[parameters(''storageAccountType'')]"
                    },
                    "kind": "StorageV2",
                    "properties": {}
                }]
            },
    
            "resourceGroup": "xx-xxxx-xxx-xxxx-rg",
            "parameters": {
    
                "storageAccountType": {
                
                    "value": "[parameters(''storageAccountType'')]"
                }
            }
        }
    }'
    
    # In the below code, 'DataStoreBlueprint' has an ARM Template added to it under the XXXXXXXX subscription...
    $restUriForAddingARMTemplateToBluePrint = 'https://management.azure.com/subscriptions/XXXXXXXX/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/templateSA?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingARMTemplateToBluePrint -Method Put -Body $someJsonStringDefiningARMTemplate -Headers $authHeader
    
    
    # Add a policy assignment just so there is one...(it may stop the publish process from error-ing?...)
    $someJsonStringDefiningPolicyAssignmentForBlueprint = '{
    
        "kind": "policyAssignment",
        "properties": {
    
            "description": "This is just a dummy",
            "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/49c88fc8-6fd1-46fd-a676-f12d1d3a4c71",
            "parameters": {
    
                  "tagName": {
                    "value": "Platform"
                },
                "tagValue": {
                    "value": "Monkey Magic"
                }
            }
        }
    }'
    
    $restUriForAddingPolicyToBluePrint = 'https://management.azure.com/subscriptions/XXXXXXXXX/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/artifacts/dummyPolicy?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForAddingPolicyToBluePrint -Method Put -Body $someJsonStringDefiningPolicyAssignmentForBlueprint -Headers $authHeader
    
    
    
    # In the below code, 'DataStoreBlueprint' is published under the XXXXXXX subscription...
    $restUriForPublishingBluePrint = 'https://management.azure.com/subscriptions/XXXXXXXXX/providers/Microsoft.Blueprint/blueprints/DataStoreBlueprint/versions/01?api-version=2018-11-01-preview'
    $response = Invoke-RestMethod -Uri $restUriForPublishingBluePrint -Method Put -Headers $authHeader

    Executing the above resulted in a blueprint that looks like this:

    Please give it a try and feel free to revert if you still see issues. Hope this helps!



    Saturday, July 27, 2019 4:36 PM
    Moderator
  • Hello IbbyRiz,

    Have you had a chance to check if the above solution helps? Please let us know otherwise and we'll be happy to assist you!

    Monday, July 29, 2019 1:12 PM
    Moderator
  • Hello IbbyRiz,

    Do check out the above solution and let us know if there is anything else related to this thread that we can assist you with, else please feel free to mark and close this out if any of the above responses have been of help! Thanks again for reaching out!
    Tuesday, July 30, 2019 4:19 PM
    Moderator