The previous lesson left Contoso Airlines' identities created and governed, but with a deliberate gap: Contoso-Desarrollo exists and still cannot do absolutely anything, while Marta Ríos is Owner of everything because she was the one who created the subscription. Neither of those is acceptable. Today you build the system that decides what each identity can do to each resource: Azure role-based access control, or RBAC. And in the second half you solve the problem we have been dragging along since module 2: app-contoso-reservas-pro currently keeps a storage account key and a connection string in its application settings. By the end of the lesson, the application will authenticate against sttarjetascontosopro and db-reservas without a single password anywhere, thanks to managed identities. It is probably the best effort-to-benefit security improvement in the whole course.
Contents
- How Azure authorizes: the role assignment triad
- Scopes and inheritance down the hierarchy
- The essential built-in roles
- The trap: Contributor does not grant access to data
- Custom roles: "Operador de Reservas de Contoso"
- Deny assignments
- Least privilege applied to Contoso's groups
- Diagnosing why somebody has no access
- Managed identities: what they are and what they remove
- System-assigned versus user-assigned
- The token flow: inside IMDS
- Contoso without passwords: storage and database
- Common Mistakes and Tips
- Exercises
- Conclusion
- How Azure authorizes: the role assignment triad
When somebody calls the Azure Resource Manager API, two things happen in order: Entra ID authenticates (who are you?) and RBAC authorizes (may you do this?). A role assignment is always the union of three elements, and if one is missing there is no access.
flowchart LR
A["SECURITY PRINCIPAL<br/>Contoso-Desarrollo"] --> D{{"ROLE<br/>ASSIGNMENT"}}
B["ROLE DEFINITION<br/>Contributor"] --> D
C["SCOPE<br/>rg-contoso-reservas-dev"] --> D
D --> E["The Contoso-Desarrollo group can<br/>manage resources, and only inside<br/>the development resource group"]
The security principal is who (a user, a group, a service principal or a managed identity); the role definition is what (a collection of operations allowed in Actions and subtracted in NotActions); and the scope is where (the level of the hierarchy it applies to).
az role assignment create \
--assignee-object-id $(az ad group show --group "Contoso-Desarrollo" --query id -o tsv) \
--assignee-principal-type Group \
--role "Contributor" \
--scope "/subscriptions/$SUB_DEV/resourceGroups/rg-contoso-reservas-dev"Using --assignee-object-id together with --assignee-principal-type instead of --assignee avoids an extra Graph lookup and, above all, avoids the intermittent failure of assignments to freshly created identities, whose propagation through the directory takes a few seconds.
- Scopes and inheritance down the hierarchy
RBAC is inherited downwards through the Azure Resource Manager hierarchy you saw in 01-05: management group (mg-contoso) → subscription (Contoso Airlines - Producción) → resource group (rg-contoso-reservas-pro) → resource (app-contoso-reservas-pro).
Whoever is Reader on the subscription is Reader on all of its resource groups and on every resource inside them. Permissions are cumulative and can only add: there is no "role-based denial", so granting Reader on a resource group to somebody who is already Contributor on the subscription takes nothing away from them.
The management group is reserved for cross-cutting governance roles (Reader for auditing) and reaches every subscription; the subscription, for platform administration; the resource, for one-off exceptions that are hard to maintain. Contoso assigns nearly everything at resource group level, which matches the lifecycle of each workload. And always to Entra ID groups, not to people: with four groups and four resource groups there are 16 possible combinations and none of them has to be redone when somebody changes team; with individual assignments, every joiner and every leaver means a manual review of the whole subscription. There is a hard limit that forces the issue too: 4,000 role assignments per subscription, and companies that assign to people do reach it.
- The essential built-in roles
Azure ships with more than 400 built-in roles. These are the ones used day to day:
| Role | Management plane | Data plane | Can assign roles | Typical use |
|---|---|---|---|---|
| Owner | Full | Depends on the service | Yes | Only with PIM, never permanent |
| Contributor | Full | No | No | Creating and managing resources |
| Reader | Read-only | No | No | Auditing, first-line support |
| User Access Administrator | Permissions only | No | Yes | Delegating access management |
| Storage Blob Data Contributor | No | Read, write, delete blobs | No | Applications that upload boarding passes |
| Storage Blob Data Reader | No | Read blobs | No | Read-only processes |
| Key Vault Secrets User | No | Read secret values | No | Applications that consume secrets |
| Key Vault Secrets Officer | No | Create and manage secrets | No | Marta managing the vault |
| Virtual Machine Contributor | Manage VMs | No (it does not grant SSH) | No | Compute operations |
The difference between Owner and Contributor comes down to one thing, but an enormous one: Owner can assign roles, that is, can grant themselves and anyone else any permission at all. That is why it is the role fewest people should have and the number one candidate for PIM (04-01).
- The trap: Contributor does not grant access to data
This is the point that causes the most confusion in all of RBAC, and it is best understood through the concrete case.
Diego Salas is Contributor on rg-contoso-reservas-pro. With that role he can see sttarjetascontosopro, change its access tier, its redundancy and its firewall, and even delete the entire storage account with two years of boarding passes inside it. And he cannot read a single blob in the tarjetas-embarque container.
It is not a misconfiguration: Azure has two planes. The management plane (management.azure.com) creates, configures and deletes resources. The data plane (<account>.blob.core.windows.net, <vault>.vault.azure.net) reads and writes the content. Contributor covers the first one completely and the second one not at all.
# Diego can do this (management plane)
az storage account show -n sttarjetascontosopro -g rg-contoso-reservas-pro
# And this FAILS with AuthorizationPermissionMismatch (data plane)
az storage blob list --account-name sttarjetascontosopro -c tarjetas-embarque --auth-mode loginThe consequence is not an inconvenience, it is the foundation of least privilege: Marta Ríos can administer the infrastructure without being able to read passengers' personal data, something the GDPR appreciates and which also limits the damage if her session is stolen. And there is an important caveat: as long as account keys exist, a Contributor can read them (listKeys) and use them to reach the data, bypassing everything above. That is why Contoso will turn off key-based authentication — you will see it in section 12 — and why module 2's keys and SAS tokens are about to disappear.
- Custom roles: "Operador de Reservas de Contoso"
Contoso-Operaciones needs something no built-in role offers: restarting the web application when it hangs and looking at metrics, without being able to change configuration or delete anything. That is a custom role.
{
"Name": "Operador de Reservas de Contoso",
"Description": "Restarts the web application and reads metrics; does not modify configuration or delete resources.",
"IsCustom": true,
"Actions": [
"Microsoft.Web/sites/read",
"Microsoft.Web/sites/restart/action",
"Microsoft.Web/sites/slots/read",
"Microsoft.Web/sites/slotsswap/action",
"Microsoft.Insights/metrics/read",
"Microsoft.Insights/metricDefinitions/read",
"Microsoft.Resources/subscriptions/resourceGroups/read"
],
"NotActions": [
"Microsoft.Web/sites/config/list/action"
],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-contoso-reservas-pro"
]
}Every block matters:
Actions: the permitted management plane operations, in the formatProvider/resourceType/operation. Here: read sites, restart them, swap slots (to promotepreproduccion) and read metrics.NotActions: these are subtracted fromActions.config/list/actionreturns the application settings, which include connection strings: subtracting it makes the exclusion explicit and documented.DataActions/NotDataActions: the equivalent for the data plane, deliberately empty, because operations has no need to read boarding passes. AndAssignableScopes: where the role can be assigned; limiting it to the production resource group prevents it being applied to the whole subscription by mistake.
az role definition create --role-definition ./rol-operador-reservas.json
az role assignment create \
--assignee-object-id $(az ad group show --group "Contoso-Operaciones" --query id -o tsv) \
--assignee-principal-type Group \
--role "Operador de Reservas de Contoso" \
--scope "/subscriptions/$SUB_PRO/resourceGroups/rg-contoso-reservas-pro"Before creating a custom role, check whether a built-in one already exists: az role definition list --query "[?contains(roleName,'Website')].roleName" -o tsv. Custom roles have to be maintained as Azure adds new operations, and that maintenance is real. The limit is 5,000 custom roles per tenant, but the practical problem arrives long before that, in the shape of an unmanageable catalog.
- Deny assignments
There is a mechanism that blocks operations even when a role permits them: the deny assignment, which always wins over any grant. It cannot be created directly from the CLI or the portal; it is generated by Azure services such as Blueprints or managed application deployments. It is mentioned here so that, if you ever see access denied while you are Owner, you know where to look: az role assignment list-deny.
- Least privilege applied to Contoso's groups
| Group | Scope | Role | Reason |
|---|---|---|---|
Contoso-Infraestructura |
Production subscription | Contributor and User Access Administrator, both eligible via PIM | Manages everything, with no privilege at rest |
Contoso-Desarrollo |
rg-contoso-reservas-dev |
Contributor | Full freedom in development |
Contoso-Desarrollo |
Production subscription | Reader | Diagnose without being able to touch |
Contoso-Operaciones |
rg-contoso-reservas-pro |
Operador de Reservas de Contoso | Restart and observe |
Contoso-DBA-Reservas |
sql-contoso-reservas-pro |
SQL Server Contributor + Entra admin on the server | Administer the database without touching the rest |
SUB_PRO=$(az account show --query id -o tsv)
DEV=$(az ad group show --group "Contoso-Desarrollo" --query id -o tsv)
# Reader on production for development: they see the problems, they do not cause them
az role assignment create --assignee-object-id $DEV --assignee-principal-type Group \
--role "Reader" --scope "/subscriptions/$SUB_PRO"
# Audit the current allocation, including what is inherited
az role assignment list --all --include-inherited \
--query "[].{Who:principalName, Role:roleDefinitionName, Scope:scope}" -o tableContoso's practical rule: Owner only through PIM and with approval, Contributor in production only for infrastructure, and everyone who "just needs to look" gets Reader. 90% of access requests are settled with Reader plus one specific data role.
- Diagnosing why somebody has no access
When somebody says "I can't", follow this order:
# 1. What that person has, including inheritance and group membership
az role assignment list --assignee [email protected] \
--all --include-inherited --include-groups -o table
# 2. What is assigned on the specific resource
az role assignment list --scope "/subscriptions/$SUB_PRO/resourceGroups/rg-contoso-reservas-pro" -o table
# 3. What exact action the failing operation requires
az provider operation show --namespace Microsoft.Storage --query "resourceTypes[].operations[].name" -o tsvIf the CLI clears nothing up, the portal has Access control (IAM) → Check access, which shows an identity's effective access on that resource along with the source of each permission. And if the access was lost, the activity log says who removed the assignment and when: filter on the operation Microsoft.Authorization/roleAssignments/delete.
Four causes explain almost every case: (1) the role is a management role and the operation is a data one — section 4; (2) the scope is narrower than people thought; (3) the assignment was made in a different subscription; (4) the assignment is correct but the user's token predates it and they need to sign out and back in. RBAC propagation takes up to five minutes, and occasionally a little longer.
- Managed identities: what they are and what they remove
Now the second problem. app-contoso-reservas-pro currently holds, in its application settings, a key for sttarjetascontosopro and a connection string with the username and password for db-reservas. Those secrets exist in at least four places: the application configuration, the .env file on Diego's laptop, the repository history and an email from eight months ago. They have never been rotated. If any of them leaks, the attacker reads every passenger's boarding passes.
A managed identity is an Entra ID service principal whose lifecycle and credentials are managed by Azure: the resource obtains tokens without there being any password for anyone to copy, write into a file or leak. There is no credential to rotate because there is no credential. It is free and it is available in App Service, Functions, VMs, VMSS, Container Apps, AKS, Data Factory, Logic Apps and practically everything else.
- System-assigned versus user-assigned
| System-assigned | User-assigned | |
|---|---|---|
| Lifecycle | Tied to the resource: it is born and dies with it | An independent resource, deleted separately |
| Relationship | 1:1 with one resource | 1:N, shared by several resources |
| When the resource is recreated | New ID: assignments have to be redone | The same ID: permissions are preserved |
| Pre-assigning permissions | No (the ID does not exist yet) | Yes, before the resource is created |
| When to use it | A single, stable application | Fleets (VMSS), infrastructure as code, blue-green deployments |
Contoso uses a system-assigned identity for app-contoso-reservas-pro, because it is a single application. For vmss-api-disponibilidad-pro, where instances are created and destroyed by autoscaling, it uses a user-assigned identity called id-contoso-api-pro: permissions are granted once to the identity and every instance inherits them, present and future. And if you are going to deploy with Bicep (05-06), the user-assigned identity avoids the chicken-and-egg problem: you create it first, give it permissions and then associate it with the resources.
- The token flow: inside IMDS
sequenceDiagram
participant App as app-contoso-reservas-pro
participant IMDS as Local endpoint<br/>(IMDS 169.254.169.254)
participant Entra as Microsoft Entra ID
participant St as sttarjetascontosopro
App->>IMDS: GET /metadata/identity/oauth2/token<br/>?resource=https://storage.azure.com/
IMDS->>Entra: Requests a token for the resource's identity
Entra-->>IMDS: JWT access token (valid ~24 h)
IMDS-->>App: Access token
App->>St: GET /tarjetas-embarque/BP-4471.pdf<br/>Authorization: Bearer <token>
St->>St: Validates the token and checks RBAC
St-->>App: The boarding pass PDF
The essential point of this flow: the token request travels to 169.254.169.254, a non-routable link-local address that only answers inside the virtual machine or instance itself. No external attacker can request that token because they cannot reach that endpoint; and since everything happens inside the resource, there is no secret to transmit. In App Service the mechanism is equivalent, exposed through the IDENTITY_ENDPOINT and IDENTITY_HEADER variables, which the SDK uses automatically.
- Contoso without passwords: storage and database
First the identity is turned on and its object identifier saved:
RG="rg-contoso-reservas-pro"; APP="app-contoso-reservas-pro"
PRINCIPAL=$(az webapp identity assign -g $RG -n $APP --query principalId -o tsv)Then it is granted access to the data, with the narrowest possible role at the narrowest possible scope — the container, not the account:
ST_ID=$(az storage account show -n sttarjetascontosopro -g $RG --query id -o tsv)
az role assignment create --assignee-object-id $PRINCIPAL --assignee-principal-type ServicePrincipal \
--role "Storage Blob Data Contributor" \
--scope "$ST_ID/blobServices/default/containers/tarjetas-embarque"
# And now the important part: the old door is closed
az storage account update -n sttarjetascontosopro -g $RG --allow-shared-key-access falseThat last line is what turns the exercise into a real improvement: with --allow-shared-key-access false, module 2's account keys and SAS tokens stop working, and the only possible access goes through Entra ID identities with their role. Before running it you have to make sure no legacy process still uses them, because the cut-off is immediate.
For db-reservas, the database already has Entra-ID-only authentication over the Contoso-DBA-Reservas group (03-02). What is missing is creating the application user, running this connected as the Entra ID administrator:
CREATE USER [app-contoso-reservas-pro] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [app-contoso-reservas-pro];
ALTER ROLE db_datawriter ADD MEMBER [app-contoso-reservas-pro];
GRANT EXECUTE ON SCHEMA::dbo TO [app-contoso-reservas-pro];The user's name is exactly that of the App Service resource, which is what its managed identity is called. Note that it is not given db_owner: reading, writing and executing procedures is everything the application needs, and with that it cannot alter the schema.
In code, all of this comes down to one class. DefaultAzureCredential tries the available credentials in order — environment variables, managed identity, Azure CLI, Visual Studio — so that the same code works on Diego's laptop and in production with no changes and no secrets:
using Azure.Identity;
using Azure.Storage.Blobs;
using Microsoft.Data.SqlClient;
// A single instance, reused: the credential caches tokens internally
var credential = new DefaultAzureCredential();
// Storage: no account key and no SAS, just the account name
var blobs = new BlobServiceClient(
new Uri("https://sttarjetascontosopro.blob.core.windows.net"),
credential);
var container = blobs.GetBlobContainerClient("tarjetas-embarque");
await container.UploadBlobAsync("BP-4471.pdf", pdfStream);
// SQL: a connection string with NO username and NO password
var connectionString = "Server=tcp:sql-contoso-reservas-pro.database.windows.net,1433;"
+ "Database=db-reservas;Authentication=Active Directory Default;Encrypt=True;";
await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();The Python equivalent is literally the same pattern: DefaultAzureCredential() is passed as the credential parameter of BlobServiceClient, and no key appears anywhere. Compare the two connection strings: module 3's carried a username and a password; this one carries nothing. There is no secret to rotate, leak or revoke. The secrets that do still exist — third-party API keys, the payment gateway certificate — are the subject of the next lesson.
Common Mistakes and Tips
- Granting Contributor and expecting access to the data. It is the number one support ticket. Data roles are separate roles (section 4).
- Assigning Owner "so it stops getting in the way", or assigning roles to people instead of groups, or moving up to subscription scope out of convenience. All three are the same laziness and all three are paid for in month twelve.
- Leaving account keys active after switching to a managed identity. If
allow-shared-key-accessis stilltrue, the old door is still open and any Contributor can use it. - Creating a custom role before looking for a built-in one. There are over 400; there is almost always one that fits, and a custom role has to be maintained.
- Forgetting that a system-assigned identity dies with the resource. If you recreate the application, its role assignments are orphaned. And be patient with propagation: RBAC takes up to five minutes, and the user's token takes until they sign in again.
- Tip: create a single instance of
DefaultAzureCredentialand reuse it. One per request drives up latency and can trigger throttling. - Tip: review
az role assignment list --allevery quarter looking for orphaned assignments (deleted identities show up as a GUID with no name) and remove them.
Exercises
Exercise 1: allocating permissions in Contoso Miles
The "Contoso Miles" project (centro-coste=CC-2077) has rg-contoso-millas-pro and rg-contoso-millas-dev. The people involved: three developers who deploy to development and need to diagnose production; an analyst who only looks at metrics and costs; a web application that reads and writes blobs in stmillascontosopro; and Marta Ríos, who administers the infrastructure.
- State the principal, role and scope for each case, as a table.
- Which of those four principals must not be a user, and what must it be?
- Which assignment would you put under PIM, and why?
Exercise 2: writing a custom role
Contoso needs a role "Soporte de Reservas de Contoso" that allows reading any resource in the production resource group, restarting virtual machines and opening support tickets, but never reading Key Vault secrets or blob data.
- Write the definition
jsonwithActions,NotActions,DataActionsandAssignableScopes. - Why does an empty
DataActionsalready prevent reading blobs, even though nothing appears inNotDataActions? - What command would you use to find the exact name of the VM restart action?
Exercise 3: removing the last password
The Availability API runs on vmss-api-disponibilidad-pro and keeps the key for stoperacionescontosopro and the password for cosmos-contoso-tarifas-pro in a configuration file.
- Which type of managed identity applies here, and why not the other one?
- List the steps, with the commands, to remove both secrets.
- A developer says "it won't work locally because there is no managed identity". What do you tell them?
Solutions
Solution 1:
- Group
Contoso-Millas-Desarrollo: Contributor onrg-contoso-millas-devand Reader onrg-contoso-millas-pro. Analyst: Reader plus Cost Management Reader on the subscription. Web application: Storage Blob Data Contributor on thestmillascontosoprocontainer, never on the whole account. Marta, throughContoso-Infraestructura: Contributor on the subscription, eligible via PIM. - The web application: it must be a managed identity, not a user and not a service principal with a secret. No application needs a password in Azure.
- Marta's, and any Owner or User Access Administrator: those are the ones that allow privilege escalation, and with PIM they do not exist at rest. Development's Reader access on production does not need it: it is read-only and it is used every day.
Solution 2:
Actions:*/read,Microsoft.Compute/virtualMachines/restart/action,Microsoft.Support/*.NotActions:Microsoft.KeyVault/vaults/secrets/read,Microsoft.Storage/storageAccounts/listKeys/action(critical: without it,*/readdoes not include it but it is worth stating explicitly, and it prevents keys being obtained if the actions were ever widened).DataActions:[].NotDataActions:[].AssignableScopes: the identifier ofrg-contoso-reservas-pro.- Because the data plane denies by default: only what appears explicitly in
DataActionsis granted.NotDataActionsexists to subtract from a granted set, and here there is nothing granted. With noDataActions, there is no data access, full stop. az provider operation show --namespace Microsoft.Compute --query "resourceTypes[?name=='virtualMachines'].operations[].name", or the same command filtered onrestart.
Solution 3:
- User-assigned (
id-contoso-api-pro). In a scale set, instances are born and die constantly; with a system-assigned identity, each instance would have its own identifier and permissions would have to be assigned to it as it was created, which is unworkable with autoscaling. With a user-assigned identity the permissions are granted once and every instance inherits them. - Create the identity (
az identity create -g rg-contoso-reservas-pro -n id-contoso-api-pro); associate it with the scale set (az vmss identity assign --identities); grant it Storage Blob Data Contributor on thestoperacionescontosoprocontainer and Cosmos DB Built-in Data Contributor on thecatalogodatabase (withaz cosmosdb sql role assignment create, which is Cosmos DB's own RBAC system); turn off key access on the storage account with--allow-shared-key-access falseand disable the Cosmos keys with--disable-key-based-metadata-write-access; and finally delete the configuration file and purge the secret from the repository history. - That it does work:
DefaultAzureCredentialwalks a chain of providers and, if it finds no managed identity, uses the Azure CLI session (az login) or the Visual Studio Code one. The code is identical locally and in production; the only thing that changes is where the token comes from. All you need is to give their user the corresponding data role in the development environment.
Conclusion
You now know how Azure authorizes. A role assignment is always a triad — security principal, role definition and scope — that is inherited downwards through the hierarchy of management group, subscription, resource group and resource, with permissions that only add. You know the built-in roles that actually get used and the decisive difference between Owner and Contributor: assigning roles. And you are clear about the trap that generates the most incidents: Contributor does not grant access to data, because the management plane and the data plane are separate universes, so Diego can delete the whole of sttarjetascontosopro and cannot read a single PDF inside it. You have written the custom role "Operador de Reservas de Contoso" understanding Actions, NotActions, DataActions and AssignableScopes, you know deny assignments exist, and you have allocated the permissions of Contoso's four groups with genuine least privilege, plus an orderly procedure for diagnosing why somebody has no access.
In the second half you have removed the problem at the root. Managed identities are service principals whose credentials Azure manages; you can tell system-assigned ones — one per resource, dying with it — from user-assigned ones — shared, with pre-assignable permissions, mandatory on vmss-api-disponibilidad-pro — and you understand the token flow against the local IMDS endpoint at 169.254.169.254, unreachable from outside. With that, app-contoso-reservas-pro reaches sttarjetascontosopro with the Storage Blob Data Contributor role and db-reservas as an external user with db_datareader and db_datawriter, shared key access has been turned off and DefaultAzureCredential makes the same code work on the laptop and in production without a single secret.
But not every secret disappears that way. Contoso still has the payment gateway key, the weather data provider's token, the TLS certificate for contosoairlines.example and a handful of legacy connection strings, today spread between application settings, the repository and a shared document. In the next lesson, Azure Key Vault, you will centralize all of that in kv-contoso-pro inside rg-contoso-seguridad-pro, with soft delete, purge protection, RBAC permissions and a private endpoint, and you will have the application read them with today's same managed identity through @Microsoft.KeyVault(...) references. That is the moment when passwords disappear from the deployment as well.
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
