Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
locals {
tags = { azd-env-name : var.environment_name }
sha = base64encode(sha256("${var.environment_name}${var.location}${data.azurerm_client_config.current.subscription_id}"))
resource_token = substr(replace(lower(local.sha), "[^A-Za-z0-9_]", ""), 0, 13)
cosmos_connection_string_key = "AZURE-COSMOS-CONNECTION-STRING"
api_runtime = var.repoUrl=="https://github.com/azure-samples/todo-nodejs-mongo-terraform"?"18-lts":"3.10"
}
# ------------------------------------------------------------------------------------------------------
# Deploy resource Group
# ------------------------------------------------------------------------------------------------------
variable "resource_group_name" {}

data "azurerm_resource_group" "rg" {
name = var.resource_group_name
}

# ------------------------------------------------------------------------------------------------------
# Deploy application insights
# ------------------------------------------------------------------------------------------------------
module "applicationinsights" {
source = "github.com/Azure-Samples/todo-python-mongo-terraform/infra/modules/applicationinsights"
location = var.location
rg_name = data.azurerm_resource_group.rg.name
environment_name = var.environment_name
workspace_id = module.loganalytics.LOGANALYTICS_WORKSPACE_ID
tags = local.tags
resource_token = local.resource_token
}

# ------------------------------------------------------------------------------------------------------
# Deploy log analytics
# ------------------------------------------------------------------------------------------------------
module "loganalytics" {
source = "github.com/Azure-Samples/todo-python-mongo-terraform/infra/modules/loganalytics"
location = var.location
rg_name = data.azurerm_resource_group.rg.name
tags = local.tags
resource_token = local.resource_token
}

# ------------------------------------------------------------------------------------------------------
# Deploy key vault
# ------------------------------------------------------------------------------------------------------
module "keyvault" {
source = "./modules/keyvault"
location = var.location
principal_id = var.principal_id
rg_name = data.azurerm_resource_group.rg.name
tags = local.tags
resource_token = local.resource_token
access_policy_object_ids = [module.api.IDENTITY_PRINCIPAL_ID,var.env_principal_id]
secrets = [
{
name = local.cosmos_connection_string_key
value = module.cosmos.AZURE_COSMOS_CONNECTION_STRING
}
]
}

# ------------------------------------------------------------------------------------------------------
# Deploy cosmos
# ------------------------------------------------------------------------------------------------------
module "cosmos" {
source = "github.com/Azure-Samples/todo-python-mongo-terraform/infra/modules/cosmos"
location = var.location
rg_name = data.azurerm_resource_group.rg.name
tags = local.tags
resource_token = local.resource_token
}

# ------------------------------------------------------------------------------------------------------
# Deploy app service plan
# ------------------------------------------------------------------------------------------------------
module "appserviceplan" {
source = "github.com/Azure-Samples/todo-python-mongo-terraform/infra/modules/appserviceplan"
location = var.location
rg_name = data.azurerm_resource_group.rg.name
tags = local.tags
resource_token = local.resource_token
}

# ------------------------------------------------------------------------------------------------------
# Deploy app service web app
# ------------------------------------------------------------------------------------------------------
module "web" {
source = "github.com/Azure-Samples/todo-python-mongo-terraform/infra/modules/appservicenode"
location = var.location
rg_name = data.azurerm_resource_group.rg.name
resource_token = local.resource_token

tags = merge(local.tags, { azd-service-name : "web" })
service_name = "web"
appservice_plan_id = module.appserviceplan.APPSERVICE_PLAN_ID

app_settings = {
"SCM_DO_BUILD_DURING_DEPLOYMENT" = "false"
"REACT_APP_APPLICATIONINSIGHTS_CONNECTION_STRING" = module.applicationinsights.APPLICATIONINSIGHTS_CONNECTION_STRING
"REACT_APP_API_BASE_URL" = "https://app-api-${local.resource_token}.azurewebsites.net"
}

app_command_line = "./entrypoint.sh -o ./env-config.js && pm2 serve /home/site/wwwroot --no-daemon --spa"
}

