Limit deployment rights to Azure from Azure DevOps - azure

I want to lock down access to the kudu tools e.g. https://.scm.azurewebsites.net/DebugConsole to a set of ip addresses that azure devops uses.
I have gone into AzureDevops -> Organisation settings -> Overview and see that my organisation's Azure Devops is held in e.g. West Europe
I have downloaded the list of ip addresses of azure data centers from here: https://www.microsoft.com/en-nz/download/details.aspx?id=41653
I have gone onto App Service -> Networking blade -> Configure Access restrictions and uploaded the list of ip addresses of e.g. West Europe for .scm.azurewebsites.net.
My understanding is that AzureDevops agents operate from the region specified in organisation settings so if I put in those IP addresses they should be able to acccess the kudu tools fine but instead I get the following error:
Failed to deploy web package to App Service.
Error Code: ERROR_COULD_NOT_CONNECT_TO_REMOTESVC
More Information: Could not connect to the remote computer ("<myappservice>.scm.azurewebsites.net") using the specified process ("Web Management Service") because the server did not respond. Make sure that the process ("Web Management Service") is started on the remote computer. Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_COULD_NOT_CONNECT_TO_REMOTESVC.
Error: The remote server returned an error: (403) Forbidden.
If I remove the ip addresses it deploys with no problems. How do I limit deployment access to Azure Devops

as the comment by Daniel Mann suggests - you should use Azure RBAC to limit what Azure Devops service principal can do in Azure. If you only allow it to manage specific App Service - it will be able to do only that.
https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal

I found a workaround for this by simply having a pre-deploy step which disables the ip address restrictions for deployments to .scm.azurewebsites.net and then immediately enables them afterwards. Predeploy step:
Write-Host ("Removing IP Address restrictions from scm site")
$apiVersion = ((Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Web).ResourceTypes | Where-Object ResourceTypeName -eq sites).apiVersions[0]
$webAppConfig = (Get-AzureRmResource -ResourceType Microsoft.Web/sites/config -ResourceName $webSiteName -ResourceGroupName $resourceGroupName -apiVersion $apiVersion)
$webAppConfig.Properties.scmIpSecurityRestrictions = #()
Set-AzureRmResource -ResourceId $webAppConfig.ResourceId -Properties $webAppConfig.Properties -apiVersion $apiVersion -Force
Write-Host ("Removed IP Address restrictions from scm site")
PostDeploy step:
Write-Host ("Cloudflare firewall enabled - Starting IP Address restrictions")
function AddRules($rulesToAdd) {
$rules = #()
foreach ($ruleToAdd in $rulesToAdd)
{
$rule = [PSCustomObject] #{
ipAddress = $ruleToAdd.ipAddress;
action = $ruleToAdd.action;
priority = $ruleToAdd.priority;
name = $ruleToAdd.name;
description = $ruleToAdd.description
}
$rules += $rule
}
return $rules
}
# Access to the main site should only be allowed through cloudflare
[PSCustomObject] $websiteRulesToAdd =
#{ipAddress="173.245.48.0/20";action="Allow";priority="100";name="CF01";description="CloudFlare Ip Address"},`
# etc
# Access to the development site should be locked down to developers (NB: These rules are temporarily disabled on deployment)
[PSCustomObject] $scmRulesToAdd =
#{ipAddress="X.X.X.X/32";action="Allow";priority="100";name="developer1";description="Developer IP Address"}
# etc
$apiVersion = ((Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Web).ResourceTypes | Where-Object ResourceTypeName -eq sites).apiVersions[0]
$webAppConfig = (Get-AzureRmResource -ResourceType Microsoft.Web/sites/config -ResourceName $webSiteName -ResourceGroupName $resourceGroupName -apiVersion $apiVersion)
Write-Host ("Writing IP Address restrictions")
$webAppConfig.Properties.ipSecurityRestrictions = AddRules -rulesToAdd $websiteRulesToAdd
$webAppConfig.Properties.scmIpSecurityRestrictions = AddRules -rulesToAdd $scmRulesToAdd
Set-AzureRmResource -ResourceId $webAppConfig.ResourceId -Properties $webAppConfig.Properties -apiVersion $apiVersion -Force
Write-Host ("Completed IP Address restrictions")
This is run by AzureDevops as part of the deployment so access is controlled. I hope this is useful to someone

