feat: Terraform implementation refactor (#215)

* testing bicep cicd - added new oidc client id for read-only access, testing what-if flag

* Adding region into the bicep yml, env var and to the what-if arm-deploy action

* testing pipeline, adding puysh trigger for this branch

* testing pipeline, adding puysh trigger for this branch

* testing with prod id as the what-if scenario requires same level of permissions

* testing with prod id as the what-if scenario requires same level of permissions

* testing the deployment

* testing the deployment

* testing cicd bicep templates

* testing cicd

* testing cicd

* testing cicd

* disabling psrule for now

* disabling psrule for now

* consolidating tf scenario 1 workflows into a single cicd pipeline

* consolidating tf scenario 1 workflows into a single cicd pipeline

* consolidating tf scenario 1 workflows into a single cicd pipeline

* consolidating tf scenario 1 workflows into a single cicd pipeline

* renaming consolidated scenario 1 tf pipeline

* Adding concurrency, removed redundant param files

* Adding concurrency, removed redundant param files

* removing test branch trigger

* cleanup

* cleanup

* wip

* Functional deployment, further testing required

* Spoke deployment fixes/cleanup

* added backend.hcl file

* shared resource group

* cleaned up windows vm create and custom script

* Add files via upload

* Add files via upload

* pulling latest

* updating latest changes for terraform

* Refactoring TF changes

* pre-commit formatting and docs

* adding scenario deployment input file

* fixing gha tf scenario deployment yaml

* fixed private endpoints for app svc slots

* fixed private endpoints for app svc slots

* fixed private endpoints for app svc slots

* fixed private endpoints for app svc slots

* removing entra data lookups for sql server

* removing entra data lookups for sql server

* removing entra data lookups for sql server

* removing /deployment dir

* constraining deployment to azurerm versions 4.5.0 - 5.0.0

---------

Co-authored-by: ahmeds <ahmeds@ms.com>
Co-authored-by: Kunal Babre <kunalbabre@gmail.com>
This commit is contained in:
Jin Lee 2024-11-20 13:31:08 -06:00 коммит произвёл GitHub
Родитель 62bd83cabf
Коммит 5153a9ae14
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
88 изменённых файлов: 1930 добавлений и 682 удалений

4
.github/workflows/.template.terraform.yml поставляемый
Просмотреть файл

@ -7,7 +7,7 @@ on:
type: string
description: 'Terraform version'
required: true
default: '1.3.9'
default: '1.9.7'
modulePath:
type: string
description: 'Path to the Terraform module'
@ -94,4 +94,4 @@ jobs:
backendStorageContainerName: ${{ secrets.AZURE_TF_STATE_STORAGE_CONTAINER_NAME }}
ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION }}
ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}

29
.github/workflows/scenario1.terraform.yml поставляемый
Просмотреть файл

@ -1,3 +1,4 @@
name: 'Scenario 1: Terraform Multi-Tenant ASEv3 Secure Baseline'
concurrency:
@ -40,9 +41,9 @@ permissions:
env:
modulePath: 'scenarios/secure-baseline-multitenant/terraform'
terraformVersion: 1.5.2 # must be greater than or equal to 1.2 for OIDC
backendStateKey: 'scenario1.hub.tfstate'
tfvarPath: 'parameters/ase-multitenant.parameters.tfvars'
terraformVersion: 1.9.7 # must be greater than or equal to 1.2 for OIDC
backendStateKey: 'scenario1.appsvclza.tfstate'
tfvarPath: '_parameters/ase-multitenant.parameters.tfvars'
jobs:
prepare-environment:
@ -56,31 +57,17 @@ jobs:
backendStateKey: ${{ env.backendStateKey }}
tfvarPath: ${{ env.tfvarPath }}
terraform-deploy-hub:
name: 'Terraform CICD (Hub Multi-tenant Secure Baseline)'
terraform-deploy:
name: 'Terraform CICD (Hub & Spoke Multi-tenant Secure Baseline)'
needs:
- prepare-environment
uses: ./.github/workflows/.template.terraform.yml
with:
modulePath: ${{ needs.prepare-environment.outputs.modulePath }}/hub
modulePath: ${{ needs.prepare-environment.outputs.modulePath }}
terraformVersion: ${{ needs.prepare-environment.outputs.terraformVersion }}
backendStateKey: 'scenario1.hub.tfstate'
backendStateKey: ${{ needs.prepare-environment.outputs.backendStateKey }}
tfvarPath: ${{ needs.prepare-environment.outputs.tfvarPath }}
# Ensure this value is a boolean
destroy: ${{ github.event.inputs.destroy == 'true' }}
secrets: inherit
terraform-deploy-spoke:
name: 'Terraform CICD (Spoke Multi-tenant Secure Baseline)'
needs:
- prepare-environment
- terraform-deploy-hub
uses: ./.github/workflows/.template.terraform.yml
with:
modulePath: ${{ needs.prepare-environment.outputs.modulePath }}/spoke
terraformVersion: ${{ needs.prepare-environment.outputs.terraformVersion }}
backendStateKey: 'scenario1.spoke.tfstate'
tfvarPath: ${{ needs.prepare-environment.outputs.tfvarPath }}
# Ensure this value is a boolean
destroy: ${{ github.event.inputs.destroy == 'true' }}
secrets: inherit

3
.gitignore поставляемый
Просмотреть файл

