Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 17

Secure CI/CD with GitHub Actions Secrets

Recommended resources

Merhaba! Önceki dersimizde, CI işlem hattımıza ruff ile bir linting adımı ekleyerek kod kalitemizi otomatik olarak denetlemeyi öğrendik. Artık işlem hattımız, kodumuzun hem işlevsel olarak doğru çalıştığını (testler aracılığıyla) hem de temiz ve tutarlı bir stile sahip olduğunu (linting aracılığıyla) doğruluyor.

Ancak, gerçek dünya veri işlem hatları genellikle dış sistemlerle etkileşime girer. Veritabanı bağlantı dizeleri (connection strings), API anahtarları veya bulut hizmeti kimlik bilgileri gibi hassas verilere ihtiyaç duyarlar. Bu bilgileri doğrudan kodunuzun veya iş akışı (workflow) dosyalarınızın içine yazmak, "hardcoding" olarak bilinir ve ciddi bir güvenlik açığıdır. Kod tabanınıza erişimi olan herkes bu hassas bilgilere de erişebilir.

Bugünkü Öğrenme Hedefimiz: CI iş akışlarımızda kimlik bilgileri ve ortam değişkenlerini güvenli bir şekilde yönetmek için GitHub Actions Secrets'ı kullanmayı öğrenmek.

Güvenliğin Temeli: Neden Asla Kimlik Bilgilerini Koda Yazmamalısınız?

Sizin de tecrübe ettiğiniz gibi, veri mühendisliği projeleri genellikle çeşitli veri kaynaklarına ve hedeflere bağlanır: PostgreSQL veritabanları, Azure veya AWS gibi bulut depolama hizmetleri, harici API'ler vb. Bu bağlantıların her biri kimlik bilgileri gerektirir.

Bu bilgileri koda gömmek:

  • Güvenlik Riski Oluşturur: Kodunuzu bir genel (public) repoda paylaşırsanız, kimlik bilgileriniz sızdırılır. Özel (private) repolarda bile, yetkisiz bir çalışanın veya saldırganın koda erişmesi felaketle sonuçlanabilir.
  • Yönetimi Zorlaştırır: Bir şifre veya anahtar değiştiğinde, kodun içinde bu değeri bulup güncellemeniz ve yeniden deploy etmeniz gerekir. Bu, hataya açık ve verimsiz bir süreçtir.
  • Ortamlar Arası Geçişi Engeller: Geliştirme (development), test (staging) ve üretim (production) ortamları genellikle farklı veritabanları veya kimlik bilgileri kullanır. Koda gömülü değerler, bu ortamlar arasında kolayca geçiş yapmanızı engeller.

Çözüm, bu hassas verileri koddan ayırmak ve bunları güvenli bir şekilde yönetmektir. GitHub Actions bu amaçla bize Secrets ve Variables özelliklerini sunar.


GitHub Secrets ve Variables: Nedir ve Nasıl Kullanılır?

GitHub, iş akışlarınızda kullanabileceğiniz iki tür yapılandırma verisi sunar:

  • Secrets: Şifreler, API anahtarları, token'lar gibi hassas veriler için kullanılır. Bir secret oluşturulduktan sonra değeri bir daha asla okunamaz, sadece güncellenebilir veya silinebilir. GitHub, iş akışı loglarında bu değerleri otomatik olarak *** şeklinde maskeler.
  • Variables: Veritabanı sunucu adı, tablo adı gibi hassas olmayan yapılandırma bilgileri için kullanılır. Değerleri okunabilir ve düzenlenebilir.

Bu iki yapı arasındaki farkı ve nasıl oluşturulduklarını anlamak için aşağıdaki videoyu izleyelim.

Secrets and Environment Variables in your GitHub Action

Dev Leonardo kanalından bu video, GitHub arayüzünde Secrets ve Variables'ın nasıl oluşturulduğunu, aralarındaki temel farkları ve loglarda nasıl davrandıklarını net bir şekilde gösteriyor.