Related

Can't configure network config on two azure web apps

Facing a problem about VNET and Azure Web Apps I don't understand.
My issue
This is my setting:
Two web apps on the same service plan SP1 (SP1 (P1v2: 1)) and a VNET, VNET1:
Both subnets have Microsoft.Web/serverFarms delegation.
I want to add network config on my webapps webapps1 and webapps4.
I run this PowerShell script:
properties = #{
subnetResourceId = "/subscriptions/XXX/resourceGroups/RG1/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/sub01"
}
$vNetParams = #{
ResourceName = "mywebapps1/VirtualNetwork"
Location = "West Europe"
ResourceGroupName = "RG1"
ResourceType = "Microsoft.Web/sites/networkConfig"
PropertyObject = $properties
}
$result = New-AzResource #vNetParams -Force
$properties = #{
subnetResourceId = "/subscriptions/XXX/resourceGroups/RG1/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/sub02"
}
$vNetParams = #{
ResourceName = "mywebapps4/VirtualNetwork"
Location = "West Europe"
ResourceGroupName = "RG1"
ResourceType = "Microsoft.Web/sites/networkConfig"
PropertyObject = $properties
}
$result = New-AzResource #vNetParams -Force
First new-azresource works fine:
But the second one throw this error message:
New-AzResource : {"Code":"Conflict","Message":"Adding this VNET would
exceed the App Service Plan VNET limit of 1
What I did
I search for this error message. But found only one situation that did not help me or maybe I did not understand.
What I need
Understand what it means.
How I should do
Thank you
Regional virtual integration can use One virtual interface per worker means one regional virtual network integration per App Service plan. All the apps in the same App Service plan can only use the same virtual network integration to a specific subnet.
Gate-way required virtual network integration Enables an app to connect to only one virtual network at a time.
This can Enables up to five virtual networks to be integrated within an App Service plan.
Refer to this documentation for more information about different virtual network integrations and their limitations as well.
For more information you can refer to these similar threads:
https://social.msdn.microsoft.com/Forums/en-US/a8b51183-d94b-48c9-9b6c-e6a4dbec9919/vnet-integration-limit-of-1?forum=azureappconfiguration
As per my understanding you're getting desired output. Please note that you are using New-AzResource which basically creates resources instead you should use Set-AzResource command.
Suggestion
Use Set-AzResource instead of New-AzResource
Configure VNet Integration
$subnetResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Network/virtualNetworks/$vNetName/subnets/$integrationSubnetName"
$webApp = Get-AzResource -ResourceType Microsoft.Web/sites -ResourceGroupName $resourceGroupName -ResourceName $siteName
$webApp.Properties.virtualNetworkSubnetId = $subnetResourceId
$webApp | Set-AzResource -Force
Regional VNet integration feature basically creates association or link between Microsoft.Network/VirtualNetwork and Microsoft.Web/Serverfarm resources using Rest API call.
In this scenario you're using New-AzResoruce which invoke REST API for creation of service association which is already existed hence its throwing error. If you try to do it from portal you shouldn't get that as portal validation takes care of type of REST API call.

VMSS registration in Custom DNS

We’re creating a VMSS and we use a custom DNS with extending AD from on-premises, but we are not sure how to register the VMs as the scale set scales out, in azure DNS we can create a private zone and use auto registration but not with our custom DNS.
• Considering that you have registered your custom DNS in Azure successfully, and now you want to replicate your on-premises infrastructure in Azure given the options of continuous availability and scalability, you are deploying VMSS (Virtual Machine Scale Set) for that purpose. Thus, to service your applications deployed on them and better security, I would suggest you deploy AADDS (Azure Active Directory Domain Services) in your tenant in Azure and synchronize the domain data from on-premises to the AADDS by extending it in here.
Hence, once the ADDS service and its roles are setup successfully using the custom DNS that you have setup in Azure, you should be able to Azure AD domain join the VMSS deployed. Thus, after domain joining the VMSS, its DNS records will be automatically managed by the AADDS role internally in your Azure AD tenant.
To enable domain joining for the VMSS successfully, you will have to add an extension like a normal VM through powershell as below. You will have to replace the ‘user, domain, ou path and password’ and it should work fine: -
$Settings = #{
"Name" = "yourdomain.onmicrosoft.com";
"User" = "DOMAIN\USERNAME";
"Restart" = "true";
"Options" = 3;
"OUPath" = "OU=TEST,OU=My Computers,DC=yourdomain,DC=onmicrosoft,DC=com"
}
$password = 'SomeReallyComplexPassword'
$ProtectedSettings = #{
"Password" = $password
}
$rgName = "yourgname"
$scaleSetName = "yourvmssname"
$vmss = Get-AzureRmVmss -ResourceGroupName $rgName -VMScaleSetName $scaleSetName
$vmss = Add-AzureRmVmssExtension -VirtualMachineScaleSet $vmss -Publisher "Microsoft.Compute" -Type "JsonADDomainExtension" -TypeHandlerVersion 1.3 -Name "vmssjoindomain" -Setting $Settings -ProtectedSetting $ProtectedSettings -AutoUpgradeMinorVersion $true
Update-AzureRmVmss -ResourceGroupName $rgName -Verbose -Name $scaleSetName -VirtualMachineScaleSet $vmss
After adding this extension, any existing servers deployed in the VMSS will have to upgrade their model to use this extension while the new ones will use it when they are deployed with it. You will need to execute the below powershell command to ensure that further extensions can be added to the VMSS: -
az vmss update-instances --resource-group yourrgname --name yourvmssname --instance-ids *
Thus, in this way, you can ensure that your VMs in the VMSS get registered with the custom DNS that you have setup in your Azure tenant.