# ------------------------------------------------------------------------------------------------------
# Deploy app service api
# ------------------------------------------------------------------------------------------------------
module "api" {
source = "./modules/appservice"
location = var.location
rg_name = data.azurerm_resource_group.rg.name
resource_token = local.resource_token
runtime_version = local.api_runtime

tags = merge(local.tags, { "azd-service-name" : "api" })
service_name = "api"
appservice_plan_id = module.appserviceplan.APPSERVICE_PLAN_ID
app_settings = {
"AZURE_COSMOS_CONNECTION_STRING_KEY" = local.cosmos_connection_string_key
"AZURE_COSMOS_DATABASE_NAME" = module.cosmos.AZURE_COSMOS_DATABASE_NAME
"SCM_DO_BUILD_DURING_DEPLOYMENT" = "true"
"AZURE_KEY_VAULT_ENDPOINT" = module.keyvault.AZURE_KEY_VAULT_ENDPOINT
"APPLICATIONINSIGHTS_CONNECTION_STRING" = module.applicationinsights.APPLICATIONINSIGHTS_CONNECTION_STRING
"API_ALLOW_ORIGINS" = "https://app-web-${local.resource_token}.azurewebsites.net"
}

app_command_line = ""

identity = [{
type = "SystemAssigned"
}]
}

# ------------------------------------------------------------------------------------------------------
# Deploy app service apim
# ------------------------------------------------------------------------------------------------------
module "apim" {
count = var.useAPIM ? 1 : 0
source = "github.com/Azure-Samples/todo-python-mongo-terraform/infra/modules/apim"
name = "apim-${local.resource_token}"
location = var.location
rg_name = data.azurerm_resource_group.rg.name
tags = merge(local.tags, { "azd-service-name" : var.environment_name })
application_insights_name = module.applicationinsights.APPLICATIONINSIGHTS_NAME
sku = "Consumption"
}

