Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 211 additions & 0 deletions samples/101-managed-publishing-script/Publish-ManagedApp.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
[cmdletbinding()]
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $SubscriptionId,

[Parameter()]
[ValidateNotNullOrEmpty()]
[string] $Location = 'westcentralus',

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $ResourceGroupName,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $Name,

[Parameter()]
[string] $DisplayName,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $Description,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $PrincipalId,

[Parameter()]
[ValidateNotNullOrEmpty()]
[string] $RoleDefinitionId = '8e3af657-a8ff-443c-a75c-2fe8c4bcb635',

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $StorageAccountName,

[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string] $StorageContainerName,

[Parameter()]
[ValidateSet('None','ReadOnly')]
[string] $LockLevel = 'ReadOnly'
)

Function Write-Verbose
{
Param(
[Parameter(Position=1)]
[string]$Message
)

Microsoft.PowerShell.Utility\Write-Verbose ("{0} - {1}" -f (Get-Date).ToString("HH:mm:ss"),$Message)
}

if($DisplayName -eq "")
{
$DisplayName = $Name
}

$Error.Clear()

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
if($here -eq $null) {$here="."}

$TemplateParameters = @{
"managedAppName" = $Name;
"lockLevel" = $LockLevel;
"authorizations" = @(
@{
"principalId" = $PrincipalId;
"roleDefinitionId" = $RoleDefinitionId
}
);
"description" = $Description;
"displayName" = $DisplayName;
"packageFileUri" = "https://$StorageAccountName.blob.core.windows.net/$StorageContainerName/$Name.zip"
}

ForEach($managedAppFile In @("createUiDefinition.json","mainTemplate.json"))
{
Write-Verbose "Verifying if $managedAppFile exists"
if(Test-Path "$here\$managedAppFile")
{
Write-Verbose "$managedAppFile exists. Checking proper cases in the file name"
if((Get-ChildItem "$here\$managedAppFile" | Select-Object -ExpandProperty Name) -cne $managedAppFile)
{
Write-Error "$managedAppFile exists but its name doesn't match the expected cases. Please verify and try again"
Exit(-1)
}
}
else
{
Write-Error "$managedAppFile doesn't exists"
Exit(-1)
}
}

Write-Verbose "Verifying output folder"
if(Test-Path "$here\output")
{
Write-Verbose "Cleaning Up output folder"
Get-ChildItem "$here\output" | Remove-Item -force | Out-Null
}
else
{
Write-Verbose "Creating output folder"
New-Item -Path "$here\output" -ItemType Directory | Out-Null
}

Write-Verbose "Verify if managedAppTemplate.json exists"
if(!(Test-Path "$here\managedAppTemplate.json"))
{
Write-Error "$managedAppTemplate not found in the current script location"
Exit(-1)
}

Get-ChildItem "$here\*" -Include mainTemplate.json, createUiDefinition.json | Compress-Archive -DestinationPath "$here\output\$Name.zip"

Write-Verbose "Logging in..."
$context = $null
try {
$context = Get-AzureRmContext
}
catch {

}

if($context.Subscription.Id -eq $null)
{
Login-AzureRmAccount | Out-Null

if($context.Subscription.Id -eq $null)
{
Write-Warning "Action cancelled"
Exit(-1)
}
}

Write-Verbose "Logged into Azure"

Write-Verbose "Selecting subscription $subscriptionId"
Select-AzureRmSubscription -SubscriptionId $subscriptionId | Out-Null

Write-Verbose "Verifying if managedApp provider is registered"
If(!(Get-AzureRmResourceProvider -ProviderNamespace "Microsoft.Solutions" -ErrorAction SilentlyContinue))
{
Write-Verbose "Registering Resource Provider"
Register-AzureRmResourceProvider -ProviderNamespace "Microsoft.Solutions" | Out-Null
}

Write-Verbose "Verifying if $ResourceGroupName exists in $Location"
If(!(Get-AzureRmResourceGroup -Name $ResourceGroupName -ErrorAction SilentlyContinue))
{
Write-Verbose "$ResourceGroupName not found, proceeding to create it"
New-AzureRmResourceGroup -Name $ResourceGroupName -Location $Location -Force | Out-Null
}
else {
Write-Verbose "Using existing resource group $ResourceGroupName at $Location"
}

