A projecthez tartozó GitHub Repository itt található

A deployment automatizálása

A probléma ezen a ponton az, hogy minden alkalommal, amikor a GitHub repository main branch frissül, mi nekünk kell elvégezni az alábbi lépéseket:

  • Gép bekapcsolása
  • Project kiválasztása
  • A main branchban lévő legfrissebb kód lehúzása (git pull)
  • Környezeti változók létrehozása (export GCP_PROJECT_ID=[A_te_projected_id-ja], export ENVIRONMENT=production)
  • Új docker image összállítása (make gcloud-docker-build)
  • Új docker image feltöltése GCR-ra. (make gcloud-docker-push)
  • Új Cloud Run változat készítése, a régi lecserélése (make gcloud-run-deploy)

Ezek a feladatok egyfajta “toil”-t képeznek, utalva arra, hogy manuálisan kell őket elvégeznünk, repetitívek, és szükségszerűek.

Tökéletes jelölt automatizálásra.

Service Account létrehozása

Mivel jelenleg a terminalodon a Te nevedben (email címeddel) autentikáltál, ezért adminként érhetsz el a GCP-n mindent, a terminálodon keresztül. Ez elég nagy hatalom, és nem szeretnénk megosztani semmilyen framework-kel, akkor sem, ha automatizál nekünk.

Ezért létrehozunk egy új “belépő kártyát”, amin megjelölhetjük, hogy milyen engedélyekkel interaktálhat a kártya tulajdonosa, a mi GCP accountunkkal.

  • A GCP console-on, válaszd ki az IAM & Admin menüt, és azon belül a Service Accounts-ot.

Service Accounts

  • Ezután menj rá felül arra, hogy Create Service Account.

    Névnek add meg pl. hogy penguin-api-github-actions, a descriptionbe pedig egy rövid leírás megteszi, pl. This SA is responsible for deploying the Penguin API from GitHub Actions.

    Ezután kattints a Create gombra.

  • Most megadhatsz jogköröket, amikkel felruházod ezt az új Service Accountot. Add hozzá az alábbi jogköröket, csak a próba kedvéért:

    • Service Account User
    • Cloud Build Editor
    • Cloud Build Service Account
    • Cloud Run Admin

    Service Accounts roles

Most hogy megvan az új “kártya” a saját jogköreivel, valahogy el kell juttatnunk a felhasználási adatokat a GitHub Actions-nek, hogy használni tudja ezt a Service Accountot.

  • Kattints rá az elkészült Service Accountodra a listában, majd kattints felül a Keys fülre.

  • Kattints az Add key-re, Create new key és válaszd a JSON opciót. Ezzel automatikusan le fogod tölteni azt a JSON fájlt, amivel ha valaki rendelkezik, azzal mind a 4 jogkörhöz hozzáférést kap a fent említettek közül. Ezért ezt a fájlt ne tartsd meg, és ne oszd meg senkivel. Egyetlen dologra fogjuk használni, a JSON fájl tartalmát át fogjuk másolni egy Github Secretbe.

GitHub Actions

Ahhoz, hogy valaki, vagy valami elvégezze nekünk ezt az ismétlődő feladatot, keresnünk kell egy framework-ot, ami segít a Continuous Deployment létrehozásában. Magyarán magától megépítí nekünk a kódot, ellenőrzi (mi ebben a projectben nem írtunk automatizált teszteket, de normális esetben azokat lefuttattnánk minden egyes build alkalmával), és deployolja a friss kódállományt, valahányszor a main branch változtatást kap.

Mi most a GitHub Actions-t fogjuk választani erre a projectre, mert 2021 májusában, amikor ez a dokumentáció íródott, havonta 2000 percet ingyenesen adnak felhasználásra.

  • GitHub Actions engedélyezése a repository-n

    • Látogass el a GitHub oldaladra, és menj rá a repositoryd tartalmára
    • Győződj meg róla, hogy a repositoryd privát és nem publikus
    • Ezután kattints a Settings-re
    • Kattints az Actions menüre
    • Győződj meg róla, hogy az “Allow all actions” van bepipálva

    GitHub Actions

  • GitHub Actions secrets

    • Ezek után kattints a Secrets menüre a bal oldalon
    • Kattints a New repository secret gombra jobb felül
    • Első secret amit hozzáadunk: GCP_SERVICE_ACCOUNT_SECRET -> Értéknek pedig másold meg a JSON fájl tartalmát, majd mentsd el a secretet, és töröld a JSON fájlt a számítógépedről.
    • Második secret amit hozzáadunk: GCP_PROJECT_ID -> Ez az az ID, amit a GCP console-on ki tudsz olvasni, amikor bal felül rákattintasz a Penguin project-re.

    GitHub Secrets

