AWS Jenkins CI/CD | DOTNET DevSecOps Project
DEVSECOPS CI-CD PROJECT
Merhaba arkadaşlar ;
Bu makalemizde .Net tabanlı bir uygulama dağıtacağız. Bu, birçok kuruluş tarafından kullanılan günlük bir kullanım senaryolarından biridir.
Jenkins’i bir CICD aracı olarak kullanacağız ve uygulamamızı bir Docker Konteyner ve Kubernetes kümesinde dağıtacağız. Umarım bu ayrıntılı blog sizlere faydalı olur.
Bu makale için “Aj7Ay” tarafından geliştirilmiş kod deposunu kullanıyor olacağız bu paylaşımı için kendisine teşekkür ediyorum.
Github: https://github.com/Aj7Ay/DotNet-monitoring.git
Adımlar
Bu makalemizde aşağıdaki adımları izleyeceğiz.
- Step 1a — Create an Ubuntu 24.04 T2 Large Instance
- Step 1b — Install Jenkins, Docker and Trivy,Sonarqube on Container using Docker.
- Step 1c — Install Plugins like JDK, Sonarqube Scanner, OWASP Dependency Check
- Step 1d — Configure Sonarqube Server in Manage Jenkins
- Step 2 — Create a Pipeline Project in Jenkins using a Declarative Pipeline
- Step 3a — Docker Image Build and Push
- Step 3b — Deploy the image using Docker
- Step 4 — Access the Real World Application
- Step 5 — Kubernetes setup
- Step 6 — Configuration kubernets to Jenkins
- Step 7 — Using jenkins Deploy to application on Kubernetes
Ön Gereksinimler
Jenkins Server için :
- AWS EC2 t2.Large Machine
- On Premis |Os:Ubuntu 24.04 | Cpu:2 Core| Ram:8GB
- Security Group Port: 8080(Jenkins),9000(Sonarqube),8000(Application) ,5000(app),22(ssh)
Kubernetes Cluster için:
- Ubuntu 24.04 LTS kurulu (1 master node ve en az 1 worker node).
- Makinelere root veya sudo erişimi.
- Makine başına en az 2 GB RAM (ana düğüm için 4 GB önerilir).
Step 1 → Jenkins Server Kurulumu
AWS üzerinde 1 adet ubuntu “T2 Large Instance” oluşturuyoruz.
Not : Eğer on prem vm üzerinde kurlum yapıyorsanız Min CPU:2 core Ram:8GB
Aşağıdaki kod bloğunu bu bölüme yapıştırarak tüm kurulumu otomatik hale getirip tüm gerekli paketleri sunucumuza yüklüyoruz.
Jenkins serverımızda kurulması gereken tüm paketleri aşağıdaki komutları çalıştırarak yüklüyoruz.
Github: https://github.com/serdarbayram01/Code_Store
#!/bin/bash apt-get update #Timezone ve Ntp saati ayarla sudo timedatectl set-timezone Europe/Istanbul sudo timedatectl set-ntp on #curl ve wget yükle sudo apt-get install curl sudo apt-get install curl sudo apt-get install git -y #install java sudo apt update -y wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | tee /etc/apt/keyrings/adoptium.asc echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list sudo apt update -y sudo apt install temurin-17-jdk -y /usr/bin/java --version #install jenkins curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null sudo apt-get update -y sudo apt-get install jenkins -y sudo systemctl start jenkins sudo systemctl status jenkins #install docker sudo apt-get update sudo apt-get install docker.io -y sudo usermod -aG docker ${USER} sudo usermod -aG docker jenkins sudo usermod -aG docker ubuntu newgrp docker sudo chmod 777 /var/run/docker.sock #install Docker Compose curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose docker-compose --version #Sonarqube docker image up docker run -d --restart always --name sonarqube-custom -p 9000:9000 sonarqube:lts-community # Install AWS CLI curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" sudo apt-get install unzip -y unzip awscliv2.zip sudo ./aws/install # Install kubectl sudo apt update sudo apt install curl -y curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl kubectl version --client #EKSCTL Setup curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp sudo mv /tmp/eksctl /usr/local/bin # Install Terraform sudo apt install wget -y wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list sudo apt update && sudo apt install terraform #Trivy sudo apt-get install wget apt-transport-https gnupg wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee -a /etc/apt/sources.list.d/trivy.list sudo apt-get update sudo apt-get install trivy
Yukarıdaki komut setini AWS EC2 makinemi oluştururken “User data” bölümüne giriyorum böylelikle bu işlemleri makineye bağlanıp tek tek çalıştırmamıza gerek kalmadan AWS bizim için makine kurulum sırasında hallediyor olacak.
AWS Security group (Firwall)
Firwall üzerinde yada AWS Security Group üzerinden aşağıdaki portların açık olması gerekmektedir .
Port: 8080(Jenkins),9000(Sonarqube),8000(Application) ,5000(app),22(ssh)
Jenkins Configuration
adresine giderek sunucumuza bağlanıyoruz aşağıdaki sayfa bizi karşılayacak.
cat /var/lib/jenkins/secrets/initialAdminPassword
Yukarıdaki komutla jenkins için oluşturulmuş parolayı alıp Jenkinsimize login oluyoruz.
install Suggested Plugin seçeneği ile devam ediyoruz.
Kendime bir admin hesabı oluşturacağım ekran geliyor buraya hesap bilgilerimi giriyorum.
Paket Versiyon Check
birçok paket kurulumu yaptık aşağıdaki komutlarla jenkins serverımıza yüklediğimiz paketlerin kontrolünü yapıyoruz.
docker -v docker compose --version trivy --version terraform --version /usr/bin/java --version jenkins --version aws --version kubectl version --client eksctl version
docker ps -a
Bu komutla aktif durumda olan containerlarımı görüntülüyorum göründüğü gibi sonarqube serverım da container olarak çalışır durumda.
Sonarqube Login
adresine gerek sonarqube serverımıza bağlanıyoruz.
user name :admin Password :admin
Yeni parola belirliyoruz.
Login olduktan sonra bizi Sonarqube ekranımız karşılıyor.
Jenkins Eklenti Kurulumları
Labımız için jenkins serverda olması gereken eklentilerin kurulumlarını yapıyoruz.
Manage Jenkins→Plugin yolunu takip ederek aşağıdaki pluginleri yüklüyoruz.
- OWASP
- Eclipse Temurin
- Sonarqube Scanner
- Pipeline: Stage View
- Blue Ocean
install diyerek kurulumu başlatıyorum.
Jenkins Tools Configuration
Jenkins Manage →Tools →Jdk
“jdk17” adını veriyoruz burada verdiğimiz isim oldukça önemli çünkü pipeline yazarken bu isimleri kullanacağız.
OWASP Dependency Check Plugins
Jenkins Manage →Tools→Dependency-Check installations
“DP-check” adını veriyoruz burada verdiğimiz isim oldukça önemli çünkü pipeline yazarken bu isimleri kullanacağız.
SonarQube Scanner Config
Jenkins Manage →Tools→SonarQube Scanner installations
“sonar-scanner” adını veriyoruz burada verdiğimiz isim oldukça önemli bir sonraki adımda sonar qube serverımızın tanımlarını yaparken bu adı kullanacağız.
Sonarqube Configuration
http://jenkins-server-ip:9000 adresine giderek sonarqube serverımıza bağlanıyoruz.
Sağ üst bölümdeki “Administrator” →My Account yolunu takip ediyoruz.
“Security” bölümüne geliyoruz ve jenkins serverımızın sonarqube ile bağlantı kurup analizler için kullanacağı “jenkins” adında token credentialı “Generate” diyerek oluşturuyoruz.
Bize vermiş olduğu keyi bir yere not ediyoruz bunu daha sonra kullanacağız.
Webhook Configuration
SonarQube webhook’ları, bir yazılım projesinin kod kalitesi analizinin tamamlandığına dair bir web adresine bildirim göndermek için kullanılan bir mekanizmadır. Bu bildirimler, genellikle bir HTTP POST isteği şeklinde gönderilir ve içerisinde analiz sonuçlarına dair JSON formatında veriler bulunur. Bu sayede, SonarQube’da gerçekleştirilen analizlerin sonuçları, başka sistemlere veya araçlara anında iletilebilir ve otomatik işlemler tetiklenebilir.
Administration→ Configuration→Webhooks
Create Diyerek webhook umuzu oluşturuyoruz.
Jenkins serverımızın public ip adresini bu alana yazarak aşağıdaki formatta giriyoruz.
#in url section of quality gate http://jenkins-public-ip:8080/sonarqube-webhook/
Jenkins Sonarqube credential
“Jenkins Manage → credential” Menüsüne gidiyoruz.
Global seçeneğini seçerek Devam ediyoruz.
“Secret txt” seçeneğini seçiyoruz ve sonarqube için oluşturduğumuz token bilgisini buraya giriyoruz.
ID bölümünü “sonar-cred” olarak giriyoruz burası oldukça önemli çünkü pipeline bölümünde bu isimle çağıracağız.
Jenkins add Sonarqube server
“Jenkins Manage → System” Menüsüne gidiyoruz.
“Add sonarqube” diyerek sonarqube serverımıza ait yukarıda tanımladığımız bilgileri giriyoruz.
Name =”sonar-server” olarak giriyoruz.
Server URL = http://localhost:9000 # şeklinde girdim çünkü sonarqube ile jenkins serverım aynı makine, Jenkins localhost u 9000 portundan çağırdığında direk sonarqube containerına gidecek.
server authentication token : buraya credential bölümünde girdiğimiz “sonar-cred” hesabını seçiyoruz.
Kayıt edip çıkıyoruz.
Step2 → Projeyi Oluşturma
“Dashboard → New Item“ yolunu izleyrek aşağıdaki ekranda Projemize bir isim veriyoruz “Dotnet CI-CD” ve pipeline ı seçerek projemizi yaratıyoruz.
pipeline{ agent any tools{ jdk 'jdk17' } environment { SCANNER_HOME=tool 'sonar-scanner' } stages { stage('clean workspace'){ steps{ cleanWs() } } stage('Checkout From Git'){ steps{ git branch: 'main', url: 'https://github.com/serdarbayram01/DotNet-monitoring.git' } } stage("Sonarqube Analysis "){ steps{ withSonarQubeEnv('sonar-server') { sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=Dotnet-Webapp \ -Dsonar.projectKey=Dotnet-Webapp ''' } } } stage("quality gate"){ steps { script { waitForQualityGate abortPipeline: false, credentialsId: 'sonar-cred' } } } stage("TRIVY File scan"){ steps{ sh "trivy fs . > trivy-fs_report.txt" } } stage("OWASP Dependency Check"){ steps{ dependencyCheck additionalArguments: '--scan ./ --format XML ', odcInstallation: 'DP-check' dependencyCheckPublisher pattern: '**/dependency-check-report.xml' } } } }
işlem sonucu Sonarqube baktığımızda aşağıdaki gibi bir analiz ekranı görüyor olacağız.
ilk çalıştırdığınızda bu işlem yaklaşık 30 dk sürecektir. Owasp DB sini indirmek bağlantı hızı ve makine performansınıza göre 20-30 dk civarı sürüyor.
Step 3 → Docker Image Build and Push
Sistemimize Docker aracını yüklememiz gerekiyor, Dashboard → Manage Plugins → Available plugins → Docker’ı arayın ve bu eklentileri yükleyin
- Docker
- Docker Commons
- Docker Pipeline
- Docker API
- docker-build-step
Dashboard → Manage Jenkins → Tools
Menüsüne gidiyoruz ve docker’ın hangi versiyonla çalıştırılacağını(latest) belirliyoruz.
Docker hub (https://hub.docker.com/) hesabımızı Jenkins serverımıza tanımlıyoruz.
Dashboard → Manage Jenkins → Credential → (Global)
Burada docker hub hesap bilgilerimi girerek “docker-cred” adıyla kayıt ediyorum.
Jobımıza giderek config menüsünü açıyoruz ve aşağıdaki kodları kendi repo ve hesap bilgilerinize göre düzenleyerek pipeline’ımıza ekliyoruz.
Dahsboard→ Dotnet CI-CD→Configure
stage('Docker Build & Push') { steps { script { withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') { sh "docker build -t dotnet-cicd ." sh "docker tag dotnet-cicd serdarbayram/dotnet-cicd:latest" sh "docker push serdarbayram/dotnet-cicd:latest" } } } } stage("TRIVY"){ steps{ sh "trivy image serdarbayram/dotnet-cicd:latest > trivy.txt" } } stage('Deploy to Container') { steps { sh 'docker run -d --name dotnet-cicd -p 5000:5000 serdarbayram/dotnet-cicd:latest' } }
Tüm işlemleri başarıyla tamamladığınızda aşağıdaki gibi tamamlanmış pipline ı göreceksiniz.
Step 4 → Public Erişim
(SG -Güvenlik Grubuna 5000 portunu ekleyin)
Ve uygulamanıza 5000 numaralı porttan erişebilirsiniz. Bu, tüm Fonksiyonel Sekmelere sahip Gerçek bir production Uygulamasıdır.
<public-ip of jenkins:5000>
Step 5 → Kubernetes kurulumu
Bir sonra ki aşamada uygulamamızı Kubernetes üzerine deploy edeceğiz bunun için bir kubernetes cluster kuracağız. Best Practickes min 3 sunucu kurulması önerilmektedir fakat biz Lab ortamımız için Master ve worker olmak üzere 2 adet Ubuntu 24.04 Makine Kurulumu gerçektelştiriyor olacağız siz bu sayıyı artırabilirsiniz.
AWS EC2 Panelimize gidiyoruz ve 2 adet “t2-medium” Makine yaratıyoruz ve her iki makinede aşağıdaki komutları çalıştırıyoruz.
#!/bin/bash sudo apt update && sudo apt upgrade -y #Timezone ve Ntp saati ayarla sudo timedatectl set-timezone Europe/Istanbul sudo timedatectl set-ntp on #curl ve wget yükle sudo apt-get install curl sudo apt-get install wget sudo apt-get install git -y
Aşağıdaki komutla Master ve Worker node larımızı isimlendiriyoruz.
#hostname isimi ver sudo hostnamectl set-hostname master
Master ve Worker Node
Aşağıdaki komutları her iki makinede de çalıştırıyoruz.
sudo apt update && sudo apt upgrade -y sudo apt install -y docker.io sudo docker --version
Kubernets kubeadm, kubelet, and kubectl Component kurulumu
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg sudo apt update sudo apt install -y kubelet kubeadm kubectl #Otomatik yükseltmeleri önlemek için paketleri mevcut sürümlerinde tutun: sudo apt-mark hold kubelet kubeadm kubectl
Disable Swap
Ubuntu Makinelerdeki Swap alanı kubernets için disable edilmeli.
sudo swapoff -a sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
Master Node üzerinde çalıştırılacak
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
YUkarıdaki komut sonrası aşağıdaki gibi bir çıktı göreceksiniz.
Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Alternatively, if you are the root user, you can run: export KUBECONFIG=/etc/kubernetes/admin.conf You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 172.31.41.49:6443 --token 6szvbv.vapkh1kqiugdkshj \ --discovery-token-ca-cert-hash sha256:638f50c4bd70dc0882b5e93d0a130bd2098d85814df0b6a985ce897ae15afb22
Burada sarı alan içindeki kısım bizim Worker node umuzu dahil etmek için kullanacağımız komut bunu bir yere not ediyoruz.
Master node için kube config dosyasını aşağıdaki komutlarla yaratıyoruz.
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
aşağıdaki komutla worket nodları görüntülüyoruz. Henüz worker eklemediğimiz için burada bi worker göremeyeceğiz.
kubectl get nodes
Ve pod network yapılandırılmadığı için master makinemiz “NotReady” olarak görünüyor.
Install a Pod Network (Önemli)
Daha sonra, pod’larınız arasında iletişimi sağlamak için bir pod ağı dağıtıyoruz. Uygun bir pod ağının olmaması, Kubernetes kümesinin işlevselliğini ve güvenilirliğini ciddi şekilde sınırlayabileceğinden bu önemli bir adımdır. Kubernetes kümesindeki birden fazla düğüm arasında ağ kurmak için Flannel’ı dağıtıyoruz.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl get nodes
Aşağıda göründüğü gibi Master makinemiz hazır duruma geçiyor.
root@master:/home/ubuntu# kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready control-plane 5m28s v1.30.6
Worker Node Ekleme
Master Makinemiz hazır durumda şimdi az önce kayıt ettiğimiz worker ekleme komutunu çalıştırıyoruz.
sudo kubeadm join <master-ip>:<master-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
Komut aşağıdaki gibi bir komut olmalı
kubeadm join 172.31.41.49:6443 --token 6szvbv.vapkh1kqiugdkshj \ --discovery-token-ca-cert-hash sha256:638f50c4bd70dc0882b5e93d0a130bd2098d85814df0b6a985ce897ae15afb22
Çıktımız aşağıdaki gibi olacaktır.
root@ip-172-31-38-216:/home/ubuntu# kubeadm join 172.31.44.218:6443 --token x4q4yk.rse3sntk6pu16yo7 \ --discovery-token-ca-cert-hash sha256:2f584a643ca7ba019427bf6bfeed201b6580b56c1056239769b3a5b96a939330 [preflight] Running pre-flight checks [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Starting the kubelet [kubelet-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s [kubelet-check] The kubelet is healthy after 1.001593307s [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
Master Node üzerinde kontrol
kubectl get nodes kubectl get nodes -o wide
Kubernetes Clusterımız başarıyla kuruldu
Aşağıdaki komutu girerek Clusterımıza ait cofig dosyasını kopyalayarak bir yere not ediyoruz birazdan Jenkins serverımızda bu dosyayı kullanarak Kubernets connect credential profilini oluşturacağız.
Master Nod credential bilgilerini alma
Kubernets credential bilgileri K8s in config dosyasında yer almaktadır bu sebeple dosyamızı vi editörle açarak içeriğini bir notepad e kopyalayacağız.
vi ~/.kube/config
dosya ile işimiz bitince aşağıki şekilde dosyadan değişiklik yapmadan çıkabilirsiniz.
:q!
Bir isim vererek kayıt ediyoruz ben “kubernets-secret-File.txt“ ismiyle kayıt ettim.
Step 6→Jenkins Kubernetes Cluster Configuration
Jenkins Serverımızda Manage Jenkins→Plugin yolunu takip ederek aşağıdaki pluginleri yüklüyoruz.
Manage Jenkins → Credential bölümüne gidiyoruz ve global altında k8s için “k8s-cred” adında yeni bir hesap tanımlıyoruz.
Step 7 → Deploy Application on Jenkins
Dashboard projemize giderek aşağıdaki kod bloğunu son step olarak son iki süslü parantezin hemen üzerine ekliyoruz.
stage('Deploy to k8s'){ steps{ dir('K8S') { withKubeConfig(caCertificate: '', clusterName: '', contextName: '', credentialsId: 'k8s-cred', namespace: '', restrictKubeConfigAccess: false, serverUrl: '') { sh 'kubectl apply -f deployment.yaml' } } } }
Projemizi Run Ettiğimizde aşağıdaki gibi başarılı bir şekilde tamamlandığını görebilirsiniz.
Kubernetes Makinemizde kontrollerimizi yapıyoruz.
kubectl get svc #copy service port <worker-ip:svc port>
Workernod ip adresimizle yaptığımız kontrol sonrası kubernetes üzerindeki görüntümüz aşağıdaki gibi olacaktır.
Jenkins pipeline çıktısı
pipeline{ agent any tools{ jdk 'jdk17' } environment { SCANNER_HOME=tool 'sonar-scanner' } stages { stage('clean workspace'){ steps{ cleanWs() } } stage('Checkout From Git'){ steps{ git branch: 'main', url: 'https://github.com/serdarbayram01/DotNet-monitoring.git' } } stage("Sonarqube Analysis "){ steps{ withSonarQubeEnv('sonar-server') { sh ''' $SCANNER_HOME/bin/sonar-scanner -Dsonar.projectName=Dotnet-Webapp \ -Dsonar.projectKey=Dotnet-Webapp ''' } } } stage("quality gate"){ steps { script { waitForQualityGate abortPipeline: false, credentialsId: 'sonar-cred' } } } stage("TRIVY File scan"){ steps{ sh "trivy fs . > trivy-fs_report.txt" } } stage("OWASP Dependency Check"){ steps{ dependencyCheck additionalArguments: '--scan ./ --format XML ', odcInstallation: 'DP-check' dependencyCheckPublisher pattern: '**/dependency-check-report.xml' } } stage('Docker Build & Push') { steps { script { withDockerRegistry(credentialsId: 'docker-cred', toolName: 'docker') { sh "docker build -t dotnet-cicd ." sh "docker tag dotnet-cicd serdarbayram/dotnet-cicd:latest" sh "docker push serdarbayram/dotnet-cicd:latest" } } } } stage("TRIVY"){ steps{ sh "trivy image serdarbayram/dotnet-cicd:latest > trivy.txt" } } stage('Deploy to Container') { steps { sh 'docker run -d --name dotnet-cicd -p 5000:5000 serdarbayram/dotnet-cicd:latest' } } stage('Deploy to k8s'){ steps{ dir('K8S') { withKubeConfig(caCertificate: '', clusterName: '', contextName: '', credentialsId: 'k8s-cred', namespace: '', restrictKubeConfigAccess: false, serverUrl: '') { sh 'kubectl apply -f deployment.yaml' } } } } } }