Write-Verbose "Verifying if Storage Account ($StorageAccountName) exists"
If(!(Get-AzureRmStorageAccount -Name $StorageAccountName -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue))
{
Write-Verbose "$StorageAccountName not found, proceeding to create it"
try {
New-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageAccountName -Location $Location -SkuName 'Standard_LRS' -ErrorAction Stop | Out-Null
}
catch {
Write-Error "Error while attempting to create $StorageAccountName storage account"
Write-Error $error[0].Exception
Exit(-2)
}
}
else {
Write-Verbose "Using existing storage account $StorageAccountName at $Location"
}

Write-Verbose "Obtain the Storage Account authentication keys using Azure Resource Manager (ARM)"
$Keys = Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroupName -Name $StorageAccountName;

Write-Verbose "Use the Azure.Storage module to create a Storage Authentication Context"
$StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $Keys[0].Value;

If(!(Get-AzureStorageContainer -Context $StorageContext -Name $StorageContainerName -ErrorAction SilentlyContinue))
{
Write-Verbose "Creating blob container ($StorageContainerName) in the Storage Account"
New-AzureStorageContainer -Context $StorageContext -Name $StorageContainerName -Permission Blob | Out-Null
}
else {
Write-Verbose "Using existing blob container ($StorageContainerName)"
}

Write-Verbose "Verifying if Managed Application exists in $managedAppResourceGroupName"
$managedApp = Get-AzureRmResource | Where-Object {$_.ResourceType -like "Microsoft.Solutions/applicationDefinitions" -and $_.Name -eq $Name}
if($managedApp)
{
Write-Warning "$Name exists and it will be removed"
Remove-AzureRmResource -Force -Verbose -ResourceId $managedApp.ResourceId | Out-Null
}
else
{
Write-Verbose "$Name not found."
}

Write-Verbose "Uploading ManagedApp Content"
Set-AzureStorageBlobContent -File "$here\output\$Name.zip" -Container $StorageContainerName -Context $StorageContext -Force | Out-Null

Write-Verbose "Publishing Managed App..."
New-AzureRmResourceGroupDeployment -ResourceGroupName $ResourceGroupName -TemplateFile "$here\managedAppTemplate.json" -TemplateParameterObject $TemplateParameters
27 changes: 27 additions & 0 deletions samples/101-managed-publishing-script/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Powershell Script to deploy a ManagedApp

When working with ManagedApps, you might find yourself publishing over and over the definition till you get it as you want it; in order to simplify the process, this script helps you to deploy the definition and creates a storage account/blob (if it doesn't exists) according to the requirements.

## The Files

1. Public-ManagedApp.ps1

*Note: CreateUiDefinition.json and mainTemplate.json must exists in the same location as the ps1.*

Powershell script to deploy the managed app. It will create, if it doesn't exist, a Storage Account and a container (with Blob security) in order to deploy the ManagedApp definition. Parameters:

* SubscriptionId: GUID with the subscription you want to deploy the definition.
* Location: Azure DC where you want to publish the managed app. This is where the resource group will be created. (Default: westcentralus)
* ResourceGroupName: Self-explanatory
* Name: ManagedApp Name
* DisplayName: ManagedApp Display Name
* Description: ManagedApp Description
* PrincipalId: Azure AD GUID of the group/user you want to grant access to the managed resource group
* RoleDefinitionId: Azure RBAC role to be granted to PrincipalId in the managed resource group (Default: "8e3af657-a8ff-443c-a75c-2fe8c4bcb635" => Owner)
* StorageAccountName: Self-explanatory
* StorageContainerName: Self-explanatory
* LockLevel: User access level to the managed resource group. (Default: ReadOnly)

2.  managedAppTemplate.json

This file is required in the same location as the PS1 since it will be used to do the actual deployment to Azure
39 changes: 39 additions & 0 deletions samples/101-managed-publishing-script/managedAppTemplate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"managedAppName": {
"type": "string"
},
"lockLevel": {
"type": "string"
},
"authorizations": {
"type": "array"
},
"description": {
"type": "string"
},
"displayName": {
"type": "string"
},
"packageFileUri": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "2017-09-01",
"name": "[parameters('managedAppName')]",
"location": "[ResourceGroup().location]",
"type": "Microsoft.Solutions/applicationDefinitions",
"properties": {
"lockLevel": "[parameters('lockLevel')]",
"authorizations": "[parameters('authorizations')]",
"description": "[parameters('description')]",
"displayName": "[parameters('displayName')]",
"packageFileUri": "[parameters('packageFileUri')]"
}
}
]
}