The managed identities in the previous lesson removed the secrets used to reach sttarjetascontosopro and db-reservas, and that is the best possible news: a secret that does not exist cannot leak. But not everything is solved that way. Contoso Airlines still needs the payment gateway key, the token for the weather data provider that feeds the delay forecasts, the connection string for the legacy billing system still running in Barcelona, and the TLS certificate for contosoairlines.example. None of those systems speaks Entra ID, so the secret exists and it has to be kept somewhere. From today, that somewhere is Azure Key Vault: a hardware-backed store with RBAC permissions, a closed network, versioning and an audit trail of every read. By the end, app-contoso-reservas-pro will read its secrets with the managed identity from 04-02 and there will not be a single password in the deployment.
Important warning: key and secret management bears directly on regulatory compliance — PCI DSS for payments, GDPR for passenger data — and a misconfiguration can cause both a breach and an irreversible loss of encrypted data. Before taking any Key Vault, rotation or customer-managed key design into production, it must be reviewed by a security professional or by your organization's compliance team.
Contents
- Where Contoso's secrets live today
- What Key Vault stores: secrets, keys and certificates
- Standard, Premium and Managed HSM tiers
- Creating
kv-contoso-prowith soft delete and purge protection - The two permission models: access policies versus RBAC
- Network access: firewall, private endpoint and trusted services
- Storing, retrieving and versioning secrets
- Rotating secrets with no downtime
- Managed TLS certificates
- Consuming secrets from App Service with Key Vault references
- Customer-managed encryption keys
- Auditing, limits and what NOT to put in the vault
- Common Mistakes and Tips
- Exercises
- Conclusion
- Where Contoso's secrets live today
An honest inventory before fixing anything:
| Secret | Where it is today | Risk |
|---|---|---|
| Payment gateway key | app-contoso-reservas-pro settings, in clear text |
Any Contributor reads it with config/list |
| Weather provider token | appsettings.json in the repository |
In the Git history forever |
| Legacy system connection string | The team's shared document | No access control and no auditing |
| TLS certificate with its private key | A .pfx file on Marta's laptop |
Lost with the laptop |
| SQL administrator password | An email from eight months ago | Nobody remembers who has it |
None of them has ever been rotated, nobody knows who has read them, and revoking them would mean hunting through five different places. Key Vault solves all four problems at once: centralized storage, identity-based access control, an audit trail of every operation and managed rotation.
- What Key Vault stores: secrets, keys and certificates
| Type | What it is | Can it be extracted | Typical use at Contoso |
|---|---|---|---|
| Secret | Any string up to 25 KB | Yes: the application receives the value | Gateway key, tokens, connection strings |
| Key | A cryptographic key (RSA, EC) | No: it never leaves the vault | Encryption for db-reservas and storage |
| Certificate | An X.509 certificate + its private key | Yes, as a PFX if the policy allows it | TLS for contosoairlines.example |
The distinction between a secret and a key is the most important one and the most often confused. A secret is stored in order to be handed back: the application asks for the gateway key and receives the text. A key is never handed back: you send the data to Key Vault so that it encrypts, signs or decrypts it, and the private key never leaves the cryptographic module. That is why encryption keys are stored as keys and not as secrets: even if somebody stole the access token, they could not exfiltrate the key material.
A certificate is really three coordinated objects: the certificate, a key, and a secret holding the complete PFX. Key Vault also manages its lifecycle, including automatic renewal.
- Standard, Premium and Managed HSM tiers
| Standard | Premium | Azure Managed HSM | |
|---|---|---|---|
| Key protection | Software (inside validated HSMs) | Dedicated HSM, FIPS 140-2 Level 3 | Dedicated single-tenant HSM |
| Cost | Cents per 10,000 operations | The same + a cost per HSM key | Several thousand € a month |
| Isolation | Multi-tenant | Multi-tenant | Single tenant |
| When | 90% of cases | A regulatory HSM requirement | Banking, certificate authorities |
Contoso chooses Standard for kv-contoso-pro. That is the right decision unless a standard explicitly demands a Level 3 certified HSM, and it is worth knowing that the tier cannot be changed from Premium back to Standard once created (Standard to Premium can). Azure Managed HSM exists, it costs thousands of euros a month and it only makes sense when the auditor themselves demands it in writing.
- Creating
kv-contoso-pro with soft delete and purge protection
kv-contoso-pro with soft delete and purge protectionRG_SEC="rg-contoso-seguridad-pro"; KV="kv-contoso-pro"
az keyvault create --name $KV --resource-group $RG_SEC --location westeurope \
--sku standard \
--enable-rbac-authorization true \ # RBAC instead of access policies
--enable-purge-protection true \ # nobody can delete permanently
--retention-days 90 \ # recovery window after a deletion
--public-network-access Disabled \ # private endpoint only
--tags entorno=produccion proyecto=contoso-reservas centro-coste=CC-1042 \
[email protected]Three options deserve a detailed explanation:
- Soft delete: it is always on and cannot be turned off. When you delete a secret, a key or the whole vault, the object moves to a deleted state and is kept for
--retention-days(from 7 to 90). During that time it can be recovered withaz keyvault recover. - Purge protection: it prevents the object being permanently deleted during retention, not even by an Owner. Once enabled it cannot be disabled either. It is deliberately inconvenient: it turns a malicious or accidental deletion into something reversible.
- The practical consequence that catches everybody out: while a deleted vault is still in retention, its name stays reserved globally and no other vault can be created with it. If you delete
kv-contoso-produring a test, you will not be able to recreate it under that name for 90 days (or sooner by purging it, unless purge protection prevents that — which is exactly this case). That is why test vaults are created with disposable names and--retention-days 7.
- The two permission models: access policies versus RBAC
| Access policies (legacy) | Azure RBAC (recommended) | |
|---|---|---|
| Where it is defined | In the vault itself | In Access control (IAM), like the rest of Azure |
| Granularity | Per whole vault | Per vault and per individual secret |
| Limit | 1,024 policies per vault | The normal role assignment limits |
| Scope inheritance | No | Yes, from the subscription or resource group |
| Auditing and PIM | Outside the standard model | Integrated with the rest of Azure |
| Recommendation | For compatibility only | Always choose it on new vaults |
With --enable-rbac-authorization true, data plane permissions are granted with the same roles as everywhere else in Azure. The ones you use:
| Role | Allows |
|---|---|
| Key Vault Secrets User | Reading the value of secrets. The applications' role |
| Key Vault Secrets Officer | Creating, updating and deleting secrets |
| Key Vault Crypto Officer | Managing keys and operating with them |
| Key Vault Reader | Seeing metadata, not values. For auditing |
| Key Vault Contributor | Managing the vault (management plane), not its data |
That last one is 04-02's trap applied here: Key Vault Contributor does not let you read a single secret. It does, however, let you change the vault's configuration, which is why it is also a privileged role worth keeping under PIM.
KV_ID=$(az keyvault show -n $KV -g $RG_SEC --query id -o tsv)
APP_PRINCIPAL=$(az webapp identity show -g rg-contoso-reservas-pro -n app-contoso-reservas-pro --query principalId -o tsv)
# The application: READ only, and only the secret it needs
az role assignment create --assignee-object-id $APP_PRINCIPAL --assignee-principal-type ServicePrincipal \
--role "Key Vault Secrets User" \
--scope "$KV_ID/secrets/pasarela-pago-clave"
# Marta manages the secrets across the whole vault
az role assignment create --assignee-object-id $(az ad group show --group "Contoso-Infraestructura" --query id -o tsv) \
--assignee-principal-type Group --role "Key Vault Secrets Officer" --scope "$KV_ID"Look at the scope of the first assignment: one specific secret, not the vault. If app-contoso-reservas-pro is compromised, the attacker gets that key and nothing else.
- Network access: firewall, private endpoint and trusted services
With --public-network-access Disabled the vault does not answer on the internet. Access arrives through a private endpoint in snet-datos, exactly like pe-sql-reservas and pe-storage-tarjetas in module 2:
az network private-endpoint create -g rg-contoso-red-pro -n pe-kv-contoso \
--vnet-name vnet-contoso-pro --subnet snet-datos \
--private-connection-resource-id $KV_ID --group-id vault \
--connection-name conn-kv-contosoAnd the name has to be registered in private DNS, or the client will carry on resolving the public IP: you create the zone privatelink.vaultcore.azure.net, link it to vnet-contoso-pro and associate it with the endpoint through a DNS zone group. Without that step the endpoint exists and nobody uses it: it is the most frequent Private Link mistake.
One operational nuance remains. Certain Azure services — App Service resolving references, Azure SQL decrypting with a customer key, Event Grid — do not go out through the virtual network. For those there is the Microsoft trusted services exception, which has to be enabled explicitly:
--bypass AzureServices lets that closed list of services through; --default-action Deny still rejects everything else. The exception is not an open hole: every service on the list must also have a role assigned.
- Storing, retrieving and versioning secrets
# Store it. The value is NOT typed into the command: it is read from a variable or standard input
read -s -p "Payment gateway key: " VALUE; echo
az keyvault secret set --vault-name $KV --name pasarela-pago-clave --value "$VALUE" \
--expires "$(date -u -d '+180 days' +%Y-%m-%dT%H:%M:%SZ)" \
--tags rotacion=semestral sistema=pagos
# Retrieve the current value (this operation is audited)
az keyvault secret show --vault-name $KV --name pasarela-pago-clave --query value -o tsv
# See every version: each 'set' creates a new one and the previous one still exists
az keyvault secret list-versions --vault-name $KV --name pasarela-pago-clave \
--query "[].{Version:id, Enabled:attributes.enabled, Created:attributes.created}" -o tableEvery secret has a versioned identifier, https://kv-contoso-pro.vault.azure.net/secrets/pasarela-pago-clave/a1b2c3..., and an unversioned one that always points at the current version. The practical rule: use the unversioned identifier so that rotation does not force a redeployment, unless you need to pin a specific version for reproducibility.
The --expires and --not-before attributes do not block reads on their own in every client: they are metadata that feed the expiry warnings and the audit queries. Always set them; ignoring them is what leaves a key unrotated for four years.
- Rotating secrets with no downtime
Rotating means replacing a secret with a new one without anything stopping working. Three mechanisms, from most to least automatic:
Fully managed rotation. For storage account keys, Key Vault can regenerate them by itself. You create a managed storage account secret, tell it how often to rotate, and Key Vault alternates between key1 and key2, regenerating whichever one is not in use:
az keyvault storage add --vault-name $KV -n sttarjetascontosopro \
--active-key-name key1 --auto-regenerate-key --regeneration-period P60D \
--resource-id $(az storage account show -n sttarjetascontosopro -g rg-contoso-reservas-pro --query id -o tsv)Note the healthy irony: Contoso no longer uses those keys because it moved to a managed identity (04-02). This mechanism is for the legacy accounts that have not migrated yet.
Expiry notification through Event Grid. Key Vault publishes SecretNearExpiry (30 days beforehand) and SecretExpired events, which can trigger a function or a Logic App that calls the provider's API, obtains a new credential and writes the version into the vault. It is the pattern for third-party secrets such as the payment gateway.
The no-downtime rotation pattern, which is what matters conceptually and works for any secret:
flowchart TB
A[1. Generate the NEW credential at the provider<br/>keeping the previous one active] --> B[2. Write the new version<br/>into Key Vault]
B --> C[3. Wait for the cache to expire<br/>on every instance]
C --> D[4. Verify in the provider's logs<br/>that traffic uses the new one]
D --> E[5. Revoke the OLD credential]
The crux is step 1: the provider has to support two valid credentials at once. If it only supports one, no-downtime rotation is impossible and a maintenance window has to be planned. It is a question worth asking every provider before integrating with them.
- Managed TLS certificates
Key Vault can issue and renew certificates automatically if it is integrated with a partner certificate authority (DigiCert, GlobalSign), or hold certificates imported from any other. You define a policy with the subject, the alternative names, the validity period and the percentage of lifetime at which it renews:
az keyvault certificate create --vault-name $KV -n cert-contosoairlines \
--policy "$(az keyvault certificate get-default-policy)"From there, app-contoso-reservas-pro imports the certificate with az webapp config ssl import --key-vault $KV --key-vault-certificate-name cert-contosoairlines, and when Key Vault renews it, App Service picks up the new version with no intervention. Application Gateway does the same by referencing the certificate's identifier, and that is where it will be used in lesson 04-04 when the web application firewall is built. The free alternative for simple cases is App Service managed certificates, which you already saw in 02-03; Key Vault is the option when the same certificate has to be shared across several services.
- Consuming secrets from App Service with Key Vault references
This is the moment when passwords disappear from the deployment. A Key Vault reference is an application setting whose value is not the secret but a pointer:
az webapp config appsettings set -g rg-contoso-reservas-pro -n app-contoso-reservas-pro --settings \
ClavePasarelaPago="@Microsoft.KeyVault(SecretUri=https://kv-contoso-pro.vault.azure.net/secrets/pasarela-pago-clave/)" \
TokenMeteorologico="@Microsoft.KeyVault(VaultName=kv-contoso-pro;SecretName=token-meteo)"What happens underneath: at startup, App Service uses the managed identity from 04-02 to request the token, resolves the reference and exposes the value to the application as an ordinary environment variable. Consequences worth being clear about:
- The code does not change: it carries on reading
ClavePasarelaPagoexactly as before. There is no SDK to add. - The secret is not in the configuration: whoever has
config/listsees the pointer, not the value. - Resolution happens at startup and is cached for 24 hours (or until a restart). After rotating a secret you have to restart the application or wait; if you used the unversioned URI, the reference picks up the new version.
- If the reference fails, the application starts without that setting and usually fails in a confusing way. Always check the status with
az webapp config appsettings list, where a broken reference is shown along with its error.
When the application needs to read secrets at runtime (not just at startup), you use the SDK's SecretClient with DefaultAzureCredential, the same credential as in 04-02, and always with your own cache, for the reason given in section 12.
- Customer-managed encryption keys
Everything Azure stores is encrypted at rest with Microsoft's keys, without you having to do anything. Customer-managed keys (CMK) change who controls the key: Contoso generates it in kv-contoso-pro, and the service uses it through its managed identity.
az keyvault key create --vault-name $KV -n clave-cifrado-tarjetas --kty RSA --size 3072 \
--ops wrapKey unwrapKey --protection softwareWhat it genuinely adds: the ability to revoke. If the key is disabled, sttarjetascontosopro immediately loses the ability to decrypt its data; it is the "red button" some auditors demand. And what it costs: if that key is deleted or lost, the data is unrecoverable, and there is nothing Microsoft can do. That is why purge protection is mandatory on vaults with CMK, and why Contoso applies them only to sttarjetascontosopro and db-reservas, where the personal data lives, and not to the rest. Rotating a CMK is transparent: the data key is re-encrypted, not the data.
- Auditing, limits and what NOT to put in the vault
Key Vault logs every data plane operation: who read which secret, from which IP and with what result. Those logs are not kept in the vault, they have to be sent somewhere:
az monitor diagnostic-settings create --name diag-kv-contoso --resource $KV_ID \
--workspace $(az monitor log-analytics workspace show -g rg-contoso-seguridad-pro -n log-contoso-pro --query id -o tsv) \
--logs '[{"category":"AuditEvent","enabled":true}]'With that, in Log Analytics (07-02) you can answer questions like "who read the gateway key outside working hours?" or "which identities have accessed this secret in the last 90 days?". It is a direct PCI DSS requirement and the reason the workspace lives in rg-contoso-seguridad-pro alongside the vault.
On performance limits: Key Vault applies throttling per vault and region (on the order of 2,000 secret operations per 10 seconds, fewer for RSA key operations). When you exceed it, it returns HTTP 429. Which is why the rule is non-negotiable: the application caches secrets in memory for hours and only re-reads them on rotation or after an authentication error. A service that requests the secret on every HTTP request takes down its own vault the moment real traffic arrives.
And what should not go into Key Vault:
- Configuration that is not secret (URLs, server names, feature flags): that belongs in App Configuration or in ordinary settings.
- Business data or personal data: it is not a database. A secret is 25 KB at most.
- Large files, even sensitive ones: encrypt them and store them in storage, with the key in Key Vault.
- End-user secrets (passengers' passwords): those live in Entra External ID (04-01), hashed, never here.
Common Mistakes and Tips
- Creating the vault with access policies "because that is what old tutorials show". Use
--enable-rbac-authorization truefrom the start; migrating later is tedious. - Expecting Key Vault Contributor to allow reading secrets. It does not: it manages the vault, not its data.
- Deleting a test vault and not being able to recreate it under the same name. The name stays reserved for the retention period. Use disposable names and 7-day retention in testing.
- Turning on purge protection without understanding it. It is irreversible. In production it is mandatory; on a course or in a test, avoid it.
- Forgetting the private DNS zone for the endpoint. The vault ends up unreachable with a network error that tells you nothing.
- Requesting the secret on every request. HTTP 429 guaranteed under load. Cache it.
- Typing the secret on the command line. It ends up in the shell history and in the pipeline logs. Read it from standard input or from a protected variable.
- Tip: one vault per environment and per trust boundary.
kv-contoso-proandkv-contoso-devkept separate, never the same vault for production and development. - Tip: put an alert on the audit log for reads from unexpected identities. It is one of the cleanest signals of compromise there is.
Exercises
Exercise 1: designing the Contoso Miles vault
"Contoso Miles" (centro-coste=CC-2077) needs to store: the key for a commercial partners API, the TLS certificate for its subdomain, an encryption key for customer data, and the connection string for a legacy database.
- Classify the four items as a secret, a key or a certificate, and justify it.
- Write the vault creation command with the right options and explain each one.
- Which roles would you assign to the application's managed identity and to the development group, and at what scope?
Exercise 2: rotating the payment gateway key
The payment gateway supports two active keys simultaneously and Contoso has to rotate every 180 days without interrupting ticket sales.
- Describe the five steps of the process, saying what is done at the provider and what in Azure.
- How would you automate the warning that expiry is approaching?
- The application caches the secret for 12 hours. What does that imply for the revocation step?
Exercise 3: diagnosing three failures
- After deploying, the application starts but fails when calling the gateway; in the settings,
ClavePasarelaPagoshows a reference error. - A batch process that reads 40 secrets at the start of each task starts receiving HTTP 429 as concurrency increases.
- The team deleted
kv-contoso-devand, on recreating it with the same name, gets a conflict error.
Solutions
Solution 1:
- Partners API key: a secret, because its value has to be handed back to the application. TLS certificate: a certificate, so as to benefit from automatic renewal and the App Service integration. Encryption key: a key, because it must never leave the vault and is only used for cryptographic operations. Legacy connection string: a secret (and in the medium term, replace it with a managed identity if the engine supports it).
az keyvault create -n kv-contoso-millas-pro -g rg-contoso-seguridad-pro -l westeurope --sku standard --enable-rbac-authorization true --enable-purge-protection true --retention-days 90 --public-network-access Disabledplus the four mandatory tags withcentro-coste=CC-2077. RBAC because it is the recommended model and it allows per-secret scope; purge protection because there is an encryption key and losing it would make the data unrecoverable; public network disabled plus a private endpoint; 90-day retention because it is production.- To the managed identity, Key Vault Secrets User scoped to the specific secret it needs, and Key Vault Crypto User on the encryption key if it operates with it. To the development group, no data role at all in the production vault: at most Key Vault Reader (metadata, no values) for diagnostics, and Secrets Officer only in
kv-contoso-millas-dev.
Solution 2:
- (a) Generate the secondary key in the gateway's portal, leaving the current one active. (b) Write the new version of the secret into Key Vault with
az keyvault secret set, using the unversioned URI in the reference so as not to redeploy. (c) Restart the application or wait for the cache to expire on every instance. (d) Check in the provider's logs that traffic is arriving with the new key. (e) Revoke the old key at the provider. - With Event Grid: the
SecretNearExpiryevent is emitted 30 days before the--expiresdate, and it is wired to a Logic App (06-04) that opens a ticket and emails the owner named in the secret's tags. It requires the expiry date to have been set when the secret was created. - That the old one cannot be revoked until at least 12 hours after the new one was written, or until every instance has been restarted. Revoking sooner causes payment failures on the instances still serving the cached key. That is why step 4 — verifying at the provider — is mandatory and not a formality.
Solution 3:
- The reference is not resolving. Causes in order: the managed identity does not have the Key Vault Secrets User role on that secret; the secret name is misspelled; the vault firewall is blocking App Service (
--bypass AzureServicesis missing); or the vault uses access policies rather than RBAC. It is diagnosed withaz webapp config appsettings list, which shows the reference's specific error. - The vault's throttling limit is being exceeded. Fix: cache the 40 secrets in memory for hours instead of re-reading them per task, load them once at process startup rather than per task, and apply retries with exponential backoff on the 429. If that volume really is necessary, split it across several vaults by functional domain.
- It is soft delete: the vault still exists in a deleted state and its name is reserved. The correct fix is
az keyvault recover -n kv-contoso-dev, which restores it with all its secrets. If the intention really was to destroy it,az keyvault purge, which only works if it did not have purge protection and which requires the corresponding permission.
Conclusion
Contoso no longer has secrets scattered around. You have taken the uncomfortable inventory of the starting point — settings in clear text, a token in the Git history, a shared document, a PFX on a laptop — and centralized it in kv-contoso-pro, inside rg-contoso-seguridad-pro. You can tell the three object types apart: secrets, which are handed back; keys, which never leave the vault and are operated on inside it; and certificates, with their lifecycle and automatic renewal. You know that Standard is enough for almost everything, that Premium adds a certified HSM and that Managed HSM costs thousands of euros a month and is only justified when an auditor demands it.
You have created the vault with soft delete — always on, impossible to turn off — and purge protection, understanding that it is irreversible and that a deleted vault's name stays reserved for the retention period. You have chosen Azure RBAC over the legacy access policies, with the decisive nuance that it allows granting one specific secret to one specific identity, and you know the data roles and the Key Vault Contributor trap. You have closed the network with the private endpoint pe-kv-contoso, its DNS zone and the trusted services exception. You can handle secret versioning and its dates, the three rotation mechanisms — managed rotation for storage keys, Event Grid warnings and the five-step no-downtime pattern, which requires the provider to support two credentials at once — and the managed TLS certificates that App Service and Application Gateway consume on their own. Above all, you have reached the moment when passwords disappear from the deployment: @Microsoft.KeyVault(...) references resolve the settings with the managed identity from 04-02 without touching a line of code. The lesson closes with customer-managed keys and their power to revoke and their risk of definitive loss, the audit trail sent to Log Analytics, and the limits that force you to cache.
With governed identities, minimal permissions and no exposed secrets, the inside of the platform is reasonably healthy. The problem is that Contoso Bookings is a public website: anybody on the internet can throw requests at it, and neither RBAC nor Key Vault helps there. In the next lesson, DDoS Protection and Web Application Firewall, you will see what attacks genuinely reach a ticket-selling website — volumetric, protocol, application layer, and the bots that drain the seats into their carts — you will build a WAF policy on fd-contoso-global with the OWASP rule set, learn why you always start in detection mode, and compare exactly what each layer protects: NSG, Azure Firewall, WAF and DDoS.
Azure Course
Module 1: Introduction to Azure
- What Is Azure?
- Service Models, Regions and Availability Zones
- Creating and Setting Up Your Azure Account
- A Tour of the Azure Portal
- Azure Resource Manager: Subscriptions, Resource Groups and Tags
- Azure CLI, PowerShell and Cloud Shell
Module 2: Core Azure Services
- Azure Virtual Machines
- Compute Scaling and High Availability
- Azure App Service
- Azure Storage: Blobs, Files, Queues and Tables
- Azure Networking: Virtual Networks, Subnets and NSGs
- Hybrid Connectivity and Global Delivery
Module 3: Azure Databases
- Choosing the Right Data Service
- Azure SQL Database
- Azure Cosmos DB
- Azure Database for MySQL
- Azure Database for PostgreSQL
- Data Analytics: Data Lake, Data Factory and Synapse
Module 4: Security in Azure
- Microsoft Entra ID and Identity Management
- RBAC and Managed Identities
- Azure Key Vault
- DDoS Protection and Web Application Firewall
- Microsoft Defender for Cloud
- Governance and Compliance with Azure Policy
Module 5: Azure DevOps
- Introduction to Azure DevOps
- Azure Repos
- Azure Pipelines: Continuous Integration
- Continuous Deployment with Environments and Approvals
- Azure Artifacts
- Infrastructure as Code with Bicep
Module 6: Advanced Azure Services
- Containers in Azure: Container Registry and Container Apps
- Azure Kubernetes Service (AKS)
- Azure Functions
- Azure Logic Apps
- Messaging and Events: Service Bus, Event Grid and Event Hubs
- Azure AI Services
Module 7: Monitoring and Management
- Azure Monitor: Metrics, Alerts and Dashboards
- Log Analytics and KQL Queries
- Application Insights
- Azure Automation and Runbooks
- Backup and Disaster Recovery
Module 8: Cost Management and Optimization
- Pricing Calculator and Cost Estimation
- Azure Cost Management: Analysis, Budgets and Alerts
- Reservations, Savings Plans and Azure Hybrid Benefit
- Azure Advisor
- Optimization Strategies and FinOps Culture
