777-azure-learning
-
az-900 study : 20250516-777-azure-notes
-
az-104 lab : 777-azure-notes-3(az-104)
-
az-104 official doc : 777-az104-offical-doc
generally , resource group β login in your azure ac β VM in brower β powershell admin β choco install docker-desktop -y
- restart and check
Image Efficiency Principles Choose an appropriate base (light weight) Avoid unnecessary packages () Adopt container modularity (single function maybe) Avoid including application data (secrets and token)
Azure Container Registry (ACR)
ACR Image flow
Create a new DOTNET core project
dotnet --list-sdks
dotnet --list-runtimes
mkdir dotnet-projects
cd .\dotnet-projects\
dotnet new mvc -o containerapp
cd .\containerapp\
ls
code .
Install the Visual Studio Code extensions (C# and Docker)
VS Code β Extensions β Search for C# β Install the extension
VS Code β Extensions β Search for Docker β Install the extension
Containerize the application
VS Code β F1 β Docker: Add docker files to workspace
.NET: ASP.NET Core
Linux
80,443 β Enter
Include optional Docker Compose files?: No
Review Dockerfile
Right click Dockerfile β Build image
Test the containerized app locally
Go back to PowerShell:
docker image ls
docker run --detach --publish 80:80 containerapp
docker container ls
start chrome http://localhost:80
docker container stop <container_id>
Create a container registry using the Azure CLI
az login
$group = "DockerOnAzureCourse-HOL-RG"
$location = "eastus"
$random = Get-Random
$acrname = "doazacr$random"
az group create --resource-group $group --location eastus
az acr create --resource-group $group --name $acrname --sku Basic --admin-enabled true
View the repositories and images in the registry
- It should be empty as we are yet to create a repository or push an image to the registry
az acr repository list --name $acrname
Upload the containerized app to the registry
# Before pushing and pulling container images, we must log in to the registry
# For this, we need our registry login server address, username and password
$acrloginserver = $(az acr show --name $acrname --query loginServer)
$acrusername = az acr credential show --name $acrname --query username
$acrpassword = az acr credential show --name $acrname --query 'passwords[0].value'
echo $acrloginserver
echo $acrusername
echo $acrpassword
# Log in to registry using Docker
docker login "$acrloginserver" --username $acrusername --password $acrpassword
# Tag the image
docker tag containerapp:latest $acrloginserver/containerapp:latest
docker image ls
# Push the image
docker push $acrloginserver/containerapp:latest
Verify the image in the registry
az acr repository list --name $acrname
az acr repository show --name $acrname --repository containerapp
az acr manifest list-metadata $acrloginserver/containerapp
Demonstration: Push a Container Image to Azure Container Registry
Create a container registry using the Azure CLI
az login
$group = "DockerOnAzureCourse-HOL-RG"
$location = "eastus"
$random = Get-Random
$acrname = "doazacr$random"
az group create --resource-group $group --location eastus
az acr create --resource-group $group --name $acrname --sku Basic --admin-enabled true
View the repositories and images in the registry
- It should be empty as we are yet to create a repository or push an image to the registry
az acr repository list --name $acrname
Upload the containerized app to the registry
# Before pushing and pulling container images, we must log in to the registry
# For this, we need our registry login server address, username and password
$acrloginserver = $(az acr show --name $acrname --query loginServer)
$acrusername = az acr credential show --name $acrname --query username
$acrpassword = az acr credential show --name $acrname --query 'passwords[0].value'
echo $acrloginserver
echo $acrusername
echo $acrpassword
# Log in to registry using Docker
docker login "$acrloginserver" --username $acrusername --password $acrpassword
# Tag the image
docker tag containerapp:latest $acrloginserver/containerapp:latest
docker image ls
# Push the image
docker push $acrloginserver/containerapp:latest
Verify the image in the registry
az acr repository list --name $acrname
az acr repository show --name $acrname --repository containerapp
az acr manifest list-metadata $acrloginserver/containerapp
Automating Container Builds Using Azure DevOps
azure devops β projects β repo url
- after git push
azure pipline:
- make another image name for easier to distinguish
yaml file
Pre-Requisites
- Azure SubScription
- Azure DevOps Organization
Create an Azure DevOps Project
-
Azure DevOps Console β New project
Project Name
: containerappVisibility
: PrivateCreate
-
Azure DevOps Console β containerapp (Project) β Repos β Clone to your computer β Copy URL
Initialize git and push code to the remote repository
git init
git remote add origin <repo_url>
git remote -v
git config --global user.name "<name>"
git config --global user.email "<email>"
git status
git add .
git commit -m "added dotnet mvc template"
git push --set-upstream origin master
git status
Create and run pipeline
-
Azure DevOps Console β containerapp β Pipelines β Create pipeline
Where is your code?
: Azure Repos Git β containerappConfigure your pipeline
: Docker - Build and push an image to Azure Container Registry β Select your Azure subscription β Continue
-
Container registry
: doazacr***** -
Image Name
: containerappdevops -
Dockerfile
: $(Build.SourcesDirectory)/Dockerfile -
Validate and configure
-
Review pipeline
-
Save and run β Save and run
-
Select and monitor Build job
Review the container image in the registry
- Azure Portal β Container registries β doazacr******* β Services β Repositories β containerappdevops
Update image automatically
-
Review the Pipeline Trigger and Container Registry
`trigger:
- master| I `
Review the pipeline trigger and container registry
- Azure DevOps Console β containerapp β Pipelines β containerapp β Edit
- Review the trigger
- Azure Portal β Container registries β doazacr******* β Services β Repositories β containerappdevops
- Review the tags
Make code changes locally and push to the remote repository
- VS Code β Views β Home β Index.cshtml
- Change βWelcomeβ to βDocker on Azure Courseβ
- Commit β Message: βmodified headerβ β Commit β Would you like to stage all changes: Yes β Sync changes
- This action will pull and push commits from and to βorigin/masterβ: OK
Review the pipeline run
- Azure DevOps Console β containerapp β Pipelines β Runs β Create pipeline
Confirm the updated container image in the registry
- Azure Portal β Container registries β doazacr******* β Services β Repositories β containerappdevops
- Review the tags
Deploy a container to ACI using Azure CLI
Deploy a container to ACI using Azure CLI
Get the credentials of the container registry
$group = "DockerOnAzureCourse-HOL-RG"
$location = "eastus"
$acrname = $(az acr list --resource-group $group --query [0].name --output tsv)
$acrloginserver = $(az acr show --name $acrname --query loginServer)
$acrusername = $(az acr credential show --name $acrname --query username)
$acrpassword = $(az acr credential show --name $acrname --query 'passwords[0].value')
Generate a random name for the container instance
$random = Get-Random
$acidnsname = "containerapp$random"
Deploy the container instance using Azure CLI
az container create --resource-group $group --name "containerapp-aci" --image "$acrloginserver/containerapp:latest" --dns-name-label "$acidnsname" --ports 80 --cpu 2 --memory 4 --registry-username $acrusername --registry-password $acrpassword
Validate that the container app is running
$acifqdn = $(az container show --resource-group $group --name "containerapp-aci" --query ipAddress.fqdn --output tsv)
start chrome http://$acifqdn
Deploy a container to ACI using Azure CLI
Get the credentials of the container registry
$group = "DockerOnAzureCourse-HOL-RG"
$location = "eastus"
$acrname = $(az acr list --resource-group $group --query [0].name --output tsv)
$acrloginserver = $(az acr show --name $acrname --query loginServer)
$acrusername = $(az acr credential show --name $acrname --query username)
$acrpassword = $(az acr credential show --name $acrname --query 'passwords[0].value')
Install/Upgrade the Azure Container Apps extension for Azure CLI
- The extension is in preview
az extension add --name containerapp --upgrade
Deploy the container app
az containerapp up --name "containerapp-aca" --resource-group $group --location $location --environment 'container-apps' --image "$acrloginserver/containerapp:latest" --target-port 80 --ingress external --registry-username $acrusername --registry-password $acrpassword
Validate that the container app is running
$acafqdn = $(az containerapp show --resource-group $group --name "containerapp-aca" --query properties.configuration.ingress.fqdn --output tsv)
start chrome http://$acafqdn
Solution Automate container deployment to ACI using Azure DevOps
Pre-Requisites
- Azure SubScription
- Azure DevOps Organization
Modify the pipeline to include a deployment stage
-
Azure DevOps Console β project β containerappdevops β Pipelines β containerappdevops β Edit
-
Add a new stage
- stage: Deploy
displayName: Deployment stage
jobs:
- job: Deploy
displayName: Deploy
pool:
vmImage: $(vmImageName)
steps:
- task: AzureCLI@2
inputs:
azureSubscription: '<YOUR SUBSCRIPTION DETAILS>'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
group="DockerOnAzureCourse-HOL-RG" location="eastus"
acrname=$(az acr list --resource-group $group --query [0].name --output tsv)
acrloginserver=$(az acr show --name $acrname --query loginServer --output tsv)
acrusername=$(az acr credential show --name $acrname --query username --output tsv)
acrpassword=$(az acr credential show --name $acrname --query 'passwords[0].value' --output tsv)
random=$RANDOM
acidnsname="containerappdevops$random"
# Retry logic
max_retries=5
retries=0
while [ $retries -lt $max_retries ]; do
# Create the container
az container create --resource-group $group --name "containerappdevops-aci" --image "$acrloginserver/containerappdevops:$(tag)" --dns-name-label "$acidnsname" --ports 80 --cpu 2 --memory 4 --registry-username $acrusername --registry-password $acrpassword
# Check if the container creation was successful
if [ $? -eq 0 ]; then
break
fi
# Check the status of the container
status=$(az container show --resource-group $group --name "containerappdevops-aci" --query "instanceView.state" --output tsv)
# If the container is transitioning, wait and retry
if [ "$status" == "Transitioning" ]; then
echo "Container is transitioning. Waiting for 30 seconds before retrying..."
sleep 30
retries=$((retries+1))
else
# If there's another error, exit the loop
break
fi
done
if [ $retries -eq $max_retries ]; then
echo "Failed to create the container after $max_retries attempts."
exit 1
fi
Network
Set variables
$group = "DockerOnAzureCourse-HOL-RG"
$location = "eastus"
$vnet = "DOAz-VNet"
Create vNet and subnet
az network vnet create -n $vnet -g $group --address-prefix 10.1.0.0/16 --subnet-name "vm-subnet" --subnet-prefix 10.1.1.0/24
az network vnet subnet create -n "aci-subnet" --address-prefixes 10.1.2.0/24 -g $group --vnet-name $vnet
Deploy a virtual machine into a subnet
az vm create -g $group -n LinuxVM --image UbuntuLTS --admin-username "azureuser" --generate-ssh-keys --vnet-name $vnet --subnet vm-subnet --size Standard_D2s_v3
az vm open-port --port 22 --resource-group $group --name LinuxVM
Deploy a container instance into a subnet
$random = Get-Random
$aciname = "nginxcontainer$random"
az container create --resource-group $group --name $aciname --image nginx --vnet $vnet --subnet aci-subnet --ports 80 443
Verify private access to the container instance
* Get the container instance private IP
$aciIP = $(az container show --resource-group $group --name $aciname --query ipAddress.ip -o tsv)
echo $aciIP # Make a note of this IP address
* Get the VM's public IP and connect to it
$LinuxVM = $(az vm show -d --resource-group $group --name LinuxVM --query publicIps -o tsv)
echo $LinuxVM
ssh azureuser@$LinuxVM
* Connect to the container instance privately
curl http://<container_private_IP>
* Exit from the VM
exit
Set variables
$group = "DockerOnAzureCourse-HOL-RG"
$location = "eastus"
$vnet = "DOAz-VNet"
$acisubnet = "aci-subnet"
$acisubnetnsg = "aci-subnet-nsg"
Create a Network Security Group (NSG)
az network nsg create --name $acisubnetnsg --resource-group $group --location $location
Create a NSG rule to block inbound traffic on port 80
az network nsg rule create --name "Block-Inbound-HTTP" --nsg-name $acisubnetnsg --priority 1000 --resource-group $group --access Deny --source-address-prefixes "*" --source-port-ranges "*" --destination-address-prefixes "*" --destination-port-ranges "80" --protocol Tcp --direction Inbound
Attach the NSG to the ACI subnet
az network vnet subnet update -g $group -n $acisubnet --vnet-name $vnet --network-security-group $acisubnetnsg
Validate security rules
* Get the VM's public IP and connect to it
$LinuxVM = $(az vm show -d --resource-group $group --name LinuxVM --query publicIps -o tsv)
echo $LinuxVM
ssh azureuser@$LinuxVM
* Attempt to connect to the container instance privately (this should fail)
curl http://<container_private_IP>
* Exit from the VM
exit
Challenge solution: Limit container outbound access
Verify outbound connectivity on port 80
az container exec -g $group --name $aciname --container-name $aciname --exec-command "/bin/bash"
curl http://www.google.com
exit
Set variables
$group = "DockerOnAzureCourse-HOL-RG"
$location = "eastus"
$vnet = "DOAz-VNet"
$acisubnet = "aci-subnet"
$acisubnetnsg = "aci-subnet-nsg"
Create a NSG rule to block outbound traffic on ports 80 and 443
az network nsg rule create --name "Block-Outbound-HTTP-HTTPS" --nsg-name $acisubnetnsg --priority 1000 --resource-group $group --access Deny --source-address-prefixes "*" --source-port-ranges "*" --destination-address-prefixes "*" --destination-port-ranges 80, 443 --protocol Tcp --direction Outbound
Verify NSG effectiveness (Wait for some minutes )
az container exec -g $group --name $aciname --container-name $aciname --exec-command "/bin/bash"
curl http://www.google.com
exit