@ -1,3 +1,4 @@
backend.hcl
deployment/bicep/localparam*.json
deployment/bicep/localmain.bicep
deployment/bicep/localtestscript.ps1
@ -7,6 +8,8 @@ deployment/bicep/main.json
# local .vscode folder
**/.vscode/*
backend.hcl
# Local .terraform directories
.terraform
**/.terraform/*

Просмотреть файл

@ -3,7 +3,8 @@ repos:
rev: v1.74.1 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases
hooks:
- id: terraform_fmt
- id: terraform_validate
# Currently disabled due to the openai module not being able to be validated
# - id: terraform_validate
- id: terraform_docs
args:
- --hook-config=--path-to-file=README.md # Valid UNIX path. I.e. ../TFDOC.md or docs/README.md etc.

Просмотреть файл

@ -1 +1,2 @@
.azure
backend.hcl

Просмотреть файл

@ -40,8 +40,11 @@ tenant_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
entra_admin_group_object_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
entra_admin_group_name = "Microsoft Entra ID SQL Admins"
vm_entra_admin_username = "bob@contoso.com"
entra_admin_group_object_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
entra_admin_group_name = "Microsoft Entra ID SQL Admins"
vm_entra_admin_username = "bob@contoso.com"
# Optionally provide non-Entra admin credentials for the VM
# Optionally provide non-entra admin credentials for the VM
# vm_admin_username = "daniem"
# vm_admin_password = "**************"
@ -172,7 +175,7 @@ az upgrade
az network bastion rdp --name bast-bastion --resource-group rg-hub --target-resource-id /subscriptions/{subscription-id}/resourceGroups/{rg-name}/providers/Microsoft.Compute/virtualMachines/{vm-name} --disable-gateway
```
If you experience issues connecting to the DevOps VM using your Microsoft Entra ID credentials, see [Unable to connect to DevOps VM using Microsoft Entra ID credentials](#unable-to-connect-to-devops-vm-using-microsoft-entra-id-credentials)
If you experience issues connecting to the DevOps VM using your Microsoft Entra ID credentials, see [Unable to connect to DevOps VM using Microsoft Entra ID credentials](#unable-to-connect-to-devops-vm-using-entra-credentials)
Once completed, you should be able to connect to the SQL Server using the Microsoft Entra ID account from SQL Server Management Studio. On the sample database (sample-db by default), run the following commands to create the user and grant minimal permissions (the exact command will be provided in the output of the Terraform deployment):
@ -207,7 +210,7 @@ az network front-door frontend-endpoint show --front-door-name <front-door-name>
### Unable to connect to DevOps VM using Microsoft Entra ID credentials
The Microsoft Entra ID enrollment can take a few minutes to complete. Check: [https://portal.manage-beta.microsoft.com/devices](https://portal.manage-beta.microsoft.com/devices)
Verify in the Azure Portal if the `aad-login-for-windows` VM extension was deployed successfully.
Verify in the Azure Portal if the `entra-login-for-windows` VM extension was deployed successfully.
Connect to the VM using the local VM admin credentials and run `dsregcmd /status`. The output should look similar to this:
@ -261,3 +264,133 @@ Connect to the VM using the local VM admin credentials and run `dsregcmd /status
```
If the VM is Microsoft Entra ID joined, try to login in with the Microsoft Entra ID credentials again after a few minutes. If it's not Microsoft Entra ID joined, attempt to re-install the VM extension or manually enroll the VM to Microsoft Entra ID 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.
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >=1.3 |
| <a name="requirement_azurecaf"></a> [azurecaf](#requirement\_azurecaf) | >=1.2.23 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 4.5.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.28 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 4.5.0 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_hub"></a> [hub](#module\_hub) | ./hub | n/a |
| <a name="module_spoke"></a> [spoke](#module\_spoke) | ./spoke | n/a |
## Resources
| Name | Type |
|------|------|
| [azurecaf_name.caf_name_spoke_rg](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_resource_group.spoke](https://registry.terraform.io/providers/hashicorp/azurerm/4.5.0/docs/resources/resource_group) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <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 = optional(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> "zone_redundant": true<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) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.0/26"<br>]</pre> | no |
| <a name="input_ase_subnet_cidr"></a> [ase\_subnet\_cidr](#input\_ase\_subnet\_cidr) | [Optional] The CIDR block for the subnet. Defaults to 10.241.0.0/26 | `list(string)` | <pre>[<br> "10.240.5.0/24"<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) | [Optional] 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> deploy_asev3 = bool<br> })</pre> | <pre>{<br> "deploy_app_config": false,<br> "deploy_asev3": false,<br> "deploy_bastion": false,<br> "deploy_openai": false,<br> "deploy_redis": false,<br> "deploy_sql_database": false,<br> "deploy_vm": false,<br> "enable_diagnostic_settings": false,<br> "enable_egress_lockdown": false,<br> "enable_waf": false<br>}</pre> | no |
| <a name="input_devops_settings"></a> [devops\_settings](#input\_devops\_settings) | [Optional] 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_entra_admin_group_name"></a> [entra\_admin\_group\_name](#input\_entra\_admin\_group\_name) | [Required] The name of the Entra group that should be granted SQL Admin permissions to the SQL Server | `string` | `null` | no |
| <a name="input_entra_admin_group_object_id"></a> [entra\_admin\_group\_object\_id](#input\_entra\_admin\_group\_object\_id) | [Required] The object ID of the Entra group that should be granted SQL Admin permissions to the SQL Server | `string` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment (dev, qa, staging, prod) | `string` | `"dev"` | no |
| <a name="input_firewall_subnet_cidr"></a> [firewall\_subnet\_cidr](#input\_firewall\_subnet\_cidr) | [Optional] The CIDR block(s) for the firewall subnet. Defaults to 10.242.0.0/26 | `list(string)` | <pre>[<br> "10.242.0.0/26"<br>]</pre> | no |
| <a name="input_firewall_subnet_name"></a> [firewall\_subnet\_name](#input\_firewall\_subnet\_name) | [Optional] Name of the subnet for firewall resources. Defaults to 'AzureFirewallSubnet' | `string` | `"AzureFirewallSubnet"` | no |
| <a name="input_front_door_subnet_cidr"></a> [front\_door\_subnet\_cidr](#input\_front\_door\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.64/26"<br>]</pre> | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | [Optional] Global settings to configure each module with the appropriate naming standards. | `map(any)` | `{}` | no |
| <a name="input_hub_vnet_cidr"></a> [hub\_vnet\_cidr](#input\_hub\_vnet\_cidr) | [Optional] The CIDR block(s) for the hub virtual network. Defaults to 10.242.0.0/20 | `list(string)` | <pre>[<br> "10.242.0.0/20"<br>]</pre> | no |
| <a name="input_location"></a> [location](#input\_location) | The Azure region where all resources in this example should be created | `string` | `"westus2"` | no |
| <a name="input_oai_deployment_models"></a> [oai\_deployment\_models](#input\_oai\_deployment\_models) | [Optional] Map to specify deployment models for the OpenAI resource | `any` | <pre>{<br> "gpt-35-turbo": {<br> "model_format": "OpenAI",<br> "model_name": "gpt-35-turbo",<br> "model_version": "0613",<br> "name": "gpt-35-turbo",<br> "scale_type": "Standard"<br> },<br> "text-embedding-ada-002": {<br> "model_format": "OpenAI",<br> "model_name": "text-embedding-ada-002",<br> "model_version": "2",<br> "name": "text-embedding-ada-002",<br> "scale_type": "Standard"<br> }<br>}</pre> | no |
| <a name="input_oai_sku_name"></a> [oai\_sku\_name](#input\_oai\_sku\_name) | [Optional] The SKU name for the OpenAI resource | `string` | `"S0"` | no |
| <a name="input_owner"></a> [owner](#input\_owner) | [Required] Owner of the deployment. | `string` | n/a | yes |
| <a name="input_private_link_subnet_cidr"></a> [private\_link\_subnet\_cidr](#input\_private\_link\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.11.0/24"<br>]</pre> | no |
| <a name="input_spoke_vnet_cidr"></a> [spoke\_vnet\_cidr](#input\_spoke\_vnet\_cidr) | [Optional] The CIDR block(s) for the virtual network for whitelisting on the firewall. Defaults to 10.240.0.0/20 | `list(string)` | <pre>[<br> "10.240.0.0/20"<br>]</pre> | no |
| <a name="input_sql_databases"></a> [sql\_databases](#input\_sql\_databases) | [Optional] The settings for the SQL databases. | <pre>list(object({<br> name = string<br> sku_name = string<br> }))</pre> | <pre>[<br> {<br> "name": "sample-db",<br> "sku_name": "S0"<br> }<br>]</pre> | no |
| <a name="input_tags"></a> [tags](#input\_tags) | [Optional] Additional tags to assign to your resources | `map(string)` | `{}` | no |
| <a name="input_tenant_id"></a> [tenant\_id](#input\_tenant\_id) | The Entra tenant ID for the identities. If no value provided, will use current deployment environment tenant. | `string` | `null` | no |
| <a name="input_vm_admin_username"></a> [vm\_admin\_username](#input\_vm\_admin\_username) | [Optional] The username for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account. | `string` | `null` | no |
| <a name="input_vm_entra_admin_object_id"></a> [vm\_entra\_admin\_object\_id](#input\_vm\_entra\_admin\_object\_id) | [Optional] The Entra object ID for the VM admin user/group. If vm\_entra\_admin\_username is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_vm_entra_admin_username"></a> [vm\_entra\_admin\_username](#input\_vm\_entra\_admin\_username) | [Optional] The Entra username for the VM admin account. If vm\_entra\_admin\_object\_id is not specified, this value will be used. | `string` | `null` | no |
## Outputs
No outputs.
<!-- END_TF_DOCS -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >=1.3 |
| <a name="requirement_azurecaf"></a> [azurecaf](#requirement\_azurecaf) | >=1.2.23 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~>4.5.0 |
## Providers
No providers.
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_hub"></a> [hub](#module\_hub) | ./hub | n/a |
| <a name="module_spoke"></a> [spoke](#module\_spoke) | ./spoke | n/a |
## Resources
No resources.
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <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 = optional(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": "I1v2",<br> "zone_redundant": true<br> },<br> "web_app": {<br> "application_stack": {<br> "current_stack": "dotnet",<br> "dotnet_version": "v6.0"<br> },<br> "slots": []<br> }<br>}</pre> | no |
| <a name="input_appsvc_subnet_cidr"></a> [appsvc\_subnet\_cidr](#input\_appsvc\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.0/26"<br>]</pre> | no |
| <a name="input_ase_subnet_cidr"></a> [ase\_subnet\_cidr](#input\_ase\_subnet\_cidr) | [Optional] The CIDR block for the subnet. Defaults to 10.241.0.0/26 | `list(string)` | <pre>[<br> "10.240.5.0/24"<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) | [Optional] 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> deploy_asev3 = bool<br> })</pre> | <pre>{<br> "deploy_app_config": false,<br> "deploy_asev3": false,<br> "deploy_bastion": false,<br> "deploy_openai": false,<br> "deploy_redis": false,<br> "deploy_sql_database": false,<br> "deploy_vm": false,<br> "enable_diagnostic_settings": false,<br> "enable_egress_lockdown": false,<br> "enable_waf": false<br>}</pre> | no |
| <a name="input_devops_settings"></a> [devops\_settings](#input\_devops\_settings) | [Optional] 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_entra_admin_group_name"></a> [entra\_admin\_group\_name](#input\_entra\_admin\_group\_name) | [Required] The name of the Entra group that should be granted SQL Admin permissions to the SQL Server | `string` | `null` | no |
| <a name="input_entra_admin_group_object_id"></a> [entra\_admin\_group\_object\_id](#input\_entra\_admin\_group\_object\_id) | [Required] The object ID of the Entra group that should be granted SQL Admin permissions to the SQL Server | `string` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment (dev, qa, staging, prod) | `string` | `"dev"` | no |
| <a name="input_firewall_subnet_cidr"></a> [firewall\_subnet\_cidr](#input\_firewall\_subnet\_cidr) | [Optional] The CIDR block(s) for the firewall subnet. Defaults to 10.242.0.0/26 | `list(string)` | <pre>[<br> "10.242.0.0/26"<br>]</pre> | no |
| <a name="input_firewall_subnet_name"></a> [firewall\_subnet\_name](#input\_firewall\_subnet\_name) | [Optional] Name of the subnet for firewall resources. Defaults to 'AzureFirewallSubnet' | `string` | `"AzureFirewallSubnet"` | no |
| <a name="input_front_door_subnet_cidr"></a> [front\_door\_subnet\_cidr](#input\_front\_door\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.64/26"<br>]</pre> | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | [Optional] Global settings to configure each module with appropriate naming standards.<br> - name\_prefix: A string to prepend to all resource names.<br> - name\_suffix: A string to append to all resource names.<br> - use\_slug: Whether to use a random slug in resource names for uniqueness.<br> - random\_length: The length of the random string to use in the slug.<br> - resource\_prefixes: A map of resource type to prefix string.<br> - resource\_suffixes: A map of resource type to suffix string. | `map(any)` | `{}` | no |
| <a name="input_hub_vnet_cidr"></a> [hub\_vnet\_cidr](#input\_hub\_vnet\_cidr) | [Optional] The CIDR block(s) for the hub virtual network. Defaults to 10.242.0.0/20 | `list(string)` | <pre>[<br> "10.242.0.0/20"<br>]</pre> | no |
| <a name="input_location"></a> [location](#input\_location) | The Azure region where all resources in this example should be created | `string` | `"westus2"` | no |
| <a name="input_oai_deployment_models"></a> [oai\_deployment\_models](#input\_oai\_deployment\_models) | [Optional] Map to specify deployment models for the OpenAI resource | `any` | <pre>{<br> "gpt-35-turbo": {<br> "model_format": "OpenAI",<br> "model_name": "gpt-35-turbo",<br> "model_version": "0613",<br> "name": "gpt-35-turbo",<br> "scale_type": "Standard"<br> },<br> "text-embedding-ada-002": {<br> "model_format": "OpenAI",<br> "model_name": "text-embedding-ada-002",<br> "model_version": "2",<br> "name": "text-embedding-ada-002",<br> "scale_type": "Standard"<br> }<br>}</pre> | no |
| <a name="input_oai_sku_name"></a> [oai\_sku\_name](#input\_oai\_sku\_name) | [Optional] The SKU name for the OpenAI resource | `string` | `"S0"` | no |
| <a name="input_owner"></a> [owner](#input\_owner) | [Required] Owner of the deployment. | `string` | n/a | yes |
| <a name="input_private_link_subnet_cidr"></a> [private\_link\_subnet\_cidr](#input\_private\_link\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.11.0/24"<br>]</pre> | no |
| <a name="input_spoke_vnet_cidr"></a> [spoke\_vnet\_cidr](#input\_spoke\_vnet\_cidr) | [Optional] The CIDR block(s) for the virtual network for whitelisting on the firewall. Defaults to 10.240.0.0/20 | `list(string)` | <pre>[<br> "10.240.0.0/20"<br>]</pre> | no |
| <a name="input_sql_databases"></a> [sql\_databases](#input\_sql\_databases) | [Optional] The settings for the SQL databases. | <pre>list(object({<br> name = string<br> sku_name = string<br> }))</pre> | <pre>[<br> {<br> "name": "sample-db",<br> "sku_name": "S0"<br> }<br>]</pre> | no |
| <a name="input_tags"></a> [tags](#input\_tags) | [Optional] Additional tags to assign to your resources | `map(string)` | `{}` | no |
| <a name="input_tenant_id"></a> [tenant\_id](#input\_tenant\_id) | The Entra tenant ID for the identities. If no value provided, will use current deployment environment tenant. | `string` | `null` | no |
| <a name="input_vm_admin_username"></a> [vm\_admin\_username](#input\_vm\_admin\_username) | [Optional] The username for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account. | `string` | `null` | no |
| <a name="input_vm_entra_admin_object_id"></a> [vm\_entra\_admin\_object\_id](#input\_vm\_entra\_admin\_object\_id) | [Optional] The Entra object ID for the VM admin user/group. If vm\_entra\_admin\_username is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_vm_entra_admin_username"></a> [vm\_entra\_admin\_username](#input\_vm\_entra\_admin\_username) | [Optional] The Entra username for the VM admin account. If vm\_entra\_admin\_object\_id is not specified, this value will be used. | `string` | `null` | no |
## Outputs
No outputs.
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Просмотреть файл

@ -0,0 +1,33 @@
locals {
deployment_name = "sec-baseline-1"
global_settings = merge({
environment = try(var.global_settings.environment, var.environment)
passthrough = try(var.global_settings.passthrough, false)
prefixes = try(var.global_settings.prefixes, [local.deployment_name, local.short_location])
suffixes = try(var.global_settings.suffixes, [var.environment])
random_length = try(var.global_settings.random_length, 0)
regions = try(var.global_settings.regions, null)
tags = try(var.global_settings.tags, null)
use_slug = try(var.global_settings.use_slug, true)
}, var.global_settings)
short_location_map = {
"eastus" : "eus"
"eastus2" : "eus2"
"westus" : "wus"
"westus2" : "wus2"
"westeurope" : "weu"
"easteurope" : "eeu"
"southcentralus" : "scus"
}
short_location = try(local.short_location_map[var.location], var.location)
base_tags = merge({
"Terraform" = true
"Environment" = local.global_settings.environment
"Owner" = var.owner
"Project" = "[Scenario 1] App Service Landing Zone Accelerator"
}, var.tags)
}

Просмотреть файл

@ -1,78 +1,73 @@
application_name = "eslz2"
environment = "prod"
location = "westus3"
owner = "cloudops@contoso.com"
# For the hub state, use the same settings as the remote state config on the hub deployment from /hub/main.tf
hub_state_resource_group_name = "backend-appsrvc-dev-westus2-001"
hub_state_storage_account_name = "stbackendappsrwestus2001"
hub_state_container_name = "tfstate"
hub_state_key = "scenario1.hub.tfstate"
entra_admin_group_object_id = "bda41c64-1493-4d8d-b4b5-7135159d4884"
entra_admin_group_name = "AppSvcLZA Microsoft Entra SQL Admins"
## Lookup the Microsoft Entra User
# vm_entra_admin_username = "my-user@contoso.com"
## Reference an existing Microsoft Entra User/Group Object ID to bypass lookup
vm_entra_admin_object_id = "bda41c64-1493-4d8d-b4b5-7135159d4884" # "AppSvcLZA Microsoft Entra SQL Admins"
## Optionally provide non-Entra ID admin credentials for the VM
# vm_admin_username = "daniem"
# 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"
firewall = {
private_ip = "10.242.0.4"
}
}
## Toggle deployment of optional features and services for the Landing Zone
deployment_options = {
enable_waf = true
enable_egress_lockdown = true
enable_diagnostic_settings = true
deploy_bastion = true
deploy_redis = true
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.
# devops_settings = {
# github_runner = {
# repository_url = "https://github.com/{organization}/{repository}"
# token = "runner_registration_token" # See: https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28
# }
#
# devops_agent = {
# organization_url = "https://dev.azure.com/{organization}/"
# token = "pat_token"
# }
# }
appsvc_options = {
service_plan = {
os_type = "Windows"
sku_name = "S1"
# Optionally configure zone redundancy (requires a minimum of three workers and Premium SKU service plan)
# worker_count = 3
# zone_redundant = true
}
web_app = {
application_stack = {
current_stack = "dotnet"
dotnet_version = "v6.0"
}
slots = ["staging"]
}
}
application_name = "eslztest"
environment = "dev"
location = "westus3"
owner = "cloudops@contoso.com"
# entra_admin_group_object_id = "bda41c64-1493-4d8d-b4b5-7135159d4884"
# entra_admin_group_name = "AppSvcLZA Entra SQL Admins"
## Lookup the Entra User
# vm_entra_admin_username = "my-user@contoso.com"
## Reference an existing Entra User/Group Object ID to bypass lookup
vm_entra_admin_object_id = "bda41c64-1493-4d8d-b4b5-7135159d4884" # "AppSvcLZA Entra SQL Admins"
## Optionally provide non-entra admin credentials for the VM
# vm_admin_username = "daniem"
# vm_admin_password = "**************"
## Toggle deployment of optional features and services for the Landing Zone
deployment_options = {
deploy_asev3 = true
enable_waf = true
enable_egress_lockdown = true
enable_diagnostic_settings = true
deploy_bastion = true
deploy_redis = true
deploy_sql_database = true
deploy_app_config = true
deploy_vm = false
deploy_openai = true
}
## OpenAI Deployment Models
oai_deployment_models = {
"text-embedding-ada-002" = {
name = "text-embedding-ada-002"
model_format = "OpenAI"
model_name = "text-embedding-ada-002"
model_version = "2"
sku_name = "Standard"
}
}
## Optionally deploy a Github runner, DevOps agent, or both to the VM.
# devops_settings = {
# github_runner = {
# repository_url = "https://github.com/{organization}/{repository}"
# token = "runner_registration_token" # See: https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28
# }
#
# devops_agent = {
# organization_url = "https://dev.azure.com/{organization}/"
# token = "pat_token"
# }
# }
appsvc_options = {
service_plan = {
os_type = "Windows"
sku_name = "I1v2"
# Optionally configure zone redundancy (requires a minimum of three workers and Premium SKU service plan)
# worker_count = 3
# zone_redundant = true
}
web_app = {
application_stack = {
current_stack = "dotnet"
dotnet_version = "v6.0"
}
slots = ["staging"]
}
}

Просмотреть файл

@ -0,0 +1,10 @@
### To use this template, rename the file to `backend.tf`
### and update the values below to match your remote state config
###
### To use this file as part of your deployment, provide the following flag as you initialize:
### terraform init -backend-config=backend.tf
resource_group_name = "my-tf-remote-state-rg-name"
storage_account_name = "my-tf-remote-state-sa-name"
container_name = "my-tf-remote-state-container-name"
key = "my-state-file-name.tfstate"

Просмотреть файл

@ -1,20 +1,20 @@
# hub
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
# hub
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >=1.3 |
| <a name="requirement_azurecaf"></a> [azurecaf](#requirement\_azurecaf) | >=1.2.23 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=3.66.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 4.5.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.26 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.85.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | >=1.2.23 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 4.5.0 |
## Modules
@ -29,7 +29,7 @@
| Name | Type |
|------|------|
| [azurecaf_name.caf_name_hub_rg](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_resource_group.hub](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_resource_group.hub](https://registry.terraform.io/providers/hashicorp/azurerm/4.5.0/docs/resources/resource_group) | resource |
## Inputs
@ -54,10 +54,10 @@
| Name | Description |
|------|-------------|
| <a name="output_bastion_name"></a> [bastion\_name](#output\_bastion\_name) | n/a |
| <a name="output_firewall_private_ip"></a> [firewall\_private\_ip](#output\_firewall\_private\_ip) | n/a |
| <a name="output_firewall_rules"></a> [firewall\_rules](#output\_firewall\_rules) | n/a |
| <a name="output_rg_name"></a> [rg\_name](#output\_rg\_name) | n/a |
| <a name="output_vnet_id"></a> [vnet\_id](#output\_vnet\_id) | n/a |
| <a name="output_vnet_name"></a> [vnet\_name](#output\_vnet\_name) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
| <a name="output_resource_group_name"></a> [resource\_group\_name](#output\_resource\_group\_name) | n/a |
| <a name="output_virtual_network"></a> [virtual\_network](#output\_virtual\_network) | n/a |
| <a name="output_virtual_network_id"></a> [virtual\_network\_id](#output\_virtual\_network\_id) | n/a |
| <a name="output_virtual_network_name"></a> [virtual\_network\_name](#output\_virtual\_network\_name) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Просмотреть файл

@ -1,5 +1,5 @@
locals {
deployment_name = "sec-baseline-1-hub"
deployment_name = "sec-baseline-hub"
global_settings = merge({
environment = try(var.global_settings.environment, var.environment)

Просмотреть файл

@ -4,14 +4,16 @@ terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=3.66.0"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
version = ">=1.2.23"
}
}
backend "azurerm" {}
# If called as a module, this backend configuration block will have no effect.
# backend "azurerm" {}
}
provider "azurerm" {
@ -32,5 +34,21 @@ provider "azurerm" {
partner_id = "cf7e9f0a-f872-49db-b72f-f2e318189a6d"
}
provider "azurecaf" {}
## Create Hub Resource Group with the name generated from global_settings
resource "azurecaf_name" "caf_name_hub_rg" {
name = var.application_name
resource_type = "azurerm_resource_group"
prefixes = local.global_settings.prefixes
suffixes = local.global_settings.suffixes
random_length = local.global_settings.random_length
clean_input = true
passthrough = local.global_settings.passthrough
use_slug = local.global_settings.use_slug
}
resource "azurerm_resource_group" "hub" {
name = azurecaf_name.caf_name_hub_rg.result
location = var.location
tags = local.base_tags
}

Просмотреть файл

@ -1,22 +1,14 @@
# Hub network config
# -----
# - VNet
# - Firewall Subnet
# - Bastion Subnet
# - Azure Firewall [optional]
# - Bastion [optional]
resource "azurecaf_name" "caf_name_hub_rg" {
name = var.application_name
resource_type = "azurerm_resource_group"
prefixes = local.global_settings.prefixes
random_length = local.global_settings.random_length
clean_input = true
passthrough = local.global_settings.passthrough
use_slug = local.global_settings.use_slug
}
resource "azurerm_resource_group" "hub" {
name = azurecaf_name.caf_name_hub_rg.result
location = var.location
tags = local.base_tags
}
## Deploy Hub VNet with Firewall and Bastion subnets
module "network" {
source = "../../../shared/terraform-modules/network"
@ -41,6 +33,7 @@ module "network" {
tags = local.base_tags
}
## Deploy Azure Firewall (enabled via deployment option)
module "firewall" {
count = var.deployment_options.enable_egress_lockdown ? 1 : 0
@ -60,6 +53,7 @@ module "firewall" {
tags = local.base_tags
}
## Deploy Bastion (enabled via deployment option)
module "bastion" {
count = var.deployment_options.deploy_bastion ? 1 : 0

Просмотреть файл

@ -1,17 +1,17 @@
output "rg_name" {
output "resource_group_name" {
value = azurerm_resource_group.hub.name
}
output "vnet_name" {
output "virtual_network_name" {
value = module.network.vnet_name
}
output "vnet_id" {
output "virtual_network_id" {
value = module.network.vnet_id
}
output "bastion_name" {
value = var.deployment_options.deploy_bastion ? module.bastion[0].name : null
output "virtual_network" {
value = module.network.vnet
}
output "firewall_private_ip" {

Просмотреть файл

@ -1,18 +0,0 @@
application_name = "eslz2"
environment = "prod"
location = "westus2"
# location_short = "wus3"
owner = "cloudops@contoso.com"
# Toggle deployment of optional features and services for the Landing Zone
deployment_options = {
enable_waf = true
enable_egress_lockdown = true
enable_diagnostic_settings = true
deploy_bastion = true
deploy_redis = true
deploy_sql_database = true
deploy_app_config = true
deploy_vm = true
deploy_openai = true
}

Просмотреть файл

@ -22,7 +22,7 @@ variable "owner" {
# variable "tenant_id" {
# type = string
# description = "[Required] The Microsoft Entra tenant ID for the identities"
# description = "[Required] The Entra tenant ID for the identities"
# }
variable "tags" {

Просмотреть файл

@ -0,0 +1,37 @@
terraform {
# 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 = {
source = "hashicorp/azurerm"
version = "~>4.5.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
version = ">=1.2.23"
}
}
# If called as a module, this backend configuration block will have no effect.
backend "azurerm" {}
}
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
virtual_machine {
delete_os_disk_on_deletion = true
graceful_shutdown = false
skip_shutdown_and_force_delete = true
}
}
# DO NOT CHANGE THE BELOW VALUES
disable_terraform_partner_id = false
partner_id = "cf7e9f0a-f872-49db-b72f-f2e318189a6d"
}

Просмотреть файл

@ -0,0 +1,63 @@
# Create Hub via module
module "hub" {
source = "./hub"
application_name = var.application_name
environment = var.environment
location = var.location
owner = var.owner
# Optional Network Config Variables
hub_vnet_cidr = var.hub_vnet_cidr
spoke_vnet_cidr = var.spoke_vnet_cidr
firewall_subnet_name = var.firewall_subnet_name
firewall_subnet_cidr = var.firewall_subnet_cidr
bastion_subnet_name = var.bastion_subnet_name
bastion_subnet_cidr = var.bastion_subnet_cidr
devops_subnet_cidr = var.devops_subnet_cidr
# Optional Deployment Variables
deployment_options = var.deployment_options
global_settings = var.global_settings
tags = var.tags
}
module "spoke" {
source = "./spoke"
application_name = var.application_name
environment = var.environment
location = var.location
owner = var.owner
tenant_id = var.tenant_id
appsvc_options = var.appsvc_options
oai_deployment_models = var.oai_deployment_models
oai_sku_name = var.oai_sku_name
# Spoke Network Configuration Variables
hub_virtual_network = module.hub.virtual_network
firewall_private_ip = module.hub.firewall_private_ip
firewall_rules = module.hub.firewall_rules
spoke_vnet_cidr = var.spoke_vnet_cidr
ase_subnet_cidr = var.ase_subnet_cidr
devops_subnet_cidr = var.devops_subnet_cidr
appsvc_subnet_cidr = var.appsvc_subnet_cidr
front_door_subnet_cidr = var.front_door_subnet_cidr
private_link_subnet_cidr = var.private_link_subnet_cidr
# Optional Self-hosted Agent Config Variables
vm_admin_username = var.vm_admin_username
vm_entra_admin_username = var.vm_entra_admin_username
vm_entra_admin_object_id = var.vm_entra_admin_object_id
# Spoke Resource Configuration Variables
sql_databases = var.sql_databases
# Optional Deployment Variables
deployment_options = var.deployment_options
global_settings = var.global_settings
tags = var.tags
}

Просмотреть файл

Просмотреть файл

@ -1,13 +1,13 @@
# spoke
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >=1.3 |
| <a name="requirement_azurecaf"></a> [azurecaf](#requirement\_azurecaf) | >=1.2.23 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=3.66.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 4.5.0 |
## Providers
@ -16,7 +16,6 @@
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.26 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.85.0 |
| <a name="provider_random"></a> [random](#provider\_random) | 3.6.0 |
| <a name="provider_terraform"></a> [terraform](#provider\_terraform) | n/a |
## Modules
@ -39,54 +38,151 @@
| Name | Type |
|------|------|
| [azurecaf_name.appsvc_subnet](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_asev3](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_id_contributor](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_id_reader](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_law](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_spoke_rg](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.law](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_log_analytics_workspace.law](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/log_analytics_workspace) | resource |
| [azurerm_resource_group.spoke](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_user_assigned_identity.contributor](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [azurerm_user_assigned_identity.reader](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [azurerm_app_service_environment_v3.this](https://registry.terraform.io/providers/hashicorp/azurerm/4.5.0/docs/resources/app_service_environment_v3) | resource |
| [azurerm_log_analytics_workspace.law](https://registry.terraform.io/providers/hashicorp/azurerm/4.5.0/docs/resources/log_analytics_workspace) | resource |
| [azurerm_resource_group.spoke](https://registry.terraform.io/providers/hashicorp/azurerm/4.5.0/docs/resources/resource_group) | resource |
| [azurerm_user_assigned_identity.contributor](https://registry.terraform.io/providers/hashicorp/azurerm/4.5.0/docs/resources/user_assigned_identity) | resource |
| [azurerm_user_assigned_identity.reader](https://registry.terraform.io/providers/hashicorp/azurerm/4.5.0/docs/resources/user_assigned_identity) | resource |
| [random_integer.unique_id](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) | resource |
| [azurerm_virtual_network.hub](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/virtual_network) | data source |
| [terraform_remote_state.hub](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/data-sources/remote_state) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_aad_admin_group_name"></a> [aad\_admin\_group\_name](#input\_aad\_admin\_group\_name) | The name of the Microsoft Entra ID 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 Microsoft Entra ID 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> 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> 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_appsvc_options"></a> [appsvc\_options](#input\_appsvc\_options) | [Optional] 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> })<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": null<br> }<br>}</pre> | no |
| <a name="input_appsvc_subnet_cidr"></a> [appsvc\_subnet\_cidr](#input\_appsvc\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.0/26"<br>]</pre> | no |
| <a name="input_ase_subnet_cidr"></a> [ase\_subnet\_cidr](#input\_ase\_subnet\_cidr) | [Optional] The CIDR block for the subnet. Defaults to 10.241.0.0/26 | `list(string)` | <pre>[<br> "10.240.5.0/24"<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_asev3 = 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_asev3": false,<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) | [Optional] 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_entra_admin_group_name"></a> [entra\_admin\_group\_name](#input\_entra\_admin\_group\_name) | [Required] The name of the Entra group that should be granted SQL Admin permissions to the SQL Server | `string` | n/a | yes |
| <a name="input_entra_admin_group_object_id"></a> [entra\_admin\_group\_object\_id](#input\_entra\_admin\_group\_object\_id) | [Required] The object ID of the Entra group that should be granted SQL Admin permissions to the SQL Server | `string` | n/a | yes |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment (dev, qa, staging, prod) | `string` | `"dev"` | no |
| <a name="input_firewall_private_ip"></a> [firewall\_private\_ip](#input\_firewall\_private\_ip) | n/a | `string` | n/a | yes |
| <a name="input_firewall_rules"></a> [firewall\_rules](#input\_firewall\_rules) | n/a | `any` | n/a | yes |
| <a name="input_front_door_subnet_cidr"></a> [front\_door\_subnet\_cidr](#input\_front\_door\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.64/26"<br>]</pre> | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | [Optional] Global settings to configure each module with the appropriate naming standards. | `map(any)` | `{}` | no |
| <a name="input_hub_virtual_network"></a> [hub\_virtual\_network](#input\_hub\_virtual\_network) | [Required] Hub virtual network object that is live in Azure. Use either a data block or output of the `Hub` module (virtual\_network) to provide this value | `any` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | The Azure region where all resources in this example should be created | `string` | `"westus2"` | no |
| <a name="input_oai_deployment_models"></a> [oai\_deployment\_models](#input\_oai\_deployment\_models) | [Optional] Map to specify deployment models for the OpenAI resource | `any` | <pre>{<br> "gpt-35-turbo": {<br> "model_format": "OpenAI",<br> "model_name": "gpt-35-turbo",<br> "model_version": "0613",<br> "name": "gpt-35-turbo",<br> "scale_type": "Standard"<br> },<br> "text-embedding-ada-002": {<br> "model_format": "OpenAI",<br> "model_name": "text-embedding-ada-002",<br> "model_version": "2",<br> "name": "text-embedding-ada-002",<br> "scale_type": "Standard"<br> }<br>}</pre> | no |
| <a name="input_oai_sku_name"></a> [oai\_sku\_name](#input\_oai\_sku\_name) | [Optional] The SKU name for the OpenAI resource | `string` | `"S0"` | no |
| <a name="input_owner"></a> [owner](#input\_owner) | [Required] Owner of the deployment. | `string` | n/a | yes |
| <a name="input_private_link_subnet_cidr"></a> [private\_link\_subnet\_cidr](#input\_private\_link\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.11.0/24"<br>]</pre> | no |
| <a name="input_spoke_vnet_cidr"></a> [spoke\_vnet\_cidr](#input\_spoke\_vnet\_cidr) | [Optional] The CIDR block(s) for the virtual network for whitelisting on the firewall. Defaults to 10.240.0.0/20 | `list(string)` | <pre>[<br> "10.240.0.0/20"<br>]</pre> | no |
| <a name="input_sql_databases"></a> [sql\_databases](#input\_sql\_databases) | [Optional] The settings for the SQL databases. | <pre>list(object({<br> name = string<br> sku_name = string<br> }))</pre> | <pre>[<br> {<br> "name": "sample-db",<br> "sku_name": "S0"<br> }<br>]</pre> | no |
| <a name="input_tags"></a> [tags](#input\_tags) | [Optional] Additional tags to assign to your resources | `map(string)` | `{}` | no |
| <a name="input_tenant_id"></a> [tenant\_id](#input\_tenant\_id) | The Entra tenant ID for the identities. If no value provided, will use current deployment environment tenant. | `string` | `null` | no |
| <a name="input_vm_admin_password"></a> [vm\_admin\_password](#input\_vm\_admin\_password) | [Optional] The password for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account. | `string` | `null` | no |
| <a name="input_vm_admin_username"></a> [vm\_admin\_username](#input\_vm\_admin\_username) | [Optional] The username for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account. | `string` | `null` | no |
| <a name="input_vm_entra_admin_object_id"></a> [vm\_entra\_admin\_object\_id](#input\_vm\_entra\_admin\_object\_id) | [Optional] The Entra object ID for the VM admin user/group. If vm\_entra\_admin\_username is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_vm_entra_admin_username"></a> [vm\_entra\_admin\_username](#input\_vm\_entra\_admin\_username) | [Optional] The Entra username for the VM admin account. If vm\_entra\_admin\_object\_id is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_zone_redundant"></a> [zone\_redundant](#input\_zone\_redundant) | [Optional] Enable zone redundancy for the app service environment. Defaults to true | `bool` | `true` | no |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_devops_vm_id"></a> [devops\_vm\_id](#output\_devops\_vm\_id) | n/a |
| <a name="output_key_vault_name"></a> [key\_vault\_name](#output\_key\_vault\_name) | n/a |
| <a name="output_key_vault_uri"></a> [key\_vault\_uri](#output\_key\_vault\_uri) | n/a |
| <a name="output_redis_connection_string"></a> [redis\_connection\_string](#output\_redis\_connection\_string) | n/a |
| <a name="output_rg_name"></a> [rg\_name](#output\_rg\_name) | n/a |
| <a name="output_sql_db_connection_string"></a> [sql\_db\_connection\_string](#output\_sql\_db\_connection\_string) | n/a |
| <a name="output_vnet_id"></a> [vnet\_id](#output\_vnet\_id) | n/a |
| <a name="output_vnet_name"></a> [vnet\_name](#output\_vnet\_name) | n/a |
| <a name="output_web_app_name"></a> [web\_app\_name](#output\_web\_app\_name) | n/a |
| <a name="output_web_app_slot_name"></a> [web\_app\_slot\_name](#output\_web\_app\_slot\_name) | n/a |
| <a name="output_web_app_uri"></a> [web\_app\_uri](#output\_web\_app\_uri) | n/a |
<!-- END_TF_DOCS -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >=1.3 |
| <a name="requirement_azurecaf"></a> [azurecaf](#requirement\_azurecaf) | >=1.2.23 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | >=1.2.23 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_app_configuration"></a> [app\_configuration](#module\_app\_configuration) | ../../../shared/terraform-modules/app-configuration | n/a |
| <a name="module_app_service"></a> [app\_service](#module\_app\_service) | ../../../shared/terraform-modules/app-service | n/a |
| <a name="module_devops_vm"></a> [devops\_vm](#module\_devops\_vm) | ../../../shared/terraform-modules/windows-vm | n/a |
| <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 |
| <a name="module_user_defined_routes"></a> [user\_defined\_routes](#module\_user\_defined\_routes) | ../../../shared/terraform-modules/user-defined-routes | n/a |
## Resources
| Name | Type |
|------|------|
| [azurecaf_name.appsvc_subnet](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_asev3](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_id_contributor](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_id_reader](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_law](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_spoke_rg](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.law](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_app_service_environment_v3.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service_environment_v3) | resource |
| [azurerm_log_analytics_workspace.law](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/log_analytics_workspace) | resource |
| [azurerm_resource_group.spoke](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_user_assigned_identity.contributor](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [azurerm_user_assigned_identity.reader](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [random_integer.unique_id](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <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) | [Optional] 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> })<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": "v6.0"<br> },<br> "slots": null<br> }<br>}</pre> | no |
| <a name="input_appsvc_subnet_cidr"></a> [appsvc\_subnet\_cidr](#input\_appsvc\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.0/26"<br>]</pre> | no |
| <a name="input_ase_subnet_cidr"></a> [ase\_subnet\_cidr](#input\_ase\_subnet\_cidr) | [Optional] The CIDR block for the subnet. Defaults to 10.241.0.0/26 | `list(string)` | <pre>[<br> "10.240.5.0/24"<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_asev3 = 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_asev3": false,<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) | [Optional] 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 |
| <a name="input_firewall_subnet_cidr"></a> [firewall\_subnet\_cidr](#input\_firewall\_subnet\_cidr) | [Optional] The CIDR block(s) for the firewall subnet. Defaults to 10.242.0.0/26 | `list(string)` | <pre>[<br> "10.242.0.0/26"<br>]</pre> | no |
| <a name="input_firewall_subnet_name"></a> [firewall\_subnet\_name](#input\_firewall\_subnet\_name) | [Optional] Name of the subnet for firewall resources. Defaults to 'AzureFirewallSubnet' | `string` | `"AzureFirewallSubnet"` | no |
| <a name="input_front_door_subnet_cidr"></a> [front\_door\_subnet\_cidr](#input\_front\_door\_subnet\_cidr) | The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.64/26"<br>]</pre> | no |
| <a name="input_firewall_private_ip"></a> [firewall\_private\_ip](#input\_firewall\_private\_ip) | n/a | `string` | n/a | yes |
| <a name="input_firewall_rules"></a> [firewall\_rules](#input\_firewall\_rules) | n/a | `any` | n/a | yes |
| <a name="input_front_door_subnet_cidr"></a> [front\_door\_subnet\_cidr](#input\_front\_door\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.0.64/26"<br>]</pre> | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | [Optional] Global settings to configure each module with the appropriate naming standards. | `map(any)` | `{}` | no |
| <a name="input_hub_settings"></a> [hub\_settings](#input\_hub\_settings) | The settings for the hub virtual network. | <pre>object({<br> rg_name = string<br> vnet_name = string<br><br> firewall = object({<br> private_ip = optional(string)<br> })<br> })</pre> | `null` | no |
| <a name="input_hub_state_container_name"></a> [hub\_state\_container\_name](#input\_hub\_state\_container\_name) | The name of the container that holds the Terraform state for the hub | `string` | n/a | yes |
| <a name="input_hub_state_key"></a> [hub\_state\_key](#input\_hub\_state\_key) | The key of the Terraform state for the hub | `string` | n/a | yes |
| <a name="input_hub_state_resource_group_name"></a> [hub\_state\_resource\_group\_name](#input\_hub\_state\_resource\_group\_name) | The name of the resource group that holds the Terraform state for the hub | `string` | n/a | yes |
| <a name="input_hub_state_storage_account_name"></a> [hub\_state\_storage\_account\_name](#input\_hub\_state\_storage\_account\_name) | The name of the storage account that holds the Terraform state for the hub | `string` | n/a | yes |
| <a name="input_hub_vnet_cidr"></a> [hub\_vnet\_cidr](#input\_hub\_vnet\_cidr) | [Optional] The CIDR block(s) for the hub virtual network. Defaults to 10.242.0.0/20 | `list(string)` | <pre>[<br> "10.242.0.0/20"<br>]</pre> | no |
| <a name="input_hub_virtual_network"></a> [hub\_virtual\_network](#input\_hub\_virtual\_network) | [Required] Hub virtual network object that is live in Azure. Use either a data block or output of the `Hub` module (virtual\_network) to provide this value | `any` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | The Azure region where all resources in this example should be created | `string` | `"westus2"` | no |
| <a name="input_oai_deployment_models"></a> [oai\_deployment\_models](#input\_oai\_deployment\_models) | [Optional] Map to specify deployment models for the OpenAI resource | `any` | <pre>{<br> "gpt-35-turbo": {<br> "model_format": "OpenAI",<br> "model_name": "gpt-35-turbo",<br> "model_version": "0613",<br> "name": "gpt-35-turbo",<br> "scale_type": "Standard"<br> },<br> "text-embedding-ada-002": {<br> "model_format": "OpenAI",<br> "model_name": "text-embedding-ada-002",<br> "model_version": "2",<br> "name": "text-embedding-ada-002",<br> "scale_type": "Standard"<br> }<br>}</pre> | no |
| <a name="input_oai_sku_name"></a> [oai\_sku\_name](#input\_oai\_sku\_name) | [Optional] The SKU name for the OpenAI resource | `string` | `"S0"` | no |
| <a name="input_owner"></a> [owner](#input\_owner) | [Required] Owner of the deployment. | `string` | n/a | yes |
| <a name="input_private_link_subnet_cidr"></a> [private\_link\_subnet\_cidr](#input\_private\_link\_subnet\_cidr) | The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.11.0/24"<br>]</pre> | no |
| <a name="input_private_link_subnet_cidr"></a> [private\_link\_subnet\_cidr](#input\_private\_link\_subnet\_cidr) | [Optional] The CIDR block for the subnet. | `list(string)` | <pre>[<br> "10.240.11.0/24"<br>]</pre> | no |
| <a name="input_spoke_vnet_cidr"></a> [spoke\_vnet\_cidr](#input\_spoke\_vnet\_cidr) | [Optional] The CIDR block(s) for the virtual network for whitelisting on the firewall. Defaults to 10.240.0.0/20 | `list(string)` | <pre>[<br> "10.240.0.0/20"<br>]</pre> | no |
| <a name="input_sql_databases"></a> [sql\_databases](#input\_sql\_databases) | [Optional] The settings for the SQL databases. | <pre>list(object({<br> name = string<br> sku_name = string<br> }))</pre> | <pre>[<br> {<br> "name": "sample-db",<br> "sku_name": "S0"<br> }<br>]</pre> | no |
| <a name="input_tags"></a> [tags](#input\_tags) | [Optional] Additional tags to assign to your resources | `map(string)` | `{}` | no |
| <a name="input_tenant_id"></a> [tenant\_id](#input\_tenant\_id) | The Microsoft Entra ID tenant ID for the identities. If no value provided, will use current deployment environment tenant. | `string` | `null` | no |
| <a name="input_vm_aad_admin_object_id"></a> [vm\_aad\_admin\_object\_id](#input\_vm\_aad\_admin\_object\_id) | The Microsoft Entra ID object ID for the VM admin user/group. If vm\_aad\_admin\_username is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_vm_aad_admin_username"></a> [vm\_aad\_admin\_username](#input\_vm\_aad\_admin\_username) | [Optional] The Microsoft Entra ID username for the VM admin account. If vm\_aad\_admin\_object\_id is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_vm_admin_password"></a> [vm\_admin\_password](#input\_vm\_admin\_password) | The password for the local VM admin account. Autogenerated if null. Prefer using the Microsoft Entra ID admin account. | `string` | `null` | no |
| <a name="input_vm_admin_username"></a> [vm\_admin\_username](#input\_vm\_admin\_username) | The username for the local VM admin account. Autogenerated if null. Prefer using the Microsoft Entra ID admin account. | `string` | `null` | no |
| <a name="input_tenant_id"></a> [tenant\_id](#input\_tenant\_id) | The Entra tenant ID for the identities. If no value provided, will use current deployment environment tenant. | `string` | `null` | no |
| <a name="input_vm_admin_password"></a> [vm\_admin\_password](#input\_vm\_admin\_password) | [Optional] The password for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account. | `string` | `null` | no |
| <a name="input_vm_admin_username"></a> [vm\_admin\_username](#input\_vm\_admin\_username) | [Optional] The username for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account. | `string` | `null` | no |
| <a name="input_vm_entra_admin_object_id"></a> [vm\_entra\_admin\_object\_id](#input\_vm\_entra\_admin\_object\_id) | [Optional] The Entra object ID for the VM admin user/group. If vm\_entra\_admin\_username is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_vm_entra_admin_username"></a> [vm\_entra\_admin\_username](#input\_vm\_entra\_admin\_username) | [Optional] The Entra username for the VM admin account. If vm\_entra\_admin\_object\_id is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_zone_redundant"></a> [zone\_redundant](#input\_zone\_redundant) | [Optional] Enable zone redundancy for the app service environment. Defaults to true | `bool` | `true` | no |
## Outputs

Просмотреть файл

@ -1,5 +1,5 @@
locals {
deployment_name = "sec-baseline-1-spoke"
deployment_name = "sec-baseline-spoke"
# used in spoke-network.tf
private_dns_zones = [for each in

Просмотреть файл

@ -7,30 +7,19 @@ module "openai" {
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"]
sku_name = var.oai_sku_name
deployment = var.oai_deployment_models
network_acls = [
{
default_action = "Deny"
virtual_network_rules = [
var.deployment_options.deploy_asev3 ? {
subnet_id = module.network.subnets["hostingEnvironments"].id
ignore_missing_vnet_service_endpoint = true
} : null,
{
subnet_id = module.network.subnets["serverFarm"].id
ignore_missing_vnet_service_endpoint = true

Просмотреть файл

@ -1,8 +1,16 @@
# Spoke application deployment
# ------
# - App Service
# -
locals {
sql_connstring = length(module.sql_database) > 0 ? module.sql_database[0].sql_db_connection_string : "SQL_NOT_PROVISIONED"
redis_connstring = length(module.redis_cache) > 0 ? module.redis_cache[0].redis_connection_string : "REDIS_NOT_PROVISIONED"
# If isolated SKU (using App Service Environment) then do not enable vnet integration
is_isolated_sku = can(regex("(?i)^I.*v2$", var.appsvc_options.service_plan.sku_name))
}
# Deploy the App Service
module "app_service" {
source = "../../../shared/terraform-modules/app-service"
@ -13,10 +21,11 @@ module "app_service" {
log_analytics_workspace_id = azurerm_log_analytics_workspace.law.id
enable_diagnostic_settings = var.deployment_options.enable_diagnostic_settings
appsvc_subnet_id = module.network.subnets["serverFarm"].id
frontend_subnet_id = module.network.subnets["ingress"].id
service_plan_options = var.appsvc_options.service_plan
# If isolated SKU (using App Service Environment) then do not enable vnet integration
appsvc_subnet_id = local.is_isolated_sku == true ? null : module.network.subnets["serverFarm"].id
frontend_subnet_id = module.network.subnets["ingress"].id
service_plan_options = var.appsvc_options.service_plan
app_service_environment_id = var.deployment_options.deploy_asev3 ? azurerm_app_service_environment_v3.this[0].id : null
identity = {
type = "UserAssigned"
identity_ids = [
@ -40,32 +49,6 @@ module "app_service" {
tags = local.base_tags
}
module "sql_database" {
count = var.deployment_options.deploy_sql_database ? 1 : 0
source = "../../../shared/terraform-modules/sql-database"
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
entra_admin_group_object_id = var.entra_admin_group_object_id
entra_admin_group_name = var.entra_admin_group_name
private_link_subnet_id = module.network.subnets["privateLink"].id
global_settings = local.global_settings
tags = local.base_tags
sql_databases = [
{
name = "sample-db"
sku_name = "S0"
}
]
private_dns_zone = local.provisioned_dns_zones["privatelink.database.windows.net"]
}
module "key_vault" {
source = "../../../shared/terraform-modules/key-vault"
@ -89,6 +72,27 @@ module "key_vault" {
private_dns_zone = local.provisioned_dns_zones["privatelink.vaultcore.azure.net"]
}
module "sql_database" {
count = var.deployment_options.deploy_sql_database ? 1 : 0
source = "../../../shared/terraform-modules/sql-database"
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
private_link_subnet_id = module.network.subnets["privateLink"].id
global_settings = local.global_settings
tags = local.base_tags
sql_databases = var.sql_databases
key_vault_id = module.key_vault.vault_id
private_dns_zone = local.provisioned_dns_zones["privatelink.database.windows.net"]
}
module "app_configuration" {
count = var.deployment_options.deploy_app_config ? 1 : 0

Просмотреть файл

@ -0,0 +1,56 @@
# Not broken into its own module as it is only used in this scenario
resource "azurecaf_name" "caf_name_asev3" {
count = var.deployment_options.deploy_asev3 ? 1 : 0
name = var.application_name
resource_type = "azurerm_app_service_environment"
prefixes = local.global_settings.prefixes
suffixes = local.global_settings.suffixes
random_length = local.global_settings.random_length
clean_input = true
passthrough = local.global_settings.passthrough
use_slug = local.global_settings.use_slug
}
resource "azurerm_app_service_environment_v3" "this" {
count = var.deployment_options.deploy_asev3 ? 1 : 0
name = azurecaf_name.caf_name_asev3.0.result
resource_group_name = azurerm_resource_group.spoke.name
# a /24 or larger CIDR is required. Once associated with an ASE, this size cannot be changed.
subnet_id = module.network.subnets["hostingEnvironments"].id
# Possible values are None (for an External VIP Type), and "Web, Publishing" (for an Internal VIP Type).
internal_load_balancing_mode = "Web, Publishing"
# Required for Private DNS and Endpoint configs
allow_new_private_endpoint_connections = true
# You can only set either dedicated_host_count or zone_redundant but not both.
# Changing this forces a new resource to be created.
# dedicated_host_count = 2
# Changing this forces a new resource to be created.
zone_redundant = var.zone_redundant
cluster_setting {
name = "DisableTls1.0"
value = "1"
}
## Caution: Enabling internal encryption will add hours to your deployment time
# cluster_setting {
# name = "InternalEncryption"
# value = "true"
# }
cluster_setting {
name = "FrontEndSSLCipherSuiteOrder"
value = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
}
tags = local.base_tags
}

Просмотреть файл

@ -1,14 +0,0 @@
data "terraform_remote_state" "hub" {
backend = "azurerm"
config = {
resource_group_name = var.hub_state_resource_group_name
storage_account_name = var.hub_state_storage_account_name
container_name = var.hub_state_container_name
key = var.hub_state_key
}
}
data "azurerm_virtual_network" "hub" {
name = data.terraform_remote_state.hub.outputs.vnet_name
resource_group_name = data.terraform_remote_state.hub.outputs.rg_name
}

Просмотреть файл

@ -3,7 +3,7 @@ locals {
az_cli_commands = <<-EOT
az login --identity --username ${azurerm_user_assigned_identity.contributor.principal_id} --allow-no-subscriptions
az keyvault secret set --vault-name ${module.key_vault.vault_name} --name 'redis-connstring' --value '${local.redis_connstring}'
az appconfig kv set --auth-mode login --endpoint ${module.app_configuration[0].endpoint} --key 'sql-connstring' --value '${local.sql_connstring}' --label '${var.environment}' -y
${var.deployment_options.deploy_app_config ? "az appconfig kv set --auth-mode login --endpoint ${module.app_configuration[0].endpoint} --key 'sql-connstring' --value '${local.sql_connstring}' --label '${var.environment}' -y" : ""}
EOT
}
@ -22,8 +22,7 @@ module "devops_vm" {
entra_admin_username = var.vm_entra_admin_username
entra_admin_object_id = var.vm_entra_admin_object_id
global_settings = local.global_settings
tags = local.base_tags
tags = local.base_tags
identity = {
type = "UserAssigned"

Просмотреть файл

@ -1,3 +1,6 @@
# Creates two user-assigned-identities for Reader and Contributor roles
# to be consumed in app.tf
resource "azurecaf_name" "caf_name_id_reader" {
name = var.application_name
resource_type = "azurerm_user_assigned_identity"

Просмотреть файл

@ -6,14 +6,17 @@ terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=3.66.0"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
version = ">=1.2.23"
}
}
backend "azurerm" {}
# If called as a module, this backend configuration block will have no effect.
# Uncomment the below block to use the AzureRM backend for a spoke-specific deplployment
# backend "azurerm" {}
}
provider "azurerm" {
@ -34,12 +37,14 @@ provider "azurerm" {
partner_id = "cf7e9f0a-f872-49db-b72f-f2e318189a6d"
}
provider "azurecaf" {}
## Create Spoke Resource Group with the name generated from global_settings
resource "azurecaf_name" "caf_name_spoke_rg" {
name = var.application_name
resource_type = "azurerm_resource_group"
prefixes = concat(["spoke"], local.global_settings.prefixes)
# prefixes = concat(["spoke"], local.global_settings.prefixes)
prefixes = local.global_settings.prefixes
suffixes = local.global_settings.suffixes
random_length = local.global_settings.random_length
clean_input = true
passthrough = local.global_settings.passthrough
@ -51,4 +56,4 @@ resource "azurerm_resource_group" "spoke" {
location = var.location
tags = local.base_tags
}
}

Просмотреть файл

@ -1,20 +1,28 @@
# Spoke network config
resource "random_integer" "unique_id" {
min = 1
max = 9999
}
# -----
# - VNet
# - Server Farm Subnet (App Service/compute resources)
# - Ingress Subnet (Azure Front Door network ingress subnet)
# - Private Link Subnet (Private DNS Zones)
# - DevOps Subnet (optional Self Hosted CICD agent)
# - Private DNS Zones
# - User Defined Routes [optional]
# - Azure FrontDoor
resource "azurecaf_name" "appsvc_subnet" {
name = var.application_name
resource_type = "azurerm_subnet"
prefixes = concat(["spoke"], local.global_settings.prefixes)
suffixes = local.global_settings.suffixes
random_length = local.global_settings.random_length
clean_input = true
passthrough = local.global_settings.passthrough
use_slug = local.global_settings.use_slug
}
## Deploy Spoke VNet with Server Farm, Ingress, Private Link and DevOps subnets
module "network" {
source = "../../../shared/terraform-modules/network"
@ -24,11 +32,12 @@ module "network" {
name = var.application_name
vnet_cidr = var.spoke_vnet_cidr
peering_vnet = {
id = data.azurerm_virtual_network.hub.id
name = data.azurerm_virtual_network.hub.name
resource_group = data.azurerm_virtual_network.hub.resource_group_name
id = var.hub_virtual_network.id
name = var.hub_virtual_network.name
resource_group = var.hub_virtual_network.resource_group_name
}
subnets = [
{
name = "serverFarm"
@ -41,6 +50,17 @@ module "network" {
}
}
},
var.deployment_options.deploy_asev3 ? {
name = "hostingEnvironments"
subnet_cidr = var.ase_subnet_cidr
delegation = {
name = "Microsoft.Web.hostingEnvironments"
service_delegation = {
name = "Microsoft.Web/hostingEnvironments"
actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
}
}
} : null,
{
name = "ingress"
subnet_cidr = var.front_door_subnet_cidr
@ -61,46 +81,30 @@ module "network" {
tags = local.base_tags
}
## Deploy Private DNS Zones
module "private_dns_zones" {
source = "../../../shared/terraform-modules/private-dns-zone"
count = length(local.private_dns_zones)
resource_group = data.terraform_remote_state.hub.outputs.rg_name
resource_group = var.hub_virtual_network.resource_group_name
global_settings = local.global_settings
dns_zone_name = local.private_dns_zones[count.index].name
dns_records = lookup(local.private_dns_zones[count.index], "records", [])
vnet_links = [
data.azurerm_virtual_network.hub.id
var.hub_virtual_network.id
]
tags = local.base_tags
}
module "user_defined_routes" {
count = var.deployment_options.enable_egress_lockdown ? 1 : 0
source = "../../../shared/terraform-modules/user-defined-routes"
resource_group = azurerm_resource_group.spoke.name
location = var.location
route_table_name = "egress-lockdown"
global_settings = local.global_settings
routes = [
{
name = "defaultRoute"
address_prefix = "0.0.0.0/0"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = data.terraform_remote_state.hub.outputs.firewall_private_ip
}
]
subnet_ids = module.network.subnet_ids
tags = local.base_tags
# TODO: Deprecate the random_integer unique_id logic
resource "random_integer" "unique_id" {
min = 1
max = 9999
}
## Deploy Azure Front Door with basic endpoint configuration for the web app
module "frontdoor" {
source = "../../../shared/terraform-modules/frontdoor"
@ -129,3 +133,27 @@ module "frontdoor" {
module.app_service
]
}
## Deploy User Defined Routes (UDR) to route all traffic to the Azure Firewall (enabled via deployment option)
module "user_defined_routes" {
count = var.deployment_options.enable_egress_lockdown ? 1 : 0
source = "../../../shared/terraform-modules/user-defined-routes"
resource_group = azurerm_resource_group.spoke.name
location = var.location
route_table_name = "egress-lockdown"
global_settings = local.global_settings
routes = [
{
name = "defaultRoute"
address_prefix = "0.0.0.0/0"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = var.firewall_private_ip
}
]
subnet_ids = module.network.subnet_ids
tags = local.base_tags
}

Просмотреть файл

@ -1,3 +1,8 @@
# spoke variables.tf
#####################################
# Common variables for naming and tagging
#####################################
variable "global_settings" {
type = map(any)
description = "[Optional] Global settings to configure each module with the appropriate naming standards."
@ -9,26 +14,6 @@ variable "owner" {
description = "[Required] Owner of the deployment."
}
variable "hub_state_resource_group_name" {
type = string
description = "The name of the resource group that holds the Terraform state for the hub"
}
variable "hub_state_storage_account_name" {
type = string
description = "The name of the storage account that holds the Terraform state for the hub"
}
variable "hub_state_container_name" {
type = string
description = "The name of the container that holds the Terraform state for the hub"
}
variable "hub_state_key" {
type = string
description = "The key of the Terraform state for the hub"
}
variable "application_name" {
type = string
description = "The name of your application"
@ -49,7 +34,7 @@ variable "location" {
variable "tenant_id" {
type = string
description = "The Microsoft Entra tenant ID for the identities. If no value provided, will use current deployment environment tenant."
description = "The Entra tenant ID for the identities. If no value provided, will use current deployment environment tenant."
default = null
}
@ -62,43 +47,17 @@ variable "tags" {
#####################################
# Spoke Resource Configuration Variables
#####################################
variable "entra_admin_group_object_id" {
type = string
description = "The object ID of the Microsoft Entra group that should be granted SQL Admin permissions to the SQL Server"
variable "hub_virtual_network" {
type = any
description = "[Required] Hub virtual network object that is live in Azure. Use either a data block or output of the `Hub` module (virtual_network) to provide this value"
}
variable "entra_admin_group_name" {
type = string
description = "The name of the Microsoft Entra group that should be granted SQL Admin permissions to the SQL Server"
variable "firewall_private_ip" {
type = string
}
variable "bastion_subnet_name" {
type = string
description = "[Optional] Name of the subnet to deploy bastion resource to. Defaults to 'AzureBastionSubnet'"
default = "AzureBastionSubnet"
}
variable "firewall_subnet_name" {
type = string
description = "[Optional] Name of the subnet for firewall resources. Defaults to 'AzureFirewallSubnet'"
default = "AzureFirewallSubnet"
}
variable "hub_vnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block(s) for the hub virtual network. Defaults to 10.242.0.0/20"
default = ["10.242.0.0/20"]
}
variable "firewall_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block(s) for the firewall subnet. Defaults to 10.242.0.0/26"
default = ["10.242.0.0/26"]
}
variable "bastion_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block(s) for the bastion subnet. Defaults to 10.242.0.64/26"
default = ["10.242.0.64/26"]
variable "firewall_rules" {
type = any
}
variable "spoke_vnet_cidr" {
@ -113,67 +72,110 @@ variable "devops_subnet_cidr" {
default = ["10.240.10.128/26"]
}
variable "ase_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block for the subnet. Defaults to 10.241.0.0/26"
default = ["10.240.5.0/24"]
}
variable "appsvc_subnet_cidr" {
type = list(string)
description = "The CIDR block for the subnet."
description = "[Optional] The CIDR block for the subnet."
default = ["10.240.0.0/26"]
}
variable "front_door_subnet_cidr" {
type = list(string)
description = "The CIDR block for the subnet."
description = "[Optional] The CIDR block for the subnet."
default = ["10.240.0.64/26"]
}
variable "private_link_subnet_cidr" {
type = list(string)
description = "The CIDR block for the subnet."
description = "[Optional] The CIDR block for the subnet."
default = ["10.240.11.0/24"]
}
variable "hub_settings" {
type = object({
rg_name = string
vnet_name = string
firewall = object({
private_ip = optional(string)
})
})
description = "The settings for the hub virtual network."
default = null
}
variable "vm_admin_username" {
type = string
description = "The username for the local VM admin account. Autogenerated if null. Prefer using the Microsoft Entra admin account."
description = "[Optional] The username for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account."
default = null
}
variable "vm_admin_password" {
type = string
description = "The password for the local VM admin account. Autogenerated if null. Prefer using the Microsoft Entra admin account."
description = "[Optional] The password for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account."
default = null
}
variable "vm_entra_admin_username" {
type = string
description = "[Optional] The Microsoft Entra username for the VM admin account. If vm_entra_admin_object_id is not specified, this value will be used."
description = "[Optional] The Entra username for the VM admin account. If vm_entra_admin_object_id is not specified, this value will be used."
default = null
}
variable "vm_entra_admin_object_id" {
type = string
description = "The Microsoft Entra object ID for the VM admin user/group. If vm_entra_admin_username is not specified, this value will be used."
description = "[Optional] The Entra object ID for the VM admin user/group. If vm_entra_admin_username is not specified, this value will be used."
default = null
}
variable "sql_databases" {
type = list(object({
name = string
sku_name = string
}))
description = "[Optional] The settings for the SQL databases."
default = [
{
name = "sample-db"
sku_name = "S0"
}
]
}
variable "zone_redundant" {
type = bool
description = "[Optional] Enable zone redundancy for the app service environment. Defaults to true"
default = true
}
variable "oai_sku_name" {
description = "[Optional] The SKU name for the OpenAI resource"
type = string
default = "S0"
}
variable "oai_deployment_models" {
description = "[Optional] Map to specify deployment models for the OpenAI resource"
type = any
default = {
"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"
}
}
}
variable "deployment_options" {
type = object({
enable_waf = bool
enable_egress_lockdown = bool
enable_diagnostic_settings = bool
deploy_asev3 = bool
deploy_bastion = bool
deploy_redis = bool
deploy_sql_database = bool
@ -188,6 +190,7 @@ variable "deployment_options" {
enable_waf = true
enable_egress_lockdown = true
enable_diagnostic_settings = true
deploy_asev3 = false
deploy_bastion = true
deploy_redis = true
deploy_sql_database = true
@ -200,10 +203,9 @@ variable "deployment_options" {
variable "appsvc_options" {
type = object({
service_plan = object({
os_type = string
sku_name = string
worker_count = optional(number)
zone_redundant = optional(bool)
os_type = string
sku_name = string
worker_count = optional(number)
})
web_app = object({
slots = list(string)
@ -226,7 +228,7 @@ variable "appsvc_options" {
})
})
description = "The options for the app service"
description = "[Optional] The options for the app service"
default = {
service_plan = {
@ -234,11 +236,11 @@ variable "appsvc_options" {
sku_name = "S1"
}
web_app = {
slots = []
slots = null
application_stack = {
current_stack = "dotnet"
dotnet_version = "6.0"
dotnet_version = "v6.0"
}
}
}
@ -272,7 +274,7 @@ variable "devops_settings" {
}))
})
description = "The settings for the Azure DevOps agent or GitHub runner"
description = "[Optional] The settings for the Azure DevOps agent or GitHub runner"
default = {
github_runner = null

Просмотреть файл

@ -0,0 +1,321 @@
# terraform variables.tf
#####################################
# Common variables for naming and tagging
#####################################
variable "global_settings" {
type = map(any)
description = <<EOT
[Optional] Global settings to configure each module with appropriate naming standards.
- name_prefix: A string to prepend to all resource names.
- name_suffix: A string to append to all resource names.
- use_slug: Whether to use a random slug in resource names for uniqueness.
- random_length: The length of the random string to use in the slug.
- resource_prefixes: A map of resource type to prefix string.
- resource_suffixes: A map of resource type to suffix string.
EOT
default = {}
}
variable "owner" {
type = string
description = "[Required] Owner of the deployment."
}
variable "application_name" {
type = string
description = "The name of your application"
default = "sec-baseline-1-spoke"
}
variable "environment" {
type = string
description = "The environment (dev, qa, staging, prod)"
default = "dev"
}
variable "location" {
type = string
description = "The Azure region where all resources in this example should be created"
default = "westus2"
}
variable "tenant_id" {
type = string
description = "The Entra tenant ID for the identities. If no value provided, will use current deployment environment tenant."
default = null
}
variable "tags" {
type = map(string)
description = "[Optional] Additional tags to assign to your resources"
default = {}
}
#####################################
# Hub Network Configuration Variables
#####################################
variable "bastion_subnet_name" {
type = string
description = "[Optional] Name of the subnet to deploy bastion resource to. Defaults to 'AzureBastionSubnet'"
default = "AzureBastionSubnet"
}
variable "firewall_subnet_name" {
type = string
description = "[Optional] Name of the subnet for firewall resources. Defaults to 'AzureFirewallSubnet'"
default = "AzureFirewallSubnet"
}
variable "hub_vnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block(s) for the hub virtual network. Defaults to 10.242.0.0/20"
default = ["10.242.0.0/20"]
}
variable "firewall_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block(s) for the firewall subnet. Defaults to 10.242.0.0/26"
default = ["10.242.0.0/26"]
}
variable "bastion_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block(s) for the bastion subnet. Defaults to 10.242.0.64/26"
default = ["10.242.0.64/26"]
}
variable "spoke_vnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block(s) for the virtual network for whitelisting on the firewall. Defaults to 10.240.0.0/20"
default = ["10.240.0.0/20"]
}
variable "devops_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block for the subnet. Defaults to 10.240.10.128/16"
default = ["10.240.10.128/26"]
}
variable "ase_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block for the subnet. Defaults to 10.241.0.0/26"
default = ["10.240.5.0/24"]
}
#####################################
# Spoke Resource Configuration Variables
#####################################
variable "oai_sku_name" {
description = "[Optional] The SKU name for the OpenAI resource"
type = string
default = "S0"
}
variable "oai_deployment_models" {
description = "[Optional] Map to specify deployment models for the OpenAI resource"
type = any
default = {
"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"
}
}
}
variable "entra_admin_group_object_id" {
type = string
description = "[Required] The object ID of the Entra group that should be granted SQL Admin permissions to the SQL Server"
default = null
}
variable "entra_admin_group_name" {
type = string
description = "[Required] The name of the Entra group that should be granted SQL Admin permissions to the SQL Server"
default = null
}
variable "appsvc_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block for the subnet."
default = ["10.240.0.0/26"]
}
variable "front_door_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block for the subnet."
default = ["10.240.0.64/26"]
}
variable "private_link_subnet_cidr" {
type = list(string)
description = "[Optional] The CIDR block for the subnet."
default = ["10.240.11.0/24"]
}
variable "vm_admin_username" {
type = string
description = "[Optional] The username for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account."
default = null
}
## Shouldn't be passing around passwords or have it captured in source control
## Use Hashicorp Vault or KeyVault instead.
# variable "vm_admin_password" {
# type = string
# description = "[Optional] The password for the local VM admin account. Autogenerated if null. Prefer using the Entra admin account."
# default = null
# }
variable "vm_entra_admin_username" {
type = string
description = "[Optional] The Entra username for the VM admin account. If vm_entra_admin_object_id is not specified, this value will be used."
default = null
}
variable "vm_entra_admin_object_id" {
type = string
description = "[Optional] The Entra object ID for the VM admin user/group. If vm_entra_admin_username is not specified, this value will be used."
default = null
}
variable "sql_databases" {
type = list(object({
name = string
sku_name = string
}))
description = "[Optional] The settings for the SQL databases."
default = [
{
name = "sample-db"
sku_name = "S0"
}
]
}
variable "deployment_options" {
type = object({
enable_waf = bool
enable_egress_lockdown = bool
enable_diagnostic_settings = bool
deploy_bastion = bool
deploy_redis = bool
deploy_sql_database = bool
deploy_app_config = bool
deploy_vm = bool
deploy_openai = bool
deploy_asev3 = bool
})
description = "[Optional] 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."
default = {
enable_waf = false
enable_egress_lockdown = false
enable_diagnostic_settings = false
deploy_bastion = false
deploy_redis = false
deploy_sql_database = false
deploy_app_config = false
deploy_vm = false
deploy_openai = false
deploy_asev3 = false
}
}
variable "appsvc_options" {
type = object({
service_plan = object({
os_type = string
sku_name = string
worker_count = optional(number)
zone_redundant = optional(bool)
})
web_app = object({
slots = optional(list(string))
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)
python = optional(bool) # windows only
python_version = optional(string) # linux only
java_server = optional(string) # linux only
java_server_version = optional(string) # linux only
go_version = optional(string) # linux only
ruby_version = optional(string) # linux only
})
})
})
description = "The options for the app service"
default = {
service_plan = {
os_type = "Windows"
sku_name = "I1v2"
zone_redundant = true
}
web_app = {
slots = []
application_stack = {
current_stack = "dotnet"
dotnet_version = "v6.0"
}
}
}
validation {
condition = contains(["Windows", "Linux"], var.appsvc_options.service_plan.os_type)
error_message = "Please, choose among one of the following operating systems: Windows or Linux."
}
# validation {
# condition = contains(["S1", "S2", "S3", "P1v2", "P2v2", "P3v2"], var.appsvc_options.service_plan.sku_name)
# error_message = "Please, choose among one of the following SKUs for production workloads: S1, S2, S3, P1v2, P2v2 or P3v2."
# }
validation {
condition = contains(["dotnet", "dotnetcore", "java", "php", "python", "node"], var.appsvc_options.web_app.application_stack.current_stack)
error_message = "Please, choose among one of the following stacks: dotnet, dotnetcore, java, php, python or node."
}
}
variable "devops_settings" {
type = object({
github_runner = optional(object({
repository_url = string
token = string
}))
devops_agent = optional(object({
organization_url = string
token = string
}))
})
description = "[Optional] The settings for the Azure DevOps agent or GitHub runner"
default = {
github_runner = null
devops_agent = null
}
}

Просмотреть файл

@ -3,14 +3,16 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.60.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -3,14 +3,16 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.26 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.75.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules
@ -25,6 +27,7 @@ No requirements.
|------|------|
| [azurecaf_name.caf_name_appinsights](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_asp](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_app_service_virtual_network_swift_connection.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service_virtual_network_swift_connection) | resource |
| [azurerm_application_insights.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/application_insights) | resource |
| [azurerm_service_plan.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/service_plan) | resource |
@ -32,6 +35,7 @@ No requirements.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_app_service_environment_id"></a> [app\_service\_environment\_id](#input\_app\_service\_environment\_id) | The app service environment id | `string` | `null` | no |
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | The name of your application | `string` | n/a | yes |
| <a name="input_appsvc_subnet_id"></a> [appsvc\_subnet\_id](#input\_appsvc\_subnet\_id) | The subnet id where the app service will be integrated | `string` | `null` | no |
| <a name="input_deploy_web_app"></a> [deploy\_web\_app](#input\_deploy\_web\_app) | Feature flag to deploy a web app as part of the module | `bool` | `true` | no |
@ -43,9 +47,9 @@ No requirements.
| <a name="input_log_analytics_workspace_id"></a> [log\_analytics\_workspace\_id](#input\_log\_analytics\_workspace\_id) | The log analytics workspace id | `string` | n/a | yes |
| <a name="input_private_dns_zone"></a> [private\_dns\_zone](#input\_private\_dns\_zone) | The private dns zone id where the app service will be integrated | <pre>object({<br> id = string<br> name = string<br> resource_group_name = string<br> })</pre> | n/a | yes |
| <a name="input_resource_group"></a> [resource\_group](#input\_resource\_group) | The name of the resource group where all resources in this example should be created. | `string` | n/a | yes |
| <a name="input_service_plan_options"></a> [service\_plan\_options](#input\_service\_plan\_options) | The options for the app service | <pre>object({<br> os_type = string<br> sku_name = string<br> app_service_environment_id = optional(string)<br> worker_count = optional(number)<br> zone_redundant = optional(bool)<br> })</pre> | <pre>{<br> "os_type": "Windows",<br> "sku_name": "S1"<br>}</pre> | no |
| <a name="input_service_plan_options"></a> [service\_plan\_options](#input\_service\_plan\_options) | The options for the app service | <pre>object({<br> os_type = string<br> sku_name = string<br> worker_count = optional(number)<br> zone_redundant = optional(bool)<br> })</pre> | <pre>{<br> "os_type": "Windows",<br> "sku_name": "S1",<br> "worker_count": 3<br>}</pre> | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
| <a name="input_webapp_options"></a> [webapp\_options](#input\_webapp\_options) | The options for the app service | <pre>object({<br> slots = optional(list(string))<br><br> application_stack = optional(object({<br> current_stack = optional(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> 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> })</pre> | <pre>{<br> "application_stack": {},<br> "slots": []<br>}</pre> | no |
| <a name="input_webapp_options"></a> [webapp\_options](#input\_webapp\_options) | The options for the app service | <pre>object({<br> slots = list(string)<br> instrumentation_key = optional(string)<br> ai_connection_string = optional(string)<br> vnet_route_all_enabled = optional(bool)<br> use_32_bit_worker = optional(bool)<br> vnet_integration_enabled = optional(bool)<br><br> application_stack = optional(object({<br> current_stack = optional(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> 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> })</pre> | <pre>{<br> "application_stack": {},<br> "slots": []<br>}</pre> | no |
## Outputs
@ -57,6 +61,6 @@ No requirements.
| <a name="output_web_app_principal_id"></a> [web\_app\_principal\_id](#output\_web\_app\_principal\_id) | n/a |
| <a name="output_web_app_slot_hostname"></a> [web\_app\_slot\_hostname](#output\_web\_app\_slot\_hostname) | n/a |
| <a name="output_web_app_slot_id"></a> [web\_app\_slot\_id](#output\_web\_app\_slot\_id) | n/a |
| <a name="output_web_app_slot_identities"></a> [web\_app\_slot\_identities](#output\_web\_app\_slot\_identities) | n/a |
| <a name="output_web_app_slot_name"></a> [web\_app\_slot\_name](#output\_web\_app\_slot\_name) | n/a |
| <a name="output_web_app_slot_principal_id"></a> [web\_app\_slot\_principal\_id](#output\_web\_app\_slot\_principal\_id) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Просмотреть файл

@ -1,16 +1,18 @@
# linux-web-app
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
# linux-web-app
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.26 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.75.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules
@ -58,8 +60,8 @@ No requirements.
| <a name="output_web_app_id"></a> [web\_app\_id](#output\_web\_app\_id) | n/a |
| <a name="output_web_app_name"></a> [web\_app\_name](#output\_web\_app\_name) | n/a |
| <a name="output_web_app_principal_id"></a> [web\_app\_principal\_id](#output\_web\_app\_principal\_id) | n/a |
| <a name="output_web_app_slot_hostname"></a> [web\_app\_slot\_hostname](#output\_web\_app\_slot\_hostname) | n/a |
| <a name="output_web_app_slot_id"></a> [web\_app\_slot\_id](#output\_web\_app\_slot\_id) | n/a |
| <a name="output_web_app_slot_name"></a> [web\_app\_slot\_name](#output\_web\_app\_slot\_name) | n/a |
| <a name="output_web_app_slot_principal_id"></a> [web\_app\_slot\_principal\_id](#output\_web\_app\_slot\_principal\_id) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
| <a name="output_web_app_slot_hostnames"></a> [web\_app\_slot\_hostnames](#output\_web\_app\_slot\_hostnames) | n/a |
| <a name="output_web_app_slot_identities"></a> [web\_app\_slot\_identities](#output\_web\_app\_slot\_identities) | n/a |
| <a name="output_web_app_slot_ids"></a> [web\_app\_slot\_ids](#output\_web\_app\_slot\_ids) | n/a |
| <a name="output_web_app_slot_names"></a> [web\_app\_slot\_names](#output\_web\_app\_slot\_names) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -28,12 +28,11 @@ resource "azurerm_linux_web_app" "this" {
use_32_bit_worker = false
application_stack {
docker_image = var.webapp_options.application_stack.docker_image
docker_image_tag = var.webapp_options.application_stack.docker_image_tag
dotnet_version = var.webapp_options.application_stack.dotnet_version
java_version = var.webapp_options.application_stack.java_version
php_version = var.webapp_options.application_stack.php_version
node_version = var.webapp_options.application_stack.node_version
docker_image_name = "${var.webapp_options.application_stack.docker_image}:${var.webapp_options.application_stack.docker_image_tag}"
dotnet_version = var.webapp_options.application_stack.dotnet_version
java_version = var.webapp_options.application_stack.java_version
php_version = var.webapp_options.application_stack.php_version
node_version = var.webapp_options.application_stack.node_version
}
}
@ -91,22 +90,11 @@ resource "azurerm_monitor_diagnostic_setting" "this" {
enabled_log {
category_group = "allLogs"
## `retention_policy` has been deprecated in favor of `azurerm_storage_management_policy` resource - to learn more https://aka.ms/diagnostic_settings_log_retention
# retention_policy {
# days = 0
# enabled = false
# }
}
metric {
category = "AllMetrics"
enabled = false
## `retention_policy` has been deprecated in favor of `azurerm_storage_management_policy` resource - to learn more https://aka.ms/diagnostic_settings_log_retention
# retention_policy {
# days = 0
# enabled = false
# }
}
}
@ -135,7 +123,8 @@ module "private_endpoint" {
}
resource "azurerm_linux_web_app_slot" "slot" {
name = var.webapp_options.slots[0]
count = length(var.webapp_options.slots)
name = var.webapp_options.slots[count.index]
app_service_id = azurerm_linux_web_app.this.id
virtual_network_subnet_id = var.appsvc_subnet_id
https_only = true
@ -150,37 +139,32 @@ resource "azurerm_linux_web_app_slot" "slot" {
use_32_bit_worker = false
application_stack {
docker_image = var.webapp_options.application_stack.docker_image
docker_image_tag = var.webapp_options.application_stack.docker_image_tag
dotnet_version = var.webapp_options.application_stack.dotnet_version
java_version = var.webapp_options.application_stack.java_version
php_version = var.webapp_options.application_stack.php_version
node_version = var.webapp_options.application_stack.node_version
docker_image_name = "${var.webapp_options.application_stack.docker_image}:${var.webapp_options.application_stack.docker_image_tag}"
dotnet_version = var.webapp_options.application_stack.dotnet_version
java_version = var.webapp_options.application_stack.java_version
php_version = var.webapp_options.application_stack.php_version
node_version = var.webapp_options.application_stack.node_version
}
}
}
resource "azurecaf_name" "slot" {
name = "${azurecaf_name.caf_name_linwebapp.result}-${var.webapp_options.slots[0]}"
resource_type = "azurerm_private_endpoint"
}
module "private_endpoint_slot" {
source = "../../private-endpoint"
count = length(azurerm_linux_web_app_slot.slot)
name = azurecaf_name.slot.result
name = "${azurerm_linux_web_app.this.name}-${azurerm_linux_web_app_slot.slot[count.index].name}"
resource_group = var.resource_group
location = var.location
subnet_id = var.frontend_subnet_id
private_connection_resource_id = azurerm_linux_web_app.this.id
private_connection_resource_id = azurerm_linux_web_app.this.id // Change this line
subresource_names = ["sites-${var.webapp_options.slots[0]}"]
subresource_names = ["sites-${azurerm_linux_web_app_slot.slot[count.index].name}"]
private_dns_zone = var.private_dns_zone
private_dns_records = [
lower("${azurerm_linux_web_app.this.name}-${azurerm_linux_web_app_slot.slot.name}"),
lower("${azurerm_linux_web_app.this.name}-${azurerm_linux_web_app_slot.slot.name}.scm")
lower("${azurerm_linux_web_app.this.name}-${azurerm_linux_web_app_slot.slot[count.index].name}"),
lower("${azurerm_linux_web_app.this.name}-${azurerm_linux_web_app_slot.slot[count.index].name}.scm")
]
depends_on = [

Просмотреть файл

@ -14,18 +14,18 @@ output "web_app_principal_id" {
value = azurerm_linux_web_app.this.identity.0.principal_id
}
output "web_app_slot_id" {
value = azurerm_linux_web_app_slot.slot.id
output "web_app_slot_ids" {
value = azurerm_linux_web_app_slot.slot.*.id
}
output "web_app_slot_name" {
value = azurerm_linux_web_app_slot.slot.name
output "web_app_slot_names" {
value = azurerm_linux_web_app_slot.slot.*.name
}
output "web_app_slot_hostname" {
value = azurerm_linux_web_app_slot.slot.default_hostname
output "web_app_slot_hostnames" {
value = azurerm_linux_web_app_slot.slot.*.default_hostname
}
output "web_app_slot_principal_id" {
value = azurerm_linux_web_app_slot.slot.identity.0.principal_id
output "web_app_slot_identities" {
value = azurerm_linux_web_app_slot.slot.*.identity
}

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -3,6 +3,9 @@ locals {
ai_connection_string = azurerm_application_insights.this.connection_string
instrumentation_key = azurerm_application_insights.this.instrumentation_key
}, var.webapp_options)
# If isolated SKU (using App Service Environment) then do not enable vnet integration
is_isolated_sku = can(regex("(?i)^I.*v2$", var.service_plan_options.sku_name))
}
resource "azurecaf_name" "caf_name_asp" {
@ -24,10 +27,13 @@ resource "azurerm_service_plan" "this" {
sku_name = var.service_plan_options.sku_name
os_type = var.service_plan_options.os_type
app_service_environment_id = lookup(var.service_plan_options, "app_service_environment_id", null)
worker_count = coalesce(var.service_plan_options.worker_count, 1)
zone_balancing_enabled = coalesce(var.service_plan_options.zone_redundant, false)
tags = local.tags
app_service_environment_id = var.app_service_environment_id
worker_count = coalesce(var.service_plan_options.worker_count, 3)
# For ASEv3 hosted ASP, zone redundancy is managed at the ASE level
zone_balancing_enabled = var.app_service_environment_id != null ? true : false
tags = local.tags
}
module "windows_web_app" {
@ -37,17 +43,18 @@ module "windows_web_app" {
resource_group = var.resource_group
web_app_name = var.application_name
# environment = var.environment
location = var.location
service_plan_id = azurerm_service_plan.this.id
service_plan_resource = azurerm_service_plan.this
appsvc_subnet_id = var.appsvc_subnet_id
frontend_subnet_id = var.frontend_subnet_id
webapp_options = local.webapp_options
private_dns_zone = var.private_dns_zone
identity = var.identity
global_settings = var.global_settings
tags = var.tags
# If isolated SKU (using App Service Environment) then do not enable vnet integration
appsvc_subnet_id = local.is_isolated_sku == true ? null : var.appsvc_subnet_id
frontend_subnet_id = var.frontend_subnet_id
webapp_options = local.webapp_options
private_dns_zone = var.private_dns_zone
identity = var.identity
global_settings = var.global_settings
tags = var.tags
log_analytics_workspace_id = var.log_analytics_workspace_id
enable_diagnostic_settings = var.enable_diagnostic_settings
@ -60,18 +67,26 @@ module "linux_web_app" {
resource_group = var.resource_group
web_app_name = var.application_name
# environment = var.environment
location = var.location
service_plan_id = azurerm_service_plan.this.id
service_plan_resource = azurerm_service_plan.this
appsvc_subnet_id = var.appsvc_subnet_id
frontend_subnet_id = var.frontend_subnet_id
webapp_options = local.webapp_options
private_dns_zone = var.private_dns_zone
identity = var.identity
global_settings = var.global_settings
tags = var.tags
# If isolated SKU (using App Service Environment) then do not enable vnet integration
appsvc_subnet_id = local.is_isolated_sku == true ? null : var.appsvc_subnet_id
frontend_subnet_id = var.frontend_subnet_id
webapp_options = local.webapp_options
private_dns_zone = var.private_dns_zone
identity = var.identity
global_settings = var.global_settings
tags = var.tags
log_analytics_workspace_id = var.log_analytics_workspace_id
enable_diagnostic_settings = var.enable_diagnostic_settings
}
}
# Only required for vnet integration (non ASE)
resource "azurerm_app_service_virtual_network_swift_connection" "this" {
count = local.is_isolated_sku == true ? 0 : 1
app_service_id = var.deploy_web_app ? length(module.windows_web_app) > 0 ? module.windows_web_app[0].web_app_id : module.linux_web_app[0].web_app_id : null
subnet_id = var.appsvc_subnet_id
}

Просмотреть файл

@ -15,17 +15,17 @@ output "web_app_principal_id" {
}
output "web_app_slot_id" {
value = var.deploy_web_app ? length(module.windows_web_app) > 0 ? module.windows_web_app[0].web_app_slot_id : module.linux_web_app[0].web_app_slot_id : null
value = var.deploy_web_app ? length(module.windows_web_app) > 0 ? module.windows_web_app[0].web_app_slot_ids : module.linux_web_app[0].web_app_slot_ids : null
}
output "web_app_slot_name" {
value = var.deploy_web_app ? length(module.windows_web_app) > 0 ? module.windows_web_app[0].web_app_slot_name : module.linux_web_app[0].web_app_slot_name : null
value = var.deploy_web_app ? length(module.windows_web_app) > 0 ? module.windows_web_app[0].web_app_slot_names : module.linux_web_app[0].web_app_slot_names : null
}
output "web_app_slot_hostname" {
value = var.deploy_web_app ? length(module.windows_web_app) > 0 ? module.windows_web_app[0].web_app_slot_hostname : module.linux_web_app[0].web_app_slot_hostname : null
value = var.deploy_web_app ? length(module.windows_web_app) > 0 ? module.windows_web_app[0].web_app_slot_hostnames : module.linux_web_app[0].web_app_slot_hostnames : null
}
output "web_app_slot_principal_id" {
value = var.deploy_web_app ? length(module.windows_web_app) > 0 ? module.windows_web_app[0].web_app_slot_principal_id : module.linux_web_app[0].web_app_slot_principal_id : null
output "web_app_slot_identities" {
value = var.deploy_web_app ? length(module.windows_web_app) > 0 ? module.windows_web_app[0].web_app_slot_identities : module.linux_web_app[0].web_app_slot_identities : null
}

Просмотреть файл

@ -42,20 +42,26 @@ variable "log_analytics_workspace_id" {
description = "The log analytics workspace id"
}
variable "app_service_environment_id" {
type = string
description = "The app service environment id"
default = null
}
variable "service_plan_options" {
type = object({
os_type = string
sku_name = string
app_service_environment_id = optional(string)
worker_count = optional(number)
zone_redundant = optional(bool)
os_type = string
sku_name = string
worker_count = optional(number)
zone_redundant = optional(bool)
})
description = "The options for the app service"
default = {
os_type = "Windows"
sku_name = "S1"
os_type = "Windows"
sku_name = "S1"
worker_count = 3
}
validation {
@ -90,7 +96,12 @@ variable "identity" {
variable "webapp_options" {
type = object({
slots = optional(list(string))
slots = list(string)
instrumentation_key = optional(string)
ai_connection_string = optional(string)
vnet_route_all_enabled = optional(bool)
use_32_bit_worker = optional(bool)
vnet_integration_enabled = optional(bool)
application_stack = optional(object({
current_stack = optional(string) # required for windows
@ -119,6 +130,8 @@ variable "webapp_options" {
default = {
slots = []
application_stack = {}
}
}

Просмотреть файл

@ -1,23 +1,24 @@
# windows-web-app
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
# windows-web-app
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.26 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.75.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_private_endpoint"></a> [private\_endpoint](#module\_private\_endpoint) | ../../private-endpoint | n/a |
| <a name="module_private_endpoint_slot"></a> [private\_endpoint\_slot](#module\_private\_endpoint\_slot) | ../../private-endpoint | n/a |
## Resources
@ -48,7 +49,7 @@ No requirements.
| <a name="input_service_plan_resource"></a> [service\_plan\_resource](#input\_service\_plan\_resource) | The service plan resource where the web application will be created | `any` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
| <a name="input_web_app_name"></a> [web\_app\_name](#input\_web\_app\_name) | The name of the web application | `string` | n/a | yes |
| <a name="input_webapp_options"></a> [webapp\_options](#input\_webapp\_options) | The options for the app service | <pre>object({<br> instrumentation_key = string<br> ai_connection_string = string<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> 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> })</pre> | n/a | yes |
| <a name="input_webapp_options"></a> [webapp\_options](#input\_webapp\_options) | [Required] The options for the app service | <pre>object({<br> slots = list(string)<br> instrumentation_key = optional(string)<br> ai_connection_string = optional(string)<br> vnet_route_all_enabled = optional(bool)<br> use_32_bit_worker = optional(bool)<br> vnet_integration_enabled = optional(bool)<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> 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> })</pre> | n/a | yes |
## Outputs
@ -58,8 +59,8 @@ No requirements.
| <a name="output_web_app_id"></a> [web\_app\_id](#output\_web\_app\_id) | n/a |
| <a name="output_web_app_name"></a> [web\_app\_name](#output\_web\_app\_name) | n/a |
| <a name="output_web_app_principal_id"></a> [web\_app\_principal\_id](#output\_web\_app\_principal\_id) | n/a |
| <a name="output_web_app_slot_hostname"></a> [web\_app\_slot\_hostname](#output\_web\_app\_slot\_hostname) | n/a |
| <a name="output_web_app_slot_id"></a> [web\_app\_slot\_id](#output\_web\_app\_slot\_id) | n/a |
| <a name="output_web_app_slot_name"></a> [web\_app\_slot\_name](#output\_web\_app\_slot\_name) | n/a |
| <a name="output_web_app_slot_principal_id"></a> [web\_app\_slot\_principal\_id](#output\_web\_app\_slot\_principal\_id) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
| <a name="output_web_app_slot_hostnames"></a> [web\_app\_slot\_hostnames](#output\_web\_app\_slot\_hostnames) | n/a |
| <a name="output_web_app_slot_identities"></a> [web\_app\_slot\_identities](#output\_web\_app\_slot\_identities) | n/a |
| <a name="output_web_app_slot_ids"></a> [web\_app\_slot\_ids](#output\_web\_app\_slot\_ids) | n/a |
| <a name="output_web_app_slot_names"></a> [web\_app\_slot\_names](#output\_web\_app\_slot\_names) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -11,7 +11,7 @@ resource "azurecaf_name" "caf_name_winwebapp" {
}
resource "azurerm_windows_web_app" "this" {
name = var.web_app_name
name = azurecaf_name.caf_name_winwebapp.result
resource_group_name = var.resource_group
location = var.location
https_only = true
@ -24,8 +24,8 @@ resource "azurerm_windows_web_app" "this" {
}
site_config {
vnet_route_all_enabled = true
use_32_bit_worker = false
vnet_route_all_enabled = coalesce(var.webapp_options.vnet_route_all_enabled, true)
use_32_bit_worker = coalesce(var.webapp_options.use_32_bit_worker, true)
application_stack {
current_stack = coalesce(var.webapp_options.application_stack.current_stack, "dotnet")
@ -81,23 +81,11 @@ resource "azurerm_monitor_diagnostic_setting" "this" {
enabled_log {
category_group = "AllLogs"
## `retention_policy` has been deprecated in favor of `azurerm_storage_management_policy` resource - to learn more https://aka.ms/diagnostic_settings_log_retention
# retention_policy {
# days = 0
# enabled = false
# }
}
metric {
category = "AllMetrics"
enabled = false
## `retention_policy` has been deprecated in favor of `azurerm_storage_management_policy` resource - to learn more https://aka.ms/diagnostic_settings_log_retention
# retention_policy {
# days = 0
# enabled = false
# }
}
}
@ -126,17 +114,19 @@ module "private_endpoint" {
}
resource "azurerm_windows_web_app_slot" "slot" {
name = var.webapp_options.slots[0]
count = length(var.webapp_options.slots)
name = var.webapp_options.slots[count.index]
app_service_id = azurerm_windows_web_app.this.id
virtual_network_subnet_id = var.appsvc_subnet_id
https_only = true
identity {
type = var.identity.type
identity_ids = var.identity.type == "SystemAssigned" ? [] : var.identity.identity_ids
identity_ids = var.identity.type == "SystemAssigned" ? null : var.identity.identity_ids
}
site_config {
vnet_route_all_enabled = true
use_32_bit_worker = false
@ -149,26 +139,26 @@ resource "azurerm_windows_web_app_slot" "slot" {
}
}
resource "azurecaf_name" "slot" {
name = "${var.web_app_name}-${var.webapp_options.slots[0]}"
resource_type = "azurerm_private_endpoint"
}
module "private_endpoint_slot" {
source = "../../private-endpoint"
count = length(azurerm_windows_web_app_slot.slot)
name = azurecaf_name.slot.result
name = "${azurerm_windows_web_app.this.name}-${azurerm_windows_web_app_slot.slot[count.index].name}"
resource_group = var.resource_group
location = var.location
subnet_id = var.frontend_subnet_id
private_connection_resource_id = azurerm_windows_web_app.this.id
private_connection_resource_id = azurerm_windows_web_app.this.id // Change this line
subresource_names = ["sites-${var.webapp_options.slots[0]}"]
subresource_names = ["sites-${azurerm_windows_web_app_slot.slot[count.index].name}"]
private_dns_zone = var.private_dns_zone
private_dns_records = [
lower("${azurerm_windows_web_app.this.name}-${azurerm_windows_web_app_slot.slot.name}"),
lower("${azurerm_windows_web_app.this.name}-${azurerm_windows_web_app_slot.slot.name}.scm")
lower("${azurerm_windows_web_app.this.name}-${azurerm_windows_web_app_slot.slot[count.index].name}"),
lower("${azurerm_windows_web_app.this.name}-${azurerm_windows_web_app_slot.slot[count.index].name}.scm")
]
depends_on = [
azurerm_windows_web_app_slot.slot
]
}

Просмотреть файл

@ -14,18 +14,18 @@ output "web_app_principal_id" {
value = azurerm_windows_web_app.this.identity.0.principal_id
}
output "web_app_slot_id" {
value = azurerm_windows_web_app_slot.slot.id
output "web_app_slot_ids" {
value = azurerm_windows_web_app_slot.slot.*.id
}
output "web_app_slot_name" {
value = azurerm_windows_web_app_slot.slot.name
output "web_app_slot_names" {
value = azurerm_windows_web_app_slot.slot.*.name
}
output "web_app_slot_hostname" {
value = azurerm_windows_web_app_slot.slot.default_hostname
output "web_app_slot_hostnames" {
value = azurerm_windows_web_app_slot.slot.*.default_hostname
}
output "web_app_slot_principal_id" {
value = azurerm_windows_web_app_slot.slot.identity.0.principal_id
output "web_app_slot_identities" {
value = azurerm_windows_web_app_slot.slot.*.identity
}

Просмотреть файл

@ -91,9 +91,12 @@ variable "service_plan_options" {
variable "webapp_options" {
type = object({
instrumentation_key = string
ai_connection_string = string
slots = list(string)
slots = list(string)
instrumentation_key = optional(string)
ai_connection_string = optional(string)
vnet_route_all_enabled = optional(bool)
use_32_bit_worker = optional(bool)
vnet_integration_enabled = optional(bool)
application_stack = object({
current_stack = string # required for windows
@ -112,7 +115,7 @@ variable "webapp_options" {
})
})
description = "The options for the app service"
description = "[Required] The options for the app service"
validation {
condition = contains(["dotnet", "dotnetcore", "java", "php", "python", "node"], var.webapp_options.application_stack.current_stack)

Просмотреть файл

@ -1,16 +1,18 @@
# bastion
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
# bastion
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.59.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules
@ -41,4 +43,4 @@ No modules.
| Name | Description |
|------|-------------|
| <a name="output_name"></a> [name](#output\_name) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -1,29 +1,32 @@
# openai
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~> 3.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >= 4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.26 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.72.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.28 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.105.0 |
## Modules
No modules.
| Name | Source | Version |
|------|--------|---------|
| <a name="module_private_endpoint"></a> [private\_endpoint](#module\_private\_endpoint) | ../../private-endpoint | n/a |
## Resources
| Name | Type |
|------|------|
| [azurecaf_name.caf_name_akv](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.caf_name_oai](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.priv_endpoint](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_cognitive_account.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cognitive_account) | resource |
| [azurerm_cognitive_deployment.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cognitive_deployment) | resource |
@ -34,21 +37,97 @@ No modules.
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | Name of the application. A corresponding tag would be created on the created resources if `var.default_tags_enabled` is `true`. | `string` | `""` | no |
| <a name="input_custom_subdomain_name"></a> [custom\_subdomain\_name](#input\_custom\_subdomain\_name) | The subdomain name used for token-based authentication. Changing this forces a new resource to be created. Leave this variable as default would use a default name with random suffix. | `string` | `null` | no |
| <a name="input_customer_managed_key"></a> [customer\_managed\_key](#input\_customer\_managed\_key) | type = object({<br> key\_vault\_key\_id = (Required) The ID of the Key Vault Key which should be used to Encrypt the data in this OpenAI Account.<br> identity\_client\_id = (Optional) The Client ID of the User Assigned Identity that has access to the key. This property only needs to be specified when there're multiple identities attached to the OpenAI Account.<br>}) | <pre>object({<br> key_vault_key_id = string<br> identity_client_id = optional(string)<br> })</pre> | `null` | no |
| <a name="input_deployment"></a> [deployment](#input\_deployment) | type = map(object({<br> name = (Required) The name of the Cognitive Services Account Deployment. Changing this forces a new resource to be created.<br> cognitive\_account\_id = (Required) The ID of the Cognitive Services Account. Changing this forces a new resource to be created.<br> model = {<br> model\_format = (Required) The format of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created. Possible value is OpenAI.<br> model\_name = (Required) The name of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created.<br> model\_version = (Required) The version of Cognitive Services Account Deployment model.<br> }<br> scale = {<br> scale\_type = (Required) Deployment scale type. Possible value is Standard. Changing this forces a new resource to be created.<br> }<br> rai\_policy\_name = (Optional) The name of RAI policy. Changing this forces a new resource to be created.<br>})) | <pre>map(object({<br> name = string<br> model_format = string<br> model_name = string<br> model_version = string<br> scale_type = string<br> rai_policy_name = optional(string)<br> }))</pre> | `{}` | no |
| <a name="input_default_tags_enabled"></a> [default\_tags\_enabled](#input\_default\_tags\_enabled) | Determines whether or not default tags are applied to resources. If set to true, tags will be applied. If set to false, tags will not be applied. | `bool` | `false` | no |
| <a name="input_deployment"></a> [deployment](#input\_deployment) | type = map(object({<br> name = (Required) The name of the Cognitive Services Account Deployment. Changing this forces a new resource to be created.<br> cognitive\_account\_id = (Required) The ID of the Cognitive Services Account. Changing this forces a new resource to be created.<br> model\_format = (Required) The format of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created. Possible value is OpenAI.<br> model\_name = (Required) The name of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created.<br> model\_version = (Required) The version of Cognitive Services Account Deployment model.<br> sku\_name = (Required) The name of the SKU. Possible values are `Standard`, `GlobalBatch`, `GlobalStandard`, and `ProvisionedManaged<br> sku_tier = (Optional) The tier of the SKU. Possible values are `Free`, `Basic`, `Standard`, `Premium`, and `Enterprise`<br> <br> rai_policy_name = (Optional) The name of RAI policy. Changing this forces a new resource to be created.<br>}))<br>` | <pre>map(object({<br> name = string<br> model_format = string<br> model_name = string<br> model_version = string<br> rai_policy_name = optional(string)<br> sku_name = optional(string)<br> sku_tier = optional(string)<br> sku_size = optional(string)<br> sku_family = optional(string)<br> sku_capacity = optional(number)<br> }))</pre> | n/a | yes |
| <a name="input_diagnostic_setting"></a> [diagnostic\_setting](#input\_diagnostic\_setting) | A map of objects that represent the configuration for a diagnostic setting."<br>type = map(object({<br> name = (Required) Specifies the name of the diagnostic setting. Changing this forces a new resource to be created.<br> log\_analytics\_workspace\_id = (Optional) (Optional) Specifies the resource id of an Azure Log Analytics workspace where diagnostics data should be sent.<br> log\_analytics\_destination\_type = (Optional) Possible values are `AzureDiagnostics` and `Dedicated`. When set to Dedicated, logs sent to a Log Analytics workspace will go into resource specific tables, instead of the legacy `AzureDiagnostics` table.<br> eventhub\_name = (Optional) Specifies the name of the Event Hub where diagnostics data should be sent.<br> eventhub\_authorization\_rule\_id = (Optional) Specifies the resource id of an Event Hub Namespace Authorization Rule used to send diagnostics data.<br> storage\_account\_id = (Optional) Specifies the resource id of an Azure storage account where diagnostics data should be sent.<br> partner\_solution\_id = (Optional) The resource id of the market partner solution where diagnostics data should be sent. For potential partner integrations, click to learn more about partner integration.<br> audit\_log\_retention\_policy = (Optional) Specifies the retention policy for the audit log. This is a block with the following properties:<br> enabled = (Optional) Specifies whether the retention policy is enabled. If enabled, `days` must be a positive number.<br> days = (Optional) Specifies the number of days to retain trace logs. If `enabled` is set to `true`, this value must be set to a positive number.<br> request\_response\_log\_retention\_policy = (Optional) Specifies the retention policy for the request response log. This is a block with the following properties:<br> enabled = (Optional) Specifies whether the retention policy is enabled. If enabled, `days` must be a positive number.<br> days = (Optional) Specifies the number of days to retain trace logs. If `enabled` is set to `true`, this value must be set to a positive number.<br> trace\_log\_retention\_policy = (Optional) Specifies the retention policy for the trace log. This is a block with the following properties:<br> enabled = (Optional) Specifies whether the retention policy is enabled. If enabled, `days` must be a positive number.<br> days = (Optional) Specifies the number of days to retain trace logs. If `enabled` is set to `true`, this value must be set to a positive number.<br> metric\_retention\_policy = (Optional) Specifies the retention policy for the metric. This is a block with the following properties:<br> enabled = (Optional) Specifies whether the retention policy is enabled. If enabled, `days` must be a positive number.<br> days = (Optional) Specifies the number of days to retain trace logs. If `enabled` is set to `true`, this value must be set to a positive number.<br>})) | <pre>map(object({<br> name = string<br> log_analytics_workspace_id = optional(string)<br> log_analytics_destination_type = optional(string)<br> eventhub_name = optional(string)<br> eventhub_authorization_rule_id = optional(string)<br> storage_account_id = optional(string)<br> partner_solution_id = optional(string)<br> audit_log_retention_policy = optional(object({<br> enabled = optional(bool, true)<br> days = optional(number, 7)<br> }))<br> request_response_log_retention_policy = optional(object({<br> enabled = optional(bool, true)<br> days = optional(number, 7)<br> }))<br> trace_log_retention_policy = optional(object({<br> enabled = optional(bool, true)<br> days = optional(number, 7)<br> }))<br> metric_retention_policy = optional(object({<br> enabled = optional(bool, true)<br> days = optional(number, 7)<br> }))<br> }))</pre> | `{}` | no |
| <a name="input_dynamic_throttling_enabled"></a> [dynamic\_throttling\_enabled](#input\_dynamic\_throttling\_enabled) | Determines whether or not dynamic throttling is enabled. If set to `true`, dynamic throttling will be enabled. If set to `false`, dynamic throttling will not be enabled. | `bool` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | Environment of the application. A corresponding tag would be created on the created resources if `var.default_tags_enabled` is `true`. | `string` | `""` | no |
| <a name="input_fqdns"></a> [fqdns](#input\_fqdns) | List of FQDNs allowed for the Cognitive Account. | `list(string)` | `null` | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | Global settings for the naming convention module. | `any` | n/a | yes |
| <a name="input_identity"></a> [identity](#input\_identity) | type = object({<br> type = (Required) The type of the Identity. Possible values are `SystemAssigned`, `UserAssigned`, `SystemAssigned, UserAssigned`.<br> identity\_ids = (Optional) Specifies a list of User Assigned Managed Identity IDs to be assigned to this OpenAI Account.<br>}) | <pre>object({<br> type = string<br> identity_ids = optional(list(string))<br> })</pre> | `null` | no |
| <a name="input_identity"></a> [identity](#input\_identity) | type = object({<br> type = (Required) The type of the Identity. Possible values are `SystemAssigned`, `UserAssigned`, `SystemAssigned, UserAssigned`.<br> identity\_ids = (Optional) Specifies a list of User Assigned Managed Identity IDs to be assigned to this OpenAI Account.<br>}) | <pre>object({<br> type = string<br> identity_ids = optional(list(string))<br> })</pre> | <pre>{<br> "type": "SystemAssigned"<br>}</pre> | no |
| <a name="input_local_auth_enabled"></a> [local\_auth\_enabled](#input\_local\_auth\_enabled) | Whether local authentication methods is enabled for the Cognitive Account. Defaults to `true`. | `bool` | `true` | no |
| <a name="input_location"></a> [location](#input\_location) | Azure OpenAI deployment region. Set this variable to `null` would use resource group's location. | `string` | n/a | yes |
| <a name="input_network_acls"></a> [network\_acls](#input\_network\_acls) | type = set(object({<br> default\_action = (Required) The Default Action to use when no rules match from ip\_rules / virtual\_network\_rules. Possible values are `Allow` and `Deny`.<br> ip\_rules = (Optional) One or more IP Addresses, or CIDR Blocks which should be able to access the Cognitive Account.<br> virtual\_network\_rules = optional(set(object({<br> subnet\_id = (Required) The ID of a Subnet which should be able to access the OpenAI Account.<br> ignore\_missing\_vnet\_service\_endpoint = (Optional) Whether ignore missing vnet service endpoint or not. Default to `false`.<br> })))<br>})) | <pre>set(object({<br> default_action = string<br> ip_rules = optional(set(string))<br> virtual_network_rules = optional(set(object({<br> subnet_id = string<br> ignore_missing_vnet_service_endpoint = optional(bool, false)<br> })))<br> }))</pre> | `null` | no |
| <a name="input_outbound_network_access_restricted"></a> [outbound\_network\_access\_restricted](#input\_outbound\_network\_access\_restricted) | Whether outbound network access is restricted for the Cognitive Account. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_pe_private_link_subnet_id"></a> [pe\_private\_link\_subnet\_id](#input\_pe\_private\_link\_subnet\_id) | The ID of the Subnet which the Private Endpoint should be created in. Changing this forces a new resource to be created. | `string` | n/a | yes |
| <a name="input_pe_subresource"></a> [pe\_subresource](#input\_pe\_subresource) | A list of subresource names which the Private Endpoint is able to connect to. `subresource_names` corresponds to `group_id`. Possible values are detailed in the product [documentation](https://docs.microsoft.com/azure/private-link/private-endpoint-overview#private-link-resource) in the `Subresources` column. Changing this forces a new resource to be created. | `list(string)` | <pre>[<br> "account"<br>]</pre> | no |
| <a name="input_private_dns_zone"></a> [private\_dns\_zone](#input\_private\_dns\_zone) | The Private DNS Zone you'd like to use. | <pre>object({<br> id = string<br> name = string<br> resource_group_name = string<br> })</pre> | n/a | yes |
| <a name="input_public_network_access_enabled"></a> [public\_network\_access\_enabled](#input\_public\_network\_access\_enabled) | Whether public network access is allowed for the Cognitive Account. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Name of the azure resource group to use. The resource group must exist. | `string` | n/a | yes |
| <a name="input_sku_name"></a> [sku\_name](#input\_sku\_name) | Specifies the SKU Name for this Cognitive Service Account. Possible values are `F0`, `F1`, `S0`, `S`, `S1`, `S2`, `S3`, `S4`, `S5`, `S6`, `P0`, `P1`, `P2`, `E0` and `DC0`. Default to `S0`. | `string` | `"S0"` | no |
| <a name="input_sku_name"></a> [sku\_name](#input\_sku\_name) | Specifies the SKU Name for this Cognitive Service Account. Possible values are `F0`, `F1`, `S0`, `S`, `S1`, `S2`, `S3`, `S4`, `S5`, `S6`, `P0`, `P1`, `P2`, `E0` and `DC0`. Default to `S0`. | `string` | `"F0"` | no |
| <a name="input_storage"></a> [storage](#input\_storage) | type = list(object({<br> storage\_account\_id = (Required) Full resource id of a Microsoft.Storage resource.<br> identity\_client\_id = (Optional) The client ID of the managed identity associated with the storage resource.<br>})) | <pre>list(object({<br> storage_account_id = string<br> identity_client_id = optional(string)<br> }))</pre> | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
| <a name="input_tracing_tags_enabled"></a> [tracing\_tags\_enabled](#input\_tracing\_tags\_enabled) | Whether enable tracing tags that generated by BridgeCrew Yor. | `bool` | `false` | no |
| <a name="input_tracing_tags_prefix"></a> [tracing\_tags\_prefix](#input\_tracing\_tags\_prefix) | Default prefix for generated tracing tags | `string` | `"avm_"` | no |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_openai_endpoint"></a> [openai\_endpoint](#output\_openai\_endpoint) | The endpoint used to connect to the Cognitive Service Account. |
| <a name="output_openai_primary_key"></a> [openai\_primary\_key](#output\_openai\_primary\_key) | The primary access key for the Cognitive Service Account. |
| <a name="output_openai_secondary_key"></a> [openai\_secondary\_key](#output\_openai\_secondary\_key) | The secondary access key for the Cognitive Service Account. |
| <a name="output_openai_subdomain"></a> [openai\_subdomain](#output\_openai\_subdomain) | The subdomain used to connect to the Cognitive Service Account. |
<!-- END_TF_DOCS -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >= 4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >= 4.0 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_private_endpoint"></a> [private\_endpoint](#module\_private\_endpoint) | ../../private-endpoint | n/a |
## Resources
| Name | Type |
|------|------|
| [azurecaf_name.caf_name_oai](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.priv_endpoint](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_cognitive_account.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cognitive_account) | resource |
| [azurerm_cognitive_deployment.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cognitive_deployment) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | Name of the application. A corresponding tag would be created on the created resources if `var.default_tags_enabled` is `true`. | `string` | `""` | no |
| <a name="input_custom_subdomain_name"></a> [custom\_subdomain\_name](#input\_custom\_subdomain\_name) | The subdomain name used for token-based authentication. Changing this forces a new resource to be created. Leave this variable as default would use a default name with random suffix. | `string` | `null` | no |
| <a name="input_customer_managed_key"></a> [customer\_managed\_key](#input\_customer\_managed\_key) | type = object({<br> key\_vault\_key\_id = (Required) The ID of the Key Vault Key which should be used to Encrypt the data in this OpenAI Account.<br> identity\_client\_id = (Optional) The Client ID of the User Assigned Identity that has access to the key. This property only needs to be specified when there're multiple identities attached to the OpenAI Account.<br>}) | <pre>object({<br> key_vault_key_id = string<br> identity_client_id = optional(string)<br> })</pre> | `null` | no |
| <a name="input_default_tags_enabled"></a> [default\_tags\_enabled](#input\_default\_tags\_enabled) | Determines whether or not default tags are applied to resources. If set to true, tags will be applied. If set to false, tags will not be applied. | `bool` | `false` | no |
| <a name="input_deployment"></a> [deployment](#input\_deployment) | type = map(object({<br> name = (Required) The name of the Cognitive Services Account Deployment. Changing this forces a new resource to be created.<br> cognitive\_account\_id = (Required) The ID of the Cognitive Services Account. Changing this forces a new resource to be created.<br> model\_format = (Required) The format of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created. Possible value is OpenAI.<br> model\_name = (Required) The name of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created.<br> model\_version = (Required) The version of Cognitive Services Account Deployment model.<br> sku\_name = (Required) The name of the SKU. Possible values are `Standard`, `GlobalBatch`, `GlobalStandard`, and `ProvisionedManaged<br> sku_tier = (Optional) The tier of the SKU. Possible values are `Free`, `Basic`, `Standard`, `Premium`, and `Enterprise`<br> <br> rai_policy_name = (Optional) The name of RAI policy. Changing this forces a new resource to be created.<br>}))<br>` | <pre>map(object({<br> name = string<br> model_format = string<br> model_name = string<br> model_version = optional(string)<br> rai_policy_name = optional(string)<br> sku_name = string<br> sku_tier = optional(string)<br> sku_size = optional(string)<br> sku_family = optional(string)<br> sku_capacity = optional(number)<br> }))</pre> | <pre>{<br> "default_deployment": {<br> "model_format": "OpenAI",<br> "model_name": "gpt-35-turbo",<br> "name": "default",<br> "sku_name": "Standard"<br> }<br>}</pre> | no |
| <a name="input_diagnostic_setting"></a> [diagnostic\_setting](#input\_diagnostic\_setting) | A map of objects that represent the configuration for a diagnostic setting."<br>type = map(object({<br> name = (Required) Specifies the name of the diagnostic setting. Changing this forces a new resource to be created.<br> log\_analytics\_workspace\_id = (Optional) (Optional) Specifies the resource id of an Azure Log Analytics workspace where diagnostics data should be sent.<br> log\_analytics\_destination\_type = (Optional) Possible values are `AzureDiagnostics` and `Dedicated`. When set to Dedicated, logs sent to a Log Analytics workspace will go into resource specific tables, instead of the legacy `AzureDiagnostics` table.<br> eventhub\_name = (Optional) Specifies the name of the Event Hub where diagnostics data should be sent.<br> eventhub\_authorization\_rule\_id = (Optional) Specifies the resource id of an Event Hub Namespace Authorization Rule used to send diagnostics data.<br> storage\_account\_id = (Optional) Specifies the resource id of an Azure storage account where diagnostics data should be sent.<br> partner\_solution\_id = (Optional) The resource id of the market partner solution where diagnostics data should be sent. For potential partner integrations, click to learn more about partner integration.<br> audit\_log\_retention\_policy = (Optional) Specifies the retention policy for the audit log. This is a block with the following properties:<br> enabled = (Optional) Specifies whether the retention policy is enabled. If enabled, `days` must be a positive number.<br> days = (Optional) Specifies the number of days to retain trace logs. If `enabled` is set to `true`, this value must be set to a positive number.<br> request\_response\_log\_retention\_policy = (Optional) Specifies the retention policy for the request response log. This is a block with the following properties:<br> enabled = (Optional) Specifies whether the retention policy is enabled. If enabled, `days` must be a positive number.<br> days = (Optional) Specifies the number of days to retain trace logs. If `enabled` is set to `true`, this value must be set to a positive number.<br> trace\_log\_retention\_policy = (Optional) Specifies the retention policy for the trace log. This is a block with the following properties:<br> enabled = (Optional) Specifies whether the retention policy is enabled. If enabled, `days` must be a positive number.<br> days = (Optional) Specifies the number of days to retain trace logs. If `enabled` is set to `true`, this value must be set to a positive number.<br> metric\_retention\_policy = (Optional) Specifies the retention policy for the metric. This is a block with the following properties:<br> enabled = (Optional) Specifies whether the retention policy is enabled. If enabled, `days` must be a positive number.<br> days = (Optional) Specifies the number of days to retain trace logs. If `enabled` is set to `true`, this value must be set to a positive number.<br>})) | <pre>map(object({<br> name = string<br> log_analytics_workspace_id = optional(string)<br> log_analytics_destination_type = optional(string)<br> eventhub_name = optional(string)<br> eventhub_authorization_rule_id = optional(string)<br> storage_account_id = optional(string)<br> partner_solution_id = optional(string)<br> audit_log_retention_policy = optional(object({<br> enabled = optional(bool, true)<br> days = optional(number, 7)<br> }))<br> request_response_log_retention_policy = optional(object({<br> enabled = optional(bool, true)<br> days = optional(number, 7)<br> }))<br> trace_log_retention_policy = optional(object({<br> enabled = optional(bool, true)<br> days = optional(number, 7)<br> }))<br> metric_retention_policy = optional(object({<br> enabled = optional(bool, true)<br> days = optional(number, 7)<br> }))<br> }))</pre> | `{}` | no |
| <a name="input_dynamic_throttling_enabled"></a> [dynamic\_throttling\_enabled](#input\_dynamic\_throttling\_enabled) | Determines whether or not dynamic throttling is enabled. If set to `true`, dynamic throttling will be enabled. If set to `false`, dynamic throttling will not be enabled. | `bool` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | Environment of the application. A corresponding tag would be created on the created resources if `var.default_tags_enabled` is `true`. | `string` | `""` | no |
| <a name="input_fqdns"></a> [fqdns](#input\_fqdns) | List of FQDNs allowed for the Cognitive Account. | `list(string)` | `null` | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | Global settings for the naming convention module. | `any` | n/a | yes |
| <a name="input_identity"></a> [identity](#input\_identity) | type = object({<br> type = (Required) The type of the Identity. Possible values are `SystemAssigned`, `UserAssigned`, `SystemAssigned, UserAssigned`.<br> identity\_ids = (Optional) Specifies a list of User Assigned Managed Identity IDs to be assigned to this OpenAI Account.<br>}) | <pre>object({<br> type = string<br> identity_ids = optional(list(string))<br> })</pre> | <pre>{<br> "type": "SystemAssigned"<br>}</pre> | no |
| <a name="input_local_auth_enabled"></a> [local\_auth\_enabled](#input\_local\_auth\_enabled) | Whether local authentication methods is enabled for the Cognitive Account. Defaults to `true`. | `bool` | `true` | no |
| <a name="input_location"></a> [location](#input\_location) | Azure OpenAI deployment region. Set this variable to `null` would use resource group's location. | `string` | n/a | yes |
| <a name="input_network_acls"></a> [network\_acls](#input\_network\_acls) | type = set(object({<br> default\_action = (Required) The Default Action to use when no rules match from ip\_rules / virtual\_network\_rules. Possible values are `Allow` and `Deny`.<br> ip\_rules = (Optional) One or more IP Addresses, or CIDR Blocks which should be able to access the Cognitive Account.<br> virtual\_network\_rules = optional(set(object({<br> subnet\_id = (Required) The ID of a Subnet which should be able to access the OpenAI Account.<br> ignore\_missing\_vnet\_service\_endpoint = (Optional) Whether ignore missing vnet service endpoint or not. Default to `false`.<br> })))<br>})) | <pre>set(object({<br> default_action = string<br> ip_rules = optional(set(string))<br> virtual_network_rules = optional(set(object({<br> subnet_id = string<br> ignore_missing_vnet_service_endpoint = optional(bool, false)<br> })))<br> }))</pre> | `null` | no |
| <a name="input_outbound_network_access_restricted"></a> [outbound\_network\_access\_restricted](#input\_outbound\_network\_access\_restricted) | Whether outbound network access is restricted for the Cognitive Account. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_pe_private_link_subnet_id"></a> [pe\_private\_link\_subnet\_id](#input\_pe\_private\_link\_subnet\_id) | The ID of the Subnet which the Private Endpoint should be created in. Changing this forces a new resource to be created. | `string` | n/a | yes |
| <a name="input_pe_subresource"></a> [pe\_subresource](#input\_pe\_subresource) | A list of subresource names which the Private Endpoint is able to connect to. `subresource_names` corresponds to `group_id`. Possible values are detailed in the product [documentation](https://docs.microsoft.com/azure/private-link/private-endpoint-overview#private-link-resource) in the `Subresources` column. Changing this forces a new resource to be created. | `list(string)` | <pre>[<br> "account"<br>]</pre> | no |
| <a name="input_private_dns_zone"></a> [private\_dns\_zone](#input\_private\_dns\_zone) | The Private DNS Zone you'd like to use. | <pre>object({<br> id = string<br> name = string<br> resource_group_name = string<br> })</pre> | n/a | yes |
| <a name="input_public_network_access_enabled"></a> [public\_network\_access\_enabled](#input\_public\_network\_access\_enabled) | Whether public network access is allowed for the Cognitive Account. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Name of the azure resource group to use. The resource group must exist. | `string` | n/a | yes |
| <a name="input_sku_name"></a> [sku\_name](#input\_sku\_name) | Specifies the SKU Name for this Cognitive Service Account. Possible values are `F0`, `F1`, `S0`, `S`, `S1`, `S2`, `S3`, `S4`, `S5`, `S6`, `P0`, `P1`, `P2`, `E0` and `DC0`. Default to `S0`. | `string` | `"F0"` | no |
| <a name="input_storage"></a> [storage](#input\_storage) | type = list(object({<br> storage\_account\_id = (Required) Full resource id of a Microsoft.Storage resource.<br> identity\_client\_id = (Optional) The client ID of the managed identity associated with the storage resource.<br>})) | <pre>list(object({<br> storage_account_id = string<br> identity_client_id = optional(string)<br> }))</pre> | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
| <a name="input_tracing_tags_enabled"></a> [tracing\_tags\_enabled](#input\_tracing\_tags\_enabled) | Whether enable tracing tags that generated by BridgeCrew Yor. | `bool` | `false` | no |
| <a name="input_tracing_tags_prefix"></a> [tracing\_tags\_prefix](#input\_tracing\_tags\_prefix) | Default prefix for generated tracing tags | `string` | `"avm_"` | no |
## Outputs

Просмотреть файл

@ -4,7 +4,7 @@ terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
version = ">= 4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"

Просмотреть файл

@ -78,8 +78,13 @@ resource "azurerm_cognitive_deployment" "this" {
name = each.value.model_name
version = each.value.model_version
}
scale {
type = each.value.scale_type
sku {
name = each.value.sku_name
tier = each.value.sku_tier
size = each.value.sku_size
family = each.value.sku_family
capacity = each.value.sku_capacity
}
}

Просмотреть файл

@ -46,23 +46,33 @@ variable "deployment" {
name = string
model_format = string
model_name = string
model_version = string
scale_type = string
model_version = optional(string)
rai_policy_name = optional(string)
sku_name = string
sku_tier = optional(string)
sku_size = optional(string)
sku_family = optional(string)
sku_capacity = optional(number)
}))
default = {}
default = {
default_deployment = {
name = "default"
model_format = "OpenAI"
model_name = "gpt-35-turbo"
sku_name = "Standard"
}
}
description = <<-DESCRIPTION
type = map(object({
name = (Required) The name of the Cognitive Services Account Deployment. Changing this forces a new resource to be created.
cognitive_account_id = (Required) The ID of the Cognitive Services Account. Changing this forces a new resource to be created.
model = {
model_format = (Required) The format of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created. Possible value is OpenAI.
model_name = (Required) The name of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created.
model_version = (Required) The version of Cognitive Services Account Deployment model.
}
scale = {
scale_type = (Required) Deployment scale type. Possible value is Standard. Changing this forces a new resource to be created.
}
model_format = (Required) The format of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created. Possible value is OpenAI.
model_name = (Required) The name of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created.
model_version = (Required) The version of Cognitive Services Account Deployment model.
sku_name = (Required) The name of the SKU. Possible values are `Standard`, `GlobalBatch`, `GlobalStandard`, and `ProvisionedManaged
sku_tier = (Optional) The tier of the SKU. Possible values are `Free`, `Basic`, `Standard`, `Premium`, and `Enterprise`
rai_policy_name = (Optional) The name of RAI policy. Changing this forces a new resource to be created.
}))
DESCRIPTION
@ -92,7 +102,7 @@ variable "identity" {
type = string
identity_ids = optional(list(string))
})
default = {
default = {
type = "SystemAssigned"
}
description = <<-DESCRIPTION
@ -144,7 +154,7 @@ variable "pe_subresource" {
}
variable "pe_private_link_subnet_id" {
type = string
type = string
description = "The ID of the Subnet which the Private Endpoint should be created in. Changing this forces a new resource to be created."
}
@ -208,7 +218,7 @@ variable "public_network_access_enabled" {
variable "sku_name" {
type = string
default = "S0"
default = "F0"
description = "Specifies the SKU Name for this Cognitive Service Account. Possible values are `F0`, `F1`, `S0`, `S`, `S1`, `S2`, `S3`, `S4`, `S5`, `S6`, `P0`, `P1`, `P2`, `E0` and `DC0`. Default to `S0`."
}

Просмотреть файл

@ -3,14 +3,16 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.59.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -3,14 +3,16 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.60.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules

Просмотреть файл

@ -1,46 +1,46 @@
# endpoint
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.60.0 |
| <a name="provider_null"></a> [null](#provider\_null) | 3.2.1 |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [azurerm_cdn_frontdoor_endpoint.web_app](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cdn_frontdoor_endpoint) | resource |
| [azurerm_cdn_frontdoor_origin.web_app](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cdn_frontdoor_origin) | resource |
| [azurerm_cdn_frontdoor_origin_group.web_app](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cdn_frontdoor_origin_group) | resource |
| [azurerm_cdn_frontdoor_route.web_app](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cdn_frontdoor_route) | resource |
| [null_resource.web_app](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_endpoint_name"></a> [endpoint\_name](#input\_endpoint\_name) | The name of the front door endpoint. | `string` | n/a | yes |
| <a name="input_frontdoor_profile_id"></a> [frontdoor\_profile\_id](#input\_frontdoor\_profile\_id) | The front door profile id | `string` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | The Azure region of the web app | `string` | n/a | yes |
| <a name="input_private_link_target_type"></a> [private\_link\_target\_type](#input\_private\_link\_target\_type) | The private link target type | `string` | n/a | yes |
| <a name="input_web_app_hostname"></a> [web\_app\_hostname](#input\_web\_app\_hostname) | The web app hostname | `string` | n/a | yes |
| <a name="input_web_app_id"></a> [web\_app\_id](#input\_web\_app\_id) | The web app id | `string` | n/a | yes |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_cdn_frontdoor_endpoint_id"></a> [cdn\_frontdoor\_endpoint\_id](#output\_cdn\_frontdoor\_endpoint\_id) | n/a |
| <a name="output_cdn_frontdoor_endpoint_uri"></a> [cdn\_frontdoor\_endpoint\_uri](#output\_cdn\_frontdoor\_endpoint\_uri) | n/a |
## Requirements
No requirements.
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | n/a |
| <a name="provider_null"></a> [null](#provider\_null) | n/a |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [azurerm_cdn_frontdoor_endpoint.web_app](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cdn_frontdoor_endpoint) | resource |
| [azurerm_cdn_frontdoor_origin.web_app](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cdn_frontdoor_origin) | resource |
| [azurerm_cdn_frontdoor_origin_group.web_app](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cdn_frontdoor_origin_group) | resource |
| [azurerm_cdn_frontdoor_route.web_app](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cdn_frontdoor_route) | resource |
| [null_resource.web_app](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_endpoint_name"></a> [endpoint\_name](#input\_endpoint\_name) | The name of the front door endpoint. | `string` | n/a | yes |
| <a name="input_frontdoor_profile_id"></a> [frontdoor\_profile\_id](#input\_frontdoor\_profile\_id) | The front door profile id | `string` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | The Azure region of the web app | `string` | n/a | yes |
| <a name="input_private_link_target_type"></a> [private\_link\_target\_type](#input\_private\_link\_target\_type) | The private link target type | `string` | n/a | yes |
| <a name="input_web_app_hostname"></a> [web\_app\_hostname](#input\_web\_app\_hostname) | The web app hostname | `string` | n/a | yes |
| <a name="input_web_app_id"></a> [web\_app\_id](#input\_web\_app\_id) | The web app id | `string` | n/a | yes |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_cdn_frontdoor_endpoint_id"></a> [cdn\_frontdoor\_endpoint\_id](#output\_cdn\_frontdoor\_endpoint\_id) | n/a |
| <a name="output_cdn_frontdoor_endpoint_uri"></a> [cdn\_frontdoor\_endpoint\_uri](#output\_cdn\_frontdoor\_endpoint\_uri) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -1,16 +1,74 @@
# key-vault
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.60.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.28 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 4.5.0 |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [azurecaf_name.caf_name_akv](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.private_endpoint](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_key_vault.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) | resource |
| [azurerm_private_dns_a_record.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_a_record) | resource |
| [azurerm_private_endpoint.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) | resource |
| [azurerm_role_assignment.secrets_officer](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.secrets_user](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | The name of your application | `string` | n/a | yes |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment (dev, test, prod...) | `string` | `"dev"` | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | Global settings for the naming convention module. | `any` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | The Azure region where all resources in this example should be created | `string` | `"westus2"` | no |
| <a name="input_private_dns_zone"></a> [private\_dns\_zone](#input\_private\_dns\_zone) | The private dns zone id where the app service will be integrated | <pre>object({<br> id = string<br> name = string<br> resource_group_name = string<br> })</pre> | n/a | yes |
| <a name="input_private_link_subnet_id"></a> [private\_link\_subnet\_id](#input\_private\_link\_subnet\_id) | The subnet id | `string` | n/a | yes |
| <a name="input_resource_group"></a> [resource\_group](#input\_resource\_group) | The name of the resource group where all resources in this example should be created. | `string` | n/a | yes |
| <a name="input_secret_officer_identities"></a> [secret\_officer\_identities](#input\_secret\_officer\_identities) | The list of identities that will be granted secret officer permissions | `list(string)` | `[]` | no |
| <a name="input_secret_reader_identities"></a> [secret\_reader\_identities](#input\_secret\_reader\_identities) | The list of identities that will be granted secret reader permissions | `list(string)` | n/a | yes |
| <a name="input_sku_name"></a> [sku\_name](#input\_sku\_name) | The sku name for the app service plan | `string` | `"standard"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
| <a name="input_tenant_id"></a> [tenant\_id](#input\_tenant\_id) | The Azure AD tenant ID for the identities. If no value provided, will use current deployment environment tenant. | `string` | `null` | no |
| <a name="input_unique_id"></a> [unique\_id](#input\_unique\_id) | The unique id | `string` | n/a | yes |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_vault_name"></a> [vault\_name](#output\_vault\_name) | n/a |
| <a name="output_vault_uri"></a> [vault\_uri](#output\_vault\_uri) | n/a |
<!-- END_TF_DOCS -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules
@ -51,6 +109,7 @@ No modules.
| Name | Description |
|------|-------------|
| <a name="output_vault_id"></a> [vault\_id](#output\_vault\_id) | n/a |
| <a name="output_vault_name"></a> [vault\_name](#output\_vault\_name) | n/a |
| <a name="output_vault_uri"></a> [vault\_uri](#output\_vault\_uri) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -4,4 +4,8 @@ output "vault_uri" {
output "vault_name" {
value = azurerm_key_vault.this.name
}
output "vault_id" {
value = azurerm_key_vault.this.id
}

Просмотреть файл

@ -3,14 +3,16 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.59.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -20,22 +20,23 @@ resource "azurerm_virtual_network" "this" {
}
resource "azurerm_subnet" "this" {
count = length(var.subnets)
for_each = { for idx, subnet in var.subnets : subnet.name => subnet if subnet != null }
name = var.subnets[count.index].name
address_prefixes = var.subnets[count.index].subnet_cidr
name = each.key
address_prefixes = each.value.subnet_cidr
resource_group_name = var.resource_group
virtual_network_name = azurerm_virtual_network.this.name
dynamic "delegation" {
for_each = var.subnets[count.index].delegation == null ? [] : [var.subnets[count.index].delegation]
for_each = each.value.delegation == null ? [] : [each.value.delegation]
content {
name = var.subnets[count.index].delegation.name
name = delegation.value.name
service_delegation {
name = var.subnets[count.index].delegation.service_delegation.name
actions = var.subnets[count.index].delegation.service_delegation.actions
name = delegation.value.service_delegation.name
actions = delegation.value.service_delegation.actions
}
}
}

Просмотреть файл

@ -1,19 +1,19 @@
# openai
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~> 3.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >= 4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.26 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.72.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.28 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 4.5.0 |
## Modules
@ -52,6 +52,65 @@ No modules.
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_openai_endpoint"></a> [openai\_endpoint](#output\_openai\_endpoint) | The endpoint used to connect to the Cognitive Service Account. |
| <a name="output_openai_primary_key"></a> [openai\_primary\_key](#output\_openai\_primary\_key) | The primary access key for the Cognitive Service Account. |
| <a name="output_openai_secondary_key"></a> [openai\_secondary\_key](#output\_openai\_secondary\_key) | The secondary access key for the Cognitive Service Account. |
| <a name="output_openai_subdomain"></a> [openai\_subdomain](#output\_openai\_subdomain) | The subdomain used to connect to the Cognitive Service Account. |
<!-- END_TF_DOCS -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >= 4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >= 4.0 |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [azurecaf_name.caf_name_oai](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_cognitive_account.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cognitive_account) | resource |
| [azurerm_cognitive_deployment.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cognitive_deployment) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | Name of the application. A corresponding tag would be created on the created resources if `var.default_tags_enabled` is `true`. | `string` | `""` | no |
| <a name="input_custom_subdomain_name"></a> [custom\_subdomain\_name](#input\_custom\_subdomain\_name) | The subdomain name used for token-based authentication. Changing this forces a new resource to be created. Leave this variable as default would use a default name with random suffix. | `string` | `null` | no |
| <a name="input_customer_managed_key"></a> [customer\_managed\_key](#input\_customer\_managed\_key) | type = object({<br> key\_vault\_key\_id = (Required) The ID of the Key Vault Key which should be used to Encrypt the data in this OpenAI Account.<br> identity\_client\_id = (Optional) The Client ID of the User Assigned Identity that has access to the key. This property only needs to be specified when there're multiple identities attached to the OpenAI Account.<br>}) | <pre>object({<br> key_vault_key_id = string<br> identity_client_id = optional(string)<br> })</pre> | `null` | no |
| <a name="input_deployment"></a> [deployment](#input\_deployment) | type = map(object({<br> name = (Required) The name of the Cognitive Services Account Deployment. Changing this forces a new resource to be created.<br> cognitive\_account\_id = (Required) The ID of the Cognitive Services Account. Changing this forces a new resource to be created.<br> model = {<br> model\_format = (Required) The format of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created. Possible value is OpenAI.<br> model\_name = (Required) The name of the Cognitive Services Account Deployment model. Changing this forces a new resource to be created.<br> model\_version = (Required) The version of Cognitive Services Account Deployment model.<br> }<br> scale = {<br> scale\_type = (Required) Deployment scale type. Possible value is Standard. Changing this forces a new resource to be created.<br> }<br> rai\_policy\_name = (Optional) The name of RAI policy. Changing this forces a new resource to be created.<br>})) | <pre>map(object({<br> name = string<br> model_format = string<br> model_name = string<br> model_version = string<br> scale_type = string<br> rai_policy_name = optional(string)<br> }))</pre> | `{}` | no |
| <a name="input_dynamic_throttling_enabled"></a> [dynamic\_throttling\_enabled](#input\_dynamic\_throttling\_enabled) | Determines whether or not dynamic throttling is enabled. If set to `true`, dynamic throttling will be enabled. If set to `false`, dynamic throttling will not be enabled. | `bool` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | Environment of the application. A corresponding tag would be created on the created resources if `var.default_tags_enabled` is `true`. | `string` | `""` | no |
| <a name="input_fqdns"></a> [fqdns](#input\_fqdns) | List of FQDNs allowed for the Cognitive Account. | `list(string)` | `null` | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | Global settings for the naming convention module. | `any` | n/a | yes |
| <a name="input_identity"></a> [identity](#input\_identity) | type = object({<br> type = (Required) The type of the Identity. Possible values are `SystemAssigned`, `UserAssigned`, `SystemAssigned, UserAssigned`.<br> identity\_ids = (Optional) Specifies a list of User Assigned Managed Identity IDs to be assigned to this OpenAI Account.<br>}) | <pre>object({<br> type = string<br> identity_ids = optional(list(string))<br> })</pre> | `null` | no |
| <a name="input_local_auth_enabled"></a> [local\_auth\_enabled](#input\_local\_auth\_enabled) | Whether local authentication methods is enabled for the Cognitive Account. Defaults to `true`. | `bool` | `true` | no |
| <a name="input_location"></a> [location](#input\_location) | Azure OpenAI deployment region. Set this variable to `null` would use resource group's location. | `string` | n/a | yes |
| <a name="input_network_acls"></a> [network\_acls](#input\_network\_acls) | type = set(object({<br> default\_action = (Required) The Default Action to use when no rules match from ip\_rules / virtual\_network\_rules. Possible values are `Allow` and `Deny`.<br> ip\_rules = (Optional) One or more IP Addresses, or CIDR Blocks which should be able to access the Cognitive Account.<br> virtual\_network\_rules = optional(set(object({<br> subnet\_id = (Required) The ID of a Subnet which should be able to access the OpenAI Account.<br> ignore\_missing\_vnet\_service\_endpoint = (Optional) Whether ignore missing vnet service endpoint or not. Default to `false`.<br> })))<br>})) | <pre>set(object({<br> default_action = string<br> ip_rules = optional(set(string))<br> virtual_network_rules = optional(set(object({<br> subnet_id = string<br> ignore_missing_vnet_service_endpoint = optional(bool, false)<br> })))<br> }))</pre> | `null` | no |
| <a name="input_outbound_network_access_restricted"></a> [outbound\_network\_access\_restricted](#input\_outbound\_network\_access\_restricted) | Whether outbound network access is restricted for the Cognitive Account. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_public_network_access_enabled"></a> [public\_network\_access\_enabled](#input\_public\_network\_access\_enabled) | Whether public network access is allowed for the Cognitive Account. Defaults to `false`. | `bool` | `false` | no |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | Name of the azure resource group to use. The resource group must exist. | `string` | n/a | yes |
| <a name="input_sku_name"></a> [sku\_name](#input\_sku\_name) | Specifies the SKU Name for this Cognitive Service Account. Possible values are `F0`, `F1`, `S0`, `S`, `S1`, `S2`, `S3`, `S4`, `S5`, `S6`, `P0`, `P1`, `P2`, `E0` and `DC0`. Default to `S0`. | `string` | `"S0"` | no |
| <a name="input_storage"></a> [storage](#input\_storage) | type = list(object({<br> storage\_account\_id = (Required) Full resource id of a Microsoft.Storage resource.<br> identity\_client\_id = (Optional) The client ID of the managed identity associated with the storage resource.<br>})) | <pre>list(object({<br> storage_account_id = string<br> identity_client_id = optional(string)<br> }))</pre> | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_openai_endpoint"></a> [openai\_endpoint](#output\_openai\_endpoint) | The endpoint used to connect to the Cognitive Service Account. |

Просмотреть файл

@ -4,7 +4,7 @@ terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
version = ">= 4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"

Просмотреть файл

@ -1,4 +1,4 @@
resource "azurecaf_name" "caf_name_akv" {
resource "azurecaf_name" "caf_name_oai" {
name = var.application_name
resource_type = "azurerm_cognitive_account"
prefixes = var.global_settings.prefixes
@ -10,13 +10,14 @@ resource "azurecaf_name" "caf_name_akv" {
use_slug = var.global_settings.use_slug
}
resource "azurerm_cognitive_account" "this" {
kind = "OpenAI"
location = var.location
name = azurecaf_name.caf_name_akv.result
name = azurecaf_name.caf_name_oai.result
resource_group_name = var.resource_group_name
sku_name = var.sku_name
custom_subdomain_name = var.custom_subdomain_name
custom_subdomain_name = coalesce(var.custom_subdomain_name, azurecaf_name.caf_name_oai.result)
dynamic_throttling_enabled = var.dynamic_throttling_enabled
fqdns = var.fqdns
local_auth_enabled = var.local_auth_enabled
@ -37,14 +38,15 @@ resource "azurerm_cognitive_account" "this" {
identity_ids = identity.value.identity_ids
}
}
dynamic "network_acls" {
for_each = var.network_acls != null ? [var.network_acls] : []
for_each = var.network_acls != null ? var.network_acls : []
content {
default_action = network_acls.value.default_action
ip_rules = network_acls.value.ip_rules
ip_rules = lookup(network_acls.value, "ip_rules", null)
dynamic "virtual_network_rules" {
for_each = network_acls.value.virtual_network_rules != null ? network_acls.value.virtual_network_rules : []
for_each = lookup(network_acls.value, "virtual_network_rules", [])
content {
subnet_id = virtual_network_rules.value.subnet_id
ignore_missing_vnet_service_endpoint = virtual_network_rules.value.ignore_missing_vnet_service_endpoint
@ -52,6 +54,7 @@ resource "azurerm_cognitive_account" "this" {
}
}
}
dynamic "storage" {
for_each = var.storage
content {
@ -75,7 +78,12 @@ resource "azurerm_cognitive_deployment" "this" {
name = each.value.model_name
version = each.value.model_version
}
scale {
type = each.value.scale_type
sku {
name = each.value.sku_name
tier = each.value.sku_tier
size = coalesce(each.value.sku_size, null)
family = coalesce(each.value.sku_family, null)
capacity = coalesce(each.value.sku_capacity, null)
}
}
}

Просмотреть файл

@ -3,13 +3,15 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.59.0 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -3,13 +3,15 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.59.0 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -8,8 +8,9 @@ resource "azurerm_private_endpoint" "this" {
private_service_connection {
name = var.name
private_connection_resource_id = var.private_connection_resource_id
subresource_names = var.subresource_names
is_manual_connection = false
subresource_names = var.subresource_names
is_manual_connection = false
}
tags = local.tags

Просмотреть файл

@ -3,14 +3,16 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.60.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -17,12 +17,12 @@ resource "azurerm_redis_cache" "this" {
capacity = 2
family = "C"
sku_name = var.sku_name
enable_non_ssl_port = false
non_ssl_port_enabled = false
minimum_tls_version = "1.2"
public_network_access_enabled = false
redis_configuration {
enable_authentication = true
authentication_enabled = true
}
tags = local.tags

Просмотреть файл

@ -1,16 +1,19 @@
# sql-database
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.60.0 |
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | 3.0.2 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.28 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 4.5.0 |
## Modules
@ -26,14 +29,15 @@ No modules.
| [azurerm_mssql_server.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server) | resource |
| [azurerm_private_dns_a_record.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_a_record) | resource |
| [azurerm_private_endpoint.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) | resource |
| [azuread_group.sql_admin_group](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | The name of your application | `string` | n/a | yes |
| <a name="input_entra_admin_group_name"></a> [entra\_admin\_group\_name](#input\_entra\_admin\_group\_name) | n/a | `string` | n/a | yes |
| <a name="input_entra_admin_group_object_id"></a> [entra\_admin\_group\_object\_id](#input\_entra\_admin\_group\_object\_id) | n/a | `string` | n/a | yes |
| <a name="input_entra_admin_group_name"></a> [entra\_admin\_group\_name](#input\_entra\_admin\_group\_name) | n/a | `string` | `null` | no |
| <a name="input_entra_admin_group_object_id"></a> [entra\_admin\_group\_object\_id](#input\_entra\_admin\_group\_object\_id) | n/a | `string` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment (dev, test, prod...) | `string` | `"dev"` | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | Global settings for the naming convention module. | `any` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | The Azure region where all resources in this example should be created | `string` | `"westus2"` | no |
@ -47,6 +51,64 @@ No modules.
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_sql_db_connection_string"></a> [sql\_db\_connection\_string](#output\_sql\_db\_connection\_string) | n/a |
| <a name="output_sql_db_name"></a> [sql\_db\_name](#output\_sql\_db\_name) | n/a |
| <a name="output_sql_server_name"></a> [sql\_server\_name](#output\_sql\_server\_name) | n/a |
<!-- END_TF_DOCS -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [azurecaf_name.caf_name_sqlserver](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurecaf_name.private_endpoint](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_key_vault_secret.sql_admin_password](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource |
| [azurerm_mssql_database.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_database) | resource |
| [azurerm_mssql_server.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server) | resource |
| [azurerm_private_dns_a_record.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_a_record) | resource |
| [azurerm_private_endpoint.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) | resource |
| [random_password.sql_admin_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_administrator_login"></a> [administrator\_login](#input\_administrator\_login) | The administrator login for the SQL Server | `string` | `null` | no |
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | The name of your application | `string` | n/a | yes |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment (dev, test, prod...) | `string` | `"dev"` | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | Global settings for the naming convention module. | `any` | n/a | yes |
| <a name="input_key_vault_id"></a> [key\_vault\_id](#input\_key\_vault\_id) | The id of the key vault where the password will be stored | `string` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | The Azure region where all resources in this example should be created | `string` | `"westus2"` | no |
| <a name="input_private_dns_zone"></a> [private\_dns\_zone](#input\_private\_dns\_zone) | The private dns zone id where the app service will be integrated | <pre>object({<br> id = string<br> name = string<br> resource_group_name = string<br> })</pre> | n/a | yes |
| <a name="input_private_link_subnet_id"></a> [private\_link\_subnet\_id](#input\_private\_link\_subnet\_id) | The subnet id where the SQL database will be integrated | `string` | n/a | yes |
| <a name="input_resource_group"></a> [resource\_group](#input\_resource\_group) | The name of the resource group where all resources in this example should be created. | `string` | n/a | yes |
| <a name="input_sql_databases"></a> [sql\_databases](#input\_sql\_databases) | The list of SQL databases to be created | <pre>list(object({<br> name = string<br> sku_name = string<br> }))</pre> | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
| <a name="input_tenant_id"></a> [tenant\_id](#input\_tenant\_id) | The tenant id where the resources will be created | `string` | n/a | yes |
| <a name="input_unique_id"></a> [unique\_id](#input\_unique\_id) | A unique identifier | `string` | n/a | yes |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_sql_db_connection_string"></a> [sql\_db\_connection\_string](#output\_sql\_db\_connection\_string) | n/a |

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -10,6 +10,22 @@ resource "azurecaf_name" "caf_name_sqlserver" {
use_slug = var.global_settings.use_slug
}
# data "azurerm_client_config" "current" { }
# data "azuread_user" "current_user" {
# object_id = data.azurerm_client_config.current.object_id
# }
resource "random_password" "sql_admin_password" {
length = 16
special = true
}
resource "azurerm_key_vault_secret" "sql_admin_password" {
name = "sql-admin-password"
value = random_password.sql_admin_password.result
key_vault_id = var.key_vault_id
}
# Create the SQL Server
resource "azurerm_mssql_server" "this" {
@ -23,12 +39,14 @@ resource "azurerm_mssql_server" "this" {
tags = local.tags
azuread_administrator {
login_username = var.entra_admin_group_name
object_id = var.entra_admin_group_object_id
azuread_authentication_only = true
tenant_id = var.tenant_id
}
administrator_login = var.administrator_login == null ? "sqladmin" : var.administrator_login
administrator_login_password = azurerm_key_vault_secret.sql_admin_password.value
# azuread_administrator {
# login_username = data.azuread_user.current_user.display_name
# object_id = data.azurerm_client_config.current.object_id
# azuread_authentication_only = true
# tenant_id = var.tenant_id
# }
}
# Create a the SQL database

Просмотреть файл

@ -1,3 +1,14 @@
variable "administrator_login" {
type = string
description = "The administrator login for the SQL Server"
default = null
}
variable "key_vault_id" {
type = string
description = "The id of the key vault where the password will be stored"
}
variable "application_name" {
type = string
description = "The name of your application"
@ -30,14 +41,6 @@ variable "tenant_id" {
description = "The tenant id where the resources will be created"
}
variable "entra_admin_group_object_id" {
type = string
}
variable "entra_admin_group_name" {
type = string
}
variable "private_link_subnet_id" {
type = string
description = "The subnet id where the SQL database will be integrated"

Просмотреть файл

@ -3,14 +3,16 @@
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.59.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
## Modules

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -7,7 +7,7 @@ resource "azurerm_route_table" "this" {
name = azurecaf_name.route_table.result
location = var.location
resource_group_name = var.resource_group
disable_bgp_route_propagation = false
bgp_route_propagation_enabled = false
tags = local.tags
}

Просмотреть файл

@ -1,6 +1,6 @@
# windows-vm-ext
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
No requirements.
@ -9,7 +9,7 @@ No requirements.
| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.59.0 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | n/a |
## Modules
@ -19,7 +19,44 @@ No modules.
| Name | Type |
|------|------|
| [azurerm_virtual_machine_extension.entra](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
| [azurerm_virtual_machine_extension.aad](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
| [azurerm_virtual_machine_extension.install_ssms](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_enable_microsoft_entra_join"></a> [enable\_microsoft\_entra\_join](#input\_enable\_microsoft\_entra\_join) | True to enable Microsoft Entra join of the VM. | `bool` | `true` | no |
| <a name="input_enroll_with_mdm"></a> [enroll\_with\_mdm](#input\_enroll\_with\_mdm) | True to enroll the device with an approved MDM provider like Intune. | `bool` | `true` | no |
| <a name="input_install_extensions"></a> [install\_extensions](#input\_install\_extensions) | n/a | `bool` | `false` | no |
| <a name="input_mdm_id"></a> [mdm\_id](#input\_mdm\_id) | The default value is the MDM Id for Intune, but you can use your own MDM id if you want to use a different MDM service. | `string` | `"0000000a-0000-0000-c000-000000000000"` | no |
| <a name="input_remote_exec_commands"></a> [remote\_exec\_commands](#input\_remote\_exec\_commands) | values to pass to the remote-exec provisioner | `list(string)` | `[]` | no |
| <a name="input_vm_id"></a> [vm\_id](#input\_vm\_id) | value of the vm id | `string` | n/a | yes |
## Outputs
No outputs.
<!-- END_TF_DOCS -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
No requirements.
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | n/a |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [azurerm_virtual_machine_extension.aad](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
| [azurerm_virtual_machine_extension.install_ssms](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
## Inputs

Просмотреть файл

@ -1,4 +1,4 @@
resource "azurerm_virtual_machine_extension" "entra" {
resource "azurerm_virtual_machine_extension" "aad" {
count = var.enable_microsoft_entra_join ? 1 : 0
name = "aad-login-for-windows"

Просмотреть файл

@ -1,18 +1,20 @@
# windows-vm
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- BEGIN_TF_DOCS -->
## Requirements
No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | 2.39.0 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.25 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.60.0 |
| <a name="provider_random"></a> [random](#provider\_random) | 3.5.1 |
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | 3.0.2 |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | 1.2.28 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 4.5.0 |
| <a name="provider_random"></a> [random](#provider\_random) | 3.6.3 |
## Modules
@ -55,6 +57,71 @@ No modules.
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_id"></a> [id](#output\_id) | n/a |
| <a name="output_name"></a> [name](#output\_name) | n/a |
| <a name="output_principal_id"></a> [principal\_id](#output\_principal\_id) | n/a |
| <a name="output_private_ip_address"></a> [private\_ip\_address](#output\_private\_ip\_address) | n/a |
| <a name="output_vm_key_vault_secret_ids"></a> [vm\_key\_vault\_secret\_ids](#output\_vm\_key\_vault\_secret\_ids) | n/a |
<!-- END_TF_DOCS -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=4.0 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | n/a |
| <a name="provider_azurecaf"></a> [azurecaf](#provider\_azurecaf) | n/a |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >=4.0 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [azurecaf_name.caf_name_winvm](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) | resource |
| [azurerm_key_vault_secret.admin_password](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource |
| [azurerm_key_vault_secret.admin_username](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource |
| [azurerm_network_interface.vm_nic](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) | resource |
| [azurerm_role_assignment.vm_admin_role_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_windows_virtual_machine.vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine) | resource |
| [random_password.password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
| [azuread_user.vm_admin](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/user) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_admin_password"></a> [admin\_password](#input\_admin\_password) | n/a | `string` | `null` | no |
| <a name="input_admin_username"></a> [admin\_username](#input\_admin\_username) | n/a | `string` | n/a | yes |
| <a name="input_entra_admin_object_id"></a> [entra\_admin\_object\_id](#input\_entra\_admin\_object\_id) | The Microsoft Entra ID for the VM admin user/group. If entra\_admin\_username is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_entra_admin_username"></a> [entra\_admin\_username](#input\_entra\_admin\_username) | [Optional] The Microsoft Entra ID username for the VM admin account. If entra\_admin\_object\_id is not specified, this value will be used. | `string` | `null` | no |
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | Global settings for the naming convention module. | `any` | n/a | yes |
| <a name="input_identity"></a> [identity](#input\_identity) | The identity type and the list of identities ids | <pre>object({<br> type = string<br> identity_ids = optional(list(string))<br> })</pre> | <pre>{<br> "identity_ids": [],<br> "type": "SystemAssigned"<br>}</pre> | no |
| <a name="input_key_vault_id"></a> [key\_vault\_id](#input\_key\_vault\_id) | Optional ID of the key vault to store the VM password | `string` | `null` | no |
| <a name="input_location"></a> [location](#input\_location) | The location (Azure region) where the resources should be created. | `string` | n/a | yes |
| <a name="input_resource_group"></a> [resource\_group](#input\_resource\_group) | The name of the resource group where all resources should be created. | `string` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
| <a name="input_vm_image_offer"></a> [vm\_image\_offer](#input\_vm\_image\_offer) | n/a | `string` | `"windows-11"` | no |
| <a name="input_vm_image_publisher"></a> [vm\_image\_publisher](#input\_vm\_image\_publisher) | n/a | `string` | `"MicrosoftWindowsDesktop"` | no |
| <a name="input_vm_image_sku"></a> [vm\_image\_sku](#input\_vm\_image\_sku) | n/a | `string` | `"win11-22h2-pro"` | no |
| <a name="input_vm_image_version"></a> [vm\_image\_version](#input\_vm\_image\_version) | n/a | `string` | `"latest"` | no |
| <a name="input_vm_name"></a> [vm\_name](#input\_vm\_name) | name of the virtual machine | `any` | n/a | yes |
| <a name="input_vm_size"></a> [vm\_size](#input\_vm\_size) | n/a | `string` | `"Standard_B2ms"` | no |
| <a name="input_vm_subnet_id"></a> [vm\_subnet\_id](#input\_vm\_subnet\_id) | n/a | `string` | n/a | yes |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_id"></a> [id](#output\_id) | n/a |

Просмотреть файл

@ -1,5 +1,9 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=4.0"
}
azurecaf = {
source = "aztfmod/azurecaf"
}

Просмотреть файл

@ -38,8 +38,7 @@ variable "key_vault_id" {
}
variable "admin_username" {
type = string
default = null
type = string
}
variable "admin_password" {