GitLab CI/CD Pipeline Kurulumu ve Gelişmiş Optimizasyon Stratejileri
GitLab CI/CD, bir projenin yaşam döngüsünü, kod deposuyla sıkı entegrasyon sağlayarak otomatize etme yeteneği sunar. Bu, yazılım geliştirme süreçlerinde tutarlılık, hız ve güvenilirlik açısından kritik bir bileşendir. Bir pipeline, kodun build edilmesinden test edilmesine, güvenlik taramalarından üretim ortamına dağıtımına kadar bir dizi aşamayı tanımlayan yapılandırılmış bir iş akışıdır.
GitLab CI/CD Temelleri: .gitlab-ci.yml Anatomisi
Her GitLab projesinin kök dizininde bulunan .gitlab-ci.yml dosyası, pipeline'ınızın kalbidir. Bu YAML dosyası, çalıştırılacak işleri (jobs), bu işlerin hangi aşamalara (stages) ait olduğunu ve hangi koşullarda tetikleneceğini belirler. Basit bir CI/CD pipeline'ı genellikle 'build', 'test' ve 'deploy' gibi temel aşamalardan oluşur.
stages:
- build
- test
- deploy
build_job:
stage: build
image: node:16-alpine
script:
- echo "Building application..."
- npm install
- npm run build
artifacts:
paths:
- build/
expire_in: 1 day
test_job:
stage: test
image: node:16-alpine
script:
- echo "Running tests..."
- npm test
deploy_staging_job:
stage: deploy
image: alpine/git
script:
- echo "Deploying to Staging environment..."
- # Simulate a deployment to a staging server
- echo "Deployment complete for Staging."
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
allow_failure: falseYukarıdaki örnekte, stages anahtar kelimesi pipeline akışını tanımlar. build_job, test_job ve deploy_staging_job adındaki işler, sırasıyla ilgili aşamalarda çalışır. Her işin kendine ait bir image (Docker imajı), çalıştırılacak script'ler ve opsiyonel olarak artifacts (işler arasında veya sonraki kullanımlar için kaydedilen dosyalar) ve environment tanımlamaları bulunur. rules bölümü, işin ne zaman tetikleneceğini dinamik olarak kontrol etmemizi sağlar; örneğin, main branch'ine yapılan commitlerde manuel olarak tetiklenen bir staging dağıtımı.
Gelişmiş Pipeline Yapılandırması
Artifacts ve Cache Yönetimi
Pipelinelar arası bağımlılıkları yönetmek ve iş yürütme sürelerini optimize etmek için artifacts ve cache kritik öneme sahiptir. artifacts, bir işin çıktılarının sonraki aşamalar için saklanmasını sağlarken, cache, tekrarlayan bağımlılık indirme işlemlerini önleyerek pipeline'ın hızını artırır. Özellikle node_modules veya Maven .m2 dizinleri gibi büyük bağımlılık setleri için cache kullanımı büyük avantaj sağlar.
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
policy: pull-push
install_dependencies:
stage: build
image: node:16-alpine
script:
- npm ci
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
policy: push # Only push cache after installation
build_application:
stage: build
image: node:16-alpine
script:
- npm run build
needs: ["install_dependencies"]
artifacts:
paths:
- build/Bu örnekte, install_dependencies işi node_modules'i indirir ve cache'ler. build_application işi ise aynı cache'i kullanarak npm ci adımını atlar ve doğrudan build işlemine geçer. policy: pull-push varsayılan davranıştır, ancak belirli işlerde push veya pull olarak özelleştirilebilir.
Dinamik Ortamlar ve Değişkenler
Farklı dağıtım ortamları (dev, test, staging, production) için pipeline'ları dinamik olarak uyarlamak, variables ve rules anahtar kelimeleriyle kolaylaşır. variables, pipeline genelinde veya belirli işler için değerler tanımlarken, rules bir işin ne zaman çalışacağını koşullu olarak belirler.
variables:
AWS_REGION: us-east-1
S3_BUCKET_NAME_DEV: my-app-dev-bucket
S3_BUCKET_NAME_PROD: my-app-prod-bucket
deploy_prod_job:
stage: deploy
image: python:3.9-slim-buster
before_script:
- pip install awscli
script:
- echo "Deploying to Production S3: $S3_BUCKET_NAME_PROD in $AWS_REGION"
- aws s3 sync ./build s3://$S3_BUCKET_NAME_PROD --delete
environment:
name: production
url: https://app.example.com
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
when: manual
allow_failure: falseBu senaryoda, üretim ortamına dağıtım sadece bir sürüm etiketi (tag) ile tetiklenen manuel bir iş olarak yapılandırılmıştır. AWS_REGION gibi değişkenler global olarak tanımlanabilirken, S3_BUCKET_NAME_PROD gibi değişkenler ortama özel değerler alabilir. Bu, aynı pipeline tanımının farklı ortamlar için kullanılabilmesini sağlar.
GitLab CI/CD Best Practices
Güvenlik Odaklı Pipeline Tasarımı
CI/CD pipeline'larında güvenlik, development sürecinin her aşamasına entegre edilmelidir. Hassas bilgilerin (API anahtarları, veritabanı şifreleri) doğrudan .gitlab-ci.yml dosyasına yazılması yerine, GitLab Secret Variables veya harici bir sır yönetimi çözümü (HashiCorp Vault gibi) kullanılmalıdır. Ayrıca, container imajlarının güvenlik taramaları (Container Scanning) ve bağımlılık taramaları (Dependency Scanning) pipeline'ın erken aşamalarına dahil edilmelidir.
sast:
stage: test
artifacts:
reports:
sast: gl-sast-report.json
dependency_scanning:
stage: test
artifacts:
reports:
dependency_scanning: gl-dependency-scanning-report.json
# .gitlab-ci.yml içerisinde harici bir şablon dahil etme örneği
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.ymlGitLab'ın sağladığı hazır güvenlik şablonları, statik kod analizi (SAST) ve bağımlılık taramalarını kolayca entegre etmenizi sağlar. Bu şablonlar, pipeline'ınıza ekleyerek güvenlik kontrollerini otomatikleştirebilirsiniz. Hassas değişkenler CI/CD Settings > Variables altından tanımlanmalı ve protected olarak işaretlenmelidir.
Optimizasyon ve Performans
Büyük projelerde pipeline sürelerini kısaltmak için paralel çalıştırma, bağımsız işleri farklı runner'larda eş zamanlı olarak çalıştırma, Docker layer caching ve DIND (Docker-in-Docker) yerine Docker socket mount gibi teknikler kullanılabilir. Custom GitLab Runner'lar ile donanım optimizasyonu veya spot instance'lar kullanarak maliyet optimizasyonu da sağlanabilir.
Reusability ve Şablonlar
Tekrarlayan iş tanımlarını önlemek ve pipeline kodunu daha okunaklı hale getirmek için extends anahtar kelimesi ve include direktifi kullanılır. extends, mevcut bir iş tanımını genişletirken, include harici YAML dosyalarını (proje içi, başka bir repo'dan veya GitLab şablonlarından) pipeline'ınıza dahil etmenizi sağlar. Bu, mikroservis tabanlı mimarilerde ortak dağıtım stratejilerini merkezileştirmek için idealdir.
# .gitlab-ci.yml içerisinde bir şablon tanımlama
.deploy_template:
image: alpine/git
script:
- echo "Generic deployment logic here"
environment:
name: ${ENVIRONMENT}
url: ${ENVIRONMENT_URL}
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy_staging:
stage: deploy
extends: .deploy_template
variables:
ENVIRONMENT: staging
ENVIRONMENT_URL: https://staging.example.com
deploy_production:
stage: deploy
extends: .deploy_template
variables:
ENVIRONMENT: production
ENVIRONMENT_URL: https://app.example.com
rules:
- if: $CI_COMMIT_TAG
when: manualBu örnekte, .deploy_template adı verilen soyut bir iş tanımı oluşturulmuştur. deploy_staging ve deploy_production işleri bu şablonu extends ederek ortak mantığı yeniden kullanır ve variables ile ortama özgü değerleri geçirebilir.
Üretim Senaryoları: Çok Katmanlı Dağıtımlar ve Mavi/Yeşil Stratejileri
Gerçek üretim ortamlarında, kesintisiz hizmet sağlamak ve riskleri minimize etmek için sofistike dağıtım stratejileri esastır. Mikroservis tabanlı bir uygulamada, birincil hedefimiz, yeni sürümleri mevcut kullanıcıları etkilemeden devreye almak ve sorun durumunda hızlıca geri alabilmektir. Mavi/Yeşil dağıtım veya Kanarya dağıtımı gibi yöntemler, bu hedeflere ulaşmak için GitLab CI/CD ile entegre edilebilir.
Örneğin, bir web uygulamasının AWS ECS üzerinde çalıştığını ve yeni bir sürümün devreye alınacağını varsayalım. Mavi/Yeşil dağıtım stratejisinde, mevcut stabil sürüm "Mavi" ortamda çalışırken, yeni sürüm "Yeşil" ortamda tamamen bağımsız olarak dağıtılır. Yeşil ortamda tüm testler tamamlandıktan sonra, yük dengeleyici (AWS ALB) trafiği Mavi ortamdan Yeşil ortama yönlendirilir. Bir sorun tespit edilirse, trafik hızla Mavi ortama geri yönlendirilir. GitLab CI/CD, bu geçişleri ve ortam yönetimini otomatikleştirmek için kullanılabilir.
# deploy_green_environment job
deploy_green_ecs:
stage: deploy_green
image: python:3.9-slim-buster
before_script:
- pip install awscli boto3
script:
- python deploy_script.py --environment green --version $CI_COMMIT_SHA
- echo "Green environment deployed. Running smoke tests..."
- curl --fail --silent --show-error https://green.example.com/health || exit 1
environment:
name: green
url: https://green.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
# switch_traffic_to_green job
switch_traffic:
stage: switch_traffic
image: python:3.9-slim-buster
before_script:
- pip install awscli boto3
script:
- python switch_alb_target_group.py --target green
- echo "Traffic switched to Green environment."
environment:
name: production
url: https://app.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
needs: ["deploy_green_ecs"]Bu senaryoda, deploy_green_ecs işi yeni uygulama sürümünü "Yeşil" bir ECS ortamına dağıtır ve temel sağlık kontrollerini yapar. switch_traffic işi ise manuel olarak tetiklenerek AWS Application Load Balancer (ALB) hedef grubunu "Yeşil" ortama yönlendirir. Bu, kesintisiz bir geçiş sağlarken, herhangi bir sorunda kolayca geri dönüş imkanı sunar. deploy_script.py ve switch_alb_target_group.py gibi özel scriptler, AWS CLI ve Boto3 kütüphaneleri kullanılarak bu otomasyonu gerçekleştirir.
GitLab CI/CD, yazılım teslim süreçlerini hızlandırmak, tekrarlayan görevleri ortadan kaldırmak ve hata oranlarını düşürmek için sağlam bir temel sunar. Doğru yapılandırma, güvenlik odaklı yaklaşımlar ve gelişmiş dağıtım stratejileri ile modern DevOps pratiklerini eksiksiz bir şekilde uygulayabilirsiniz. Sürekli iyileştirme ve pipeline'ların düzenli olarak gözden geçirilmesi, bu sistemlerin uzun vadeli başarısı için anahtardır.