Octopus.Script exported 2024-05-17 by NielsDM belongs to ‘Azure’ category.
Marks a release point in Application Insights. This step template uses Azure CLI and Role-Based Access Control instead of an API Key. Used application-insights-annotate-release.json as inspiration.
Parameters
When steps based on the template are included in a project’s deployment process, the parameters below can be set.
Application Insights Account
AppInsights.ApplicationInsightsAccount =
Azure account for the Application Insights instance
Application Name
AppInsights.ApplicationName =
The Application Insights Application name.
Resource Group
AppInsights.ResourceGroup =
The Resource Group of the Application Insights instance
Release Name
AppInsights.ReleaseName = #{Octopus.Release.Number}
The release name. Typically bound to #{Octopus.Release.Number}
Release Properties
AppInsights.ReleaseProperties =
List of key/value pairs separated by a new-line. For example:
ReleaseDescription = Release with annotation
TriggerBy = John Doe
Script body
Steps based on this template will execute the following PowerShell script.
# Function to decrypt data
function Convert-PasswordToPlainText {
$base64password = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($OctopusParameters["AppInsights.ApplicationInsightsAccount.Password"]))
return [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($base64password))
}
# Function to ensure all Unicode characters in a JSON string are properly escaped
function Convert-UnicodeToEscapeHex {
param (
[parameter(Mandatory = $true)][string]$JsonString
)
$JsonObject = ConvertFrom-Json -InputObject $JsonString
foreach ($property in $JsonObject.PSObject.Properties) {
$name = $property.Name
$value = $property.Value
if ($value -is [string]) {
$value = [regex]::Unescape($value)
$OutputString = ""
foreach ($char in $value.ToCharArray()) {
$dec = [int]$char
if ($dec -gt 127) {
$hex = [convert]::ToString($dec, 16)
$hex = $hex.PadLeft(4, '0')
$OutputString += "\u$hex"
}
else {
$OutputString += $char
}
}
$JsonObject.$name = $OutputString
}
}
return ConvertTo-Json -InputObject $JsonObject -Compress
}
$applicationName = $OctopusParameters["AppInsights.ApplicationName"]
$resourceGroup = $OctopusParameters["AppInsights.ResourceGroup"]
$releaseName = $OctopusParameters["AppInsights.ReleaseName"]
$properties = $OctopusParameters["AppInsights.ReleaseProperties"]
# Authenticate via Service Principal
$securePassword = Convert-PasswordToPlainText
$azEnv = if($OctopusParameters["AppInsights.ApplicationInsightsAccount.AzureEnvironment"]) { $OctopusParameters["AppInsights.ApplicationInsightsAccount.AzureEnvironment"] } else { "AzureCloud" }
$azEnv = Get-AzEnvironment -Name $azEnv
if (!$azEnv) {
Write-Error "No Azure environment could be matched given the name $($OctopusParameters["AppInsights.ApplicationInsightsAccount.AzureEnvironment"])"
exit -2
}
Write-Verbose "Authenticating with Service Principal"
# Force any output generated to be verbose in Octopus logs.
az login --service-principal -u $OctopusParameters["AppInsights.ApplicationInsightsAccount.Client"] -p $securePassword --tenant $OctopusParameters["AppInsights.ApplicationInsightsAccount.TenantId"]
Write-Verbose "Initiating the body of the annotation"
$releaseProperties = $null
if ($properties -ne $null)
{
$releaseProperties = ConvertFrom-StringData -StringData $properties
}
$annotation = @{
Id = [GUID]::NewGuid();
AnnotationName = $releaseName;
EventTime = (Get-Date).ToUniversalTime().GetDateTimeFormats("s")[0];
Category = "Deployment"; #Application Insights only displays annotations from the "Deployment" Category
Properties = ConvertTo-Json $releaseProperties -Compress
}
$annotation = ConvertTo-Json $annotation -Compress
$annotation = Convert-UnicodeToEscapeHex -JsonString $annotation
$body = $annotation -replace '(\\+)"', '$1$1"' -replace "`"", "`"`""
Write-Verbose "Send the annotation to Application Insights"
az rest --method put --uri "/subscriptions/$($OctopusParameters["AppInsights.ApplicationInsightsAccount.SubscriptionNumber"])/resourceGroups/$($resourceGroup)/providers/microsoft.insights/components/$($applicationName)/Annotations?api-version=2015-05-01" --body "$($body) "
Provided under the Apache License version 2.0.
To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.
{
"Id": "bc4eae30-786a-4974-a003-948b7a4ed023",
"Name": "Application Insights - Annotate Release with Azure CLI and RBAC",
"Description": "Marks a release point in Application Insights. This step template uses Azure CLI and Role-Based Access Control instead of an API Key. Used application-insights-annotate-release.json as inspiration.",
"Version": 1,
"ExportedAt": "2024-05-17T06:54:43.852Z",
"ActionType": "Octopus.Script",
"Author": "NielsDM",
"Packages": [],
"Parameters": [
{
"Id": "ef9d044d-3765-4cb0-af55-22c15ce4013c",
"Name": "AppInsights.ApplicationInsightsAccount",
"Label": "Application Insights Account",
"HelpText": "Azure account for the Application Insights instance",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "AzureAccount"
}
},
{
"Id": "98174616-d9dd-4e8e-9b01-2961a061360f",
"Name": "AppInsights.ApplicationName",
"Label": "Application Name",
"HelpText": "The Application Insights Application name.",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "41835ca3-76d3-47f8-b863-d26c782c4ba4",
"Name": "AppInsights.ResourceGroup",
"Label": "Resource Group",
"HelpText": "The Resource Group of the Application Insights instance",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "e008808c-622d-4efe-91a0-ac666d264996",
"Name": "AppInsights.ReleaseName",
"Label": "Release Name",
"HelpText": "The release name. Typically bound to #{Octopus.Release.Number}",
"DefaultValue": "#{Octopus.Release.Number}",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "551f06ad-9470-415b-aed9-dd80f3a4123d",
"Name": "AppInsights.ReleaseProperties",
"Label": "Release Properties",
"HelpText": "List of key/value pairs separated by a new-line. For example:\n\n```\nReleaseDescription = Release with annotation\nTriggerBy = John Doe\n```",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "MultiLineText"
}
}
],
"Properties": {
"Octopus.Action.Script.Syntax": "PowerShell",
"Octopus.Action.Script.ScriptBody": "# Function to decrypt data\nfunction Convert-PasswordToPlainText {\n\t$base64password = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($OctopusParameters[\"AppInsights.ApplicationInsightsAccount.Password\"]))\n return [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($base64password))\n}\n\n# Function to ensure all Unicode characters in a JSON string are properly escaped\nfunction Convert-UnicodeToEscapeHex {\n param (\n [parameter(Mandatory = $true)][string]$JsonString\n )\n $JsonObject = ConvertFrom-Json -InputObject $JsonString\n foreach ($property in $JsonObject.PSObject.Properties) {\n $name = $property.Name\n $value = $property.Value\n if ($value -is [string]) {\n $value = [regex]::Unescape($value)\n $OutputString = \"\"\n foreach ($char in $value.ToCharArray()) {\n $dec = [int]$char\n if ($dec -gt 127) {\n $hex = [convert]::ToString($dec, 16)\n $hex = $hex.PadLeft(4, '0')\n $OutputString += \"\\u$hex\"\n }\n else {\n $OutputString += $char\n }\n }\n $JsonObject.$name = $OutputString\n }\n }\n return ConvertTo-Json -InputObject $JsonObject -Compress\n}\n\n$applicationName = $OctopusParameters[\"AppInsights.ApplicationName\"]\n$resourceGroup = $OctopusParameters[\"AppInsights.ResourceGroup\"]\n$releaseName = $OctopusParameters[\"AppInsights.ReleaseName\"]\n$properties = $OctopusParameters[\"AppInsights.ReleaseProperties\"]\n\n# Authenticate via Service Principal\n$securePassword = Convert-PasswordToPlainText\n$azEnv = if($OctopusParameters[\"AppInsights.ApplicationInsightsAccount.AzureEnvironment\"]) { $OctopusParameters[\"AppInsights.ApplicationInsightsAccount.AzureEnvironment\"] } else { \"AzureCloud\" }\n\n$azEnv = Get-AzEnvironment -Name $azEnv\nif (!$azEnv) {\n\tWrite-Error \"No Azure environment could be matched given the name $($OctopusParameters[\"AppInsights.ApplicationInsightsAccount.AzureEnvironment\"])\"\n\texit -2\n}\n\nWrite-Verbose \"Authenticating with Service Principal\"\n\n# Force any output generated to be verbose in Octopus logs.\naz login --service-principal -u $OctopusParameters[\"AppInsights.ApplicationInsightsAccount.Client\"] -p $securePassword --tenant $OctopusParameters[\"AppInsights.ApplicationInsightsAccount.TenantId\"]\n\nWrite-Verbose \"Initiating the body of the annotation\"\n\n$releaseProperties = $null\n\nif ($properties -ne $null)\n{\n $releaseProperties = ConvertFrom-StringData -StringData $properties\n}\n\n$annotation = @{\n Id = [GUID]::NewGuid();\n AnnotationName = $releaseName;\n EventTime = (Get-Date).ToUniversalTime().GetDateTimeFormats(\"s\")[0];\n Category = \"Deployment\"; #Application Insights only displays annotations from the \"Deployment\" Category\n Properties = ConvertTo-Json $releaseProperties -Compress\n}\n\n$annotation = ConvertTo-Json $annotation -Compress\n$annotation = Convert-UnicodeToEscapeHex -JsonString $annotation \n\n$body = $annotation -replace '(\\\\+)\"', '$1$1\"' -replace \"`\"\", \"`\"`\"\"\n\nWrite-Verbose \"Send the annotation to Application Insights\"\n\naz rest --method put --uri \"/subscriptions/$($OctopusParameters[\"AppInsights.ApplicationInsightsAccount.SubscriptionNumber\"])/resourceGroups/$($resourceGroup)/providers/microsoft.insights/components/$($applicationName)/Annotations?api-version=2015-05-01\" --body \"$($body) \"",
"Octopus.Action.Script.ScriptSource": "Inline"
},
"Category": "Azure",
"HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/application-insights-annotate-release-with-rbac.json",
"Website": "/step-templates/bc4eae30-786a-4974-a003-948b7a4ed023",
"Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRF////AHjXf7vrv931QJrh7/f8EIDaIIncMJHfYKvmz+b3n8zw3+76j8Ttr9XycLPpUKLkkKvYFAAABGZJREFUeNrsnNmCqjoQRc1MEiD8/9cer7Yt2KBJZQC8ez07sKlKTQlcLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzoUSnt8YxXlFuGHSbIaxvj+fip4btkLn1blkWLaF5v03yLhLOYlVuGYfMOMZzNGxCOzhjTJqFkXnjq3Dr1yyvPI3hGl3Ih3zzHHNKudRstRhX5O58vIcShY67Gq6EPIESlzUWvazaGAOGbvU7ArDu/g8M4o8opDZWvbvPzlL/MMBE8jT9T9W7PbAJlHPTBFRf9yVTEcs63msXz2UHLSgf650G/d5t+wjbxxB2UCMqGrk8/LFSD7uJMeNt5bcJCyQZyAe5Fo9KYfWS2flQrr4b4tpuzaeWjYs49rt9LHf9uZD7+VbyVi9EBNrjYjuq2sxQOrl+p+HuBVu45qvqfq691ttYFQ5KyKbyJgaIY/NGxrlWZwlwGvmvu1oY3PuAv0niTq6tZ78jk//9uc1r1r4lQki7y7sp2Tu4V1y2iLoqFTqi1lIGcpFiebrZNZ1dOkF0cCIlO8jQ47nCkam9Lilz9GhDF1I6XGLzfnhwDIIZVfI7+8SSgfHsijqXENOGJF5QorG4EcW0OrScqX/dDrXpr70Ut/BII+1OfECPuYz/NWxYmgrCsUskxPvyhgmrw+WGZ6lGTuOlIyCYWTFyWjpM5KIZRUIOwjRNYRQ6tZF9BXtk8hWAHPtLNJ727Fq0JSkC1FDRRF0Jalj0d5qVh2KEpM2TuSsCYTCT6ZkdmFYI9LrYp5QayWbo6NXlZwcRD/61pth5Fq5EX423QQxNjhqWvvklkljOLkYjrmphXPZOJOk6Pg7HKMsrtQKcowzZoK3rx1ZUelGMdQA/HaKkjAt2RgqpZeYqbNbH7Hp2ct4nqfSPOfe0ftiSTZJydOV6rG5bQbyLK+nRuCC0343PzDgiOXyQA5c14BTZi98uR/5KJ1SnatLdoO50WWBQZPTq0VgsklU3h932actuo17ayrHrb/3ykiegd3KbqF2wbV6RrlsJ07yLcpsWFTul9RyK6ZScr+tk7oNrFj0o7HQUlj4EiEvJ6rPLKSmlMZCrksl1OnLaRkxc+/HB1naMhNtT/6yM2bDs6azCRHrM3aVPN7aW8irD/10B8njpAMcsl8okXcdKrl4sPsLmQVy/Sj90ucPRc/d/Bxxj+dXSpCayen32D+hLi16MsIV8gfCXrYp6ySsiJKRUF0XXiLpVbFU+fNv4r7mOwhFsX4ZdwpSi1DYs2jb6ebZ9788cblTzMrYhu7sf/17IFdtuviJ2ioHA6pMHkoH4CLUeMBU7iGkxuM/YgcdderF9ibRdc7O982F1HpYhjfWUe+x5a6pjop9iNLfoePvlsdZdTSMwfxSmTY20Q0eHnUNzga1edeNmmqbg18aMVR1L9vwSXHF9TfIWBxpKLs2hj3eQeBC0USvp2HHF3eIkRdhFOd6ER8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/I/4J8AAo/80BciBec4AAAAASUVORK5CYII=",
"$Meta": {
"Type": "ActionTemplate"
}
}
Page updated on Friday, May 17, 2024