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
6 changes: 3 additions & 3 deletions 03-Azure/01-03-Infrastructure/01_Sovereign_Cloud/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ This Hackathon has a few but important prerequisites
In order to use the Hackathon time most effectively, the following tasks should be completed prior to starting the session.

> [!NOTE]
> Prerequisites 1 - 3 are handled by the organizers for events hosted by Microsoft.
> For eligible Microsoft-hosted events, use the [Hacks Console runbook](./resources/hosted-events/readme.md). Outside those events, use [manual infrastructure setup](./resources/manual-setup/readme.md). Both paths require LocalBox preparation and health validation before participants begin.

1. Your own Azure subscription with Owner RBAC rights at the subscription level
2. Contributor or Owner permissions on your subscription or resource group
Expand All @@ -73,7 +73,7 @@ The shared Challenge 4/5/7 platform requires **4 AMD SEV-SNP confidential-family
The default candidate order is Sweden Central/v5, Spain Central/v5, Sweden Central/v6, then Spain Central/v6. Shared preparation persists the first candidate with supported VM sizes and sufficient confidential-family, DSv5-family, and regional quota so every participant deployment in that subscription uses the same selection.

```powershell
./resources/subscription-preparations/2-vcpu-quotas.ps1 -Region swedencentral -NumberOfLabUsers 2 -ConfidentialVmGeneration v5 -SubmitQuotaRequests
./resources/manual-setup/subscription-preparations/2-vcpu-quotas.ps1 -Region swedencentral -NumberOfLabUsers 2 -ConfidentialVmGeneration v5 -SubmitQuotaRequests
```

Run the check for `spaincentral` as well if it should remain available for fallback. If v5 is restricted for the subscription, repeat the checks with `-ConfidentialVmGeneration v6`.
Expand All @@ -94,7 +94,7 @@ Use the AZQR report for planning and preferred-region ordering, not as the deplo

The main cost driver for this Hackathon is virtual machines:

- **LocalBox** cost is approximately 100-110 USD per day. We recommend setting it up the week before the event, so for example 5 days before the event would result in a cost between 5-600 USD.
- **LocalBox** cost is approximately 100-110 USD per subscription per day. For hosted events, schedule provisioning at least 24 hours ahead and budget for preparation time; avoid leaving it running for a week by default. Follow the [hosted-event budget guidance](./resources/hosted-events/readme.md).
- **Challenges 4, 5, and 7** share one pre-provisioned participant platform: a two-node AKS system pool, one Confidential VM AKS node, one standalone Confidential VM, one K3s VM, Azure Bastion Standard, and a NAT Gateway. Budget approximately 45-55 USD per participant per day, depending on region and data transfer. The platform starts during lab deployment so participants can focus on validation rather than waiting for capacity-sensitive resources.
- Plan subscription quotas for at least 12 general-purpose vCPUs and 4 DCasv5- or DCasv6-family confidential vCPUs per participant. Keep the default maximum of two participants per subscription unless larger aggregate increases have been approved in advance.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Challenge 1 - Enforce Sovereign Controls with Azure Policy and RBAC

**[Home](../Readme.md)** - [Next Challenge](challenge-02.md)

- All policy assignments in this challenge should be scoped to your own resource group (e.g. "LabUser-01")
- All resources created in Microsoft Entra should be prefixed with your prefix (e.g. "LabUser01")

