Automated provisioning
According to Enterprise Management Associates’ (EMA) 2014 study on the software-defined data center, 47 percent of enterprise IT teams take from one week to over a month to provide infrastructure resources to developers and testers. There is an upcoming trend of answers to this problem which can auto provision resources in minutes. Check out the two flavors of automated provisioning. First one use Powershell and second uses Chef. Both are simple and straightforward to implement for DevTest and DevOps scenarios.
PowerShell
Azure PowerShell is a scripting module that programmatic way to provision and configure cloud services, virtual machines, virtual networks, and web apps. We developed a PowerShell script to provision simple two tier web application on Azure.
We’ve developed a PowerShell script to provision Azure resources. To run this script, you need the following:
- An Azure account
- The Azure SDK, downloadable from Microsoft
- A web deploy package of your Visual Studio solution, packaged as a zip file
Before running the script you need to run the command “Add-AzureAccount” from your Azure powershell command line and login using the email address and password for you Azure subscription.
PS C:\Users\iLink\Documents\Azure DevOps> Add-AzureAccount
{ location: "West US", resourceGroup: { name: "ilinkresourcegroup1126" }, server: { name: "ilinkserver1126", admin: "peterharnish", password: "********" }, database: { name: "ilinksample1126_db", edition: "Basic" }, appServicePlan: { name: "ilinkappserviceplan1126", Sku: "Standard", numberOfWorkers: 1, workerSize: "Small" }, website: { name: "ilinksample1126" }, appInsights: { name: "ilinkappinsights1126", location: "Central US" }, requests: { get: "https://ilinksample1126.azurewebsites.net/people", create: "https://ilinksample1126.azurewebsites.net/people/Create?Name=Peter Harnish&ZipCode=98054", edit: "https://ilinksample1126.azurewebsites.net/people/Edit?ID=1&Name=Peter Harnish&ZipCode=98055", delete: "https://ilinksample1126.azurewebsites.net/people/Delete/1" } }
The script does the following things:
- Creates a new resource group
- Creates a SQL Server
- Creates an App Service plan
- Creates a web site
- Creates application insights
- Creates a database
- Publishes the web app using the given zip file. The path is passed as a parameter.
- Opens the SQL Server firewall
- Runs the following tests to the web app:
- Get request
- Create request
- Edit request
- Delete request
- Removes the resource group, which removes all the resources underneath it
The full text of the script is given below:
Param( [string] [Parameter(Mandatory=$true)] $Configuration, [string] [Parameter(Mandatory=$true)] $Package ) # read inputs from file Write-Verbose -message "Reading inputs..." $inputs = (Get-Content $Configuration) -join "`n" | ConvertFrom-Json #select the azure subscription Write-Verbose -message "Selecting the Azure Subscription..." Select-AzureSubscription -SubscriptionName "Free Trial" Write-Verbose -message "Switching Azure mode to Azure Resource Manager..." Switch-AzureMode AzureResourceManager -Verbose:$false # create resource group Write-Verbose -message "Creating Azure Resource Group..." New-AzureResourceGroup -Location $inputs.location -Name $inputs.resourceGroup.Name # create database server $securePassword1 = ConvertTo-SecureString -String $inputs.server.password -AsPlainText -Force $cred1 = New-Object System.Management.Automation.PSCredential($inputs.server.admin, $securePassword1) Write-Verbose -message "Creating Azure SQL Server..." New-AzureSqlServer -ResourceGroupName $inputs.resourceGroup.Name -Location $inputs.location -ServerName $inputs.server.name -SqlAdministratorCredentials $cred1 #create app service plan Write-Verbose -message "Creating Azure App Service Plan..." $plan = New-AzureAppServicePlan -ResourceGroupName $inputs.resourceGroup.Name -Name $inputs.appServicePlan.name -location $inputs.location -Sku $inputs.appServicePlan.Sku -NumberofWorkers $inputs.appServicePlan.numberOfWorkers -WorkerSize $inputs.appServicePlan.workerSize #create web site Write-Verbose -message "Creating web site..." New-AzureResource -name $inputs.website.name -ResourceGroupName $inputs.resourceGroup.Name -ResourceType "Microsoft.Web/sites" -Location $inputs.location -Force -PropertyObject @{serverFarmId = $plan.ResourceId} -OutputObjectFormat New #create application insights Write-Verbose -message "Creating application insights..." New-AzureResource -ResourceName $inputs.appInsights.name -ResourceGroupName $inputs.resourceGroup.Name -ResourceType "Microsoft.Insights/Components" -Location $inputs.appInsights.location -PropertyObject @{"Type" ="ASP.NET"} -Force -OutputObjectFormat New #create sql database Write-Verbose -message "Creating SQL database..." New-AzureSqlDatabase -ResourceGroupName $inputs.resourceGroup.name -ServerName $inputs.server.name -DatabaseName $inputs.database.name -Edition $inputs.database.edition Write-Verbose -message "Switching Azure mode to Azure Service management..." Switch-AzureMode AzureServiceManagement -Verbose:$false $connectionString = "Server=tcp:{0}.database.windows.net,1433;Database={1};User ID={2}@{0};Password={3};Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" -f $inputs.server.name,$inputs.database.name,$inputs.server.admin,$inputs.server.password # publish the web app Write-Verbose -message "Publishing the web application..." Publish-AzureWebsiteProject -Name $inputs.website.name -Package $Package -ConnectionString @{ DefaultConnection = $connectionString } # allow connections to the server Write-Verbose -message "Creating the server firewall rule..." New-AzureSqlDatabaseServerFirewallRule -StartIPAddress 0.0.0.0 -EndIPAddress 0.0.0.0 -RuleName "AllowAllWindowsAzureIps" -ServerName $inputs.server.name # do a get request Write-Verbose -message "Performing a get request..." Invoke-WebRequest -Uri $inputs.requests.get -Method GET # create a record Write-Verbose -message "Creating a record..." Invoke-WebRequest -Uri $inputs.requests.create -Method POST # editing a record Write-Verbose -message "Editing a record..." Invoke-WebRequest -Uri $inputs.requests.edit -Method POST # deleting a record Write-Verbose -message "Deleting a record..." Invoke-WebRequest -Uri $inputs.requests.delete -Method POST Write-Host "Press any key to continue..." $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") Write-Verbose -message "Switching Azure mode to Azure Resource Manager..." Switch-AzureMode AzureResourceManager -Verbose:$false # removing the resource group Write-Verbose -message "Removing the resource group..." Remove-AzureResourceGroup -Name $inputs.resourceGroup.Name -Force
You run the script using the following command in Azure Powershell:
PS C:\Users\iLink\Documents\Azure DevOps> .\ProvisionWebApp.ps1 -Configuration "ProvisionWebApp.json" -Package "C:\SampleAzureWebApp.zip"
Before deleting the resource group the script pauses for input and you can view the resources created in the portal.
Coming soon: How to provision Azure resources using Chef!