зеркало из https://github.com/microsoft/cobalt.git
Resolve issues and concerns with resource naming strategy and naming collisions (#281)
* *Refactor single-service template to use locals block *Resolve names of resources that can be overridden in tfvars *Refactor HW template to use locals block *Moved provider to commons.tf *Following same pattern as other templates for resource naming *Compute the basename consistently *Fallback to admin RG for ACR if not specified in TF vars *Randomization element for HW template resource names *Randomization element for simple single-service template *Terraform insists on determinism for count metaproperty *Randomization element for ISO template *Include randomized string in shortened names * Tdevani workingbranch (#274) * adding commits to pull out resource name into the templates * updating az-isolated template for single region to update app service module * *Use name prefixes on app services too *updating the iso template documentation for inputs & outputs based on the recent changes *updating readme for single region with the required variables *Unit test fixes *Remove resource names from asserts *Remove resource names that are indeterminate *Deterministic trigger for webhook creation *Set ACR flag in ISO template *Fix webhook URLs *Remove hardcoded name checks from integration tests *Webhook Name must be <= 50 chars *Escaped res group param *Resolves problems with AZ CLI commands for management of app service ACR pull and authentication * Missed during rebase * Global Web App name is capped at 60 characters total (https://docs.microsoft.com/en-us/azure/architecture/best-practices/naming-conventions#web) * Proper name of trigger
This commit is contained in:
Родитель
6f50be7ce0
Коммит
37722f874f
|
@ -18,7 +18,7 @@ data "azurerm_app_service_plan" "appsvc" {
|
|||
}
|
||||
|
||||
resource "azurerm_app_service" "appsvc" {
|
||||
name = format("%s-%s", lower(local.app_names[count.index]), lower(terraform.workspace))
|
||||
name = format("%s-%s", var.app_service_name_prefix, lower(local.app_names[count.index]))
|
||||
resource_group_name = data.azurerm_resource_group.appsvc.name
|
||||
location = data.azurerm_resource_group.appsvc.location
|
||||
app_service_plan_id = data.azurerm_app_service_plan.appsvc.id
|
||||
|
@ -47,25 +47,23 @@ resource "azurerm_app_service" "appsvc" {
|
|||
}
|
||||
|
||||
resource "null_resource" "acr_webhook_creation" {
|
||||
count = var.docker_enable_ci == true && var.azure_container_registry_name != "" ? length(local.app_names) : 0
|
||||
count = var.docker_enable_ci == true && var.uses_acr ? length(local.app_names) : 0
|
||||
depends_on = [azurerm_app_service.appsvc]
|
||||
|
||||
triggers = {
|
||||
images_to_deploy = "${join(",", [for config in local.app_configs : config.image])}"
|
||||
acr_name = var.azure_container_registry_name
|
||||
uses_acr = var.uses_acr
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "az acr webhook create --registry $ACRNAME --name $APPNAME$WRKSPACE$WEBHOOKNAME --actions push --uri $(az webapp deployment container show-cd-url -n $APPNAME_URL-$WRKSPACE_URL -g $APPSVCNAME --query CI_CD_URL -o tsv)"
|
||||
command = "az acr webhook create --registry \"$ACRNAME\" --name \"$APPNAME$WEBHOOKNAME\" --actions push --uri $(az webapp deployment container show-cd-url -n $APPNAME_URL -g $APPSVCNAME --query CI_CD_URL -o tsv)"
|
||||
|
||||
environment = {
|
||||
ACRNAME = var.azure_container_registry_name
|
||||
APPNAME = replace(lower(local.app_names[count.index]), "-", "")
|
||||
WRKSPACE = replace(lower(terraform.workspace), "-", "")
|
||||
APPNAME_URL = lower(local.app_names[count.index])
|
||||
WRKSPACE_URL = lower(terraform.workspace)
|
||||
WEBHOOKNAME = local.acr_webhook_name
|
||||
APPSVCNAME = data.azurerm_resource_group.appsvc.name
|
||||
ACRNAME = var.azure_container_registry_name
|
||||
APPNAME = replace(lower(local.app_names[count.index]), "-", "")
|
||||
APPNAME_URL = format("%s-%s", var.app_service_name_prefix, lower(local.app_names[count.index]))
|
||||
WEBHOOKNAME = local.acr_webhook_name
|
||||
APPSVCNAME = data.azurerm_resource_group.appsvc.name
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -73,7 +71,7 @@ resource "null_resource" "acr_webhook_creation" {
|
|||
|
||||
resource "azurerm_app_service_slot" "appsvc_staging_slot" {
|
||||
name = "staging"
|
||||
app_service_name = format("%s-%s", lower(local.app_names[count.index]), lower(terraform.workspace))
|
||||
app_service_name = format("%s-%s", var.app_service_name_prefix, lower(local.app_names[count.index]))
|
||||
count = length(local.app_names)
|
||||
location = data.azurerm_resource_group.appsvc.location
|
||||
resource_group_name = data.azurerm_resource_group.appsvc.name
|
||||
|
@ -89,11 +87,11 @@ data "azurerm_app_service" "all" {
|
|||
|
||||
resource "azurerm_template_deployment" "access_restriction" {
|
||||
name = "access_restriction"
|
||||
count = var.vnet_name == "" ? 0 : length(local.app_names)
|
||||
count = var.uses_vnet ? length(local.app_names) : 0
|
||||
resource_group_name = data.azurerm_resource_group.appsvc.name
|
||||
|
||||
parameters = {
|
||||
service_name = format("%s-%s", lower(local.app_names[count.index]), lower(terraform.workspace))
|
||||
service_name = format("%s-%s", var.app_service_name_prefix, lower(local.app_names[count.index]))
|
||||
vnet_subnet_id = var.vnet_subnet_id
|
||||
access_restriction_name = local.access_restriction_name
|
||||
access_restriction_description = local.access_restriction_description
|
||||
|
|
|
@ -8,6 +8,17 @@ variable "service_plan_name" {
|
|||
type = string
|
||||
}
|
||||
|
||||
variable "app_service_name_prefix" {
|
||||
description = "String value prepended to the name of each app service"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "uses_acr" {
|
||||
description = "Determines whether or not an Azure container registry is being used"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "azure_container_registry_name" {
|
||||
description = "The name of the azure container registry resource"
|
||||
type = string
|
||||
|
@ -52,6 +63,12 @@ variable "site_config_always_on" {
|
|||
default = true
|
||||
}
|
||||
|
||||
variable "uses_vnet" {
|
||||
description = "Determines whether or not a virtual network is being used"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "vnet_name" {
|
||||
description = "The vnet integration name."
|
||||
type = string
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
module "provider" {
|
||||
source = "../../modules/providers/azure/provider"
|
||||
}
|
||||
|
||||
resource "random_string" "workspace_scope" {
|
||||
keepers = {
|
||||
# Generate a new id each time we switch to a new workspace or app id
|
||||
ws_name = replace(trimspace(lower(terraform.workspace)), "_", "-")
|
||||
app_id = replace(trimspace(lower(var.name)), "_", "-")
|
||||
}
|
||||
|
||||
length = max(1, var.randomization_level) // error for zero-length
|
||||
special = false
|
||||
upper = false
|
||||
}
|
||||
|
||||
locals {
|
||||
// sanitize names
|
||||
app_id = random_string.workspace_scope.keepers.app_id
|
||||
region = replace(trimspace(lower(var.resource_group_location)), "_", "-")
|
||||
ws_name = random_string.workspace_scope.keepers.ws_name
|
||||
suffix = var.randomization_level > 0 ? "-${random_string.workspace_scope.result}" : ""
|
||||
|
||||
// base name for resources, name constraints documented here: https://docs.microsoft.com/en-us/azure/architecture/best-practices/naming-conventions
|
||||
base_name = "${local.app_id}-${local.ws_name}${local.suffix}"
|
||||
base_name_21 = length(local.base_name) < 22 ? local.base_name : "${substr(local.base_name, 0, 21 - length(local.suffix))}${local.suffix}"
|
||||
base_name_46 = length(local.base_name) < 47 ? local.base_name : "${substr(local.base_name, 0, 46 - length(local.suffix))}${local.suffix}"
|
||||
base_name_60 = length(local.base_name) < 61 ? local.base_name : "${substr(local.base_name, 0, 60 - length(local.suffix))}${local.suffix}"
|
||||
base_name_76 = length(local.base_name) < 77 ? local.base_name : "${substr(local.base_name, 0, 76 - length(local.suffix))}${local.suffix}"
|
||||
base_name_83 = length(local.base_name) < 84 ? local.base_name : "${substr(local.base_name, 0, 83 - length(local.suffix))}${local.suffix}"
|
||||
|
||||
// Resolved resource names
|
||||
app_rg_name = "${local.base_name_83}-app-rg" // app resource group (max 90 chars)
|
||||
sp_name = "${local.base_name}-sp" // service plan
|
||||
app_svc_name_prefix = local.base_name_21
|
||||
|
||||
// Resolved TF Vars
|
||||
reg_url = var.docker_registry_server_url
|
||||
app_services = {
|
||||
for target in var.deployment_targets :
|
||||
target.app_name => {
|
||||
image = "${target.image_name}:${target.image_release_tag_prefix}"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +1,20 @@
|
|||
|
||||
module "provider" {
|
||||
source = "../../modules/providers/azure/provider"
|
||||
}
|
||||
|
||||
resource "azurerm_resource_group" "main" {
|
||||
name = var.prefix
|
||||
location = var.resource_group_location
|
||||
name = local.app_rg_name
|
||||
location = local.region
|
||||
}
|
||||
|
||||
module "service_plan" {
|
||||
source = "../../modules/providers/azure/service-plan"
|
||||
resource_group_name = azurerm_resource_group.main.name
|
||||
service_plan_name = "${azurerm_resource_group.main.name}-sp"
|
||||
service_plan_name = local.sp_name
|
||||
}
|
||||
|
||||
module "app_service" {
|
||||
source = "../../modules/providers/azure/app-service"
|
||||
app_service_name_prefix = local.app_svc_name_prefix
|
||||
service_plan_name = module.service_plan.service_plan_name
|
||||
service_plan_resource_group_name = azurerm_resource_group.main.name
|
||||
docker_registry_server_url = var.docker_registry_server_url
|
||||
app_service_config = {
|
||||
for target in var.deployment_targets :
|
||||
target.app_name => {
|
||||
image = "${target.image_name}:${target.image_release_tag_prefix}"
|
||||
}
|
||||
}
|
||||
docker_registry_server_url = local.reg_url
|
||||
app_service_config = local.app_services
|
||||
}
|
||||
|
||||
|
|
|
@ -3,14 +3,15 @@
|
|||
# responsibility to choose the values that make sense for your application.
|
||||
#
|
||||
# Note: These values will impact the names of resources. If your deployment
|
||||
# fails due to a resource name colision, consider using different values for
|
||||
# the `prefix` variable.
|
||||
# fails due to a resource name collision, consider using different values for
|
||||
# the `name` variable or increasing the value for `randomization_level`.
|
||||
|
||||
resource_group_location = "eastus"
|
||||
prefix = "az-hello-world"
|
||||
name = "az-hello-world"
|
||||
randomization_level = 8
|
||||
|
||||
deployment_targets = [{
|
||||
app_name = "cobalt-backend-api",
|
||||
image_name = "appsvcsample/static-site",
|
||||
image_release_tag_prefix = "latest"
|
||||
}]
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -44,14 +43,10 @@ func httpGetRespondsWith200(goTest *testing.T, output infratests.TerraformOutput
|
|||
}
|
||||
|
||||
func TestAzureSimple(t *testing.T) {
|
||||
workspace := terraform.RunTerraformCommand(t, tfOptions, "workspace", "show")
|
||||
testFixture := infratests.IntegrationTestFixture{
|
||||
GoTest: t,
|
||||
TfOptions: tfOptions,
|
||||
ExpectedTfOutputCount: 1,
|
||||
ExpectedTfOutput: infratests.TerraformOutput{
|
||||
"app_service_default_hostname": strings.ToLower(fmt.Sprintf("https://cobalt-backend-api-%s.azurewebsites.net", workspace)),
|
||||
},
|
||||
TfOutputAssertions: []infratests.TerraformOutputValidation{
|
||||
httpGetRespondsWith200,
|
||||
},
|
||||
|
|
|
@ -18,7 +18,7 @@ var tfOptions = &terraform.Options{
|
|||
TerraformDir: "../../",
|
||||
Upgrade: true,
|
||||
Vars: map[string]interface{}{
|
||||
"prefix": prefix,
|
||||
"name": prefix,
|
||||
"resource_group_location": datacenter,
|
||||
},
|
||||
BackendConfig: map[string]interface{}{
|
||||
|
@ -31,12 +31,11 @@ func TestAzureSimple(t *testing.T) {
|
|||
testFixture := infratests.UnitTestFixture{
|
||||
GoTest: t,
|
||||
TfOptions: tfOptions,
|
||||
ExpectedResourceCount: 9,
|
||||
ExpectedResourceCount: 10,
|
||||
PlanAssertions: nil,
|
||||
Workspace: workspace,
|
||||
ExpectedResourceAttributeValues: infratests.ResourceDescription{
|
||||
"module.app_service.azurerm_app_service.appsvc[0]": map[string]interface{}{
|
||||
"resource_group_name": prefix,
|
||||
"app_settings": map[string]interface{}{
|
||||
"WEBSITES_ENABLE_APP_SERVICE_STORAGE": "false",
|
||||
},
|
||||
|
@ -53,7 +52,6 @@ func TestAzureSimple(t *testing.T) {
|
|||
},
|
||||
"azurerm_resource_group.main": map[string]interface{}{
|
||||
"location": datacenter,
|
||||
"name": prefix,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,13 +1,25 @@
|
|||
variable "prefix" {
|
||||
description = "The prefix used for all resources in this example"
|
||||
// ---- General Configuration ----
|
||||
|
||||
variable "name" {
|
||||
description = "An identifier used to construct the names of all resources in this template."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "randomization_level" {
|
||||
description = "Number of additional random characters to include in resource names to insulate against unexpected resource name collisions."
|
||||
type = number
|
||||
default = 8
|
||||
}
|
||||
|
||||
variable "resource_group_location" {
|
||||
description = "The Azure location where all resources in this example should be created."
|
||||
description = "The Azure region where all resources in this template should be created."
|
||||
type = string
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---- App Service Configuration ----
|
||||
|
||||
variable "deployment_targets" {
|
||||
description = "Metadata about apps to deploy, such as image metadata."
|
||||
type = list(object({
|
||||
|
|
|
@ -10,12 +10,12 @@ provider "azurerm" {
|
|||
|
||||
resource "azurerm_resource_group" "app_rg" {
|
||||
name = local.app_rg_name
|
||||
location = var.resource_group_location
|
||||
location = local.region
|
||||
provider = azurerm.app_dev
|
||||
}
|
||||
|
||||
resource "azurerm_management_lock" "app_rg_lock" {
|
||||
name = format("%s-delete-lock", local.app_rg_name)
|
||||
name = local.app_rg_lock
|
||||
scope = azurerm_resource_group.app_rg.id
|
||||
lock_level = "CanNotDelete"
|
||||
provider = azurerm.app_dev
|
||||
|
@ -64,7 +64,7 @@ module "container_registry" {
|
|||
module "app_service_principal_contributor" {
|
||||
source = "../../modules/providers/azure/service-principal"
|
||||
create_for_rbac = true
|
||||
display_name = local.svc_principal_name
|
||||
display_name = local.svc_princ_name
|
||||
role_name = "Contributor"
|
||||
role_scope = "${module.container_registry.container_registry_id}"
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ module "app_service_principal_secrets" {
|
|||
module "acr_service_principal_acrpull" {
|
||||
source = "../../modules/providers/azure/service-principal"
|
||||
create_for_rbac = true
|
||||
display_name = local.acr_svc_principal_name
|
||||
display_name = local.acr_svc_princ_name
|
||||
role_name = "acrpull"
|
||||
role_scope = "${module.container_registry.container_registry_id}"
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ provider "azurerm" {
|
|||
|
||||
resource "azurerm_resource_group" "admin_rg" {
|
||||
name = local.admin_rg_name
|
||||
location = var.resource_group_location
|
||||
location = local.region
|
||||
provider = azurerm.admin
|
||||
}
|
||||
|
||||
resource "azurerm_management_lock" "admin_rg_lock" {
|
||||
name = format("%s-delete-lock", local.admin_rg_name)
|
||||
name = local.admin_rg_lock
|
||||
scope = azurerm_resource_group.admin_rg.id
|
||||
lock_level = "CanNotDelete"
|
||||
provider = azurerm.admin
|
||||
|
@ -53,8 +53,10 @@ module "service_plan" {
|
|||
module "app_service" {
|
||||
source = "../../modules/providers/azure/app-service"
|
||||
service_plan_name = module.service_plan.service_plan_name
|
||||
app_service_name_prefix = local.app_svc_name_prefix
|
||||
service_plan_resource_group_name = azurerm_resource_group.admin_rg.name
|
||||
app_insights_instrumentation_key = module.app_insights.app_insights_instrumentation_key
|
||||
uses_acr = true
|
||||
vault_uri = module.keyvault.keyvault_uri
|
||||
azure_container_registry_name = module.container_registry.container_registry_name
|
||||
docker_registry_server_url = module.container_registry.container_registry_login_server
|
||||
|
@ -85,9 +87,11 @@ module "app_service_keyvault_access_policy" {
|
|||
module "authn_app_service" {
|
||||
source = "../../modules/providers/azure/app-service"
|
||||
service_plan_name = module.service_plan.service_plan_name
|
||||
app_service_name_prefix = local.auth_svc_name_prefix
|
||||
service_plan_resource_group_name = azurerm_resource_group.admin_rg.name
|
||||
vault_uri = module.keyvault.keyvault_uri
|
||||
app_insights_instrumentation_key = module.app_insights.app_insights_instrumentation_key
|
||||
uses_acr = true
|
||||
azure_container_registry_name = module.container_registry.container_registry_name
|
||||
docker_registry_server_url = module.container_registry.container_registry_login_server
|
||||
docker_registry_server_username = module.container_registry.admin_username
|
||||
|
@ -143,7 +147,7 @@ resource "null_resource" "auth" {
|
|||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "az webapp auth update -g $RES_GRP -n $APPNAME --enabled true --action LoginWithAzureActiveDirectory --aad-token-issuer-url \"$ISSUER\" --aad-client-id \"$APPID\""
|
||||
command = "az webapp auth update -g \"$RES_GRP\" -n \"$APPNAME\" --enabled true --action LoginWithAzureActiveDirectory --aad-token-issuer-url \"$ISSUER\" --aad-client-id \"$APPID\""
|
||||
|
||||
environment = {
|
||||
RES_GRP = azurerm_resource_group.admin_rg.name
|
||||
|
|
|
@ -6,17 +6,60 @@ data "azurerm_subscription" "current" {}
|
|||
|
||||
data "azurerm_client_config" "current" {}
|
||||
|
||||
resource "random_string" "workspace_scope" {
|
||||
keepers = {
|
||||
# Generate a new id each time we switch to a new workspace or app id
|
||||
ws_name = replace(trimspace(lower(terraform.workspace)), "_", "-")
|
||||
app_id = replace(trimspace(lower(var.name)), "_", "-")
|
||||
}
|
||||
|
||||
length = max(1, var.randomization_level) // error for zero-length
|
||||
special = false
|
||||
upper = false
|
||||
}
|
||||
|
||||
locals {
|
||||
prefix = "${lower(var.name)}-${lower(terraform.workspace)}"
|
||||
tenant_id = data.azurerm_client_config.current.tenant_id
|
||||
admin_rg_name = "${local.prefix}-admin-rg" // name of resource group used for admin resources
|
||||
app_rg_name = "${local.prefix}-app-rg" // name of app resource group
|
||||
sp_name = "${local.prefix}-sp" // name of service plan
|
||||
ai_name = "${local.prefix}-ai" // name of app insights
|
||||
kv_name = format("%s%s-kv", format("%.10s", lower(var.name)), format("%.10s", lower(terraform.workspace))) // name of key vault
|
||||
acr_name = replace(format("%s%sacr", format("%.10s", lower(var.name)), format("%.10s", lower(terraform.workspace))), "/\\W/", "") // name of acr
|
||||
ase_sub_id = var.ase_subscription_id == "" ? data.azurerm_subscription.current.subscription_id : var.ase_subscription_id
|
||||
app_sub_id = var.app_dev_subscription_id == "" ? data.azurerm_subscription.current.subscription_id : var.app_dev_subscription_id
|
||||
// sanitize names
|
||||
app_id = random_string.workspace_scope.keepers.app_id
|
||||
region = replace(trimspace(lower(var.resource_group_location)), "_", "-")
|
||||
ws_name = random_string.workspace_scope.keepers.ws_name
|
||||
suffix = var.randomization_level > 0 ? "-${random_string.workspace_scope.result}" : ""
|
||||
|
||||
// base name for resources, name constraints documented here: https://docs.microsoft.com/en-us/azure/architecture/best-practices/naming-conventions
|
||||
base_name = "${local.app_id}-${local.ws_name}${local.suffix}"
|
||||
base_name_21 = length(local.base_name) < 22 ? local.base_name : "${substr(local.base_name, 0, 21 - length(local.suffix))}${local.suffix}"
|
||||
base_name_46 = length(local.base_name) < 47 ? local.base_name : "${substr(local.base_name, 0, 46 - length(local.suffix))}${local.suffix}"
|
||||
base_name_60 = length(local.base_name) < 61 ? local.base_name : "${substr(local.base_name, 0, 60 - length(local.suffix))}${local.suffix}"
|
||||
base_name_76 = length(local.base_name) < 77 ? local.base_name : "${substr(local.base_name, 0, 76 - length(local.suffix))}${local.suffix}"
|
||||
base_name_83 = length(local.base_name) < 84 ? local.base_name : "${substr(local.base_name, 0, 83 - length(local.suffix))}${local.suffix}"
|
||||
|
||||
tenant_id = data.azurerm_client_config.current.tenant_id
|
||||
|
||||
// Resource names
|
||||
admin_rg_name = "${local.base_name_83}-adm-rg" // resource group used for admin resources (max 90 chars)
|
||||
app_rg_name = "${local.base_name_83}-app-rg" // app resource group (max 90 chars)
|
||||
admin_rg_lock = "${local.base_name_83}-adm-rg-delete-lock" // management lock to prevent deletes
|
||||
app_rg_lock = "${local.base_name_83}-app-rg-delete-lock" // management lock to prevent deletes
|
||||
sp_name = "${local.base_name}-sp" // service plan
|
||||
ai_name = "${local.base_name}-ai" // app insights
|
||||
kv_name = "${local.base_name_21}-kv" // key vault (max 24 chars)
|
||||
acr_name = "${replace(local.base_name_46, "-", "")}acr" // container registry (max 50 chars, alphanumeric *only*)
|
||||
vnet_name = "${local.base_name_60}-net" // virtual network (max 64 chars)
|
||||
tm_profile_name = "${local.base_name_60}-tf" // traffic manager profile (max 63 chars)
|
||||
tm_endpoint_name = "${local.region}_${local.app_id}" // traffic manager endpoint
|
||||
tm_dns_name = "${local.base_name}-dns" // traffic manager dns relative name
|
||||
appgateway_name = "${local.base_name_76}-gw" // app gateway (max 80 chars)
|
||||
public_pip_name = "${local.base_name_76}-ip" // public IP (max 80 chars)
|
||||
svc_princ_name = "${local.base_name}-svc-principal" // service principal
|
||||
acr_svc_princ_name = "${local.base_name}-acr-svc-principal" // container registry service principal
|
||||
app_svc_name_prefix = local.base_name_21
|
||||
auth_svc_name_prefix = "${local.base_name_21}-au"
|
||||
|
||||
// Resolved TF Vars
|
||||
ase_sub_id = var.ase_subscription_id == "" ? data.azurerm_subscription.current.subscription_id : var.ase_subscription_id
|
||||
app_sub_id = var.app_dev_subscription_id == "" ? data.azurerm_subscription.current.subscription_id : var.app_dev_subscription_id
|
||||
// id of App Service Environment
|
||||
ase_id = "/subscriptions/${local.ase_sub_id}/resourceGroups/${var.ase_resource_group}/providers/Microsoft.Web/hostingEnvironments/${var.ase_name}"
|
||||
|
||||
app_secrets = {
|
||||
"app-service-principal-object-id" = module.app_service_principal_contributor.service_principal_object_id,
|
||||
|
@ -33,8 +76,4 @@ locals {
|
|||
acr_password = {
|
||||
"acr-service-principal-password" = module.acr_service_principal_acrpull.service_principal_password
|
||||
}
|
||||
svc_principal_name = "${local.prefix}-svc-principal"
|
||||
acr_svc_principal_name = "${local.prefix}-acr-svc-principal"
|
||||
// id of App Service Environment
|
||||
ase_id = "/subscriptions/${local.ase_sub_id}/resourceGroups/${var.ase_resource_group}/providers/Microsoft.Web/hostingEnvironments/${var.ase_name}"
|
||||
}
|
||||
|
|
|
@ -79,18 +79,48 @@ Only one terraform template can be deployed within a given workspace. The use ca
|
|||
## Module and Template Deep Dive
|
||||
|
||||
### Template Inputs
|
||||
General Configuration
|
||||
| name | type | default | description |
|
||||
|---|---|---|---|
|
||||
| `resource_group_location` | string | | The deployment location of resource group container all the resources |
|
||||
| `name` | string | | The name of the deployment. This will be used across the resource created in this solution |
|
||||
| `app_service_containers` | map(str) | | The name key value pair where the key is the name assigned to the app service and value is the source container |
|
||||
| `metrics_configuration` | MetricsConfig **see below** | `[]` | A list of metrics configuration that should be configured for the app service plan |
|
||||
| `resource_group_location` | string | | The Azure region where all resources in this template should be created |
|
||||
| `name` | string | | It serves as an identifier used to construct the names of all resources in this template
|
||||
| `randomization_level` | number | | Number of additional random characters to include in resource names to insulate against unexpected resource name collisions |
|
||||
|
||||
App Service Environment Configuration
|
||||
| name | type | default | description |
|
||||
|---|---|---|---|
|
||||
| `app_service_containers` | string | | The ID of the subscription in which the ASE lives in |
|
||||
| `ase_name` | string | | The name of the App Service Environment in which to deploy the app services |
|
||||
| `ase_resource_group` | string | | The resource group of the App Service Environment in which to deploy the app services |
|
||||
| `monitoring_dimension_values` | `["*"]` | | Dimensions used to determine service plan scaling |
|
||||
| `ase_vnet_name` | string | | The name of the VNET in which the ASE lives |
|
||||
| `service_plan_scaling_rules` | list(rule) **see below** | `[]` | A list of scaline rules to apply to the service plan
|
||||
| `provision_sql` | bool | `false` | True if SQL Server should be deployed, false otherwise
|
||||
| `provision_storage_account` | bool | `false` | True if s storage account should be deployed, false otherwise
|
||||
| `authenticated_clients` | list(string) | `[]` | List of clients to authenticate if `enable_auth` is true
|
||||
| `ase_vnet_name` | string | | The name of the VNET that the App Service Environment is deployed to |
|
||||
|
||||
App Service Configuration
|
||||
| name | type | default | description |
|
||||
|---|---|---|---|
|
||||
| `unauthn_deployment_targets` | list(obj) | | DMetadata about apps to deploy, such as repository location, docker file metadata and image names |
|
||||
| `authn_deployment_targets` | list(obj) | | Metadata about apps to deploy that also require authentication |
|
||||
|
||||
Service Plan Configuration
|
||||
| name | type | default | description |
|
||||
|---|---|---|---|
|
||||
| `monitoring_dimension_values` | `["*"]` | | Dimensions used to determine service plan scaling |
|
||||
| `service_plan_size` | string | | The size of the service plan instance. Valid values are I1, I2, I3 |
|
||||
| `service_plan_kind` | string | | The kind of Service Plan to be created. Possible values are Windows/Linux/FunctionApp/App |
|
||||
| `scaling_rules` | list(obj) | | The scaling rules for the app service plan. |
|
||||
|
||||
App Service Authentication Configuration
|
||||
| name | type | default | description |
|
||||
|---|---|---|---|
|
||||
| `auth_suffix` | string | | easy-auth | A name to be appended to all azure ad applications
|
||||
| `graph_role_id` | string | | 00000002-0000-0000-c000-000000000000The size of the service plan instance. Valid values are I1, I2, I3 |
|
||||
| `graph_id` | string | 00000002-0000-0000-c000-000000000000 | The kind of Service Plan to be created. Possible values are Windows/Linux/FunctionApp/App |
|
||||
|
||||
App Dev Subscription and Networking
|
||||
| name | type | default | description |
|
||||
|---|---|---|---|
|
||||
| `App Dev Subscription` | string | | Subscription in which the application dependencies will be deployed to |
|
||||
| `resource_ip_whitelist` | list[string] | | A list of IPs and/or IP ranges that should have access to VNET isolated resources provisioned by this template |
|
||||
|
||||
**Notes**
|
||||
|
||||
|
|
|
@ -3,8 +3,12 @@
|
|||
# responsibility to choose the values that make sense for your application.
|
||||
#
|
||||
# Note: These values will impact the names of resources. If your deployment
|
||||
# fails due to a resource name colision, consider using different values for
|
||||
# the `name` variable.
|
||||
# fails due to a resource name collision, consider using different values for
|
||||
# the `name` variable or increasing the value for `randomization_level`.
|
||||
|
||||
resource_group_location = "eastus2"
|
||||
name = "isolated-service"
|
||||
randomization_level = 8
|
||||
|
||||
# Targets that will be configured to also setup AuthN with Easy Auth
|
||||
authn_deployment_targets = [
|
||||
|
@ -30,9 +34,7 @@ unauthn_deployment_targets = [
|
|||
|
||||
# Note: this is configured as such only to test IP Whitelists. This is a well
|
||||
# known DNS address
|
||||
resource_ip_whitelist = ["13.107.6.0/24", "13.107.9.0/24", "13.107.42.0/24", "13.107.43.0/24", "40.74.0.0/15", "40.76.0.0/14", "40.80.0.0/12", "40.96.0.0/12", "40.112.0.0/13", "40.120.0.0/14", "40.124.0.0/16", "40.125.0.0/17"]
|
||||
ase_name = "co-static-ase"
|
||||
name = "isolated-service"
|
||||
ase_resource_group = "co-static-ase-rg"
|
||||
ase_vnet_name = "co-static-ase-vnet"
|
||||
resource_group_location = "eastus2"
|
||||
resource_ip_whitelist = ["13.107.6.0/24", "13.107.9.0/24", "13.107.42.0/24", "13.107.43.0/24", "40.74.0.0/15", "40.76.0.0/14", "40.80.0.0/12", "40.96.0.0/12", "40.112.0.0/13", "40.120.0.0/14", "40.124.0.0/16", "40.125.0.0/17"]
|
||||
ase_name = "co-static-ase"
|
||||
ase_resource_group = "co-static-ase-rg"
|
||||
ase_vnet_name = "co-static-ase-vnet"
|
||||
|
|
|
@ -54,8 +54,6 @@ var tfOptions = &terraform.Options{
|
|||
}
|
||||
|
||||
func TestIsoSingleRegion(t *testing.T) {
|
||||
workspace = terraform.RunTerraformCommand(t, tfOptions, "workspace", "show")
|
||||
|
||||
// Note: creating an App Service Plan configured with an Isolated SKU can take > 1.5
|
||||
// hours. In order to prevent a very long test cycle this test uses a static environment
|
||||
// that lives beyond the lifetime of this test. This is achieved using the
|
||||
|
@ -68,12 +66,6 @@ func TestIsoSingleRegion(t *testing.T) {
|
|||
GoTest: t,
|
||||
TfOptions: tfOptions,
|
||||
ExpectedTfOutputCount: 10,
|
||||
ExpectedTfOutput: infratests.TerraformOutput{
|
||||
"fqdns": []string{
|
||||
"http://co-backend-api-1-" + workspace + "." + aseName + ".p.azurewebsites.net",
|
||||
"http://co-frontend-api-1-" + workspace + "." + aseName + ".p.azurewebsites.net",
|
||||
},
|
||||
},
|
||||
TfOutputAssertions: []infratests.TerraformOutputValidation{
|
||||
// These are commented because we are using hosted build agents
|
||||
// and would need to add all azure ips in whitelist. When we move to
|
||||
|
|
|
@ -65,17 +65,13 @@ func asMap(t *testing.T, jsonString string) map[string]interface{} {
|
|||
func TestTemplate(t *testing.T) {
|
||||
expectedStagingSlot := asMap(t, `{"name":"staging"}`)
|
||||
expectedAppDevResourceGroup := asMap(t, `{
|
||||
"name": "isolated-service-`+workspace+`-app-rg",
|
||||
"location": "`+region+`"
|
||||
}`)
|
||||
expectedAdminResourceGroup := asMap(t, `{
|
||||
"name": "isolated-service-`+workspace+`-admin-rg",
|
||||
"location": "`+region+`"
|
||||
}`)
|
||||
expectedAppInsights := asMap(t, `{
|
||||
"name": "isolated-service-`+workspace+`-ai",
|
||||
"application_type": "Web",
|
||||
"resource_group_name": "isolated-service-`+workspace+`-admin-rg"
|
||||
"application_type": "Web"
|
||||
}`)
|
||||
// expectedKeyVault := asMap(t, `{
|
||||
// "network_acls": [{
|
||||
|
@ -149,11 +145,9 @@ func TestTemplate(t *testing.T) {
|
|||
aseResourceGroup,
|
||||
aseName)
|
||||
expectedAppServicePlan := asMap(t, `{
|
||||
"app_service_environment_id": "`+expectedAppServiceEnvID+`",
|
||||
"app_service_environment_id": "`+expectedAppServiceEnvID+`",
|
||||
"kind": "Linux",
|
||||
"name": "isolated-service-`+workspace+`-sp",
|
||||
"reserved": true,
|
||||
"resource_group_name": "isolated-service-`+workspace+`-admin-rg",
|
||||
"sku": [{ "capacity": 1, "size": "I1", "tier": "Isolated" }]
|
||||
}`)
|
||||
expectedAutoScalePlan := asMap(t, `{
|
||||
|
@ -202,22 +196,18 @@ func TestTemplate(t *testing.T) {
|
|||
}`)
|
||||
expectedAppServiceSchema := `{
|
||||
"identity": [{ "type": "SystemAssigned" }],
|
||||
"name": "co-backend-api-%d-%s",
|
||||
"resource_group_name": "isolated-service-%s-admin-rg",
|
||||
"site_config": [{
|
||||
"always_on": true
|
||||
}]
|
||||
}`
|
||||
expectedAppServiceSchema2 := `{
|
||||
"identity": [{ "type": "SystemAssigned" }],
|
||||
"name": "co-frontend-api-%d-%s",
|
||||
"resource_group_name": "isolated-service-%s-admin-rg",
|
||||
"site_config": [{
|
||||
"always_on": true
|
||||
}]
|
||||
}`
|
||||
expectedAppService1 := asMap(t, fmt.Sprintf(expectedAppServiceSchema, 1, workspace, workspace))
|
||||
expectedAppService2 := asMap(t, fmt.Sprintf(expectedAppServiceSchema2, 1, workspace, workspace))
|
||||
expectedAppService1 := asMap(t, expectedAppServiceSchema)
|
||||
expectedAppService2 := asMap(t, expectedAppServiceSchema2)
|
||||
|
||||
testFixture := infratests.UnitTestFixture{
|
||||
GoTest: t,
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
// ---- General Configuration ----
|
||||
|
||||
variable "resource_group_location" {
|
||||
description = "The deployment location of resource group container all the resources"
|
||||
variable "name" {
|
||||
description = "An identifier used to construct the names of all resources in this template."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "The name of the deployment. This will be used across the resource created in this solution"
|
||||
variable "randomization_level" {
|
||||
description = "Number of additional random characters to include in resource names to insulate against unexpected resource name collisions."
|
||||
type = number
|
||||
default = 8
|
||||
}
|
||||
|
||||
variable "resource_group_location" {
|
||||
description = "The Azure region where all resources in this template should be created."
|
||||
type = string
|
||||
}
|
||||
|
||||
|
|
|
@ -97,8 +97,8 @@ terraform destroy
|
|||
|
||||
#### Required Variables
|
||||
|
||||
1. `resource_group_location`: The deployment location of resource group container all the resources.
|
||||
2. `name`: The name of the deployment. This will be used across the resource created in this solution.
|
||||
1. `resource_group_location`: The deployment location of resource group container all the resource
|
||||
2. `name`: An identifier used to construct the names of all resources in this template.
|
||||
3. `app_service_name`: The name key value pair where the key is representative to the app service name and value is the source container.
|
||||
|
||||
#### Optional Variables
|
||||
|
|
|
@ -1,20 +1,6 @@
|
|||
locals {
|
||||
prefix = "${lower(var.name)}-${lower(terraform.workspace)}"
|
||||
prefix_short = format("%.20s", local.prefix)
|
||||
tm_profile_name = "${local.prefix}-tf"
|
||||
vnet_name = "${local.prefix}-vnet"
|
||||
tm_endpoint_name = "${var.resource_group_location}_${var.name}"
|
||||
tm_dns_name = "${local.prefix}-dns"
|
||||
appgateway_name = "${local.prefix}-gateway"
|
||||
public_pip_name = "${local.prefix}-ip"
|
||||
kv_name = "${local.prefix_short}kv"
|
||||
acr_name = "${replace(local.prefix, "-", "")}acr"
|
||||
resource_group_name = "${local.prefix}"
|
||||
}
|
||||
|
||||
resource "azurerm_resource_group" "svcplan" {
|
||||
name = local.resource_group_name
|
||||
location = var.resource_group_location
|
||||
name = local.admin_rg_name
|
||||
location = local.region
|
||||
}
|
||||
|
||||
module "vnet" {
|
||||
|
@ -65,8 +51,8 @@ module "app_gateway" {
|
|||
|
||||
module "container_registry" {
|
||||
source = "../../modules/providers/azure/container-registry"
|
||||
container_registry_name = var.azure_container_resource_name == "" ? local.acr_name : var.azure_container_resource_name
|
||||
resource_group_name = var.azure_container_resource_group == "" ? azurerm_resource_group.svcplan.name : var.azure_container_resource_group
|
||||
container_registry_name = local.resolved_acr_name
|
||||
resource_group_name = local.resolved_acr_rg_name
|
||||
container_registry_admin_enabled = true
|
||||
container_registry_tags = var.azure_container_tags
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
locals {
|
||||
service_plan_name = "${local.prefix}-sp"
|
||||
app_insights_name = "${local.prefix}-ai"
|
||||
}
|
||||
|
||||
data "azurerm_container_registry" "acr" {
|
||||
name = module.container_registry.container_registry_name
|
||||
resource_group_name = var.azure_container_resource_group == "" ? azurerm_resource_group.svcplan.name : var.azure_container_resource_group
|
||||
name = local.resolved_acr_name
|
||||
resource_group_name = local.resolved_acr_rg_name
|
||||
depends_on = ["azurerm_resource_group.svcplan", "module.container_registry"]
|
||||
}
|
||||
|
||||
|
@ -32,25 +27,24 @@ resource "null_resource" "acr_image_deploy" {
|
|||
}
|
||||
}
|
||||
|
||||
module "provider" {
|
||||
source = "../../modules/providers/azure/provider"
|
||||
}
|
||||
|
||||
module "service_plan" {
|
||||
source = "../../modules/providers/azure/service-plan"
|
||||
resource_group_name = azurerm_resource_group.svcplan.name
|
||||
service_plan_name = local.service_plan_name
|
||||
service_plan_name = local.sp_name
|
||||
}
|
||||
|
||||
module "app_service" {
|
||||
source = "../../modules/providers/azure/app-service"
|
||||
app_service_name = local.app_service_name
|
||||
service_plan_name = module.service_plan.service_plan_name
|
||||
service_plan_resource_group_name = azurerm_resource_group.svcplan.name
|
||||
app_insights_instrumentation_key = module.app_insight.app_insights_instrumentation_key
|
||||
uses_acr = true
|
||||
azure_container_registry_name = module.container_registry.container_registry_name
|
||||
docker_registry_server_url = module.container_registry.container_registry_login_server
|
||||
docker_registry_server_username = data.azurerm_container_registry.acr.admin_username
|
||||
docker_registry_server_password = data.azurerm_container_registry.acr.admin_password
|
||||
uses_vnet = true
|
||||
vnet_name = module.vnet.vnet_name
|
||||
vnet_subnet_id = module.vnet.vnet_subnet_ids[0]
|
||||
vault_uri = module.keyvault.keyvault_uri
|
||||
|
@ -72,7 +66,7 @@ resource "azurerm_role_assignment" "acr_pull" {
|
|||
module "app_insight" {
|
||||
source = "../../modules/providers/azure/app-insights"
|
||||
service_plan_resource_group_name = azurerm_resource_group.svcplan.name
|
||||
appinsights_name = local.app_insights_name
|
||||
appinsights_name = local.ai_name
|
||||
appinsights_application_type = var.application_type
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
module "provider" {
|
||||
source = "../../modules/providers/azure/provider"
|
||||
}
|
||||
|
||||
resource "random_string" "workspace_scope" {
|
||||
keepers = {
|
||||
# Generate a new id each time we switch to a new workspace or app id
|
||||
ws_name = replace(trimspace(lower(terraform.workspace)), "_", "-")
|
||||
app_id = replace(trimspace(lower(var.name)), "_", "-")
|
||||
}
|
||||
|
||||
length = max(1, var.randomization_level) // error for zero-length
|
||||
special = false
|
||||
upper = false
|
||||
}
|
||||
|
||||
locals {
|
||||
// sanitize names
|
||||
app_id = random_string.workspace_scope.keepers.app_id
|
||||
region = replace(trimspace(lower(var.resource_group_location)), "_", "-")
|
||||
ws_name = random_string.workspace_scope.keepers.ws_name
|
||||
suffix = var.randomization_level > 0 ? "-${random_string.workspace_scope.result}" : ""
|
||||
|
||||
// base name for resources, name constraints documented here: https://docs.microsoft.com/en-us/azure/architecture/best-practices/naming-conventions
|
||||
base_name = "${local.app_id}-${local.ws_name}${local.suffix}"
|
||||
base_name_21 = length(local.base_name) < 22 ? local.base_name : "${substr(local.base_name, 0, 21 - length(local.suffix))}${local.suffix}"
|
||||
base_name_46 = length(local.base_name) < 47 ? local.base_name : "${substr(local.base_name, 0, 46 - length(local.suffix))}${local.suffix}"
|
||||
base_name_60 = length(local.base_name) < 61 ? local.base_name : "${substr(local.base_name, 0, 60 - length(local.suffix))}${local.suffix}"
|
||||
base_name_76 = length(local.base_name) < 77 ? local.base_name : "${substr(local.base_name, 0, 76 - length(local.suffix))}${local.suffix}"
|
||||
base_name_83 = length(local.base_name) < 84 ? local.base_name : "${substr(local.base_name, 0, 83 - length(local.suffix))}${local.suffix}"
|
||||
|
||||
// Resource names
|
||||
admin_rg_name = "${local.base_name_83}-adm-rg" // resource group used for admin resources (max 90 chars)
|
||||
app_rg_name = "${local.base_name_83}-app-rg" // app resource group (max 90 chars)
|
||||
sp_name = "${local.base_name}-sp" // service plan
|
||||
ai_name = "${local.base_name}-ai" // app insights
|
||||
kv_name = "${local.base_name_21}-kv" // key vault (max 24 chars)
|
||||
acr_name = "${replace(local.base_name_46, "-", "")}acr" // container registry (max 50 chars, alphanumeric *only*)
|
||||
vnet_name = "${local.base_name_60}-net" // virtual network (max 64 chars)
|
||||
tm_profile_name = "${local.base_name_60}-tf" // traffic manager profile (max 63 chars)
|
||||
tm_endpoint_name = "${local.region}_${local.app_id}" // traffic manager endpoint
|
||||
tm_dns_name = "${local.base_name}-dns" // traffic manager dns relative name
|
||||
appgateway_name = "${local.base_name_76}-gw" // app gateway (max 80 chars)
|
||||
public_pip_name = "${local.base_name_76}-ip" // public IP (max 80 chars)
|
||||
app_svc_name_prefix = local.base_name
|
||||
|
||||
// Resolved TF Vars
|
||||
resolved_acr_rg_name = var.azure_container_resource_group == "" ? azurerm_resource_group.svcplan.name : var.azure_container_resource_group
|
||||
resolved_acr_name = var.azure_container_resource_name == "" ? local.acr_name : var.azure_container_resource_name
|
||||
}
|
||||
|
|
@ -3,11 +3,13 @@
|
|||
# responsibility to choose the values that make sense for your application.
|
||||
#
|
||||
# Note: These values will impact the names of resources. If your deployment
|
||||
# fails due to a resource name colision, consider using different values for
|
||||
# the `name` variable.
|
||||
# fails due to a resource name collision, consider using different values for
|
||||
# the `name` variable or increasing the value for `randomization_level`.
|
||||
|
||||
resource_group_location = "eastus"
|
||||
name = "az-simple"
|
||||
randomization_level = 8
|
||||
|
||||
deployment_targets = [{
|
||||
app_name = "cobalt-backend-api",
|
||||
image_name = "msftcse/az-service-single-region",
|
||||
|
|
|
@ -86,14 +86,12 @@ func verifyRequestFails(goTest *testing.T, host string, protocol string, client
|
|||
func TestAzureSimple(t *testing.T) {
|
||||
azure.CliServicePrincipalLogin(t)
|
||||
|
||||
workspace := terraform.RunTerraformCommand(t, tfOptions, "workspace", "show")
|
||||
testFixture := infratests.IntegrationTestFixture{
|
||||
GoTest: t,
|
||||
TfOptions: tfOptions,
|
||||
ExpectedTfOutputCount: 5,
|
||||
ExpectedTfOutput: infratests.TerraformOutput{
|
||||
"app_gateway_health_probe_backend_address": "cobalt-backend-api-" + workspace + ".azurewebsites.net",
|
||||
"app_gateway_health_probe_backend_status": "Healthy",
|
||||
"app_gateway_health_probe_backend_status": "Healthy",
|
||||
},
|
||||
TfOutputAssertions: []infratests.TerraformOutputValidation{
|
||||
verifyHTTPSSuccessOnFrontEnd,
|
||||
|
|
|
@ -35,7 +35,6 @@ func asMap(t *testing.T, jsonString string) map[string]interface{} {
|
|||
|
||||
func TestTemplate(t *testing.T) {
|
||||
expectedAppServicePlan := asMap(t, `{
|
||||
"name": "cobalt-backend-api-`+workspace+`"
|
||||
}`)
|
||||
|
||||
expectedAppGatewayPlan := asMap(t, `{
|
||||
|
@ -97,18 +96,13 @@ func TestTemplate(t *testing.T) {
|
|||
TfOptions: tfOptions,
|
||||
Workspace: workspace,
|
||||
PlanAssertions: nil,
|
||||
ExpectedResourceCount: 35,
|
||||
ExpectedResourceCount: 36,
|
||||
ExpectedResourceAttributeValues: infratests.ResourceDescription{
|
||||
"azurerm_resource_group.svcplan": map[string]interface{}{
|
||||
"location": region,
|
||||
"name": "az-simple-" + workspace,
|
||||
},
|
||||
"module.app_gateway.data.azurerm_resource_group.appgateway": map[string]interface{}{
|
||||
"name": "az-simple-" + workspace,
|
||||
},
|
||||
"module.app_insight.data.azurerm_resource_group.appinsights": map[string]interface{}{
|
||||
"name": "az-simple-" + workspace,
|
||||
},
|
||||
"module.app_gateway.data.azurerm_resource_group.appgateway": map[string]interface{}{},
|
||||
"module.app_insight.data.azurerm_resource_group.appinsights": map[string]interface{}{},
|
||||
"module.app_service.azurerm_app_service_slot.appsvc_staging_slot[0]": map[string]interface{}{
|
||||
"name": "staging",
|
||||
},
|
||||
|
|
|
@ -1,24 +1,41 @@
|
|||
# Resource Group
|
||||
variable "resource_group_location" {
|
||||
description = "The deployment location of resource group container all the resources"
|
||||
// ---- General Configuration ----
|
||||
|
||||
variable "name" {
|
||||
description = "An identifier used to construct the names of all resources in this template."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "randomization_level" {
|
||||
description = "Number of additional random characters to include in resource names to insulate against unexpected resource name collisions."
|
||||
type = number
|
||||
default = 8
|
||||
}
|
||||
|
||||
variable "resource_group_location" {
|
||||
description = "The Azure region where all resources in this template should be created."
|
||||
type = string
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---- App Service Configuration ----
|
||||
|
||||
variable "application_type" {
|
||||
description = "Type of the App Insights Application. Valid values are ios for iOS, java for Java web, MobileCenter for App Center, Node.JS for Node.js, other for General, phone for Windows Phone, store for Windows Store and web for ASP.NET."
|
||||
default = "Web"
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "The name of the deployment. This will be used across the resource created in this solution"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "acr_build_git_source_url" {
|
||||
description = "The URL to a git repository (e.g., 'https://github.com/Azure-Samples/acr-build-helloworld-node.git') containing the docker build manifests."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "acr_build_docker_file" {
|
||||
description = "The relative path of the the docker file to the source code root folder. Default to 'Dockerfile'."
|
||||
type = string
|
||||
default = "Dockerfile"
|
||||
}
|
||||
|
||||
variable "deployment_targets" {
|
||||
description = "Metadata about apps to deploy, such as image metadata."
|
||||
type = list(object({
|
||||
|
@ -67,7 +84,9 @@ variable "subnet_prefixes" {
|
|||
default = ["10.0.1.0/24"]
|
||||
}
|
||||
|
||||
# Monitoring Service
|
||||
|
||||
// ---- Monitoring Service Configuration ----
|
||||
|
||||
variable "action_group_name" {
|
||||
description = "The name of the action group."
|
||||
type = string
|
||||
|
@ -133,9 +152,3 @@ variable "monitoring_dimension_values" {
|
|||
type = list(string)
|
||||
default = ["*"]
|
||||
}
|
||||
|
||||
variable "acr_build_docker_file" {
|
||||
description = "The relative path of the the docker file to the source code root folder. Default to 'Dockerfile'."
|
||||
type = string
|
||||
default = "Dockerfile"
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче