To build the image and push it to ACR then deploy the image into AKS. Follow the below steps: I tried this in my test environment in two ways and succeeded.
- The one approach is simple and clear way to do this job from ACR to AKS, using service connection. without PAT.
- Another approach is yours's I successfully achieve this too, with PAT
I will demonstrate both methods to help you understand and resolve your case.
- Approach:
create the service connection in azure DevOps to enable secure connection b/w your subscription
Recommended:
App registration (automatic)
Work identity federation
Subscription level
create Docker file and index.html
in my case I used below simple docker file and html
Simple Docker file:
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
Simple html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome to Nginx</title>
</head>
<body>
<h1>Hello from Nginx on Alpine!</h1>
<p>This is a simple static HTML page.</p>
</body>
</html>
Create Resource Group:
az group create -l centralindia -n anji-rg
create Container registry:
az acr create -g anji-rg -n acranji2654 --sku Basic
Create aks cluster by attaching the acr in-order to communicate:
az aks create -g anji-rg -n aksanji2654 -c 2 --attach-acr acranji2654
Configure AKS to communicate with clusters:
az aks get-credentials -g anji-rg -n aksanji2654 --overwrite-existing
Later create new pipeline by selecting Deploy to azure Kubernetes service by choosing your subscription then it will open configuration page then give your cluster name along with your registry details. Then it will generate pipeline file.
After pipeline got succeeded you will get two manifest files like deployment.yml & service.yml
Note: For the first time, you should grant permission to deploy the environment by opening another tab on the pipeline page.
The above process is usually followed. However, you can also create your own HTML file and custom Docker file using this same approach. It is easy to reuse and modify any files.
- Approach:
Regarding your approach, ensure you grant the correct permissions to your PAT and then save it in the pipeline variables.
Code: Read & Write
Build: Read & Execute
I will share my files to help you understand. You can configure your files by referring to these examples.
Make sure to update each service connection name separately. For example, the AKS service connection has one AKS service connection created, and similarly for ACR. Please refer to the details below.
Azure-pipeline.yml
trigger:
- main
variables:
dockerRegistryServiceConnection: 'acranji2654'
imageRepository: 'tesproject'
containerRegistry: 'acranji2654.azurecr.io'
dockerfilePath: '**/Dockerfile'
tag: '$(Build.BuildId)'
imagePullSecret: 'acranji2654f506-auth'
vmImageName: 'ubuntu-latest'
stages:
- stage: Build
displayName: Build and Push Image
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: Docker@2
displayName: Build and Push Docker Image
inputs:
command: buildAndPush
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
- publish: manifests
artifact: manifests
- stage: Deploy
displayName: Deploy to AKS
dependsOn: Build
jobs:
- deployment: Deploy
displayName: Deploy to AKS Cluster
pool:
vmImage: $(vmImageName)
environment: 'Tesproject.default'
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: manifests
- task: KubernetesManifest@0
displayName: Create imagePullSecret
inputs:
action: createSecret
secretName: $(imagePullSecret)
dockerRegistryEndpoint: $(dockerRegistryServiceConnection)
kubernetesServiceConnection: 'aksanji2654-default'
namespace: 'default'
- task: KubernetesManifest@0
displayName: Create AZP_TOKEN Secret
inputs:
action: deploy
kubernetesServiceConnection: 'aksanji2654-default'
namespace: 'default'
manifests: |
$(Pipeline.Workspace)/manifests/azp-secret.yaml
- task: KubernetesManifest@0
displayName: Deploy App to AKS
inputs:
action: deploy
kubernetesServiceConnection: 'aksanji2654-default'
namespace: 'default'
manifests: |
$(Pipeline.Workspace)/manifests/deployment.yml
$(Pipeline.Workspace)/manifests/service.yml
imagePullSecrets: |
$(imagePullSecret)
containers: |
$(containerRegistry)/$(imageRepository):$(tag)
deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tesproject
labels:
app: tesproject
spec:
replicas: 1
selector:
matchLabels:
app: tesproject
template:
metadata:
labels:
app: tesproject
spec:
containers:
- name: tesproject
image: acranji2654.azurecr.io/tesproject:$(Build.BuildId)
ports:
- containerPort: 80
imagePullSecrets:
- name: acranji2654f506-auth
service.yml
apiVersion: v1
kind: Service
metadata:
name: tesproject
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: tesproject
Make sure you have to create a file called azp-secret.yaml
It keeps your PAT securely stored in the Kubernetes cluster, also the agent reads this secret via environment variable or volume mount when it starts up.
azp-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: azp-token-secret
type: Opaque
stringData:
AZP_TOKEN: $(AZP_TOKEN)
Please let me know how these approaches work for you. If you need any further clarity, please feel free to reach out to me.