Securing a "tiered" application in Azure - azure

Ok.
So I'm new to deploying infrastructure to Azure.
I do understand the basics.
I've been tasked to create a "web tier", "middle tier machine", and "database server" in Azure. I'm probably using on-premise terms for these....maybe they map to Azure.
I am using App-Service-Plan and App-Service. Windows flavored.
I am also liking terraform very much, but this question isn't terraform dependent I think. (terraform is just the fancier way to create the necessary objects in Azure, or that's my novice understanding).
So right now, I've been able to create.
App-Service (which would be my "web-server"). I'll call this AppServiceWT.
App-Service (which would be my "middle tier"). I'll call this AppServiceMT.
And Sql-Server/Sql-Server database.
I've been able to create some of this using terraform flavored scripts.
resource "azurerm_resource_group" "testrg" {}
..
resource "azurerm_app_service_plan" "testaspwt" {
name = "some-app-service-plan-for-webtier"
sku {
tier = "Standard"
size = "S1"
}
}
resource "azurerm_app_service" "testaswt" {
name = "AppServiceWT_SomeGlobalUniqueName"
}
..
resource "azurerm_app_service_plan" "testaspmt" {
name = "some-app-service-plan-for-middletier"
sku {
tier = "Standard"
size = "S1"
}
}
resource "azurerm_app_service" "testasmt" {
name = "AppServiceMT_SomeGlobalUniqueName"
}
..
resource "azurerm_sql_server" "primary_azurerm_sql_server" {}
resource "azurerm_sql_database" "primary_azurerm_sql_database" {}
So I have the "parts" ( I think ??? ).
So my hurdle now is.
What am I doing to secure the network traffic.
Requirements:
The middleTier can make requests sql-server-tier. sql-server-tier is not accessible to anything besides middle-tier. In the on-premise world, we would open up port 1433 on the sql-server to allow traffic.
The webTier can make requests middle-tier. middle-tier is not accessible to anything besides web-tier. In the on-premise world, we would open up port 80/443 on the middle-tier to allow traffic.
WebTier is open to world.
What azure "objects" am I missing?
Bonus points for pointing to terraform "tasks" (or whatever they are called).
https://www.terraform.io/docs/providers/azurerm/index.html
But yeah, I'm reaching out to SOF for help to fill in the "traffic" and "secure network" gaps in my head.
Thanks in Advance.
If I'm asking the wrong questions, let me know.
I do not want to maintain my own VM's. So I think Azure App-Service-Plan and App-Service is the correct choice. While I'm a little familiar with Azure-Functions and Logic-Apps, we want to not use those for this project.
To add a little more info.
I'm eventually trying to do a "hello world" using the below microsoft how-to article. The article above does not have a middle-tier, but once I have the concepts down, I think I can make a web/middle/sql 'hello world'.
https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-dotnetcore-sqldb

There are a few ways you can secure the application in the app service you are creating -
1.I believe you are already doing it or not sure if you require it but
we can authenticate access to the web app (using OAuth2.0 etc..).
2.If you want more control over the network where we are deploying the apps we
can utilize App service Environments which provides
virtual network integration feature that helps you restrict incoming
source IP addresses through network security groups (NSGs).
Probably once can use it for both the front end and middle tier.
3.White-list the allowed ranges of IP Address in the database.In your case if
any other service should not access the database other
than the web app , then it should be the IP of the frontend web app.

With webapps, your only option is opening webapp external ip addresses to sql to be able to talk to each other.
webapp has got several potential external ip addresses it can have, so you open those on sql. traffic will use azure back bone as long as azure sql\webapp are in the same region.
On the middle tier you should use ip restrictions (web.config can do that).

Related

Are the outbound IPs of a consumption logic app static?

