This is a really nice project which includes both icons for Visio and icons as pictures. Have a look if you are in need for icons to your Azure stencils.
Set osDisk size when deploying a VM in Azure
If you need a larger OS disk, at deployment, for your VM you can add {“diskSizeGB”: integer} under osDisk in an ARM deployment template. This is an easy way to increase the size of the OS disk when creating a VM.
Below is an example from an ARM deployment template for an Ubuntu VM.
"storageProfile": { "osDisk": { "createOption": "fromImage", "diskSizeGB": 512, "managedDisk": { "storageAccountType": "[parameters('osDiskType')]" } },
For more information and example visit: https://docs.microsoft.com/en-us/azure/templates/microsoft.compute/virtualmachines
Add a Tag when creating an Azure Resource Group
I have an Azure Automation Runbook, see post Clean up Azure Resource Groups with a Tag, that deletes Azure Resource Groups every night based on a tag.
Instead of typing the tag name every time, when creating new Resource Groups, I use a script that adds the tag and the location of the Resource Group.
To use the script, use Azure Cli in Azure or on a Linux host by running:
.\create_resourcegroup_with_tag.sh -g myrg
Download the script from GitHub or copy it from below.
# Creates a resource group with a tag # Example: .\create_resourcegroup_with_tag.sh -g myrg # Variables to be set when creating the resource group location="westeurope" tagname="RemoveResourceGroup" tagvalue="Yes" # input section POSITIONAL=() while [[ $# -gt 0 ]] do key="$1" case $key in -g|--resourcegroup) rg="$2" shift shift ;; -h|--help) echo "Please add -g for Resource Group Name" >&2; exit 1 ;; -*) echo "unknown option: $1" >&2; exit 1;; *) handle_argument "$1"; shift 1;; esac done if [ "$rg" == "" ] then echo "Missing argument Resource Group Name" exit 1 fi az group create -n "$rg" -l "$location" --tag "$tagname"="$tagvalue"
Clean up Azure Resource Groups with a Tag
In my environment I use an Azure Automation Runbook that every evening is cleaning up my environment based on a Tag. When the tag “RemoveResourceGroup” is set to “Yes” on a Resource Group I will delete it and everything in that group.
If you want to try my Runbook you can download the script and run it on your local client or in Azure Automation. I have tested the script with PowerShell module AzureRM.Resources version 6.7.3. If you need to upgrade the module in Azure Automation, to a newer version, just do a new import of the module from the gallery.
The script can be downloaded from GitHub.
<# .DESCRIPTION Removes Resource Groups that have a tag "RemoveResourceGroup" set to "Yes" Script can be used in both Azure Automation and direct from PowerShell prompt The script have been tested in Azure Automation with module AzureRM.Resources version 6.7.3 .NOTES Author: Jonathan Andersson Last Updated: 12/09/2019 .PARAMETER TagResourceGroupName Tag name .PARAMETER TagValue Tag value .PARAMETER AzureAutomation If script sould be run in Azure Automation .PARAMETER ConnectionName A<ure Automation RunAs Connection to Azure .EXAMPLE RemoveResourceGroupAutomation -TagResourceGroupName "RGName" -TagValue "Yes" -AzureAutomation $false #> [CmdletBinding()] param ( [Parameter()] [string] $TagResourceGroupName = "RemoveResourceGroup", [Parameter()] [string] $TagValue = "Yes", [Parameter()] [bool] $AzureAutomation = $true, [Parameter()] [string] $ConnectionName = "AzureRunAsConnection" ) # Create a Tag object [object] $Tag = @{} try { if ($AzureAutomation) { # Get the connection "AzureRunAsConnection " $servicePrincipalConnection = Get-AutomationConnection -Name $ConnectionName # Logging in to Azure Add-AzureRmAccount ` -ServicePrincipal ` -TenantId $servicePrincipalConnection.TenantId ` -ApplicationId $servicePrincipalConnection.ApplicationId ` -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint | Out-Null } $Tag.Add($TagResourceGroupName, $TagValue) Write-Output "Using TagResourceGroupName: $TagResourceGroupName and TagValue: $TagValue" $ResourceGroups = Get-AzureRmResourceGroup -Tag $Tag foreach ($ResourceGroup in $ResourceGroups) { Remove-AzureRmResourceGroup -Name $ResourceGroup.ResourceGroupName -Force | Out-Null Write-Output "Removed Resource Group: " $ResourceGroup.ResourceGroupName } } catch { if (!$servicePrincipalConnection) { $ErrorMessage = "Connection $ConnectionName not found." throw $ErrorMessage } else{ Write-Error -Message $_.Exception throw $_.Exception } }
Creating Azure Function and SQL Database with Azure DevOps Pipeline
I have started a small project with an Azure Function that collects data from an external API and pushes the information into an Azure SQL Database. I will not go into detail what the solution does but wanted to share the Azure DevOps Pipeline that I am using.
Hope this can be useful for anyone in the world ?
Some background
The Azure Function is written in .Net Core C# and connects to a database with an application setting. All Azure services are created with Azure json templates and the database table is created with a SQL script. To be able to deploy the SQL script two PowerShell scripts are used to open and close the Database Server Firewall ports for Azure DevOps.
The image, “windows-latest”, is used because of problems with the “vs2017-win2016” image when using Sqlcmd. When using the “vs2017-win2016” image Sqlcmd command could not be found. I didn’t troubleshoot this, instead I just changed to “windows-latest”.
Azure Repos have been used for the code, scripts and templates. The templates and SQL scripts are placed in different folders.
All variables that are used in the pipeline are defined in the yaml expect for the password to the database. That variable is defined in the Azure Pipeline variables as a secure string.
# Build and Deploy pipeline that creates an Azure .NET Core Function on Windows and Azure SQL Database trigger: - master variables: azureSubscription: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' functionAppName: 'MyApp' vmImageName: 'windows-latest' workingDirectory: '$(System.DefaultWorkingDirectory)/StocksApplication' solution: '**/*.sln' buildPlatform: 'Any CPU' buildConfiguration: 'Release' resourcegroup: 'myRG' connectedServiceName: 'myconnectedServiceName' sqlServerName: 'mysqlServerName' sqlUserName: 'mysqlUserName' sqlDatabaseName: 'myDatabaseName' location: 'West Europe' stages: - stage: Build displayName: Build stage jobs: - job: Build displayName: Build pool: vmImage: $(vmImageName) steps: - task: DotNetCoreCLI@2 displayName: Build inputs: command: 'build' projects: | $(workingDirectory)/*.csproj arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration Release - task: ArchiveFiles@2 displayName: 'Archive files' inputs: rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output' includeRootFolder: false archiveType: zip archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip replaceExistingArchive: true - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip artifact: drop - task: PublishPipelineArtifact@0 inputs: targetPath: 'Templates' artifactName: 'templates' publishLocation: 'Container' displayName: 'Publish Template folder to drop' - task: PublishPipelineArtifact@0 inputs: targetPath: 'SQL' artifactName: 'sql' publishLocation: 'Container' displayName: 'Publish SQL folder to drop' - stage: Deploy displayName: Deploy stage dependsOn: Build condition: succeeded() jobs: - deployment: Deploy displayName: Deploy environment: 'development' pool: vmImage: $(vmImageName) strategy: runOnce: deploy: steps: # https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-tutorial-use-azure-pipelines#create-a-pipeline # https://github.com/microsoft/azure-pipelines-yaml/issues/363 # Deploy Function by template - task: AzureResourceManagerTemplateDeployment@3 displayName: 'Deploy Function template' inputs: deploymentScope: 'Resource Group' connectedServiceName: ${{variables.connectedServiceName}} azureSubscription: '$(azureSubscription)' action: 'Create Or Update Resource Group' resourceGroupName: '$(resourcegroup)' location: '$(location)' templateLocation: 'Linked artifact' csmFile: '$(Pipeline.Workspace)\Templates\functionApp.json' csmParametersFile: '$(Pipeline.Workspace)\Templates\functionAppParamenter.json' deploymentMode: 'Incremental' # Deploy SQL Database server by template - task: AzureResourceManagerTemplateDeployment@3 displayName: 'SQL Server - Azure Deployment: Create Or Update Resource Group' inputs: deploymentScope: 'Resource Group' connectedServiceName: ${{variables.connectedServiceName}} azureSubscription: '$(azureSubscription)' action: 'Create Or Update Resource Group' resourceGroupName: '$(resourcegroup)' location: '$(location)' templateLocation: 'Linked artifact' csmFile: '$(Pipeline.Workspace)\Templates\sqlServer.json' csmParametersFile: '$(Pipeline.Workspace)\Templates\sqlServerParameters.json' overrideParameters: -administratorLoginPassword $(sqlAdministratorLoginPassword) deploymentMode: 'Incremental' # Deploy SQL Database by template - task: AzureResourceManagerTemplateDeployment@3 displayName: 'SQL Database - Azure Deployment: Create Or Update Resource Group' inputs: deploymentScope: 'Resource Group' connectedServiceName: ${{variables.connectedServiceName}} azureSubscription: '$(azureSubscription)' action: 'Create Or Update Resource Group' resourceGroupName: '$(resourcegroup)' location: '$(location)' templateLocation: 'Linked artifact' csmFile: '$(Pipeline.Workspace)\Templates\sqlDatabase.json' csmParametersFile: '$(Pipeline.Workspace)\Templates\sqlDatabaseparameters.json' deploymentMode: 'Incremental' # PowerShell # https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/azure-sqldb?view=azure-devops&tabs=yaml#deploying-conditionally # https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/utility/powershell?view=azure-devops - task: AzurePowerShell@2 displayName: 'Azure PowerShell: Deploy FW opening' inputs: azureSubscription: '$(azureSubscription)' scriptPath: '$(Pipeline.Workspace)\SQL\SetAzureFirewallRule.ps1' scriptArguments: -ResourceGroup '$(resourcegroup)' -ServerName '$(sqlServerName)' -AzureFirewallName 'AzureWebAppFirewall-$(Build.BuildId)' azurePowerShellVersion: LatestVersion # Create tables and stored procedure - task: CmdLine@1 displayName: 'Run Sqlcmd to create table and stored procedure' inputs: filename: Sqlcmd arguments: '-S $(sqlServerName).database.windows.net -U $(sqlUserName) -P $(sqlAdministratorLoginPassword) -d $(sqlDatabaseName) -i $(Pipeline.Workspace)\SQL\StocksSQLCreate.sql' - task: AzurePowerShell@2 displayName: 'Azure PowerShell: Delete FW opening' inputs: azureSubscription: '$(azureSubscription)' scriptPath: '$(Pipeline.Workspace)\SQL\RemoveAzureFirewall.ps1' scriptArguments: -ResourceGroup '$(resourcegroup)' -ServerName '$(sqlServerName)' -AzureFirewallName 'AzureWebAppFirewall-$(Build.BuildId)' azurePowerShellVersion: LatestVersion - task: AzureFunctionApp@1 displayName: 'Azure functions app deploy' inputs: azureSubscription: '$(azureSubscription)' appType: functionApp appName: $(functionAppName) package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip' # https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-app-service-settings?view=azure-devops - task: AzureAppServiceSettings@1 inputs: azureSubscription: '$(azureSubscription)' appName: $(functionAppName) resourceGroupName: '$(resourcegroup)' appSettings: | [ { "name": "sqldb_connection", "value": "Server=tcp:$(sqlServerName).database.windows.net,1433;Initial Catalog=$(sqlDatabaseName);Persist Security Info=False;User ID=$(sqlUserName);Password=$(sqlAdministratorLoginPassword);MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;", "slotSetting": false } ]