Cloud architecture

The documentation of this section describes the system infrastructural architecture and example implementations. In this context, system infrastructure typically refers to fundamental physical and virtual infrastructure, including system components such as:

  • Physical and virtual machines.
  • Network devices.
  • IaaS and PaaS services that provide a fundamental system function.
  • System-level monitoring and logging.
  • System-level access control.

HeartAI system-level components are cloud-native by design, with current deployments implemented with Microsoft Azure.

Cloud infrastructure overview

HeartAI deploys to Microsoft Azure and implements modern and best-practice cloud technologies. Instances of HeartAI are often contained within corresponding Microsoft Enterprise Agreements as a subscription that bounds management, resource use, and billing. This allows HeartAI to deploy onto a corresponding Microsoft Azure Active Directory (AAD) tenancy. The system deploys to instances of Azure Virtual Networks. These networks are strictly private with no exposure of system endpoints to the public internet. The system deploys instances of Azure Key Vault as a sensitive data store, Azure Red Hat OpenShift for service orchestration, Azure Database for PostgreSQL as a managed data service, Azure Storage for general and secure cloud storage, Azure Monitor for near-real-time logging and monitoring, Azure Private DNS provides internal name resolution, Azure Network Watcher for logging and monitoring of network instances, Azure Network security groups for network traffic control, Azure DDoS Protection Standard as a modern denial-of-service mitigation framework, Azure Sentinel as an integrated and intelligent security information and event management stack, and Azure Defender for security alerts and advanced threat protection. Cloud resources are managed with the declarative Terraform infrastructure as code software tool. System resources of HeartAI are scalable, maintainable, cost-effective, and represent an implementation of best-practice hyper-converged infrastructure.

Identity and access management

Although the system implementation to Microsoft Azure deploys onto a Azure AAD tenancy, HeartAI also implements Keycloak at the service level and federates identity with AAD. Further information may be found with the following documentation:

Deploying to a development environment

In addition to the cloud- and cluster-based environments described in this documentation section, HeartAI is also deployable to a standalone development environment for the purposes of local system development. Further information about deploying HeartAI to a development environment may be found with the following documentation:

Azure naming standards

HeartAI naming standards for Azure resources follow Microsoft-recommended guidelines for resource naming and tagging:

Azure subscription for HeartAI production environment

The HeartAI production environment is managed through the following Azure Subscription:

  • sah-heartai-prod

The following Resource Groups partition the HeartAI production environment:

Resource Group Description
sah-heartai-rg-prod-keyvault-aue-001 Azure Key Vault
sah-heartai-rg-prod-tfstate-aue-001 Terraform State backend
sah-heartai-rg-prod-aue-001 HeartAI production environment resources
aro-u541ij0x HeartAI production environment resources for Microsoft Azure Red Hat OpenShift

The subsections of this page describes the roles and structures of the resources contained within these Resource Groups.

Example: Azure Portal for subscription

The following image shows the Azure Portal web interface for an Azure subscription. This interface displays:

  • Information about the subscription, including the subscription ID and resource location directory.
  • Costing by resource, including aggregated costing reports and forecasted costing.
  • Summary details about the subscription.

sah-heartai-prod subscription Azure Portal overview

heartai-azure-subscription.png

Example: Azure Portal for Resource Group

The following image shows Azure Portal for the HeartAI production environment sah-heartai-rg-prod-aue-001 Resource Group resource:

sah-heartai-rg-prod-aue-001 resource group

azure-sah-heartai-rg-prod-aue-001.png

Azure deployment overview

The following figure shows a high-level overview of Microsoft Azure cloud resources within the HeartAI production environment:

HeartAI-System-Infrastructure.svg

Terraform implementation

The HeartAI implementation of Microsoft Azure is managed with the Terraform declarative infrastructure-as-code software framework. Terraform allows for the declaration of system components using configuration files specified with the HashiCorp Configuration Language (HCL). Collections of these configuration files provide a declarative representation of HeartAI infrastructure-level components, which are synchronisable with the state of Microsoft Azure environments through the Azure Resource Manager API. Infrastructure deployment with Terraform supports HeartAI system infrastructure management in a way that is consistent, maintainable, scalable, and reproducible.