We have a requirement to call a 3rd party API via a source with a fixed set of IPs. The IPs need to be static.
Since we are already using Logicapps(consumption) to do other processing, my initial thought was to continue using logic apps. I have already checked the concurrency and message size and they are all within acceptable range to use Logicapps.
My only question is on the IP of the Logicapp when it makes an API call. We had explored using Logic apps standard with VNET integration and Natgateway but this adds additional cost. The other option was to use APIM to provide a static IP, but the Logic would need to integrate with AAD for oAuth2 authentication and we would face challenges in managing the AAD tokens. We don't want to call AAD for a new token for each and every execution.
From the portal I can see a set of outbound IPs for my Logicapp.
I have already tested that the IP exposed is within this list. But I wanted to know if there is a chance that this can change in the future. I was not able to find any concrete Microsoft documentation around this question.
You should always take in account those IPs can change.
Microsoft exposes a downloadable list of Azure Ip Ranges here
This file contains the IP address ranges for Public Azure as a whole, each Azure region within Public, and ranges for several Azure Services (Service Tags) such as Storage, SQL and AzureTrafficManager in Public. Service Tags are each expressed as one set of cloud-wide ranges and broken out by region within that cloud. This file is updated weekly. New ranges appearing in the file will not be used in Azure for at least one week. Please download the new json file every week and perform the necessary changes at your site to correctly identify services running in Azure.
You can also get this data using the PowerShell Get-AzNetworkServiceTag in case you want to automate things. Example:
$serviceTags = Get-AzNetworkServiceTag -Location westeurope
$logicApps = $serviceTags.Values | Where-Object { $_.Name -eq "LogicApps" }
$logicApps.Properties
Region :
SystemService : LogicApps
ChangeNumber : 11
AddressPrefixes : {4.232.111.16/28, 4.232.111.32/27, 13.64.231.196/32, 13.65.39.247/32...}

How to connect a "azurerm_windows_web_app" resource in Terrafrom with a Virtual Network

I am using the "azurerm_windows_web_app" resource type in terraform to create an app service. I am using this resource because the "azurerm_app_service" is being deprecated as indicated by the docs.
I need to setup the outbound traffic section of the app service to use a virtual network like below. I already have the virtual network being created successfully, so I just need to find a way to link it to the app service via terraform.
I cannot see any property on the resource that allows me to achieve this. On the "azurerm_app_service" resource I can see a "azurerm_app_service_virtual_network_swift_connection" which I think might achieve this, but I cannot see a corresponding resource for a "azurerm_windows_web_app" resource to connect it to a virtual network.
Does anybody know if there is currently a way to achieve this?
app_service_virtual_network_swift_connection should still be the right one. The app services resources have been split up with the latest 3.0 TF provider release but I believe the swift resource will cover both, Windows and Linux app services.

Is it possible to provision backend address pool separately from application gateway

