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

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

Related

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.

Terraform EKS: get security group created by Ingress ALB

I am using Terraform to create EKS cluster. The traffic is routed through AWS Application Load Balancer (ALB) - Ingress controller.
I can get the host name through following output
kubernetes_ingress.app.status.0.load_balancer.0.ingress.0.hostname
However, the problem is Ingress and ALB automatically create one security group, which I needed to create AWS API Gateway & VPC Link, how to get that security group's id?
I think the link below might help you, but in case it's unavailable, you can sort of hack an LB object via the name.
You first get your LB hostname (as you already have, except split on the hyphen), then make an 'aws_lb' data type using that name, which should then populate 'aws_lb' as if you had deployed an LB. Or at least enough to be able to query that type of object to get the bits you need.
locals {
lb_name_parts = split("-", split(".", kubernetes_ingress.alb_nginx_primary_ingress.status.0.load_balancer.0.ingress.0.hostname).0)
}
data "aws_lb" "alb_primary_ingress" {
name = join("-", slice(local.lb_name_parts, 0, length(local.lb_name_parts) - 1))
}
(my variable for the hostname is slightly different to yours but you should get the idea)
The clever person who figured it out:
https://github.com/hashicorp/terraform-provider-kubernetes/issues/942

How to associate an Azure app service with an application insights resource (new or existing) using terraform?

I looked at the documentation of both azurerm_app_service and azurerm_application_insights and I just do not see a way to tie them.
Yet on the App Service page in the portal there is a link to Application Insights, currently grayed out:
So, how do I enable it with terraform?
You need numerous app settings to get this to work properly as intended. The ones I had to add to get it all working were:
"APPINSIGHTS_INSTRUMENTATIONKEY"
"APPINSIGHTS_PROFILERFEATURE_VERSION"
"APPINSIGHTS_SNAPSHOTFEATURE_VERSION"
"APPLICATIONINSIGHTS_CONNECTION_STRING"
"ApplicationInsightsAgent_EXTENSION_VERSION"
"DiagnosticServices_EXTENSION_VERSION"
"InstrumentationEngine_EXTENSION_VERSION"
"SnapshotDebugger_EXTENSION_VERSION"
"XDT_MicrosoftApplicationInsights_BaseExtensions"
"XDT_MicrosoftApplicationInsights_Mode"
It seems that enabling application insights using Terraform is not working yet currently. There is a Feature Request: Attach azurerm_application_insights to a azurerm_app_service in Github.
It might be possible to set a tag on the azurerm_application_insights resource,
resource "azurerm_application_insights" "test" {
tags {
"hidden-link:/subscriptions/<subscription id>/resourceGroups/<rg name>/providers/Microsoft.Web/sites/<site name>": "Resource"
}
}
Usually, if you need to enable application insights component in your app service, you need to add APPINSIGHTS_* environment variables to the app_settings of your web app.
For example,
app_settings {
"APPINSIGHTS_INSTRUMENTATIONKEY" = "${azurerm_application_insights.test.instrumentation_key}"
}
See argument reference even it's about Azure function.
ref:
https://www.olivercoding.com/2018-06-24-terraform/
https://github.com/terraform-providers/terraform-provider-azurerm/issues/2457

Is it possible to add a new listener, backend address pool, and request routing rule(s) to an existing Azure Application Gateway using Terraform?

My use-case is multiple AppService apps with different lifecycles sitting behind a single Application Gateway. I'd like to add a new listener, new multi-site routing rules, and a new backend pool whenever I add a new app without tearing down and re-creating the gateway.
Initially, my plan was to have a Terraform config for shared infra that creates a skeleton Application Gateway and then have separate application-specific Terraform configs to add listeners, backend address pools, and routing rules to this gateway for each app. It seems to be impossible to accomplish with TF though.
I can clearly add listeners, routing rules and backend pools to an exiting gateway using Azure CLI or Portal. Is there a way to do it with Terraform?
It seems that this is not currently possible due to the fact that the Application Gateway must be initialised with at least one of each of these configuration blocks.
While it is possible to add further definitions using the Azure CLI, that behaviour isn't currently compatible with the way Terraform works. Consider what would happen if backend address pools were initially defined inline as part of the azurerm_application_gateway block and then further definitions of azurerm_application_gateway_backend_address_pool (hypothetical resource block) were also specified.
It would be nice if Terraform could deal with this situation with a union of those two definitions but unfortunately it doesn't play nicely with both inline and standalone resource blocks. Hence the warning on azurerm_subnet resources explaining that inline subnets on azurerm_virtual_network would conflict.
NOTE on Virtual Networks and Subnet's:
Terraform currently provides both a standalone Subnet resource, and allows for Subnets to be defined in-line within the Virtual Network resource. At this time you cannot use a Virtual Network with in-line Subnets in conjunction with any Subnet resources. Doing so will cause a conflict of Subnet configurations and will overwrite Subnet's.
Logically it wouldn't be possible to have a similar warning for Application Gateway since it's inline resource blocks are mandatory (not so for Azure Virtual Networks)
For now, the options here would seem to be
Manage all application-specific aspects of the Application Gateway in the same place with native Terraform.
Create the skeleton definition of the Application Gateway and run local-exec provisioner CLI commands for application-specific configuration
provisioner "local-exec" {
command = <<EOT
az network application-gateway address-pool create `
--resource-group MyResourceGroup `
--gateway-name MyAppGateway `
--name MyAddressPool `
--servers 10.0.0.4 10.0.0.5 `
EOT
interpreter = ["PowerShell", "-command"]
}
Here is the reference doc from Terraform for managing Azure Application Gateway.
You can refer this sample code for adding new listeners,routing rules as well as backend pools to the existing application gateway. This template carries all the required arguments like,
http_listener - (Required) One or more http_listener blocks.
http_listener {
name = "https-listener-1"
frontend_ip_configuration_name = "feip"
frontend_port_name = "http-port"
protocol = "Http"
}
request_routing_rule - (Required) One or more request_routing_rule blocks.
request_routing_rule {
name = "${local.request_routing_rule_name}"
rule_type = "Basic"
http_listener_name = "${local.listener_name}"
backend_address_pool_name = "${local.backend_address_pool_name}"
backend_http_settings_name = "${local.http_setting_name}"
}
}
backend_address_pool - (Required) One or more backend_address_pool blocks as defined below.
backend_address_pool {
name = "${local.backend_address_pool_name}"
}

Securing a "tiered" application in 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).

Resources