Skip to content

Commit

Permalink
Deploy front web app with VNet injection and Back web app with a Priv…
Browse files Browse the repository at this point in the history
…ate Endpoint (#507)

* Deploy two App Services - Front web app with VNet injection and Back web app with a Private Endpoint

---------

Co-authored-by: Łukasz Biały <[email protected]>
  • Loading branch information
polkx and lbialy authored Aug 22, 2024
1 parent 58c0ef8 commit 7da20a4
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 1 deletion.
10 changes: 10 additions & 0 deletions examples/azure-webapp-privateendpoint-vnet-injection/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
### Scala an JVM
*.class
*.log
.bsp
.scala-build

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

kubeconfig.json
161 changes: 161 additions & 0 deletions examples/azure-webapp-privateendpoint-vnet-injection/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import besom.*
import besom.api.azurenative

@main def main = Pulumi.run {

// setup a resource group
val resourceGroup = azurenative.resources.ResourceGroup("resourcegroup")

val serverfarm = azurenative.web.AppServicePlan(
"appServerFarm",
azurenative.web.AppServicePlanArgs(
kind = "app",
resourceGroupName = resourceGroup.name,
sku = azurenative.web.inputs.SkuDescriptionArgs(
capacity = 1,
family = "P1v2",
name = "P1v2",
size = "P1v2",
tier = "PremiumV2"
)
)
)

// Setup backend app
val backendApp = azurenative.web.WebApp(
"backendApp",
azurenative.web.WebAppArgs(
kind = "app",
resourceGroupName = resourceGroup.name,
serverFarmId = serverfarm.id
)
)

// Setup frontend app
val frontendApp = azurenative.web.WebApp(
"frontendApp",
azurenative.web.WebAppArgs(
kind = "app",
resourceGroupName = resourceGroup.name,
serverFarmId = serverfarm.id
)
)

// Setup a vnet
val virtualNetworkCIDR = config.getString("virtualNetworkCIDR") getOrElse ("10.200.0.0/16")
val virtualNetwork = azurenative.network.VirtualNetwork(
"virtualNetwork",
azurenative.network.VirtualNetworkArgs(
addressSpace = azurenative.network.inputs.AddressSpaceArgs(
addressPrefixes = List(virtualNetworkCIDR)
),
resourceGroupName = resourceGroup.name,
virtualNetworkName = "vnet"
),
opts = opts(ignoreChanges = List("subnets"))
) // https://github.com/pulumi/pulumi-azure-nextgen/issues/103

// Setup private DNS zone
val privateDnsZone = azurenative.network.PrivateZone(
"privateDnsZone",
azurenative.network.PrivateZoneArgs(
location = "global",
privateZoneName = "privatelink.azurewebsites.net",
resourceGroupName = resourceGroup.name
),
opts = opts(dependsOn = virtualNetwork)
)

// Setup a private subnet for backend
val backendCIDR = config.getString("backendCIDR").getOrElse("10.200.1.0/24")
val backendSubnet = azurenative.network.Subnet(
"subnetForBackend",
azurenative.network.SubnetArgs(
addressPrefix = backendCIDR,
privateEndpointNetworkPolicies = azurenative.network.enums.VirtualNetworkPrivateEndpointNetworkPolicies.Disabled,
resourceGroupName = resourceGroup.name,
virtualNetworkName = virtualNetwork.name
)
)

// Private endpoint in the private subnet for backend
val privateEndpoint = azurenative.network.PrivateEndpoint(
"privateEndpointForBackend",
azurenative.network.PrivateEndpointArgs(
privateLinkServiceConnections = List(
azurenative.network.inputs.PrivateLinkServiceConnectionArgs(
groupIds = List("sites"),
name = "privateEndpointLink1",
privateLinkServiceId = backendApp.id
)
),
resourceGroupName = resourceGroup.name,
subnet = azurenative.network.inputs.SubnetArgs(
id = backendSubnet.id
)
)
)

// Setup a private DNS Zone for private endpoint
val privateDNSZoneGroup = azurenative.network.PrivateDnsZoneGroup(
"privateDnsZoneGroup",
azurenative.network.PrivateDnsZoneGroupArgs(
privateDnsZoneConfigs = List(
azurenative.network.inputs.PrivateDnsZoneConfigArgs(
name = "config1",
privateDnsZoneId = privateDnsZone.id
)
),
privateDnsZoneGroupName = privateEndpoint.name,
privateEndpointName = privateEndpoint.name,
resourceGroupName = resourceGroup.name
)
)

val virtualNetworkLink = azurenative.network.VirtualNetworkLink(
"virtualNetworkLink",
azurenative.network.VirtualNetworkLinkArgs(
location = "global",
privateZoneName = privateDnsZone.name,
registrationEnabled = false,
resourceGroupName = resourceGroup.name,
virtualNetwork = azurenative.network.inputs.SubResourceArgs(
id = virtualNetwork.id
)
)
)

// Now setup frontend subnet
val frontendCIDR = config.getString("frontendCIDR").getOrElse("10.200.2.0/24")
val frontendSubnet = azurenative.network.Subnet(
"frontendSubnet",
azurenative.network.SubnetArgs(
addressPrefix = frontendCIDR,
delegations = List(
azurenative.network.inputs.DelegationArgs(
name = "delegation",
serviceName = "Microsoft.Web/serverfarms"
)
),
privateEndpointNetworkPolicies = azurenative.network.enums.VirtualNetworkPrivateEndpointNetworkPolicies.Enabled,
resourceGroupName = resourceGroup.name,
virtualNetworkName = virtualNetwork.name
)
)

val virtualNetworkConn = azurenative.web.WebAppSwiftVirtualNetworkConnection(
"virtualNetworkConnForFrontend",
azurenative.web.WebAppSwiftVirtualNetworkConnectionArgs(
name = frontendApp.name,
resourceGroupName = resourceGroup.name,
subnetResourceId = frontendSubnet.id
)
)

Stack(virtualNetworkLink, virtualNetworkConn).exports(
backendURL = backendApp.defaultHostName,
frontEndURL = frontendApp.defaultHostName,
privateEndpointURL = privateDNSZoneGroup.privateDnsZoneConfigs
.flatMap(zoneConfigs => zoneConfigs.get.head.recordSets.map(_.head.fqdn))
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: azure-webapp-privateendpoint-vnet-injection
description: Deploy two App Services - Front web app with VNet injection and Back web app with a Private Endpoint.
runtime: scala
54 changes: 54 additions & 0 deletions examples/azure-webapp-privateendpoint-vnet-injection/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Deploy two App Services - Front web app with VNet injection and Back web app with a Private Endpoint

This deploys a secure front end - back end web app. The front end web app is plugged in a subnet with the feature
regional VNet integration enabled. Settings are set to consume a DNS private zone. The backend web app is only exposed
through a private endpoint.

It will create a VNet, two subnets, one where your Private Endpoint will exist, the second where you will inject the
front web app, an App Service Plan in PremiumV2 tier (mandatory for Private Endpoint), a Private Endpoint, settings for
DNS queries to the DNS Private Zone, and a private DNS zone with record for the Private Endpoint.

## Deploying the App

To deploy your infrastructure, follow the below steps.

### Optional config params

1. `virtualNetworkCIDR` - CIDR range for the vnet (defaults to `10.200.0.0/16`)
2. `backendCIDR` - subnet CIDR range for the backend (defaults to `10.200.1.0/24`)
3. `frontendCIDR` - subnet CIDR range for the frontend (defaults to `10.200.2.0/24`)

### Prerequisites

1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/)
2. [Configure Azure Credentials](https://www.pulumi.com/docs/intro/cloud-providers/azure/setup/)

## Running the App

1. Create a new stack:

```bash
$ pulumi stack init dev
```

2. Set the Azure region location to use:

```bash
$ pulumi config set azure-native:location westus2
```

3. Run `pulumi up` to preview and deploy changes:

```bash
$ pulumi up
```

4. From there, feel free to experiment. Simply making edits and running `pulumi up` will incrementally update your
stack.

5. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:

```bash
$ pulumi destroy --yes
$ pulumi stack rm --yes
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//> using scala "3.3.1"
//> using options -Werror -Wunused:all -Wvalue-discard -Wnonunit-statement
//> using dep "org.virtuslab::besom-core:0.4.0-SNAPSHOT"
//> using dep "org.virtuslab::besom-azure-native:2.56.0-core.0.4-SNAPSHOT"
//> using repository sonatype:snapshots
2 changes: 1 addition & 1 deletion examples/kubernetes-keycloak/AppConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ object AppConfig:
def adminDb: Output[DbConfig] = o.map(_.adminDb)
def keycloakDb: Output[DbConfig] = o.map(_.keycloakDb)
def keycloak: Output[KeycloakConfig] = o.map(_.keycloak)

val default = AppConfig(
adminDb = DbConfig(
user = "postgres",
Expand Down
1 change: 1 addition & 0 deletions examples/kubernetes-keycloak/Nginx.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ object Nginx:
namespace = ingressController.status.namespace
)
}
end Nginx

0 comments on commit 7da20a4

Please sign in to comment.