Skip to content
Merged
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
Empty file added core
Empty file.
64 changes: 64 additions & 0 deletions infrastructure/modules/container-apps/jobs.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
locals {
scheduled_jobs = {
collect_metrics = {
cron_expression = "0 */6 * * *"
environment_variables = {
ENVIRONMENT = var.environment
}
job_short_name = "rs"
job_container_args = "request_summary"
}
}
}

module "db_setup" {
source = "../dtos-devops-templates/infrastructure/modules/container-app-job"

Expand Down Expand Up @@ -25,3 +38,54 @@ module "db_setup" {
]

}

module "scheduled_jobs" {
source = "../dtos-devops-templates/infrastructure/modules/container-app-job"

for_each = local.scheduled_jobs

name = "${var.app_short_name}-${each.value.job_short_name}-${var.environment}"
container_app_environment_id = var.container_app_environment_id
resource_group_name = azurerm_resource_group.main.name

fetch_secrets_from_app_key_vault = var.fetch_secrets_from_app_key_vault
app_key_vault_id = var.app_key_vault_id

container_command = ["/bin/sh", "-c"]
container_args = [
"python manage.py ${each.value.job_container_args}"
]

docker_image = var.docker_image
replica_retry_limit = 0
user_assigned_identity_ids = flatten([
[module.azure_blob_storage_identity.id],
var.deploy_database_as_container ? [] : [module.db_connect_identity[0].id]
])

environment_variables = merge(
local.common_env,
{
"STORAGE_ACCOUNT_NAME" = module.storage.storage_account_name,
"BLOB_MI_CLIENT_ID" = module.azure_blob_storage_identity.client_id,
},
each.value.environment_variables,
var.deploy_database_as_container ? local.container_db_env : local.azure_db_env
)
secret_variables = merge(
{ SLACK_WEBHOOK_URL = var.slack_webhook_url },
var.deploy_database_as_container ? { DATABASE_PASSWORD = resource.random_password.admin_password[0].result } : {}
)

# alerts
action_group_id = var.action_group_id
enable_alerting = var.enable_alerting
log_analytics_workspace_id = var.log_analytics_workspace_audit_id

# Ensure RBAC role assignments are created before the job definition finalizes
depends_on = [
module.blob_storage_role_assignment,
]

cron_expression = each.value.cron_expression
}
5 changes: 5 additions & 0 deletions infrastructure/modules/container-apps/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ variable "infra_key_vault_rg" {
type = string
}

variable "slack_webhook_url" {
description = "slack_webhook_url is the URL used to send alerts to Slack. It should be stored as a secret in the infra key vault with the name 'slack-webhook-url'."
type = string
}