Lütfen şu bölümlere odaklanın: 00:17 - 01:59: Repository ayarlarında "Secrets and variables" menüsüne nasıl gidileceğini, bir secret ve bir variable oluşturma sürecini ve aralarındaki temel farkı (secret'ın değerinin gizlenmesi) öğrenin. 03:29 - 05:23: Bir iş akışı YAML dosyasında ${{ secrets.SECRET_NAME }} ve ${{ vars.VARIABLE_NAME }} sözdizimi ile bu değerlere nasıl erişildiğini ve en önemlisi, secret'ların log çıktısında nasıl otomatik olarak maskelendiğini gözlemleyin.

Videoda da gördüğünüz gibi, bir secret oluşturmak oldukça basittir.

Creating GitHub Actions Repository Secrets
Bu görsel, bir GitHub reposunun **Settings -> Secrets and variables -> Actions** menüsünde yeni bir repository secret'ının nasıl oluşturulacağını adım adım göstermektedir. **New repository secret** butonuna tıklayarak bu işlemi başlatabilirsiniz.

Secret'ları İş Akışından Python Koduna Aktarma

Bir secret oluşturduktan sonra, onu CI ortamında çalışan Python veya PySpark betiğinizin içinde kullanmanız gerekir. Doğrudan ve en güvenli yöntem, secret'ı bir ortam değişkeni (environment variable) olarak betiğinize aktarmaktır.

Bu süreç iki adımdan oluşur:

  1. YAML Dosyasında: GitHub secret'ını, iş akışınızdaki bir işin (job) veya adımın (step) env bloğunu kullanarak bir ortam değişkenine atarsınız.
  2. Python Betiğinde: Python'un standart os modülünü kullanarak bu ortam değişkenini okursunuz.

Bu akışın tamamını gösteren aşağıdaki video, konuyu pekiştirmenize yardımcı olacaktır.

How To Use GitHub Action Secrets In Your Python Script In 3 Steps

Data Engineering With Nick kanalından gelen bu video, bir GitHub secret'ının bir Python betiği içinde nasıl kullanılacağını baştan sona pratik bir şekilde anlatıyor. Bu, tam olarak bizim PySpark işlerimizde ihtiyaç duyacağımız yöntemdir.

Lütfen şu bölümlere odaklanın: 01:03 - 01:52: İş akışı YAML dosyasında env bloğunun nasıl kullanıldığını ve ${{ secrets.SECRET_NAME }} sözdizimi ile bir secret'ın bir ortam değişkenine nasıl atandığını gösteren bölümü izleyin. 01:52 - 02:55: Python kodunda import os ve os.environ.get('VARIABLE_NAME') kullanarak bu ortam değişkeninin nasıl okunduğunu ve print edildiğinde bile loglarda nasıl maskelendiğini görün.


CI İşlem Hattımızı Güncelleme Zamanı

Şimdi öğrendiklerimizi uygulayalım ve ci.yml dosyamızı bir secret kullanacak şekilde güncelleyelim.

1. Adım: GitHub'da Bir Secret Oluşturun

Kendi proje reponuzun GitHub sayfasına gidin:

  1. Settings sekmesine tıklayın.
  2. Sol menüden Secrets and variables -> Actions'ı seçin.
  3. Secrets sekmesindeyken New repository secret butonuna tıklayın.
  4. Secret'ınıza DUMMY_API_KEY adını verin ve değer olarak abc-123-def-456 gibi rastgele bir metin girin.
  5. Add secret'a tıklayarak kaydedin.

2. Adım: ci.yml Dosyasını Güncelleyin

Mevcut .github/workflows/ci.yml dosyanızdaki run-tests işine, secret'ı okuduğumuzu ve loglarda maskelendiğini doğrulayan yeni bir adım ekleyelim. Bu adımı Run Pytest adımından hemen önce ekleyebilirsiniz.




# .github/workflows/ci.yml




# ... (workflows, jobs, run-tests, ve önceki adımlar aynı kalır)




      # ...
      - name: Check formatting with Ruff
        uses: astral-sh/ruff-action@v3
        with:
          args: "format . --check"




      # YENİ ADIM: Secret kullanımını göster
      - name: Demonstrate Secret Usage
        env:



          # GitHub Secret'ını bir ortam değişkenine ata
          DEMO_SECRET: ${{ secrets.DUMMY_API_KEY }}
        run: |
          echo "Python betiği aracılığıyla ortam değişkenini okumaya çalışılıyor..."
          python -c "import os; secret_value = os.environ.get('DEMO_SECRET'); print(f'Alınan gizli değerin varlığı: {secret_value is not None}'); print(f'Değer: {secret_value}')"
      
      - name: Run Pytest
        run: pytest -v

Bu Demonstrate Secret Usage adımı, DUMMY_API_KEY adlı GitHub secret'ını DEMO_SECRET adlı bir ortam değişkenine atar. Ardından, kısa bir Python komutu çalıştırarak bu ortam değişkenini okur ve ekrana yazdırır.

Değişikliklerinizi commit edip push ettiğinizde, GitHub Actions loglarında Demonstrate Secret Usage adımının çıktısını inceleyin. Şöyle bir sonuç görmelisiniz:

Python betiği aracılığıyla ortam değişkenini okumaya çalışılıyor...
Alınan gizli değerin varlığı: True
Değer: ***

Bu çıktı, secret'ı başarıyla okuduğumuzu ancak GitHub'ın güvenlik nedeniyle değeri loglarda maskelediğini kanıtlar. Bu, secret yönetiminin temel taşıdır.


Gelişmiş Konu: Ortamlar (Environments)

Gerçek bir CI/CD sürecinde genellikle geliştirme (dev), test (staging) ve üretim (prod) gibi farklı ortamlarınız olur. Her ortamın kendi veritabanı şifresi veya API anahtarı olabilir. GitHub Actions Environments özelliği, bu senaryoyu yönetmenizi sağlar.

Bir environment oluşturarak, ona özel secret'lar tanımlayabilirsiniz. Bir iş akışı belirli bir environment'da çalışacak şekilde yapılandırıldığında, o environment'a ait secret'lar, repository seviyesindeki aynı isimli secret'ları geçersiz kılar (override).

GitHub Environments: Secrets and Variables Configuration
Bu görsel, bir GitHub Environment yapılandırma sayfasını göstermektedir. Burada bir ortama özel secret'lar ve değişkenler ekleyebileceğiniz bölümleri görebilirsiniz. Bu, dev/prod gibi farklı ortamlar için farklı kimlik bilgilerini yönetmenin standart yoludur.

Bu konuya, kursumuzun ilerleyen modüllerinde (özellikle Modül 5 ve 6'da) Rancher Fleet ile deployment yaparken daha detaylı değineceğiz. Şimdilik, farklı ortamlar için farklı secret'lar yönetme yeteneğinin var olduğunu bilmeniz yeterlidir.


Sonuç

Bu derste, CI/CD işlem hatlarının en kritik konularından biri olan güvenlik konusuna giriş yaptık. Hassas verileri koddan ayırmanın ve güvenli bir şekilde yönetmenin önemini öğrendik.

Temel Çıkarımlar:

  • Kimlik bilgileri, API anahtarları gibi hassas verileri asla koda yazmayın.
  • Hassas veriler için GitHub Secrets'ı, hassas olmayan yapılandırmalar için GitHub Variables'ı kullanın.
  • Bir secret'ı betiğinize aktarmanın en güvenli yolu, onu iş akışı YAML dosyasındaki env bloğu aracılığıyla bir ortam değişkenine atamaktır.
  • Python'da os.environ.get() fonksiyonu ile ortam değişkenlerini okuyabilirsiniz.
  • GitHub, secret değerlerini loglarda otomatik olarak *** ile maskeleyerek sızıntıları önler.

Gelecek Dersin Önizlemesi:
Artık test edilen, lintlenen ve kimlik bilgilerini güvenli bir şekilde yöneten bir CI işlem hattımız var. Sıradaki mantıklı adım, PySpark ETL uygulamamızı taşınabilir ve yeniden üretilebilir bir formatta paketlemektir. Bir sonraki dersimizde, uygulamamız için bir Dockerfile yazarak onu bir konteyner imajına dönüştüreceğiz. Bu, Kubernetes gibi platformlarda dağıtım yapmanın temelini oluşturacaktır.