GitHub Actions workflow

Most, hogy minden elő van készítve, létre tudunk hozni egy workflow-t, amit a GitHub felismer, és végrehajt.

  • Létrehozunk két új alkönyvtárat a project gyökérkönyvtárába. A neveik fontosak, hogy pontosan ezek legyenek:

    mkdir -p .github/workflows/

  • Létrehozunk egy új cloudrun-deploy-production.yml fájlt a workflows könyvtárban.

name: cloudrun-deploy-production

# Azt szeretnénk, ha a GitHub Actions ezeket a feladatokat akkor végezné el, amikor
# valaki pushol a main branch-ba.
on:
push:
	branches:
	- main

jobs:
build:
	name: 'Cloud Run Production Deployment'
	
	# A parancsok egy ubuntun fognak lefutni
	runs-on: ubuntu-latest
	steps:
	- name: 'Checkout'
		uses: actions/checkout@master

	# Autentikálunk a GCP-vel, de nem a saját accountunk adatait adjuk át, hanem
	# a Service Account adatait, amit korábban létrehoztunk
	# Kiolvassuk az értékeiket a GitHub Secrets-ből
	- name: 'Setup GCP Service Account'
		uses: google-github-actions/setup-gcloud@master
		with:
		project_id: ${{ secrets.GCP_PROJECT_ID }}
		service_account_key: ${{ secrets.GCP_SERVICE_ACCOUNT_SECRET }}
		export_default_credentials: true

	# Ezért hagytuk bent ezt a parancsok a Makefile-ban. A GitHub Actions minden alkalommal egy
	# új agent-et ad nekünk, ezért be kell állítania a dockert minden lefutáskor.
	- name: 'Configure Docker'
		run: make gcloud-docker-init

	# A Makefile segítségével megépíttetjük a saját microservice-ünket, és átadunk neki
	# két környezeti változót. Az egyiket "production"-két definiáljuk, mert a main branchból 
	# deployolunk.
	- name: 'Build'
		env:
		GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
		ENVIRONMENT: 'production'
		run: make gcloud-docker-build
	
	# A GitHub Actions miután összeállította nekünk az új Docker Image-t, megkérjük, hogy töltse 
	# fel nekünk azt a Google Cloud Container Registrybe, a mi accountunkhoz.
	- name: 'Push'
		env:
		GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
		ENVIRONMENT: 'production'
		run: make gcloud-docker-push

	# Végül pedig megkérjük, hogy deployolja a legújabb release-t a Cloud Runba.
	- name: 'Deploy'
		env:
		GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
		ENVIRONMENT: 'production'
		run: make gcloud-run-deploy

Tesztelés

Legvégül pedig állítsd össze a módosításaidat és commitold őket GitHubra. Abban a pillanatban, hogy ezt felpusholod a main branchba, a GitHub Actions elkezdi összeállítani a projectünket, felpusholni, és deployolni Cloud Runba.

git status  # Információt ad vissza a git repo aktuális állapotáról
git add .   # a stage-re helyezi a módosított/hozzáadott fájlokat
git commit -m "Adding GitHub Actions to deploy to Cloud Run" # A stage tartalmát commitolja a lokális repositoryba
git push origin main # Felpusholja a commitodat a GitHub repositoryba, aminek a UI-on is megnézheted a tartalmát

GitHub Actions deployment

Végül pedig

  • Soha ne írass ki GitHub secreteket a Makefileodban, vagy bárhol máshol, ahol a log üzenetekben később kiolvasható. Minden szenzitív adatot kezelj nagy körültekintéssel és odafigyeléssel.
  • Ne felejts el minden GCP erőforrást törölni, ha már nincsen rájuk szükséged. Nem tudhatod, hogy a Google mikor változtat az üzletpolitikáján, és kezd el felszámolni díjat olyan erőforrásokért, amik korábban ingyenesek voltak.