I want to provision my infrastructure with terraform and to have some shared infrastructure. For example, to have 1 shared application gateway and multiple application specific webapps sitting behind it.
Is it possible to provision this with separate terraform projects?
terraform project that would be for a shared infrastructure - to create an empty/default app gateway.
other projects that would create a webapp and some extra configuration for that shared app gw - backend_address_pool, probe, backend_http_settings, etc.
Could not find how can you do it in documentation. There is this - application_gateway example where everything is provided in 1 go and then this - network_interface_application_gateway_backend_address_pool_association where you can make a assotiation between app gw and a network interface, but not a webapp.
EDIT
To expand a bit on what I want to achieve - the application gateway will be one application gateway for the whole non-prod environment (hence "shared") and it is there to save the cost. Behind it I want to configure multiple applications for multiple environments, for example, "Accounts.DEV", "Accounts.UAT", "Calculator.Dev", etc. Hope this makes my intentions a bit clearer.
For now I am trying to create empty Application gateway in the shared project (with a default pool, front-end config and rules). And then, after each application deployment to run some extra az cli logic (documentation).
It is possible to provision the application gateway and web apps separately.
By default, this application_gateway example creates an empty backend pool without any targets with one default HTTP setting, one listener for 80 port, and a basic rule for this backend pool. When you want to associate your backend web apps behind this application gateway, you need to target default_site_hostname of your web app to the backend pool and modify some specific configurations to match your backend web apps.
For example,
In the azurerm_app_service project, you can add the value of default_site_hostname for an app service at the provision time or use the data source to access an existing app service.
output "default_site_hostname" {
value = "${azurerm_app_service.test.default_site_hostname}"
}
In the azurerm_application_gateway project, you can add the value of default_site_hostname to the fqdns, then associate the backend pool with them.
# since these variables are re-used - a locals block makes this more maintainable
locals {
backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap"
frontend_port_name = "${azurerm_virtual_network.test.name}-feport"
frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip"
http_setting_name = "${azurerm_virtual_network.test.name}-be-htst"
listener_name = "${azurerm_virtual_network.test.name}-httplstn"
request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt"
redirect_configuration_name = "${azurerm_virtual_network.test.name}-rdrcfg"
fqdns = ["${azurerm_app_service.test.default_site_hostname}","${data.azurerm_app_service.example.default_site_hostname}"]
...
backend_address_pool {
name = "${local.backend_address_pool_name}"
fqdns = "${local.fqdns}"
}
Currently this is not possible with terraform due the fact that Azure API does not allow creating an App Gateway step by step. If this is an issue for you and would like it to change, please vote for this and this feature request.
Source: https://github.com/terraform-providers/terraform-provider-azurerm/issues/727

How to know the origin resource group of a App Service Plan?

I have an Azure App Service Plan and a Web App. I want to move them to another subscription. There is a limitation that app service plan and app service must be moved together from the origin resource group of the app service plan. Someone had moved the resources from their origin resource group and deleted the resource group. Now, how can I find the name of the origin resource group ?
In some cases it can be found in the WebSpace property of app service plan. For example [ "webSpace": "RG-SK-MarkIII-CentralUSwebspace" ], RG-SK-MarkIII is the origin resource group of the app plan. But in my case the webSpace is like this ["webSpace": "AustraliaEastwebspace" ]. Is there any other way to find it through CloudShell ?
You can look up the actions taken by a particular user, even for a resource group that no longer exists.
az monitor activity-log list -g ExampleGroup --caller someone#contoso.com --offset 5d
Kindly try these steps:
If you don't remember the original resource group, you can find it through diagnostics.
For your web app, select Diagnose and solve problems.
Then, select Configuration and Management.
Select Migration Options.
Select the option for recommended steps to move the web app.
You see the recommended actions to take before moving the resources. The information includes the original resource group for the web app.
- I understand you're referring to RG deletion scenario, kindly try this and let me know how it goes.
Reference document move across subscription.
Furthermore, you can only change to a plan that was created in the same "webspace" as your original app. Webspace is an internal concept that's not exposed, but you can verify whether your source and destination plans are in the same webspace or not.
To verify, do the following:
https://resources.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{serverFarmName}
Confirm whether the webSpace property of your source plan matches the webSpace property of your new plan

Can Windows Azure roles detect which datacenter the roles are in?

Our Windows Azure roles need to know programmatically which datacenter the roles are in.
I know a REST API ( http://msdn.microsoft.com/en-us/library/ee460806.aspx) return location property.
And if I deploy to, let’s say, West US, the REST API returns West US as location property.
However, if I deploy to Anywhere US, the property is Anywhere US.
I would like to know which datacenter our roles are in even if location property is Anywhere US.
The reason why I ask is our roles need to download some data from Windows Azure storage.
The cost of downloading data from the same datacenter is free but the that of downloading data from the different datacenter is not free.
It is a great question and I have talked about it couple of time with different partners. Based on my understanding when you create your service and provide where you want this service to location ("South Central US" or "Anywhere US"), this information is stored at the RDFE server specific to your service in your Azure subscription. So when you choose a fixed location such as "South Central US" or "North Central US" the service actually deployed to that location and exact location is stored however when you choose "Anywhere US", the selection to choose "South Center" or "North Central" is done internally however the selected location never updated to RDFE server related to your service.
That's why whenever you try to get location info related to your service in your subscription over SM API or Powershell or any other way (even on Azure Portal it is listed as "Anywhere US" because the information is coming from same storage), you will get exactly what you have selected at first place during service creation.
#Sandrino idea will work as long as you can validate your service location IP address from a given IP address range published by Windows Azure team.
Two days ago Microsoft published an XML file containing a list of IP ranges per region. Based on this file and the IP address of your role you can find in which datacenter the role has been deployed.
<?xml version="1.0" encoding="UTF-8"?>
<regions>
...
<region name="USA">
<subregion name="South Central US">
<network>65.55.80.0/20</network>
<network>65.54.48.0/21</network>
...
</subregion>
<subregion name="North Central US">
<network>207.46.192.0/20</network>
<network>65.52.0.0/19</network>
...
</subregion>
</region>
</regions>
Note: It looks like the new datacenters (West and East US) are not covered by this XML file, which might make it useless in your case.
I had some services deployed in Anywhere US and in order to find out which data centre it was deployed in I had to log a support call with Microsoft. They were helpful and got me the information but even they had to go away and look it up. As a result of this I would never use and the the "Anywhere ..." locations. Knowing which data centre your services are running in is very important for knowing where to deploy things like SQL Azure and service bus which don't support affinity groups and don't have an Anywhere option.

Resources