Terraform implementation

Further information about the HeartAI implementation of Terraform may be found with the following documentation:

To support the operation of this approach, the representative state of the Terraform instance is itself stored within the Azure environment and managed by Terraform. This state is used by Terraform to map resources to its local representation, keep track of metadata, and to improve performance. Terraform uses this state to coordinate synchronisations to the Azure Resource Manager API. Prior to any operation, Terraform performs a refresh to update this state with the corresponding Azure environment. For the HeartAI Azure environment, all modifications to the Azure environment are administered through Terraform, such that the Terraform state should be the representative state of the Azure environment.

The following figure shows the process through which a user agent or client may utilise Terraform to communicate with Terraform State and Microsoft Azure to perform a sychronisation of Azure resources:

heartai-azure-terraform-process.svg

Example: Terraform configuration for Azure management

The following example shows Terraform declarations to configure Terraform to utilise the Azure Resource Manager API and coordinate with corresponding Azure resources.

This implementation coordinates instances of the following Azure components:

Azure component Functionality for Terraform Azure configuration
Storage Account Persists Terraform state
Key Vault access policy Manages a SystemAssigned service principal and associates an access policy.
Key Vault key Enables Terraform state data encryption .
Storage Account customer managed key Uses the above key for data encryption
Private Endpoint Provides network endpoint within the corresponding Azure Private DNS zone
Private DNS zone A record Resolves network endpoint within the corresponding Azure Private DNS zone
provider "azurerm" {
  features {}
}


