Added jumpbox for Azure Prod DB - #966
Open
SanderBuSu wants to merge 1 commit into
Open
Conversation
Comment on lines
+47
to
+52
| resource "azurerm_subnet" "jumpbox" { | ||
| name = "${var.name}-subnet" | ||
| resource_group_name = data.azurerm_resource_group.prod.name | ||
| virtual_network_name = data.azurerm_virtual_network.prod_vnet.name | ||
| address_prefixes = ["10.0.32.0/24"] # sørg for at dette er ledig i VNet'et | ||
| } |
Check failure
Code scanning / checkov
Ensure VNET subnet is configured with a Network Security Group (NSG) Error
Comment on lines
+71
to
+83
| resource "azurerm_network_security_rule" "allow_ssh" { | ||
| name = "Allow-SSH" | ||
| priority = 100 | ||
| direction = "Inbound" | ||
| access = "Allow" | ||
| protocol = "Tcp" | ||
| source_port_range = "*" | ||
| destination_port_range = "22" | ||
| source_address_prefix = "*" | ||
| destination_address_prefix = "*" | ||
| resource_group_name = azurerm_resource_group.rg.name | ||
| network_security_group_name = azurerm_network_security_group.nsg.name | ||
| } |
Check failure
Code scanning / checkov
Ensure that SSH access is restricted from the internet Error
Comment on lines
+101
to
+114
| resource "azurerm_network_interface" "nic" { | ||
| name = "${var.name}-nic" | ||
| location = azurerm_resource_group.rg.location | ||
| resource_group_name = azurerm_resource_group.rg.name | ||
|
|
||
| ip_configuration { | ||
| name = "ipcfg" | ||
| subnet_id = azurerm_subnet.jumpbox.id | ||
| private_ip_address_allocation = "Dynamic" | ||
| public_ip_address_id = azurerm_public_ip.pip.id | ||
| } | ||
|
|
||
| tags = local.common_tags | ||
| } |
Check failure
Code scanning / checkov
Ensure that Network Interfaces don't use public IPs Error
Comment on lines
+124
to
+161
| resource "azurerm_linux_virtual_machine" "vm" { | ||
| name = "${var.name}-vm" | ||
| location = azurerm_resource_group.rg.location | ||
| resource_group_name = azurerm_resource_group.rg.name | ||
| network_interface_ids = [azurerm_network_interface.nic.id] | ||
| size = var.jumpbox_vm_size | ||
| admin_username = var.admin_username | ||
| disable_password_authentication = true | ||
|
|
||
| dynamic "admin_ssh_key" { | ||
| for_each = toset(var.ssh_public_keys) | ||
| content { | ||
| username = var.admin_username | ||
| public_key = admin_ssh_key.value | ||
| } | ||
| } | ||
|
|
||
| os_disk { | ||
| caching = "ReadWrite" | ||
| storage_account_type = "Standard_LRS" | ||
| } | ||
|
|
||
| source_image_reference { | ||
| publisher = "Canonical" | ||
| offer = "0001-com-ubuntu-server-jammy" | ||
| sku = "22_04-lts" | ||
| version = "latest" | ||
| } | ||
|
|
||
| custom_data = base64encode( | ||
| templatefile("${path.module}/cloud-init.yaml.tmpl", { | ||
| timezone = "Europe/Oslo" | ||
| db_host = local.db_fqdn | ||
| }) | ||
| ) | ||
|
|
||
| tags = local.common_tags | ||
| } |
Check failure
Code scanning / checkov
Ensure Virtual Machine Extensions are not Installed Error
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
##Proposed changes
This PR introduces a secure VM jumpbox infrastructure for administering production database resources without exposing them to the public internet.
What's being added:
-Private network integration with existing production VNet and MySQL Flexible Server
Why this is needed:
The team creating the new backend for TIHLDE need real data from the production database to test there application.
The jumpbox provides a secure, auditable, and convenient way to access production database and other internal resources through a hardened VM within the private network.
Key features:
Network isolation: Deployed in its own subnet within the prod VNet with NSG rules
SSH-only access to the VM: No RDP or unnecessary services exposed
Managed identity support: Uses Azure AD authentication for state management (use_azuread_auth = true)
Infrastructure as Code: Fully versioned and reproducible with Terraform
Separate lifecycle: Can be destroyed/recreated without affecting main Lepton infrastructure
Nginx config to forward traffic to the database
##Further comments
Architecture decisions:
Why a separate Terraform workspace?
Isolated state file prevents accidental changes to production infrastructure
Independent lifecycle - can spin up/down the jumpbox without touching main app
Different update cadence - jumpbox updates don't require app deployments
Why a VM instead of Azure Bastion?
Cost-effective: Azure Bastion charges ~$140/month; a small VM is ~$15-30/month
More flexible: Can install database clients, run scripts, use as admin workstation
Familiar tooling: Standard SSH access that dev team already uses
Security considerations:
Jumpbox placed in private subnet with restricted NSG rules
Only SSH traffic allowed (port 22)
SSH key-based authentication (no passwords) to VM
Cloud-init script handles initial configuration
The script opens for direct connection to the DB, no SSH key is needed for DB access
Can be stopped when not in use to reduce costs and attack surface
Alternatives considered:
Azure Bastion: Too expensive for occasional admin tasks
VPN Gateway: Overkill for database admin; requires client config on all machines
Public database endpoint: Requiers rebuild of the database