Azure powershell command to get the reserved IP details for a VM in a subscription

I am trying to get the list of reserved IP's that are assigned to resources in my subscriptions in ARM model.
Get-AzureReservedIP command does not work saying the default subscription is not selected. However I selected a default subscription and still the command does not work.
here is the snippet
Add-AzureRmAccount
$subName="subscriptioname"
Select-AzureSubscription -SubscriptionName $subName -Current
Get-AzureReservedIP
Any Suggestions?
Azure has two ways of deployment: Azure service management (ASM) and Azure resource manager (ARM).
You sign in with ARM mode and the "Get-AzureReservedIP" is a ASM command. In ARM, the reserved IP address is called static public IP address. To get them, please run the commands below:
Add-AzureRmAccount
$subName="subscriptioname"
Select-AzureRmSubscription -SubscriptionName $subName
Get-AzureRmPublicIpAddress | Where-Object { $_.PublicIpAllocationMethod -eq "Static" }
If you want to get the reserved IP address in ASM mode, please run the commands below:
Add-AzureAccount
$subName="subscriptioname"
Select-AzureSubscription -SubscriptionName $subName -Current
Get-AzureReservedIP
You can try :
Get-AzureRmNetworkInterface -Name TestNIC -ResourceGroupName TestRG

Scripting WebApp VNET integration with Azure Powershell