data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "rg_terraform" {
  name = "sah-heartai-rg-prod-tfstate-aue-001"
  location = "australiaeast"

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

resource "azurerm_storage_account" "terraform_state_storage" {
  name = "tfstate29819"
  resource_group_name = azurerm_resource_group.rg_terraform.name
  location = azurerm_resource_group.rg_terraform.location
  account_tier = "Standard"
  account_replication_type = "LRS"

  identity {
    type = "SystemAssigned"
  }

  network_rules {
    default_action = "Deny"
    bypass = [
      "AzureServices"]
  }

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

resource "azurerm_key_vault_access_policy" "keyvault_access_policy_terraform_storage" {
  key_vault_id = azurerm_key_vault.keyvault.id
  tenant_id = data.azurerm_client_config.current.tenant_id
  object_id = azurerm_storage_account.terraform_state_storage.identity[0].principal_id

  key_permissions = [
    "Get",
    "Create",
    "List",
    "Restore",
    "Recover",
    "Unwrapkey",
    "Wrapkey",
    "Purge",
    "Encrypt",
    "Decrypt",
    "Sign",
    "Verify"]
  secret_permissions = [
    "Get"]
}

resource "azurerm_key_vault_key" "terraform_storage_key" {
  depends_on = [
    azurerm_key_vault_access_policy.keyvault_access_policy_keyvault_client,
    azurerm_key_vault_access_policy.keyvault_access_policy_terraform_storage
  ]

  name = "sah-heartai-terraform-state-sa-key"
  key_vault_id = azurerm_key_vault.keyvault.id
  key_type = "RSA"
  key_size = 2048
  key_opts = [
    "decrypt",
    "encrypt",
    "sign",
    "unwrapKey",
    "verify",
    "wrapKey"]
}

resource "azurerm_storage_account_customer_managed_key" "terraform_state_storage_cmk" {
  storage_account_id = azurerm_storage_account.terraform_state_storage.id
  key_vault_id = azurerm_key_vault.keyvault.id
  key_name = azurerm_key_vault_key.terraform_storage_key.name
}

resource "azurerm_private_endpoint" "terraform_state_storage_private_endpoint" {
  depends_on = [
    azurerm_resource_group.rg,
    azurerm_virtual_network.vnet,
    azurerm_subnet.snet_paas,
    azurerm_storage_account.terraform_state_storage]
  name = "sah-heartai-pe-sa-terraform-state-prod-aue-001"
  location = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  subnet_id = azurerm_subnet.snet_paas.id

  private_service_connection {
    name = "sah-heartai-pe-sa-terraform-state-prod-aue-001"
    is_manual_connection = false
    private_connection_resource_id = azurerm_storage_account.terraform_state_storage.id
    subresource_names = [
      "blob"]
  }

  private_dns_zone_group {
    name = azurerm_private_dns_zone.azure_storage_blob_dns_private.name
    private_dns_zone_ids = [
      azurerm_private_dns_zone.azure_storage_blob_dns_private.id]
  }

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

data "azurerm_private_endpoint_connection" "terraform_state_storage_private_endpoint_connection" {
  depends_on = [
    azurerm_resource_group.rg,
    azurerm_private_endpoint.terraform_state_storage_private_endpoint]
  name = azurerm_private_endpoint.terraform_state_storage_private_endpoint.name
  resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_private_dns_a_record" "terraform_state_storage_dns_a_record" {
  depends_on = [
    azurerm_resource_group.rg,
    azurerm_storage_account.terraform_state_storage,
    azurerm_private_dns_zone.azure_storage_blob_dns_private,
    data.azurerm_private_endpoint_connection.terraform_state_storage_private_endpoint_connection]
  name = lower(azurerm_storage_account.terraform_state_storage.name)
  zone_name = azurerm_private_dns_zone.azure_storage_blob_dns_private.name
  resource_group_name = azurerm_resource_group.rg.name
  ttl = 300
  records = [
    data.azurerm_private_endpoint_connection.terraform_state_storage_private_endpoint_connection.private_service_connection.0.private_ip_address]

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

output terraform_state_storage_private_ip {
  value = data.azurerm_private_endpoint_connection.terraform_state_storage_private_endpoint_connection.private_service_connection.0.private_ip_address
}

terraform {
  backend "azurerm" {
    resource_group_name = "sah-heartai-rg-prod-tfstate-aue-001"
    storage_account_name = "tfstate29819"
    container_name = "tfstate"
    key = "terraform-tfstate-prod-dnszone"
  }

  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "=2.49.0"
    }
    postgresql = {
      source  = "cyrilgdn/postgresql"
    }
    random = {
      source  = "hashicorp/random"
    }
  }
}

Azure Virtual Network

Azure Virtual Network (VNet) provides cloud-hosted networking infrastructure. HeartAI services do not expose network endpoints to the public internet - All network resolution occurs internal to the HeartAI network or through private network extension.

HeartAI Azure Virtual Network address spaces

Network name Description Network address range Hosting network
sah-heartai-vnet-prod-aue-001 HeartAI production environment 10.X.X.0/24 Microsoft Azure
sah-heartai-vnet-test-aue-001 HeartAI testing environment 10.X.X.0/24 Microsoft Azure

The HeartAI production environment partitions an Azure Virtual Network to the following subnetworks:

HeartAI production environment subnetworks

Subnet name Description Subnet address Address range Available IPs Hosts
sah-heartai-snet-aroworker-prod-aue-001 Azure Red Hat Openshift worker nodes 10.X.X.0/25 10.X.X.0 - 10.X.X.127 10.X.X.1 - 10.X.X.126 126
sah-heartai-snet-aromaster-prod-aue-002 Azure Red Hat Openshift master nodes 10.X.X.128/27 10.X.X.128 - 10.X.X.159 10.X.X.129 - 10.X.X.158 30
Subnet range unassigned 10.X.X.160/27 10.X.X.160 - 10.X.X.191 10.X.X.161 - 10.X.X.190 30
sah-heartai-snet-paas-prod-aue-004 Azure PaaS endpoints 10.X.X.192/26 10.X.X.192 - 10.X.X.255 10.X.X.193 - 10.X.X.254 62
Network architecture

Further information about HeartAI network archtecture may be found with the following documentation:

The following example shows Terraform declarations to specify an Azure Virtual Network. This implementation coordinates instances of the following Azure components:

Azure component Functionality for Azure Virtual Network
Private DNS Provides private name resolution for Azure Storage Account network endpoints within the corresponding Azure Private DNS zone
Virtual Network Configures and deploys an Azure Virtual Network
Network Watcher Integrates an instance of Azure Network Watcher to a corresponding Azure Virtual Network
resource "azurerm_private_dns_zone" "heartai-dns-private" {
  name = "sah.heartai.net"
  resource_group_name = azurerm_resource_group.rg.name

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

resource "azurerm_virtual_network" "vnet" {
  name = "sah-heartai-vnet-prod-aue-001"
  location = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  address_space = [
    var.vnet-prod-aue-001-address-space.vnet]

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

resource "azurerm_subnet" "snet_aroworker" {
  name = "sah-heartai-snet-aroworker-prod-aue-001"
  resource_group_name = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes = [
    var.vnet-prod-aue-001-address-space.snet1]
  service_endpoints = [
    "Microsoft.ContainerRegistry"]
  enforce_private_link_endpoint_network_policies = true
}

resource "azurerm_subnet" "snet_aromaster" {
  name = "sah-heartai-snet-aromaster-prod-aue-002"
  resource_group_name = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes = [
    var.vnet-prod-aue-001-address-space.snet2]
  service_endpoints = [
    "Microsoft.ContainerRegistry"]
  enforce_private_link_service_network_policies = true
}

resource "azurerm_subnet" "snet_vpn_gateway" {
  name = "GatewaySubnet"
  resource_group_name = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes = [
    var.vnet-prod-aue-001-address-space.snet3]
  enforce_private_link_endpoint_network_policies = true
}

resource "azurerm_subnet" "snet_paas" {
  name = "sah-heartai-snet-paas-prod-aue-004"
  resource_group_name = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes = [
    var.vnet-prod-aue-001-address-space.snet4]
  enforce_private_link_endpoint_network_policies = true
}

resource "azurerm_network_watcher" "network_watcher" {
  name = "NetworkWatcher_australiaeast"
  location = "australiaeast"
  resource_group_name = "NetworkWatcherRG"

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

Azure Private Link

Azure Private Link provides networking approaches to securely interface with Azure cloud services, such as Azure Key Vault, Azure Database for PostgreSQL, and Azure Cosmos DB. Through private link these service endpoints addresses extend onto the HeartAI virtual network and are routable entirely through the Microsoft backbone network.

Example: Azure Key Vault private endpoint

The following Terraform declaration shows the HeartAI production environment Azure Private Link private endpoint for the system instance of Azure Key Vault. This implementation coordinates instances of the following Azure components:

Azure component Functionality for Azure Key Vault private endpoint
Azure Private DNS Provides private name resolution for Azure Key Vault network endpoints within the corresponding Private DNS zone
Storage Account customer managed key Uses the above key for data encryption
Private Endpoint Provides network endpoint within the corresponding Azure Private DNS zone
Private DNS zone A record Resolves network endpoint within the corresponding Azure Private DNS zone
Azure Virtual Network Link Exposes Azure Key Vault network endpoints within the corresponding Azure Virtual Network
resource "azurerm_private_dns_zone" "keyvault_dns_private" {
  name = "privatelink.vaultcore.azure.net"
  resource_group_name = azurerm_resource_group.rg.name

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

resource "azurerm_private_endpoint" "keyvault_private_endpoint" {
  depends_on = [
    azurerm_key_vault.keyvault]
  name = "sah-heartai-pe-kv-prod-aue-001"
  location = azurerm_resource_group.rg_keyvault.location
  resource_group_name = azurerm_resource_group.rg_keyvault.name
  subnet_id = azurerm_subnet.snet_paas.id

  private_service_connection {
    name = "sah-heartai-pe-kv-prod-aue-001"
    is_manual_connection = false
    private_connection_resource_id = azurerm_key_vault.keyvault.id
    subresource_names = [
      "vault"]
  }

  private_dns_zone_group {
    name = azurerm_private_dns_zone.keyvault_dns_private.name
    private_dns_zone_ids = [azurerm_private_dns_zone.keyvault_dns_private.id]
  }

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

data "azurerm_private_endpoint_connection" "keyvault_private_endpoint_connection" {
  depends_on = [
    azurerm_private_endpoint.keyvault_private_endpoint]
  name = azurerm_private_endpoint.keyvault_private_endpoint.name
  resource_group_name = azurerm_resource_group.rg_keyvault.name
}

resource "azurerm_private_dns_a_record" "keyvault_dns_a_record" {
  depends_on = [
    azurerm_key_vault.keyvault]
  name = lower(azurerm_key_vault.keyvault.name)
  zone_name = azurerm_private_dns_zone.keyvault_dns_private.name
  resource_group_name = azurerm_resource_group.rg.name
  ttl = 300
  records = [
    data.azurerm_private_endpoint_connection.keyvault_private_endpoint_connection.private_service_connection.0.private_ip_address]

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

resource "azurerm_private_dns_zone_virtual_network_link" "keyvault_dns_vnet_link" {
  name                  = "sah-heartai-keyvault-vnetlink-prod-aue-001"
  resource_group_name   = azurerm_resource_group.rg.name
  private_dns_zone_name = azurerm_private_dns_zone.keyvault_dns_private.name
  virtual_network_id    = azurerm_virtual_network.vnet.id

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

output keyvault_private_ip {
  value = data.azurerm_private_endpoint_connection.keyvault_private_endpoint_connection.private_service_connection.0.private_ip_address
}

Azure Key Vault

Azure Key Vault provides a secure store for sensitive data such as cryptographic keys and configuration secrets. These sensitive values are injectable to system environments by calling Key Vault and retrieving the corresponding data. The following features support the HeartAI system:

  • Applications and secrets have no direct access to keys.
  • Encryption keys may be created and imported within minutes.
  • Highly available with 99.9% availability.
  • Transaction processing within 5 seconds.

The HeartAI system provisions the following Azure Key Vault resources:

Resource Specification
Region Australia East
Operations 10,000 / month
OpenShift sensitive key-value stores

In addition to the infrastructural-level sensitive key-value store provided by Azure Key Vault, the HeartAI system Azure Red Hat OpenShift implements integrated sensitive key-value stores with Kubernetes Secrets functionalities.

Further information about the HeartAI implementation of Red Hat OpenShift may be found with the following documentation:

The following example shows Terraform declarations to configure and deploy an instance of Azure Key Vault. This implementation coordinates instances of the following Azure components:

Azure component Functionality for Azure Key Vault
Azure Key Vault Configure and deploy an instance of Azure Key Vault
resource "azurerm_key_vault" "keyvault" {
  name = "sah-heartai-kv-prod"
  resource_group_name = azurerm_resource_group.rg_keyvault.name
  location = azurerm_resource_group.rg_keyvault.location
  enabled_for_disk_encryption = true
  tenant_id = data.azurerm_client_config.client.tenant_id
  soft_delete_retention_days = var.kv_prod_aue_001_soft_delete_retention_days
  purge_protection_enabled = true

  sku_name = "standard"

  network_acls {
    default_action = "Deny"
    bypass = "AzureServices"
  }

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

Azure Database for PostgreSQL

Azure Database for PostgreSQL provides a fully-managed PostgreSQL database service. The following features support the HeartAI system:

  • Highly available with 99.99% availability.
  • Data redundancy with 3x replication.

The HeartAI production environment provisions the following Azure Database for PostgreSQL instance:

Resource Specification
Region Australia East
Database option Single server
Tier General purpose
Compute Gen 5, 2 vCPU
Service usage 730 hours / month
Storage 50 GB
Redundancy Geo-redundant storage
Savings options Pay as you go

The following example shows Terraform declarations to configure and deploy an instance of Azure Database for PostgreSQL. This implementation coordinates instances of the following Azure components:

Azure component Functionality for Azure Database for PostgreSQL
Private DNS Provides private name resolution for Azure Database for PostgreSQL network endpoints within the corresponding Private DNS zone
Azure Database for PostgreSQL Configures and deploys an instance of Azure Database for PostgreSQL
Virtual Network Link Exposes Azure Database for PostgreSQL network endpoints within the corresponding Azure Virtual Network
Private endpoint Provides network endpoint within the corresponding Azure Private DNS zone
Private DNS zone A record Resolves Azure Database for PostgreSQL network endpoints within the corresponding Azure Private DNS zone
Key Vault access policy Assigns an access policy to the Azure Database for PostgresSQL SystemAssigned service principal.
Key Vault key Enables data encryption .
PostgreSQL server key Uses the above key for data encryption
resource "azurerm_private_dns_zone" "postgresql_dns_private" {
  depends_on = [
    azurerm_resource_group.rg]
  name = "privatelink.postgres.database.azure.com"
  resource_group_name = azurerm_resource_group.rg.name

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

resource "azurerm_postgresql_server" "postgresql" {
  name = "sah-heartai-psql-prod-aue-001"
  location = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  administrator_login = var.postgres_admin_credentials_id
  administrator_login_password = var.postgres_admin_credentials_key

  sku_name = "GP_Gen5_2"
  version = "11"
  storage_mb = 51200

  backup_retention_days = var.postgres_backup_retention_days
  geo_redundant_backup_enabled = true
  auto_grow_enabled = true

  public_network_access_enabled = false
  ssl_enforcement_enabled = true
  ssl_minimal_tls_version_enforced = "TLS1_2"

  identity {
    type = "SystemAssigned"
  }

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

resource "azurerm_private_dns_zone_virtual_network_link" "postgresql_dns_vnet_link" {
  depends_on = [
    azurerm_resource_group.rg,
    azurerm_virtual_network.vnet,
    azurerm_private_dns_zone.postgresql_dns_private]
  name = "sah-heartai-psql-vnetlink-prod-aue-001"
  resource_group_name = azurerm_resource_group.rg.name
  private_dns_zone_name = azurerm_private_dns_zone.postgresql_dns_private.name
  virtual_network_id = azurerm_virtual_network.vnet.id
}

resource "azurerm_private_endpoint" "postgresql_private_endpoint" {
  depends_on = [
    azurerm_resource_group.rg,
    azurerm_virtual_network.vnet,
    azurerm_subnet.snet_paas,
    azurerm_postgresql_server.postgresql]
  name = "sah-heartai-pe-psql-prod-aue-001"
  location = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  subnet_id = azurerm_subnet.snet_paas.id

  private_service_connection {
    name = "sah-heartai-pe-psql-prod-aue-001"
    is_manual_connection = false
    private_connection_resource_id = azurerm_postgresql_server.postgresql.id
    subresource_names = [
      "postgresqlServer"]
  }

  private_dns_zone_group {
    name = azurerm_private_dns_zone.postgresql_dns_private.name
    private_dns_zone_ids = [
      azurerm_private_dns_zone.postgresql_dns_private.id]
  }

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

data "azurerm_private_endpoint_connection" "postgres_private_endpoint_connection" {
  depends_on = [
    azurerm_resource_group.rg,
    azurerm_private_endpoint.postgresql_private_endpoint]
  name = azurerm_private_endpoint.postgresql_private_endpoint.name
  resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_private_dns_a_record" "postgresql_dns_a_record" {
  depends_on = [
    azurerm_resource_group.rg,
    azurerm_postgresql_server.postgresql,
    azurerm_private_dns_zone.postgresql_dns_private,
    data.azurerm_private_endpoint_connection.postgres_private_endpoint_connection]
  name = lower(azurerm_postgresql_server.postgresql.name)
  zone_name = azurerm_private_dns_zone.postgresql_dns_private.name
  resource_group_name = azurerm_resource_group.rg.name
  ttl = 300
  records = [
    data.azurerm_private_endpoint_connection.postgres_private_endpoint_connection.private_service_connection.0.private_ip_address]

  tags = {
    "Application Name" = var.heartai-environment.application-name
    "Application Owner" = var.heartai-environment.application-owner
    "Environment" = var.heartai-environment.environment
    "Division Department" = var.heartai-environment.division-department
    "Cost Centre" = var.heartai-environment.cost-centre
  }
}

resource "azurerm_key_vault_access_policy" "keyvault_access_policy_postgresql_server" {
  depends_on = [
    azurerm_key_vault.keyvault,
    data.azurerm_client_config.client,
    azurerm_postgresql_server.postgresql]
  key_vault_id = azurerm_key_vault.keyvault.id
  tenant_id = data.azurerm_client_config.current.tenant_id
  object_id = azurerm_postgresql_server.postgresql.identity[0].principal_id

  key_permissions = [
    "Get",
    "Unwrapkey",
    "Wrapkey"]
  secret_permissions = [
    "Get"]
}

resource "azurerm_key_vault_key" "postgresql_key" {
  depends_on = [
    azurerm_key_vault_access_policy.keyvault_access_policy_keyvault_client,
    azurerm_key_vault_access_policy.keyvault_access_policy_postgresql_server]

  name = "sah-heartai-psql-key"
  key_vault_id = azurerm_key_vault.keyvault.id
  key_type = "RSA"
  key_size = 2048
  key_opts = [
    "decrypt",
    "encrypt",
    "sign",
    "unwrapKey",
    "verify",
    "wrapKey"]
}

resource "azurerm_postgresql_server_key" "postgresql_key" {
  depends_on = [
    azurerm_postgresql_server.postgresql,
    azurerm_key_vault_key.postgresql_key]
  server_id = azurerm_postgresql_server.postgresql.id
  key_vault_key_id = azurerm_key_vault_key.postgresql_key.id
}

Azure Red Hat OpenShift

Microsoft Azure Red Hat OpenShift provides a fully managed Red Hat OpenShift service on Microsoft Azure. The following features support the HeartAI system:

  • Fully managed Red Hat OpenShift cluster.
  • Fully managed infrastructure for master and worker nodes.
  • Enhanced security with integration through Azure Active Directory.
  • Highly available with 99.95% availability.
  • Jointly engineered and operated by Microsoft and Red Hat.
Red Hat OpenShift implementation

HeartAI orchestrates system services with the Kubernetes-based Red Hat OpenShift container platform. Further information about the HeartAI implementation of Red Hat OpenShift may be found with the following documentation:

The HeartAI production environment deploys Azure Red Hat OpenShift with the following specifications:

Resource Specification
Region Australia East
Version Red Hat OpenShift 4
Master nodes 3
Master node compute D8s v3: 8 vCPUs, 32 GB RAM
Master node storage P30: 1024 GiB, 5000 IOPS, 200 MB/sec
Worker nodes 3
Worker node compute D4s v3: 4 vCPUs, 16 GB RAM
Worker storage P10: 128 GiB, 500 IOPS, 100 MB/sec
Savings options Pay as you go
OpenShift implementation

HeartAI orchestrates system services with the Kubernetes-compliant Red Hat OpenShift container platform. Further information about the HeartAI implementation of Red Hat OpenShift may be found with the following documentation:

Example: OpenShift console

The following image shows the OpenShift console overview dashboard for the HeartAI production environment:

openshift-console-cluster-overview.png

Example: OpenShift console for cluster Nodes

The following image shows the OpenShift console for cluster Nodes:

openshift-console-cluster-nodes.png

Example: Azure Portal for Resource Group of Red Hat OpenShift resources

The following image shows Azure Portal for the aro-u541ij0x Resource Group, which is dynamically generated alongside a deployment of Microsoft Azure Red Hat OpenShift. The resources in this Resource Group are managed by Azure.

azure-sah-heartai-arorg-prod-aue-001.png