# ------------------------------------------------------------------------------------------------------
# Deploy app service apim-api
# ------------------------------------------------------------------------------------------------------
module "apimApi" {
count = var.useAPIM ? 1 : 0
source = "github.com/Azure-Samples/todo-python-mongo-terraform/infra/modules/apim-api"
name = module.apim[0].APIM_SERVICE_NAME
rg_name = data.azurerm_resource_group.rg.name
web_front_end_url = module.web.URI
api_management_logger_id = module.apim[0].API_MANAGEMENT_LOGGER_ID
api_name = "todo-api"
api_display_name = "Simple Todo API"
api_path = "todo"
api_backend_url = module.api.URI
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: App-Service-with-Cosmos-using-TF
summary: Creates App Service with Cosmos using TF
description: Deploys App Service with Cosmos environment using Terraform, it is compatible with azd.
runner: Terraform
templatePath: main.tf
parameters:
- id: "environment_name"
name: "Environment Name"
required: true
type: "string"
- id: "location"
name: "Location"
required: true
type: "string"
- id: "principal_id"
name: "Principal Id"
required: true
type: "string"
- id: "env_principal_id"
name: "Env Principal Id"
required: true
type: "string"
- id: "repoUrl"
name: "Repository URL"
required: true
type: "string"
description: Path the the application source code
allowed:
- "https://github.com/azure-samples/todo-nodejs-mongo-terraform"
- "https://github.com/azure-samples/todo-python-mongo-terraform"

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
output "URI" {
value = var.runtime_version=="18-lts"?"https://${azurerm_linux_web_app.webnode[0].default_hostname}" :"https://${azurerm_linux_web_app.webpython[0].default_hostname}"
}

output "IDENTITY_PRINCIPAL_ID" {
value = var.runtime_version=="18-lts"?(length(azurerm_linux_web_app.webnode[0].identity) == 0 ? "" : azurerm_linux_web_app.webnode[0].identity.0.principal_id):length(azurerm_linux_web_app.webpython[0].identity) == 0 ? "" : azurerm_linux_web_app.webpython[0].identity.0.principal_id
sensitive = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
variable "location" {
description = "The supported Azure location where the resource deployed"
type = string
}

variable "rg_name" {
description = "The name of the resource group to deploy resources into"
type = string
}

variable "appservice_plan_id" {
description = "The id of the appservice plan to use."
type = string
}

variable "service_name" {
description = "A name to reflect the type of the app service e.g: web, api."
type = string
}

variable "app_settings" {
description = "A list of app settings pairs to be assigned to the app service"
type = map(string)
}

variable "identity" {
description = "A list of application identity"
type = list(any)
default = []
}

variable "app_command_line" {
description = "The cmd line to configure the app to run."
type = string
}

variable "tags" {
description = "A list of tags used for deployed services."
type = map(string)
}

variable "resource_token" {
description = "A suffix string to centrally mitigate resource name collisions."
type = string
}

variable "runtime_version" {
description = "the application stack python version to set for the app service."
type = string
default = "3.10"
}

variable "always_on" {
description = "The always on setting for the app service."
type = bool
default = true
}

variable "use_32_bit_worker" {
description = "The use 32 bit worker setting for the app service."
type = bool
default = false
}

variable "health_check_path" {
description = "The path to the health check endpoint"
type = string
default = ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
terraform {
required_providers {
azurerm = {
version = "~>3.47.0"
source = "hashicorp/azurerm"
}
azurecaf = {
source = "aztfmod/azurecaf"
version = "~>1.2.24"
}
}
}

# ------------------------------------------------------------------------------------------------------
# Deploy app service web app
# ------------------------------------------------------------------------------------------------------
resource "azurecaf_name" "web_name" {
name = "${var.service_name}-${var.resource_token}"
resource_type = "azurerm_app_service"
random_length = 0
clean_input = true
}


resource "azurerm_linux_web_app" "webpython" {
count = var.runtime_version=="3.10"?1:0
name = azurecaf_name.web_name.result
location = var.location
resource_group_name = var.rg_name
service_plan_id = var.appservice_plan_id
https_only = true
tags = var.tags

site_config {
always_on = var.always_on
use_32_bit_worker = var.use_32_bit_worker
ftps_state = "FtpsOnly"
app_command_line = var.app_command_line
application_stack {
python_version = var.runtime_version
}
health_check_path = var.health_check_path
}

app_settings = var.app_settings

dynamic "identity" {
for_each = { for k, v in var.identity : k => v if var.identity != [] }
content {
type = identity.value["type"]
}
}

logs {
application_logs {
file_system_level = "Verbose"
}
detailed_error_messages = true
failed_request_tracing = true
http_logs {
file_system {
retention_in_days = 1
retention_in_mb = 35
}
}
}
}
resource "azurerm_linux_web_app" "webnode" {
count = var.runtime_version=="18-lts"?1:0
name = azurecaf_name.web_name.result
location = var.location
resource_group_name = var.rg_name
service_plan_id = var.appservice_plan_id
https_only = true
tags = var.tags

site_config {
always_on = var.always_on
use_32_bit_worker = var.use_32_bit_worker
ftps_state = "FtpsOnly"
app_command_line = var.app_command_line
application_stack {
node_version = var.runtime_version
}
health_check_path = var.health_check_path
}

app_settings = var.app_settings

dynamic "identity" {
for_each = { for k, v in var.identity : k => v if var.identity != [] }
content {
type = identity.value["type"]
}
}

logs {
application_logs {
file_system_level = "Verbose"
}
detailed_error_messages = true
failed_request_tracing = true
http_logs {
file_system {
retention_in_days = 1
retention_in_mb = 35
}
}
}
}

# This is a temporary solution until the azurerm provider supports the basicPublishingCredentialsPolicies resource type
resource "null_resource" "webapp_basic_auth_disable" {
triggers = {
account = var.runtime_version=="18-lts"?azurerm_linux_web_app.webnode[0].name:azurerm_linux_web_app.webpython[0].name
}
provisioner "local-exec" {
command = "az resource update --resource-group ${var.rg_name} --name ftp --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/${var.runtime_version=="18-lts"?azurerm_linux_web_app.webnode[0].name:azurerm_linux_web_app.webpython[0].name} --set properties.allow=false && az resource update --resource-group ${var.rg_name} --name scm --namespace Microsoft.Web --resource-type basicPublishingCredentialsPolicies --parent sites/${var.runtime_version=="18-lts"?azurerm_linux_web_app.webnode[0].name:azurerm_linux_web_app.webpython[0].name} --set properties.allow=false"
}
}
Loading