Regions and service types
- Lesson 10
- 40 min
- Module 4: Cloud building blocks
Lesson 10 of 15 · Docker and Cloud Essentials for AI DevelopersRegions and service types
1. Understand containers
2. Build the application image
3. Networking, configuration and persistence
4. Cloud building blocks
5. Deploy and clean up
What you will be able to do
Before you rent anything in the cloud, know what your service needs and which kind of cloud service gives it. Then you can choose the smallest design that works, put it in the right place, and know which parts are still your job.
Before you startWhat to know and to have ready
What you need to know
- The five things that a hosting platform does (build, start, listen, configure, keep it running), from Hosting bridge: What a hosting platform does.
- One image with different settings for each environment, from Runtime configuration: One image, many environments.
- Where data belongs (a volume, a database, object storage), from Persistent data: Where data belongs.
- Why files in a container are disposable, from Persistent data: Container files are disposable.
What you need on your computer
- The project folder
~/projects/ticket-apiat the end of Module 3, withcompose.yamland the settings table inREADME.md. They come from Persistent data: Write compose.yaml and Guided practice: the API and its database. You read these files in this lesson. You do not change them. - If your project is missing or broken, copy the snapshot
end-of-m03, as in Use a snapshot. - You do not need an Azure account for this module. Module 4 creates nothing in the cloud and costs nothing. The Azure outputs in it are live outputs, recorded in one real run. One optional command needs an Azure account.
The Azure steps were run with Azure CLI 2.88.0 and the containerapp extension 1.3.0b5, in region canadacentral. The facts about Azure, AWS and Google Cloud come from their documentation.
What the API needs
Section titled “What the API needs”Start with the service, not with the cloud. On her computer, Amira runs ticket-api with docker compose up -d. She lists what the API uses there:
| What the API needs | On Amira’s computer (Module 3) |
|---|---|
| A computer that runs the container from the image | Docker Desktop runs ticket-api:1.1.0 |
| An address that clients can reach | -p 127.0.0.1:8000:8000: only her computer |
| Settings | REQUIRE_API_KEY, SHOW_DOCS, DATABASE_URL from compose.yaml and .env |
| A secret | the API key in secrets/api_key.txt, mounted as a file |
| A place for records | PostgreSQL in the db container, with the volume ticket-api_pgdata |
| Logs | docker compose logs api |
A cloud provider, such as Azure, AWS or Google Cloud, rents you each of these things as a service. You pay for what you use, and you can delete it at the end. Every provider has the same kinds of building blocks, with different names. This module uses Azure as the example, because Module 5 deploys there. The ideas work on the other clouds too.
Regions
Section titled “Regions”A region is a place in the world where a cloud provider has its data centres, for example canadacentral (Toronto) or westeurope (the Netherlands). When you create a resource, you choose its region, and the resource runs and keeps its data there.
The region matters for four reasons:
- Distance (latency). Each request travels to the region and back. A region near your users answers faster.
- Where the data is kept (data residency). Some laws and contracts say that data must stay in a country or in the EU. Azure groups its regions in geographies, such as Canada or Europe, and a geography is a data residency boundary.
- Price. The same service can cost a different amount in a different region.
- Which services exist there. Not every service is in every region.
Many regions also have availability zones: separate groups of data centres in the same region, each with its own power, cooling and network. A service that uses more than one zone keeps working when one zone fails. The practice in this course uses one region and does not set up zones.
If you have an Azure account, you can list the regions with the Azure CLI. This command only reads, and it creates nothing:
az account list-locations --query "[?name=='canadacentral' || name=='westeurope'].{Name:name, DisplayName:displayName, Geography:metadata.geographyGroup}" -o tableThe output (live):
Name DisplayName Geography------------- -------------- -----------westeurope West Europe Europecanadacentral Canada Central CanadaThe Name is what you type in commands, for example --location canadacentral. In the course’s subscription on that day, virtual machines were in 49 regions, and Azure Container Apps in 46. For example, Israel Central and Qatar Central had virtual machines but not Container Apps. Check that every service in your design is in the region that you choose.
The course used canadacentral. Choose a region near you that has Azure Container Apps, and use it in every command where the course shows canadacentral. Use the same region for every resource of one service, so that the parts do not send data between regions.
Service types
Section titled “Service types”Each building block is a kind of service. Here they are with their general names first. The other clouds are only for orientation: this course does not use them.
| Kind | What it gives you | Azure | AWS | Google Cloud | On your computer |
|---|---|---|---|---|---|
| Compute: a virtual machine | A whole server. You manage its operating system. | Virtual Machines | Amazon EC2 | Compute Engine | Your computer |
| Compute: serverless containers | Runs your image. Starts and stops copies of it with the traffic. | Azure Container Apps | Amazon ECS on AWS Fargate | Cloud Run | docker run, Compose |
| Compute: a container orchestrator | Many containers on a cluster of servers, with full control | Azure Kubernetes Service | Amazon EKS | Google Kubernetes Engine | Compose (a small version) |
| Compute: functions | Runs one function for each event or request | Azure Functions | AWS Lambda | Cloud Run functions | none |
| Storage: object storage | Files, such as uploads and model files, by name | Blob Storage | Amazon S3 | Cloud Storage | A folder, a bind mount |
| Database: managed PostgreSQL | A PostgreSQL server that the provider patches and backs up | Azure Database for PostgreSQL flexible server | Amazon RDS for PostgreSQL | Cloud SQL for PostgreSQL | postgres:18.6-trixie with a volume |
| Networking: HTTPS ingress | A public HTTPS address that sends requests to your app | Container Apps ingress | Application Load Balancer | Built into Cloud Run | -p 127.0.0.1:8000:8000, no HTTPS |
| Networking: a private network | Parts that talk to each other but not to the internet | Virtual Network | Amazon VPC | VPC network | A Compose network |
| Managed service: a container registry | Keeps your images | Azure Container Registry | Amazon ECR | Artifact Registry | docker image ls |
| Managed service: a secret store | Keeps secrets, gives them to allowed identities | Key Vault | AWS Secrets Manager | Secret Manager | secrets/api_key.txt |
| Managed service: logs | Collects and searches the logs | Log Analytics workspace | Amazon CloudWatch Logs | Cloud Logging | docker logs |
A managed service is software that the provider runs for you. You use the database, the registry or the log store. The provider keeps it running, patched and backed up. You still choose its settings, and you still pay for it.
On AWS, the simplest way to run one container image with a public HTTPS address used to be App Runner. AWS closed App Runner to new customers on 30 April 2026, and suggests Amazon ECS Express Mode, which runs on Fargate. Names change. The kinds of service do not.
Who manages what
Section titled “Who manages what”The kinds of compute differ in one important way: who manages each layer. On your computer, you manage everything. A rented virtual machine is IaaS (infrastructure as a service). The provider manages the hardware, and you manage the operating system and everything above it. On a serverless service, the provider also manages the servers, their operating system, the HTTPS certificate, and starting and stopping copies of your app. You do not see or manage any server. You pay for what runs.
Text description of the diagram
The grid compares three places to run the ticket API. Each row is one job, and each cell says who does it. On your computer with Docker, you do all eight jobs. On a virtual machine, the provider does only one: the servers, the network and the data centre. You still patch the operating system, set up HTTPS, and restart the app when it stops. On serverless containers, the provider also does the host operating system, the HTTPS certificate and the public address. For scaling and restarts, you set the limits (for example, 0 to 2 copies) and the provider follows them. Four rows stay yours on every platform. They are your code and the image, the OS packages in the image, and the settings, secrets and identities. The fourth is the decision of what exists and when to delete it.
Look at the second row. The image contains Debian 13 and Python 3.14.8 (Module 2). On serverless, the provider patches its servers, but not the packages in your image. When the base image gets a security fix, you build your image again and deploy it again. Nobody else does it for you.
Resource groups, subscriptions and tenants
Section titled “Resource groups, subscriptions and tenants”Every thing that you create in Azure, such as a registry or a container app, is a resource. Resources go into containers at three levels:
- A resource group is a folder for resources that have the same lifecycle: you create them together, and you delete them together. When you delete a resource group, Azure deletes every resource in it. Each resource is in exactly one resource group. The practice uses one group,
rg-ticket-api-practice, so that one command can remove everything. - A subscription is an agreement with Azure, with one way to pay and its own limits. Every resource group is in one subscription, and the costs of its resources go on that subscription’s bill. A company often has separate subscriptions for production and for tests.
- A tenant is your organisation’s directory of users and identities, in Microsoft Entra ID. When you run
az login, you sign in as a user in a tenant. A tenant can have many subscriptions.
AWS and Google Cloud have the same ideas with other names (an account or a project, with tags or folders). The rule is the same everywhere: put a practice deployment in one container that you can delete at once.
Here is the first command of the real run in Module 5. It makes the group in a region, with two tags (labels that you choose, as name=value pairs; Lesson 3 uses them):
az group create --name rg-ticket-api-practice --location canadacentral --tags purpose=practice course=C18 -o tableThe output (live):
Location Name------------- ----------------------canadacentral rg-ticket-api-practiceWorked example: Amira’s minimal design
Section titled “Worked example: Amira’s minimal design”Amira maps each need from her list to the smallest building block that gives it. She writes down why for each one:
| Need | Building block | Azure resource in the practice | Why this one |
|---|---|---|---|
| Run the container from the image | Serverless containers | Container app ticket-api in the environment cae-ticket-api |
It runs the same image. It can scale to zero, so it costs nothing when nobody uses it. |
| A place for the image | Container registry | ticketapi4821 (Basic) |
The cloud cannot read the images on her computer. The registry name must be unique in all of Azure. |
| A public HTTPS address | HTTPS ingress | The app’s ingress, external, target port 8000 | The platform gives HTTPS without a certificate of her own. |
| The settings | The app’s configuration | Environment variables on the app | The same image, other settings (Module 3). |
| The API key | A secret | A Container Apps secret, api-key (Key Vault is optional) |
The key must never be in the image or in a plain setting. Lesson 2. |
| Permission to pull the image | An identity | Managed identity id-ticket-api with the role AcrPull |
No password to store. Lesson 2. |
| Logs | A log store | The Log Analytics workspace | The environment makes one automatically. Lesson 3 explains why that matters for cost. |
| History records | Managed PostgreSQL | None for the practice | A database server charges for every hour that it exists. Without DATABASE_URL, the API runs with history off. |
The last row is a decision, not a gap. The API was built for it in Module 3: without a database, classifying still works, and /v1/history answers 503 with history_unavailable. A real service would add a managed PostgreSQL server and give the app its DATABASE_URL as a secret.
Text description of the diagram
Outside Azure are two things: your computer and the clients. Your computer builds the image and pushes ticket-api:1.1.0 to the registry ticketapi4821. The clients, such as the help desk system or curl, send HTTPS requests with the X-API-Key header. Everything else is in the resource group rg-ticket-api-practice, in the region canadacentral. The requests enter through the HTTPS ingress, which the Container Apps environment cae-ticket-api runs. The ingress accepts HTTPS on port 443 and sends the requests to port 8000 of the container app ticket-api. The app runs 0 to 2 copies of the container and has one secret, api-key. To get its image, the app uses the managed identity id-ticket-api. This identity has one permission, AcrPull, on this registry only. Optionally, the same identity can read the secret from the Key Vault kv-ticket-api-4821. The environment sends the app’s logs to a Log Analytics workspace, which it created automatically. You manage the image and its packages, the settings, the secret, the identity and its role, the scale limits and the clean-up. Azure manages the servers and their operating system, the HTTPS certificate, starting and stopping the copies, and storing the images and the logs.
In the real run, after the registry, the identity and the environment were created, the group held these resources. This is the output of az resource list -g rg-ticket-api-practice -o table (live, before the container app existed):
Name ResourceGroup Location Type Status--------------------------------- ---------------------- ------------- ------------------------------------------------ ---------ticketapi4821 rg-ticket-api-practice canadacentral Microsoft.ContainerRegistry/registries Succeededid-ticket-api rg-ticket-api-practice canadacentral Microsoft.ManagedIdentity/userAssignedIdentities Succeededworkspace-rgticketapipracticeXXXX rg-ticket-api-practice canadacentral Microsoft.OperationalInsights/workspaces Succeededcae-ticket-api rg-ticket-api-practice canadacentral Microsoft.App/managedEnvironments SucceededPredict: which line is a resource that Amira did not ask for? The workspace. az containerapp env create printed No Log Analytics workspace provided. and made one. With the container app, the group has five resources, or six with the optional Key Vault.
Guided practice: map the needs
Section titled “Guided practice: map the needs”You make the design that Module 5 builds. Write your answers in a text file or on paper. You turn them into docs/cloud-design.md in Lesson 3.
- Open
compose.yamland the settings table inREADME.mdin~/projects/ticket-api. - List every thing that the API uses when it runs: the container, the port, each setting, the secret, the database and the logs.
- For each one, write the general kind of building block from the table in Service types.
- Mark each one as “needed for the practice” or “not needed for the practice”, with one reason.
- Write the region that you would use and one reason for it. Check that Azure Container Apps is in that region.
- Write the name of the resource group that holds everything.
Show an example answer
| What the API uses | Kind of building block | For the practice? |
|---|---|---|
The container from ticket-api:1.1.0 |
Serverless containers, and a container registry for the image | Needed |
| Port 8000 | HTTPS ingress to target port 8000 | Needed: clients must reach it |
REQUIRE_API_KEY=true, SHOW_DOCS=false |
Settings in the app’s configuration | Needed |
API_KEY |
A secret | Needed: REQUIRE_API_KEY=true stops the app without it |
DATABASE_URL and PostgreSQL |
Managed PostgreSQL | Not needed: history is off, and a database server charges by the hour |
ALLOWED_ORIGINS |
A setting | Not needed: the help desk system does not call from a browser |
| Logs | A log store | Needed to check the deployment (Module 5) |
Region: canadacentral for the course, or the region nearest to you that has Container Apps, for example westeurope in Europe. Resource group: rg-ticket-api-practice.
Your turn: data that must stay in Europe
Section titled “Your turn: data that must stay in Europe”The help desk moves to Germany. Its tickets contain customer names, and the company says that ticket data must stay in the EU. Change your design for this one condition. Which region do you choose? Which resources must be in it?
Show one answer
Choose a region in the Europe geography, for example germanywestcentral or westeurope, and check that Container Apps is there. Every resource that keeps or processes ticket data must be in that region: the container app, and its database if you add one. The logs count too. The workspace keeps whatever the app writes. The ticket API logs the method, the path, the status and a request ID, not the ticket text. That is a design choice from the API course and Module 3, and it helps here. Put the whole resource group, with its registry and its workspace, in the same region. Then you do not need to check each resource.
Common mistake
The design keeps the history inside the container
Symptom: In a design review, a colleague proposes to skip the database and to write the history to a file in the container. “The app runs all the time anyway.”
Cause: Files in a container are disposable. You proved it in Module 3: after docker compose up -d --force-recreate api, the file was gone (cat: /tmp/note.txt: No such file or directory). In the cloud, it happens more often. Each new revision starts new containers from the image. The app scales to zero and starts again. With 2 replicas, each replica has its own files, so two requests can see two different histories.
Fix:
- Keep records in a managed database, for example Azure Database for PostgreSQL flexible server. Give the app its address in
DATABASE_URL, as a secret. - Keep files, such as uploads or model files, in object storage (Blob Storage).
- Use the container’s own files only for things that can be lost, such as a cache.
For a real AI service, the same rule protects the expensive data: predictions, feedback from users and model files must outlive every container.
Check your understanding
Name four reasons to care which region you choose, and give one example of each.
Show the answer
Distance: a region near the users answers faster, because each request travels there and back. Data residency: a law or a contract can require that customer data stays in a country or in the EU. You then choose a region in that geography. Price: the same service can cost a different amount in another region. Availability: not every service is in every region. For example, the course’s subscription could use virtual machines in Israel Central, but not Container Apps.
Does your answer have the main points of ours?
Sign in and enroll in the course to save your answers. Every check counts toward the certificate.
Check your understanding
The ticket API runs on serverless containers. A security fix comes out for a library in Debian 13. Who installs it, and how?
Show the answer
You do. The provider patches its own servers, but the Debian packages are inside your image, and the image is yours on every platform. You build the image again from the updated base image, run the tests, push the new tag and deploy it. Serverless does not mean that nobody has to maintain anything. It means that you no longer maintain the servers.
Does your answer have the main points of ours?
Sign in and enroll in the course to save your answers. Every check counts toward the certificate.
Check your understanding
Why does the practice put every resource in one resource group?
Show the answer
A resource group is a folder for resources with the same lifecycle. When you delete the group, Azure deletes every resource in it. That includes the ones that you did not create yourself, such as the Log Analytics workspace that the environment made. One group means one clear inventory and one command to remove it all. Lesson 3 and Module 5 show the one exception: a deleted Key Vault keeps its name for 90 days.
Does your answer have the main points of ours?
Sign in and enroll in the course to save your answers. Every check counts toward the certificate.
Recap
- Start from what the service needs: run an image, a public address, settings, a secret, logs and maybe a database. Every cloud has a building block for each.
- A region is where the resources run and keep their data. Choose it for distance, data residency, price and the services that it has.
- Serverless means that the provider manages the servers and starts and stops your app. Your image, its packages, your settings, your identities and your clean-up stay your job.
- A resource group holds resources with one lifecycle. Delete the group, and everything in it goes.
- The practice design has five resources: a registry, an identity, an environment with its automatic log workspace, and the container app. A Key Vault is optional. A database is left out on purpose.
Next, you give the app an identity instead of a password, and you decide where its secret lives.
Next: Identity and secrets