locals {
resource_group_name = "rg-${var.app_short_name}-${var.environment}-container-app-uks"

Expand Down
24 changes: 24 additions & 0 deletions infrastructure/modules/infra/logic_app.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module "logic_app_slack_alert" {
count = var.enable_alerting ? 1 : 0

source = "../dtos-devops-templates/infrastructure/modules/logic-app-slack-alert"

name = "logic-${var.app_short_name}-${var.environment}-slack-alerts"
resource_group_name = azurerm_resource_group.main.name
location = var.region
slack_webhook_url = var.slack_webhook_url
}

resource "azurerm_monitor_action_group" "slack" {
count = var.enable_alerting ? 1 : 0

name = "ag-slack-${var.app_short_name}-${var.environment}-uks"
resource_group_name = azurerm_resource_group.main.name
short_name = "slack"

webhook_receiver {
name = "logic-app-slack"
service_uri = module.logic_app_slack_alert[0].trigger_callback_url
use_common_alert_schema = true
}
}
5 changes: 5 additions & 0 deletions infrastructure/modules/infra/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ variable "enable_alerting" {
type = bool
}

variable "slack_webhook_url" {
description = "slack_webhook_url is the URL used to send alerts to Slack. It should be stored as a secret in the infra key vault with the name 'slack-webhook-url'."
type = string
}

locals {
hub_vnet_rg_name = "rg-hub-${var.hub}-uks-bootstrap"
hub_vnet_name = "vnet-hub-${var.hub}-uks"
Expand Down
14 changes: 14 additions & 0 deletions infrastructure/terraform/spoke/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,17 @@ data "azurerm_application_insights" "app_insights" {
name = "appi-${var.env_config}-uks-${var.app_short_name}"
resource_group_name = local.resource_group_name
}

data "azurerm_key_vault" "infra" {
provider = azurerm.hub

name = local.infra_key_vault_name
resource_group_name = local.infra_key_vault_rg
}

data "azurerm_key_vault_secret" "slack_webhook_url" {
name = "slack-webhook-url"
key_vault_id = data.azurerm_key_vault.infra.id
}

# git-sha-a85180497c23d742b5f92262b3b43069e44a4110
2 changes: 2 additions & 0 deletions infrastructure/terraform/spoke/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module "infra" {
vnet_address_space = var.vnet_address_space
cae_zone_redundancy_enabled = var.cae_zone_redundancy_enabled
enable_alerting = var.enable_alerting
slack_webhook_url = data.azurerm_key_vault_secret.slack_webhook_url.value
}

module "container-apps" {
Expand Down Expand Up @@ -69,4 +70,5 @@ module "container-apps" {
use_apex_domain = var.use_apex_domain
container_memory = var.container_memory
min_replicas = var.min_replicas
slack_webhook_url = data.azurerm_key_vault_secret.slack_webhook_url.value
}
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import logging
import os

import requests
from django.core.management.base import BaseCommand, CommandError
from lung_cancer_screening.questions.services.request_summary import RequestSummary

logger = logging.getLogger(__name__)

class Command(BaseCommand):
help = "Counts the number of submitted requests."

def handle(self, *args, **options):

logger.info("Command: Request Summary.")
try:
rs = RequestSummary()
summary = rs.get_summary()

self.stdout.write(str(summary))

slack_webhook_url = os.environ.get("SLACK_WEBHOOK_URL")

if not slack_webhook_url:
logger.warning("SLACK_WEBHOOK_URL is not set; skipping Slack notification.")
return

payload = {
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Request Summary",
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": f"*Requests:*\n{rs.get_count()}"
},
{
"type": "mrkdwn",
"text": f"*Submitted:*\n{rs.get_submitted_count()}"
}
]
}
]
}

response = requests.post(
slack_webhook_url,
json=payload,
timeout=10,
)
response.raise_for_status()

logger.info("Request summary sent to Slack.")

except Exception as e:
logger.error(e, exc_info=True)
raise CommandError(e)
Empty file.
23 changes: 23 additions & 0 deletions lung_cancer_screening/questions/services/request_summary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import logging
from ..models.response_set import ResponseSet

logger = logging.getLogger(__name__)

class RequestSummary:

def __init__(self):
logger.info("RequestSummary: init")

def get_submitted_count(self):

return ResponseSet.objects.submitted().count()

def get_count(self):

return ResponseSet.objects.count()

def get_summary(self):
return {
"total": self.get_count(),
"submitted": self.get_submitted_count(),
}
1 change: 1 addition & 0 deletions scripts/terraform/terraform.mk
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ prod: # Target the prod environment - make prod <action>
review: # Target the review infrastructure, or a review app if PR_NUMBER is used - make review <action> [PR_NUMBER=<pr_number>]
$(eval include infrastructure/environments/review/variables.sh)
$(if ${PR_NUMBER}, $(eval export TF_VAR_deploy_infra=false), $(eval export TF_VAR_deploy_container_apps=true))
$(if ${PR_NUMBER},,$(eval export TF_VAR_deploy_container_apps=false))
$(if ${PR_NUMBER}, $(eval export ENVIRONMENT=pr-${PR_NUMBER}), $(eval export ENVIRONMENT=review))

db-setup:
Expand Down
Loading