Expand Down Expand Up @@ -37,15 +35,3 @@ The goal of this exercise is to establish foundational sovereign cloud governanc
- [Azure RBAC overview](https://learn.microsoft.com/azure/role-based-access-control/overview)
- [Create custom roles for Azure RBAC](https://learn.microsoft.com/azure/role-based-access-control/custom-roles)
- [Remediate non-compliant resources](https://learn.microsoft.com/azure/governance/policy/how-to/remediate-resources)

## Solution

> [!TIP]
> We encourage you to try solving the challenge on your own before looking at the solution. This will help you learn and understand the concepts better.

<details>
<summary>Click here to view the solution</summary>

[Solution for Challenge 1](../walkthrough/challenge-01/solution-01.md)

</details>
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Challenge 2 - Encryption at Rest with Customer-Managed Keys (CMKs) in Azure Key Vault

[Previous Challenge](challenge-01.md) - **[Home](../Readme.md)** - [Next Challenge](challenge-03.md)

## Goal

Understand Customer-Managed Keys in Azure Key Vault. Configure an Azure Storage account to use a customer-managed key stored in Azure Key Vault (or Azure Managed HSM) for encryption at rest. Validate the configuration and understand operational considerations for sovereign scenarios.
Expand All @@ -27,15 +25,3 @@ Understand Customer-Managed Keys in Azure Key Vault. Configure an Azure Storage
* [What is Azure Key Vault Managed HSM?](https://learn.microsoft.com/azure/key-vault/managed-hsm/overview)
* [Azure Key & Certificate Management](https://learn.microsoft.com/azure/key-vault/general/overview)
* [Services that support CMKs with Key Vault & Managed HSM](https://learn.microsoft.com/azure/security/fundamentals/encryption-customer-managed-keys-support)

## Solution

> [!TIP]
> We encourage you to try solving the challenge on your own before looking at the solution. This will help you learn and understand the concepts better.

<details>
<summary>Click here to view the solution</summary>

[Solution for Challenge 2](../walkthrough/challenge-02/solution-02.md)

</details>
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Challenge 3 - Encryption in transit: enforcing TLS

[Previous Challenge](challenge-02.md) - **[Home](../Readme.md)** - [Next Challenge](challenge-04.md)

## Goal

Understand encryption in transit considerations for sovereign scenarios. Verify that Azure Storage accounts require secure transfer (HTTPS only), confirm the TLS 1.2+ baseline, apply Azure Policy for governance, and monitor client protocol usage through Log Analytics.
Expand All @@ -27,15 +25,3 @@ Understand encryption in transit considerations for sovereign scenarios. Verify
* [Enforce a minimum required TLS version for Storage](https://learn.microsoft.com/azure/storage/common/transport-layer-security-configure-minimum-version)
* [Azure Resource Manager TLS support](https://learn.microsoft.com/azure/azure-resource-manager/management/tls-support)
* [Policy: Storage accounts should have the specified minimum TLS version](https://learn.microsoft.com/azure/storage/common/transport-layer-security-configure-minimum-version?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&tabs=portal#detect-the-tls-version-used-by-client-applications)

## Solution

> [!TIP]
> We encourage you to try solving the challenge on your own before looking at the solution. This will help you learn and understand the concepts better.

<details>
<summary>Click here to view the solution</summary>

[Solution for Challenge 3](../walkthrough/challenge-03/solution-03.md)

</details>
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Challenge 4 - Encryption in use with Azure Confidential Compute – VM

[Previous Challenge](challenge-03.md) - **[Home](../Readme.md)** - [Next Challenge](challenge-05.md)

## Goal

Validate guest attestation on a pre-provisioned Azure Confidential VM to confirm that business logic only executes in a trusted, hardware-backed confidential computing environment. You will inspect the VM's security configuration, connect through Azure Bastion using username/password credentials, build and run a sample attestation application, and verify the cryptographic JWT proof of VM integrity using a dedicated Microsoft Azure Attestation (MAA) provider.
Expand All @@ -24,15 +22,3 @@ Validate guest attestation on a pre-provisioned Azure Confidential VM to confirm
* [Azure Confidential Computing Overview](https://learn.microsoft.com/azure/confidential-computing/overview)
* [Microsoft Azure Attestation](https://learn.microsoft.com/azure/attestation/overview)
* [About Azure confidential VMs](https://learn.microsoft.com/azure/confidential-computing/confidential-vm-overview)

## Solution

> [!TIP]
> We encourage you to try solving the challenge on your own before looking at the solution. This will help you learn and understand the concepts better.

<details>
<summary>Click here to view the solution</summary>

[Solution for Challenge 4](../walkthrough/challenge-04/solution-04.md)

</details>
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Challenge 5 - Encryption in use with Confidential VMs/Node Pools in Azure Kubernetes Service (AKS)

[Previous Challenge](challenge-04.md) - **[Home](../Readme.md)** - [Next Challenge](challenge-06.md)

## Goal

Validate guest attestation on a pre-provisioned Azure Confidential VM node pool in AKS to ensure business logic only executes in trusted, compliant confidential computing environments. You'll inspect the AKS cluster and Confidential VM node pool that were deployed for you, then deploy a sample application that implements secure attestation flows. The application leverages Microsoft Azure Attestation (MAA) to validate VM integrity before executing protected business logic, demonstrating "encryption in use" capabilities.
Expand All @@ -24,15 +22,3 @@ Validate guest attestation on a pre-provisioned Azure Confidential VM node pool
* [Azure Confidential Computing Overview](https://learn.microsoft.com/azure/confidential-computing/overview)
* [Microsoft Azure Attestation](https://learn.microsoft.com/azure/attestation/overview)
* [Confidential containers on Azure](https://learn.microsoft.com/azure/confidential-computing/confidential-containers)

## Solution

> [!TIP]
> We encourage you to try solving the challenge on your own before looking at the solution. This will help you learn and understand the concepts better.

<details>
<summary>Click here to view the solution</summary>

[Solution for Challenge 5](../walkthrough/challenge-05/solution-05.md)

</details>
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Challenge 6 - Operating a Sovereign Hybrid Cloud with Azure Arc & Azure Local

[Previous Challenge](challenge-05.md) - **[Home](../Readme.md)** - [Next Challenge](challenge-07.md)

## Goal

The goal of this challenge is to operate a sovereign hybrid cloud environment by combining Microsoft Sovereign Public Cloud and Sovereign Private Cloud components. You will work with Azure Local, simulated via Azure Arc Jumpstart LocalBox, and provision your own VM. You will use Azure Arc to manage that VM through Azure, review its security posture with Microsoft Defender for Cloud, and assess its OS updates with Azure Update Manager.
Expand Down Expand Up @@ -34,15 +32,3 @@ Your organization must run workloads in a sovereign cloud while still leveraging
* [Microsoft Defender for Cloud with Arc-enabled servers](https://learn.microsoft.com/azure/defender-for-cloud/quickstart-onboard-machines)
* [Azure Update Manager overview](https://learn.microsoft.com/azure/update-manager/overview)
* [Azure Arc Jumpstart - LocalBox](https://jumpstart.azure.com/azure_jumpstart_localbox)

## Solution

> [!TIP]
> We encourage you to try solving the challenge on your own before looking at the solution. This will help you learn and understand the concepts better.

<details>
<summary>Click here to view the solution</summary>

[Solution for Challenge 6](../walkthrough/challenge-06/solution-06.md)

</details>
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Challenge 7 - Adaptive Apps Across Sovereign Environments

[Previous Challenge](challenge-06.md) - **[Home](../Readme.md)** - [Finish](finish.md)

## Goal

Deploy one unchanged application model to two sovereign execution environments: Azure Kubernetes Service (AKS) and a private, self-managed K3s cluster representing an on-premises or edge location. Use independent [Radius](https://radapp.io/) control planes so either site can continue operating when the other site or its network connection is unavailable.
Expand Down Expand Up @@ -52,16 +50,4 @@ The lab platform has already provisioned:
* [Microsoft Entra Workload ID on AKS](https://learn.microsoft.com/azure/aks/workload-identity-overview)
* [Azure Bastion native client connections](https://learn.microsoft.com/azure/bastion/connect-vm-native-client-windows)
* [Azure Arc-enabled Kubernetes overview](https://learn.microsoft.com/azure/azure-arc/kubernetes/overview)
* [Full Adaptive Apps MicroHack source](https://github.com/djong1/MicroHack/tree/djong1-adaptive-apps-microhack/03-Azure/01-01-App%20Innovation/04-adaptive-apps)

## Solution

> [!TIP]
> Attempt the challenge before opening the worked solution. Use the success criteria to decide when you are finished.

<details>
<summary>Click here to view the solution</summary>

[Solution for Challenge 7](../walkthrough/challenge-07/solution-07.md)

</details>
* [Full Adaptive Apps MicroHack source](https://github.com/djong1/MicroHack/tree/djong1-adaptive-apps-microhack/03-Azure/01-01-App%20Innovation/04-adaptive-apps)
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Finish

[Previous Challenge](challenge-06.md) - **[Home](../Readme.md)**


Congratulations! You finished the MicroHack Microsoft Sovereign Cloud. We hope you had the chance to learn about how to implement sovereign cloud controls using Azure native platform capabilities — from policy and RBAC, through encryption at rest, in transit, and in use, to operating a hybrid sovereign environment with Azure Arc and Azure Local.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ $sovereignLabResult = Invoke-MhhDeploymentWithRegionFallback `
-Tag @{
workload = 'sovereign-lab'
challenges = '4,5,7'
CostControl = 'Ignore'
}

# Assign the lab-specific subscription-scoped RBAC (Security Reader + Resource Policy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ The Azure region for the LocalBox Azure resources.
Optional host administrator password. For unattended deployment, prefer the
LOCALBOX_ADMIN_PASSWORD environment variable so the secret is not in the process list.
A random password is generated when neither value is supplied.
.PARAMETER UseConsoleCredentials
Use the Console's stable LocalBox password instead of a supplied or random password.
It is not published as a participant credential. Coach/event-lead-only retrieval
requires a supported mechanism from the Console owner.
.PARAMETER GithubRef
The azure_arc branch, tag, or commit used for both Bicep and runtime artifacts.
.PARAMETER AzureLocalResourceProviderObjectId
Expand All @@ -36,6 +40,8 @@ param(

[string]$WindowsAdminPassword,

[switch]$UseConsoleCredentials,

[bool]$DeployBastion = $true,

[ValidateSet('Standard_E32s_v5', 'Standard_E32s_v6')]
Expand Down Expand Up @@ -207,7 +213,16 @@ if ([string]::IsNullOrWhiteSpace($AzureLocalResourceProviderObjectId)) {
}

$generatedPassword = $false
if ([string]::IsNullOrEmpty($WindowsAdminPassword) -and -not [string]::IsNullOrEmpty($env:LOCALBOX_ADMIN_PASSWORD)) {
if ($UseConsoleCredentials) {
if (-not [string]::IsNullOrEmpty($WindowsAdminPassword) -or -not [string]::IsNullOrEmpty($env:LOCALBOX_ADMIN_PASSWORD)) {
throw 'UseConsoleCredentials cannot be combined with WindowsAdminPassword or LOCALBOX_ADMIN_PASSWORD.'
}
$WindowsAdminPassword = New-MhhStablePassword -Purpose 'localbox-admin-v1' -Length 24 -ErrorAction Stop
if ([string]::IsNullOrWhiteSpace($WindowsAdminPassword)) {
throw 'Console did not provide a LocalBox password.'
}
}
elseif ([string]::IsNullOrEmpty($WindowsAdminPassword) -and -not [string]::IsNullOrEmpty($env:LOCALBOX_ADMIN_PASSWORD)) {
$WindowsAdminPassword = $env:LOCALBOX_ADMIN_PASSWORD
}
elseif ([string]::IsNullOrEmpty($WindowsAdminPassword)) {
Expand All @@ -230,13 +245,13 @@ if ($resourceGroupExists -eq 'true') {
)
Invoke-AzJson -Arguments @(
'group', 'update', '--subscription', $SubscriptionId, '--name', $ResourceGroupName,
'--set', 'tags.workload=sovereign-localbox', 'tags.challenge=6', 'tags.SecurityControl=Ignore'
'--set', 'tags.workload=sovereign-localbox', 'tags.challenge=6', 'tags.SecurityControl=Ignore', 'tags.CostControl=Ignore'
) | Out-Null
}
else {
$resourceGroup = Invoke-AzJson -Arguments @(
'group', 'create', '--subscription', $SubscriptionId, '--name', $ResourceGroupName,
'--location', $Location, '--tags', 'workload=sovereign-localbox', 'challenge=6', 'SecurityControl=Ignore'
'--location', $Location, '--tags', 'workload=sovereign-localbox', 'challenge=6', 'SecurityControl=Ignore', 'CostControl=Ignore'
)
}
Write-Host "Resource group ready: $($resourceGroup.name) ($($resourceGroup.location))" -ForegroundColor Green
Expand Down Expand Up @@ -264,6 +279,12 @@ try {
Invoke-WebRequest -Uri "$baseUri/$file" -OutFile (Join-Path $tempDirectory $file) -UseBasicParsing
}

$resourceTags = @{
Project = 'jumpstart_LocalBox'
SecurityControl = 'Ignore'
CostControl = 'Ignore'
}

@{
'$schema' = 'https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#'
contentVersion = '1.0.0.0'
Expand All @@ -278,10 +299,7 @@ try {
azureLocalInstanceLocation = @{ value = $AzureLocalInstanceLocation }
deployBastion = @{ value = $DeployBastion }
vmSize = @{ value = $VmSize }
tags = @{ value = @{
Project = 'jumpstart_LocalBox'
SecurityControl = 'Ignore'
} }
tags = @{ value = $resourceTags }
governResourceTags = @{ value = $false }
}
} | ConvertTo-Json -Depth 10 | Set-Content -Path $parametersFile -Encoding utf8NoBOM
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
function Get-LocalBoxConsoleGroupCredential {
[CmdletBinding()]
param()

$group = Get-MhhDefaultLabGroup -ErrorAction Stop
$objectId = [guid]::Empty
if (-not [guid]::TryParse([string]$group.ObjectId, [ref]$objectId) -or $objectId -eq [guid]::Empty -or
[string]::IsNullOrWhiteSpace($group.GroupName) -or [string]::IsNullOrWhiteSpace($group.DisplayName)) {
throw 'Console did not return a valid default lab group. Complete Entra user/group creation before shared deployment.'
}

@{ HackboxCredential = @{ name = 'Lab Group ObjectId'; value = [string]$group.ObjectId; note = 'Use as AksAdminGroupObjectId for LocalBox preparation' } }
@{ HackboxCredential = @{ name = 'Lab Group GroupName'; value = $group.GroupName; note = '' } }
@{ HackboxCredential = @{ name = 'Lab Group DisplayName'; value = $group.DisplayName; note = '' } }
}

function Wait-LocalBoxDeployment {
[CmdletBinding()]
param(
[Parameter(Mandatory)][string]$ResourceGroupName,
[Parameter(Mandatory)][string]$DeploymentName,
[ValidateRange(1, 21600)][int]$TimeoutSeconds = 21600
)

$deadline = (Get-Date -AsUTC).AddSeconds($TimeoutSeconds)
do {
Update-MhhToken | Out-Null
$deployment = Get-AzResourceGroupDeployment -ResourceGroupName $ResourceGroupName -Name $DeploymentName -ErrorAction Stop
if ($deployment.ProvisioningState -eq 'Succeeded') {
break
}
if ($deployment.ProvisioningState -in @('Failed', 'Canceled')) {
throw "LocalBox deployment '$DeploymentName' ended as $($deployment.ProvisioningState)."
}
if ((Get-Date -AsUTC) -ge $deadline) {
throw "Timed out waiting for LocalBox deployment '$DeploymentName'. Rerun the shared hook after investigating the deployment."
}
Write-Host "Waiting for LocalBox ARM deployment '$DeploymentName' ($($deployment.ProvisioningState))..."
Start-Sleep -Seconds 30
} while ($true)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// deploymentType = resourcegroup: the platform pre-creates one resource group
// per participant in the shared subscription and grants the participant Owner on
// that resource group plus Reader on the subscription. This template adds the
// same subscription-scoped permissions that resources/subscription-preparations/3-rbac.ps1
// same subscription-scoped permissions that resources/manual-setup/subscription-preparations/3-rbac.ps1
// previously assigned to the LabUsers group:
// - Security Reader (view Defender for Cloud secure score / recommendations)
// - Resource Policy Contributor (author and assign Azure Policy at subscription scope)
Expand Down
Loading
Loading