I can use the azure portal to add a web app to a virtual network for communications between various services hosted on it. However I have everything else in the environment scripted via Powershell and would like to automate the WebApp/VNET integration too.
I have read the following article so far:
https://azure.microsoft.com/en-gb/documentation/articles/web-sites-integrate-with-vnet/
However that is just how to do it via the portal. I am thinking that the Set-AzureRMWebApp cmdlet is the right thing to use, but i can't see any parameters that might help.
https://msdn.microsoft.com/en-us/library/mt652487.aspx
I had the same issue and couldn't find a way to do this using a PS modules. However functionality has now been added to azure CLI. So you can just involke this from a script.
az webapp vnet-integration add -g "resource group name" -n "app service name" --vnet "vnet name" --subnet "subnet name"
First you need an existing VNet with P2S configured as per my post at http://www.techdiction.com/2016/01/12/creating-a-point-to-site-vpn-connection-on-an-azure-resource-manager-virtual-network/
Then use the below PowerShell to connect the AppService to the VNet using P2S VPN:
$subscription_id = "<Subscription_ID>"
$NetworkName = "<Network_Name>"
$location = "<Region>"
$netrgname = "<Resource_Group_VNet_is_in>"
$AppServiceName = "<AppService_Name>"
$props = #{
"vnetResourceId" = "/subscriptions/$subscription_id/resourcegroups/$netrgname/providers/Microsoft.ClassicNetwork/virtualNetworks/$NetworkName";
"certThumbprint"= "<Client_cert_thumbprint>";
"certBlob"= "<Base64_Cert_Data>";
"routes" = $null;
}
New-AzureRMResource -ResourceName "$AppServiceName/$AppServiceName-to-$NetworkName" -Location $location -ResourceGroupName MarcusWebsites -ResourceType Microsoft.Web/sites/virtualNetworkConnections -PropertyObject $props -ApiVersion "2015-08-01" -force
You can configure custom routes if you require by modifying the routes property. Let me know how you get on and if it resolves the situation please mark this post as the answer.
Marcus
This is currently not supported, we have it on our to-do list, unfortunately I don't have an eta right now

How programatically restart a Azure VM role (PaaS VM)

I have a PaaS VM role that need to be restart using Azure Management libraries. I tried following codes but failed with "BadRequest: The operation is not supported on a role of type MyPaaSVmName". But I successfully restarted IaaS VM using below Method1.
Is it possible to restart a PaaS VM role using Azure Management Libraries?
if not, is there any other way to achieve it using c#.
1.
ComputeManagementClient client = new ComputeManagementClient(cloudCredentials);
client.VirtualMachines.Restart(hostedServiceName, deploymentName, vmName);
2.
ComputeManagementClient client = new ComputeManagementClient(cloudCredentials);
VirtualMachineOperationsExtensions.Restart(client.VirtualMachines, hostserviceName, deploymentName, vmName);
Thank you.
Found the issue,
Method1 should be like this as I am restarting a Role Instance. Method2 is wrong.
client.Deployments.RebootRoleInstanceByDeploymentName(hostserviceName, deploymentName, roleName);
Here's how you can do it using Azure Powershell:
ReSet-AzureRoleInstance -ServiceName "MySvc1" -Slot Staging -InstanceName "MyWebRole_IN_0" –reboot
https://msdn.microsoft.com/en-us/library/azure/dn495202.aspx
And here's a snippet from an Azure Automation Runbook which can reboot all cloud service's instances, per update domain (so you have no downtime):
https://gallery.technet.microsoft.com/Reboot-Cloud-Service-PaaS-b337a06d
$roleInstances = Get-AzureRole -ServiceName $cloudServiceName -Slot Production -InstanceDetails
Write-Output "Retrieved all role instances for cloud service: $cloudServiceName. Number of instances: " + $roleInstances.Count
# Group instances per update domain
$roleInstanceGroups = $roleInstances | Group-Object -AsHashTable -AsString -Property InstanceUpgradeDomain
Write-Output "Number of update domains found: " + $roleInstanceGroups.Keys.Count
# Visit each update domain
foreach ($key in $roleInstanceGroups.Keys)
{
$count = $perDomainInstances.Count;
Write-Output "Rebooting $count instances in domain $key"
$perDomainInstances = $roleInstanceGroups.Get_Item($key)
foreach -parallel($instance in $perDomainInstances)
{
$instanceName = $instance.InstanceName
Write-Output "Rebooting instance $instanceName"
Reset-AzureRoleInstance -ServiceName $cloudServiceName -Slot Production -InstanceName $instanceName -Reboot -ErrorAction Stop
}
}

Resources