Skip to content

Commit

Permalink
Added OpenAI module to multitenant spoke deployment (#190)
Browse files Browse the repository at this point in the history
* Added AI module to multitenant spoke

* OpenAI module added to multitenant scenario with private networking config.

* fixing bug with repeat go_version definition on appsvc_options

* fix: variable hub_settings
We have that in the documentation
we need it for tfvars, to connect to existing hub

* fixed something that didn't work for me

---------

Co-authored-by: Thodoris Theodorou <[email protected]>
  • Loading branch information
JinLee794 and thotheod authored Oct 25, 2023
1 parent a649b19 commit a06d5e0
Show file tree
Hide file tree
Showing 37 changed files with 1,335 additions and 126 deletions.
2 changes: 1 addition & 1 deletion scenarios/secure-baseline-multitenant/terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ deployment_options = {
deploy_sql_database = true
deploy_app_config = true
deploy_vm = true
deploy_openai = true
}

# Optionally deploy a Github runner, DevOps agent, or both to the VM.
Expand Down Expand Up @@ -260,4 +261,3 @@ Connect to the VM using the local VM admin credentials and run `dsregcmd /status
```

If the VM is AAD joined, try to login in with the Azure AD credentials again after a few minutes. If it's not AAD joined, attempt to re-install the VM extension or manually enroll the VM to AAD by following the steps in Edge: open Edge and click "Sign in to sync data", select "Work or school account", and then press OK on "Allow my organization to manage my device". It takes a few minutes for the policies to be applied, device scanned and confirmed as secure to access corporate resources. You will know that the process is complete.

Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ deployment_options = {
deploy_sql_database = true
deploy_app_config = true
deploy_vm = true
deploy_openai = true
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ vm_aad_admin_object_id = "bda41c64-1493-4d8d-b4b5-7135159d4884" # "AppSvcLZA Azu
# vm_admin_password = "**************"

## These settings are used for peering the spoke to the hub. Fill in the appropriate settings for your environment
# hub_settings = {
# rg_name = "rg-hub-scenario1-wus3"
# vnet_name = "vnet-hub-scenario1-wus3"
hub_settings = {
rg_name = "rg-hub-scenario1-wus3"
vnet_name = "vnet-hub-scenario1-wus3"

# firewall = {
# private_ip = "10.242.0.4"
# }
# }
firewall = {
private_ip = "10.242.0.4"
}
}

## Toggle deployment of optional features and services for the Landing Zone
deployment_options = {
Expand All @@ -42,6 +42,7 @@ deployment_options = {
deploy_sql_database = true
deploy_app_config = true
deploy_vm = false
deploy_openai = true
}

## Optionally deploy a Github runner, DevOps agent, or both to the VM.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.26 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.67.0 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.75.0 |
| <a name="provider_random"></a> [random](#provider\_random) | 3.5.1 |
| <a name="provider_terraform"></a> [terraform](#provider\_terraform) | n/a |

Expand All @@ -28,6 +28,7 @@
| <a name="module_frontdoor"></a> [frontdoor](#module\_frontdoor) | ../../../shared/terraform-modules/frontdoor | n/a |
| <a name="module_key_vault"></a> [key\_vault](#module\_key\_vault) | ../../../shared/terraform-modules/key-vault | n/a |
| <a name="module_network"></a> [network](#module\_network) | ../../../shared/terraform-modules/network | n/a |
| <a name="module_openai"></a> [openai](#module\_openai) | ../../../shared/terraform-modules/cognitive-services/openai | n/a |
| <a name="module_private_dns_zones"></a> [private\_dns\_zones](#module\_private\_dns\_zones) | ../../../shared/terraform-modules/private-dns-zone | n/a |
| <a name="module_redis_cache"></a> [redis\_cache](#module\_redis\_cache) | ../../../shared/terraform-modules/redis | n/a |
| <a name="module_sql_database"></a> [sql\_database](#module\_sql\_database) | ../../../shared/terraform-modules/sql-database | n/a |
Expand Down Expand Up @@ -58,11 +59,11 @@
| <a name="input_aad_admin_group_name"></a> [aad\_admin\_group\_name](#input\_aad\_admin\_group\_name) | The name of the Azure AD group that should be granted SQL Admin permissions to the SQL Server | `string` | n/a | yes |
| <a name="input_aad_admin_group_object_id"></a> [aad\_admin\_group\_object\_id](#input\_aad\_admin\_group\_object\_id) | The object ID of the Azure AD group that should be granted SQL Admin permissions to the SQL Server | `string` | n/a | yes |
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | The name of your application | `string` | `"sec-baseline-1-spoke"` | no |
| <a name="input_appsvc_options"></a> [appsvc\_options](#input\_appsvc\_options) | The options for the app service | <pre>object({<br> service_plan = object({<br> os_type = string<br> sku_name = string<br> worker_count = optional(number)<br> zone_redundant = optional(bool)<br> })<br> web_app = object({<br> slots = list(string)<br><br> application_stack = object({<br> current_stack = string # required for windows<br> dotnet_version = optional(string)<br> php_version = optional(string)<br> node_version = optional(string)<br> java_version = optional(string)<br> python = optional(bool) # windows only<br> python_version = optional(string) # linux only<br> java_server = optional(string) # linux only<br> java_server_version = optional(string) # linux only<br> go_version = optional(string) # linux only<br> docker_image = optional(string) # linux only<br> docker_image_tag = optional(string) # linux only<br> go_version = optional(string) # linux only<br> ruby_version = optional(string) # linux only<br> })<br> })<br> })</pre> | <pre>{<br> "service_plan": {<br> "os_type": "Windows",<br> "sku_name": "S1"<br> },<br> "web_app": {<br> "application_stack": {<br> "current_stack": "dotnet",<br> "dotnet_version": "6.0"<br> },<br> "slots": []<br> }<br>}</pre> | no |
| <a name="input_appsvc_options"></a> [appsvc\_options](#input\_appsvc\_options) | The options for the app service | <pre>object({<br> service_plan = object({<br> os_type = string<br> sku_name = string<br> worker_count = optional(number)<br> zone_redundant = optional(bool)<br> })<br> web_app = object({<br> slots = list(string)<br><br> application_stack = object({<br> current_stack = string # required for windows<br> dotnet_version = optional(string)<br> docker_image = optional(string) # linux only<br> docker_image_tag = optional(string) # linux only<br> php_version = optional(string)<br> node_version = optional(string)<br> java_version = optional(string)<br> python = optional(bool) # windows only<br> python_version = optional(string) # linux only<br> java_server = optional(string) # linux only<br> java_server_version = optional(string) # linux only<br> go_version = optional(string) # linux only<br> ruby_version = optional(string) # linux only<br> })<br> })<br> })</pre> | <pre>{<br> "service_plan": {<br> "os_type": "Windows",<br> "sku_name": "S1"<br> },<br> "web_app": {<br> "application_stack": {<br> "current_stack": "dotnet",<br> "dotnet_version": "6.0"<br> },<br> "slots": []<br> }<br>}</pre> | no |
| <a name="input_appsvc_subnet_cidr"></a> [appsvc\_subnet\_cidr](#input\_appsvc\_subnet\_cidr) | The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.0/26"<br>]</pre> | no |
| <a name="input_bastion_subnet_cidr"></a> [bastion\_subnet\_cidr](#input\_bastion\_subnet\_cidr) | [Optional] The CIDR block(s) for the bastion subnet. Defaults to 10.242.0.64/26 | `list(string)` | <pre>[<br> "10.242.0.64/26"<br>]</pre> | no |
| <a name="input_bastion_subnet_name"></a> [bastion\_subnet\_name](#input\_bastion\_subnet\_name) | [Optional] Name of the subnet to deploy bastion resource to. Defaults to 'AzureBastionSubnet' | `string` | `"AzureBastionSubnet"` | no |
| <a name="input_deployment_options"></a> [deployment\_options](#input\_deployment\_options) | Opt-in settings for the deployment: enable WAF in Front Door, deploy Azure Firewall and UDRs in the spoke network to force outbound traffic to the Azure Firewall, deploy Redis Cache. | <pre>object({<br> enable_waf = bool<br> enable_egress_lockdown = bool<br> enable_diagnostic_settings = bool<br> deploy_bastion = bool<br> deploy_redis = bool<br> deploy_sql_database = bool<br> deploy_app_config = bool<br> deploy_vm = bool<br> })</pre> | <pre>{<br> "deploy_app_config": true,<br> "deploy_bastion": true,<br> "deploy_redis": true,<br> "deploy_sql_database": true,<br> "deploy_vm": true,<br> "enable_diagnostic_settings": true,<br> "enable_egress_lockdown": true,<br> "enable_waf": true<br>}</pre> | no |
| <a name="input_deployment_options"></a> [deployment\_options](#input\_deployment\_options) | Opt-in settings for the deployment: enable WAF in Front Door, deploy Azure Firewall and UDRs in the spoke network to force outbound traffic to the Azure Firewall, deploy Redis Cache. | <pre>object({<br> enable_waf = bool<br> enable_egress_lockdown = bool<br> enable_diagnostic_settings = bool<br> deploy_bastion = bool<br> deploy_redis = bool<br> deploy_sql_database = bool<br> deploy_app_config = bool<br> deploy_vm = bool<br> deploy_openai = bool<br> })</pre> | <pre>{<br> "deploy_app_config": true,<br> "deploy_bastion": true,<br> "deploy_openai": true,<br> "deploy_redis": true,<br> "deploy_sql_database": true,<br> "deploy_vm": true,<br> "enable_diagnostic_settings": true,<br> "enable_egress_lockdown": true,<br> "enable_waf": true<br>}</pre> | no |
| <a name="input_devops_settings"></a> [devops\_settings](#input\_devops\_settings) | The settings for the Azure DevOps agent or GitHub runner | <pre>object({<br> github_runner = optional(object({<br> repository_url = string<br> token = string<br> }))<br><br> devops_agent = optional(object({<br> organization_url = string<br> token = string<br> }))<br> })</pre> | <pre>{<br> "devops_agent": null,<br> "github_runner": null<br>}</pre> | no |
| <a name="input_devops_subnet_cidr"></a> [devops\_subnet\_cidr](#input\_devops\_subnet\_cidr) | [Optional] The CIDR block for the subnet. Defaults to 10.240.10.128/16 | `list(string)` | <pre>[<br> "10.240.10.128/26"<br>]</pre> | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment (dev, qa, staging, prod) | `string` | `"dev"` | no |
Expand Down
51 changes: 33 additions & 18 deletions scenarios/secure-baseline-multitenant/terraform/spoke/_locals.tf
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@

locals {
deployment_name = "sec-baseline-1-spoke"

# used in spoke-network.tf
private_dns_zones = [
{
name : "privatelink.azurewebsites.net"
records : []
}, {
name : "privatelink.database.windows.net"
records : []
}, {
name : "privatelink.azconfig.io"
records : []
}, {
name : "privatelink.vaultcore.azure.net"
records : []
}, {
name : "privatelink.redis.cache.windows.net"
records : []
}
private_dns_zones = [for each in
[
{
name : "privatelink.azurewebsites.net"
records : []
enabled : true
},
{
name : "privatelink.vaultcore.azure.net"
records : []
enabled : true
},
{
name : "privatelink.database.windows.net"
records : []
enabled : var.deployment_options.deploy_sql_database
},
{
name : "privatelink.azconfig.io"
records : []
enabled : var.deployment_options.deploy_app_config
},
{
name : "privatelink.redis.cache.windows.net"
records : []
enabled : var.deployment_options.deploy_redis
},
{
name : "privatelink.openai.azure.com"
records : []
enabled : var.deployment_options.deploy_openai
}
] : each if each.enabled
]

provisioned_dns_zones = { for i, dns_zone in module.private_dns_zones : dns_zone.name => dns_zone.dns_zone }
Expand Down
55 changes: 55 additions & 0 deletions scenarios/secure-baseline-multitenant/terraform/spoke/ai.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module "openai" {
count = var.deployment_options.deploy_openai ? 1 : 0

source = "../../../shared/terraform-modules/cognitive-services/openai"

global_settings = local.global_settings
resource_group_name = azurerm_resource_group.spoke.name
location = azurerm_resource_group.spoke.location

deployment = {
"text-embedding-ada-002" = {
name = "text-embedding-ada-002"
model_format = "OpenAI"
model_name = "text-embedding-ada-002"
model_version = "2"
scale_type = "Standard"
}
"gpt-35-turbo" = {
name = "gpt-35-turbo"
model_format = "OpenAI"
model_name = "gpt-35-turbo"
model_version = "0613"
scale_type = "Standard"
}
}

pe_private_link_subnet_id = module.network.subnets["privateLink"].id
private_dns_zone = local.provisioned_dns_zones["privatelink.openai.azure.com"]

network_acls = [
{
default_action = "Deny"
virtual_network_rules = [
{
subnet_id = module.network.subnets["serverFarm"].id
ignore_missing_vnet_service_endpoint = true
},
{
subnet_id = module.network.subnets["ingress"].id
ignore_missing_vnet_service_endpoint = true
},
{
subnet_id = module.network.subnets["devops"].id
ignore_missing_vnet_service_endpoint = true
},
{
subnet_id = module.network.subnets["privateLink"].id
ignore_missing_vnet_service_endpoint = true
}
]
}
]

tags = local.base_tags
}
32 changes: 16 additions & 16 deletions scenarios/secure-baseline-multitenant/terraform/spoke/app.tf
Original file line number Diff line number Diff line change
Expand Up @@ -66,52 +66,52 @@ module "sql_database" {
private_dns_zone = local.provisioned_dns_zones["privatelink.database.windows.net"]
}

module "app_configuration" {
count = var.deployment_options.deploy_app_config ? 1 : 0

source = "../../../shared/terraform-modules/app-configuration"
module "key_vault" {
source = "../../../shared/terraform-modules/key-vault"

resource_group = azurerm_resource_group.spoke.name
application_name = var.application_name
environment = var.environment
location = var.location
unique_id = random_integer.unique_id.result
tenant_id = var.tenant_id
unique_id = random_integer.unique_id.result
sku_name = "standard"
private_link_subnet_id = module.network.subnets["privateLink"].id
global_settings = local.global_settings
tags = local.base_tags
data_reader_identities = [
secret_reader_identities = [
azurerm_user_assigned_identity.reader.principal_id
]

data_owner_identities = [
secret_officer_identities = [
azurerm_user_assigned_identity.contributor.principal_id
]

private_dns_zone = local.provisioned_dns_zones["privatelink.azconfig.io"]
private_dns_zone = local.provisioned_dns_zones["privatelink.vaultcore.azure.net"]
}

module "key_vault" {
source = "../../../shared/terraform-modules/key-vault"
module "app_configuration" {
count = var.deployment_options.deploy_app_config ? 1 : 0

source = "../../../shared/terraform-modules/app-configuration"

resource_group = azurerm_resource_group.spoke.name
application_name = var.application_name
environment = var.environment
location = var.location
tenant_id = var.tenant_id
unique_id = random_integer.unique_id.result
sku_name = "standard"
tenant_id = var.tenant_id
private_link_subnet_id = module.network.subnets["privateLink"].id
global_settings = local.global_settings
tags = local.base_tags
secret_reader_identities = [
data_reader_identities = [
azurerm_user_assigned_identity.reader.principal_id
]

secret_officer_identities = [
data_owner_identities = [
azurerm_user_assigned_identity.contributor.principal_id
]
private_dns_zone = local.provisioned_dns_zones["privatelink.vaultcore.azure.net"]

private_dns_zone = local.provisioned_dns_zones["privatelink.azconfig.io"]
}

module "redis_cache" {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
terraform {
required_version = ">=1.3" # must be greater than or equal to 1.2 for OIDC
# must be greater than or equal to 1.2 for OIDC
# must be greater than or equal to 1.3 for OpenAI
required_version = ">=1.3"

required_providers {
azurerm = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ module "private_dns_zones" {
global_settings = local.global_settings

dns_zone_name = local.private_dns_zones[count.index].name
dns_records = local.private_dns_zones[count.index].records
dns_records = lookup(local.private_dns_zones[count.index], "records", [])
vnet_links = [
data.azurerm_virtual_network.hub.id
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module "devops_vm" {
resource_group = azurerm_resource_group.spoke.name
vm_name = "devops"
location = var.location
vm_subnet_id = module.network.subnets[index(module.network.subnets.*.name, "devops")].id
vm_subnet_id = module.network.subnets["devops"].id
admin_username = var.vm_admin_username
admin_password = var.vm_admin_password
aad_admin_username = var.vm_aad_admin_username
Expand Down
29 changes: 15 additions & 14 deletions scenarios/secure-baseline-multitenant/terraform/spoke/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -132,20 +132,20 @@ variable "private_link_subnet_cidr" {
default = ["10.240.11.0/24"]
}

# variable "hub_settings" {
# type = object({
# rg_name = string
# vnet_name = string
variable "hub_settings" {
type = object({
rg_name = string
vnet_name = string

# firewall = object({
# private_ip = optional(string)
# })
# })
firewall = object({
private_ip = optional(string)
})
})

# description = "The settings for the hub virtual network."
description = "The settings for the hub virtual network."

# default = null
# }
default = null
}

variable "vm_admin_username" {
type = string
Expand Down Expand Up @@ -179,6 +179,7 @@ variable "deployment_options" {
deploy_sql_database = bool
deploy_app_config = bool
deploy_vm = bool
deploy_openai = bool
})

description = "Opt-in settings for the deployment: enable WAF in Front Door, deploy Azure Firewall and UDRs in the spoke network to force outbound traffic to the Azure Firewall, deploy Redis Cache."
Expand All @@ -192,6 +193,7 @@ variable "deployment_options" {
deploy_sql_database = true
deploy_app_config = true
deploy_vm = true
deploy_openai = true
}
}

Expand All @@ -209,6 +211,8 @@ variable "appsvc_options" {
application_stack = object({
current_stack = string # required for windows
dotnet_version = optional(string)
docker_image = optional(string) # linux only
docker_image_tag = optional(string) # linux only
php_version = optional(string)
node_version = optional(string)
java_version = optional(string)
Expand All @@ -217,9 +221,6 @@ variable "appsvc_options" {
java_server = optional(string) # linux only
java_server_version = optional(string) # linux only
go_version = optional(string) # linux only
docker_image = optional(string) # linux only
docker_image_tag = optional(string) # linux only
go_version = optional(string) # linux only
ruby_version = optional(string) # linux only
})
})
Expand Down
Loading

0 comments on commit a06d5e0

Please sign in to comment.