Serverless automation using PowerShell Core in Azure Functions – Bölüm 3

Artık ilk Event-Based Automation çözümümüzü beraber geliştirebiliriz, senaryomuzu basit ve anlaşılır yapmak için hemen beraber belirleyelim. Başlangıç seviyesi için kesinlikle basit bir senaryodan ilerleyeceğiz. Örneğin, Azure Function ‘HTTP’ trigger (tetikleyicisini) kullanarak parametrik olarak gönderilen sanal sunucunun adına göre Azure Function bizim için HTML bir Report oluşturmasını isteyelim. Giriş yazımızı hatırlarsanız, o kısımda ‘HTTP’ kullanırsak bize bir RESTful HTTP uç noktaları sunar API gibi davranacağından bahsetmiştik. Şimdi ön gereksinimlerimiz neler bunlara bir göz gezdirelim.

  • Azure Subscription
  • Visual Studio Code
  • Powershell Core – 6
  • Visual Studio Code üzerinde AZ Function Core Tools eklentisi

Yukarıda ön gereksinimleri elde ettiğinizi varsayarak çözümü geliştirmeye başlayabiliriz. Önce hemen bir VS Code üzerinde Azure Function projesi oluşturalım. Visual Studio Code üzerinde terminal’e gelip hızlı bir şekilde aşağıdaki işlemleri yaparak yeni bir Azure Function App Projesi oluşturalım.

Visual Studio Code kullanarak Azure Function App Projesi oluşturmak

Not: Aşağıdaki adımları isterseniz, VS Code – Command Palette alanından görsel biçimde yapma şansınız var. Ben size Azure Function Core Tools terminal üzerinden üzerinden kullanarak oluşturma adımlarını gösteriyor olacağım. Komut olarak: ‘func’ bize Azure Function Core tools çağırıyor olacak.

Yukarıdaki adımları tek tek yaptığınız zaman Azure Function App Projenizi oluşturup olup Visual Code üzerinde görebileceksiniz. Eğer yukarıdaki adımları gerçekleştirdiysek karşımıza direk Azure Function için bir takım temel gereksinim dosyalarını göreceksiniz. Yukarıdaki adımlarda zaten bizim için bu dosyaları oluşturduğunu zaten belirtmişti.

Function App Projesinin temel öğelerini içeren bir takım dosyaları var. Gördüğünüz gibi yukarıdaki resim içerisinde mevcut. Şimdi bunları sırasıyla inceleyelim.

host.json’: metadata dosyası, geliştirdiğiniz azure fonksiyonunuzu etkileyen genel yapılandırma seçenekleri içerir. Örneğin, hangi ‘Run Time’ kullanacağım, hangi extensionları kullanmalıyım gibi detayları buradan belirtme şansınız var. Şu sayfadan örnek bir ‘host.json’ dosyasının alabilecek tüm olası seçenekleri bulabilirsiniz. VSCode üzerinde bu dosyanın olmasının sebebi, Azure Function App üzerine geliştirdiğiniz fonksiyonlarınızı deploy ettiğiniz zaman bu dosya içerisindeki yapılandırmalar dikkate alınır ve fonskiyonunuz ona göre deploy edilecektir.

‘Profile.ps1’: Profile.ps1 dosyasının bize en büyük sağladığı özellik, Microsoft Managed Identity kullanarak Azure Aboneliğiniz üzerinde oturum açmanıza sağlıyor ve ayrıca, talep ederseniz AZ Powershell Modülü kullanmak yerine, AzureRM kullanabiliyorsunuz. Aslında Powershell Profile Script mantığına hakimseniz size çok yabancı gelmeyecektir. Herhangi bir Function Start olduğu zaman bu dosyanın içerisindekiler öncellikle çalışırlar ve işlevlerini yaparlar. İstediğiniz özel bir yapılandırmayı bu script içerisinde barındırabilirsiniz ve bu sayede fonksiyonunuz her başlatıldığında, profile.ps1 script’i içerisindekiler sırasıyla çalışırlar ve işlerini yaparlar.

‘requirements.ps1’: Powershell ile geliştirdiğiniz fonksiyonunuz için zaman zaman bir takım Powershell Modülleri bağımlılıkları olabiliyor ve onları yönetmek için size harika bir yol sağlamaktadır. Bu dosyanın içerisine baktığınız zaman ‘Az Powershell Module’ otomatik bir şekilde yüklendiğini göreceksiniz. Dependency yönetimi etkinleştirmek için öncelikle fonksiyonunuzun genel yapılandırması dosyası olan ‘host.json’ metadata içerisinde ‘managedDependency’ niteliğinin açık olması gerekmektedir. Bu özellik belirtikten sonra, requirements.ps1 içerisinde bulunan Powershell Modülleri otomatik olarak sizin için yüklenecek ve Azure Fonksiyonun her başladığında o modülü indirmek için zaman kaybetmeyeceksiniz, sizin için indirip saklıyor olacak.

‘Local.settings.json’: Azure function içerisinden erişmek istediğiniz bir SQL Database, CosmosDB, Connection String, Key Vault Secret, Fonksiyon içerisinden değil değişken olarak saklayabileceğiniz ayarlar ( version vs), bu tarz bilgileri developer makinesi ( local ) olarak saklanırlar. Bu dosyadaki ayarlar tüm veriler yalnızca projeleri yerel olarak çalıştırırken kullanılır.

‘.gitingore’: Eğer source control sistemlerini kullanıyorsanız bu dosya sizin için hiç yabancı olmamalı, bir şekilde herkesin yolu Source Control sistemleri ile kesişmiştir. Dosyanın isminden anlaşılabileceği gibi, bazı durumlarda dosya ya da dosyaları ya da dizinleri, source control dışında tutmak istersiniz. İçerisine baktığınız zaman zaten ‘Local Settings.Json’ Source Control içerisine dahil etmediğini göreceksiniz. Eğer GitHub, Azure Repo gibi bir upstream kullanıyor olacaksınız ‘.gitignore’ içerisindekiler source control tarafından dikkate alınmayacaklardır.

‘.vsCode’: Visual Studio Code içerisindeki Azure Function eklentisi, projenizin kök dizinindeki “.vscode” klasöründe birkaç dosya oluşturur. Bunun içerisinden, hangi versiyon ile çalıştıracağını, ne tür kısayol task oluşturacağınızı söyleyebildiğiniz yer. Daha fazlası için lütfen şu sayfaya göz gezdiriniz.

Azure Functions için örnek folder mimarisi

Yukarıdaki resim üzerinden biraz konuşalım. Sol tarafta gördüğünüz Best Practices olması açısından sizler için bir Azure Function Apps nasıl bir folder structure sahip olması gerektiğinin örneği bulunmakta, en üst klasör aslında Azure Function App bulunduğu root folder yani ‘PSFunctionApp‘, diğer gördüğünz klasörler örneğin, ‘MyFirstFunction veya MySecondFunction’ benim geliştirdiğim asıl fonksiyonlarımın barındığı işi/süreci başlatıp bitirecek olan fonksiyonlarım. Sağ tarafta gördüğünüz resim ise benim aktif olarak geliştirdiğim bir örnek bulunmaktadır. Baktığınız zaman farklı farklı fonksiyonları görebiliyorsunuz. Bu iki resmi yan yana koymamım sebebi, sol taraftadaki bir function app projesine başladığınız zaman fonksiyonlarınız nasıl ve ne şekilde yer alacağını almanız için bir template gibi düşünebilirsiniz. Sağ taraftaki ise, benim canlı olarak kullandığım içlerinde Trigers, Bindings olarak, ServiceBus, http, Storage Queue kullandığım fonksiyonlarım.

Not: Tanımların karışmaması için Azure Function App, size geliştirdiğiniz veya geliştirmekte olduğunuz fonksiyonlarınızı çalıştırmak için bir yol sunar. Her function bir adet Azure Function App içerisine gönderilerek çalıştırılır. Aslında Azure Function App göndermenizdeki temel sebep, bir Instance ihtiyaç duymanız. Yani Function var evet geliştirdim ama hangi kaynağı kullanması gerektiğini söylemek için Azure Function App’e göndererek söylüyorsunuz. Örnekte sıfırdan bir projeye başladığımız için Azure Function App ihtiyacımız olacak ve fonksiyonlarımız orada çalışacağını düşünebilirsiniz. Özetle her fonksiyonunuz, Azure Function App içerisine gönderilir ve orada çalışır. Örnek verelim hızlıca; Azure Function App hizmetini oluşturduğunuz zaman Azure size aşağıdaki şekilde bir endpoint verir.

  • Azure function app – endpoint: Microsoft Azure size verdiğiniz kaynağın adı ile ortaya çıkan bir public endpoint verecek ve function app root adresi şu şekilde olacaktır. https://mydev-func.azurewebsites.net
  • getResourceType – Function : Örneğin, fonksiyonum adı : getResourceType olsun ve bu fonksiyon ‘HTTP’ Trigger olarak kullansın. Yukarıdaki VSCode içerisine baktığınız zaman bu şekilde fonksiyon klasörünü oluşturulduğunu varsayalım, Projeyi eğer Azure function app deploy ettiğim zaman benim fonksiyonumun endpoint şu şekilde olacak. https://mydev-func.azurewebsites.net/api/getResourceType

Mevcut Azure Function App projesi içerisine yeni bir function oluşturmak

Uzun açıklamalardan sonra, yazımızın üçüncü bölümde sonunda ilk Function oluşturma adımına gelebildik. Azure Function App projesi oluştururken ‘func‘ komut satırını kullanmıştım. Yine o şekilde devam edeceğim, ama isterseniz, VS Code Command Palette kullanabilirsiniz. Kullanacağımız ile ilk function oluşturalım.

Şu komut sayesinde ilk fonksiyonumu oluşturabiliyorum. ‘func new –language Powershell –template HTTPTrigger.” Daha sonra bu komut bize yeni oluşturacağımız fonksiyonumuzun adının ne olması gerektiğini soruyor. Bunuda belirtiyoruz, “getResourceStatus.”

Yazdığımız ‘func’ komutları bize yeni bir fonksiyon oluşturdu. Yukarıdaki resimde görebileceğiniz gibi verdiğimiz fonksiyonun adında bir adet klasör oluşturdu ve içerisinde ‘function.json’ ve ‘run.ps1’ adında iki adet dosyalar var. Şimdi hızlıca bunları tanıyalım ve neler yaptığını anlayalım.

  • Run.ps1: Fonksiyonunuz çalıştırdığınız zaman çalışacak olacak powershell script. Bu fonksiyonunuz tetikleyeciler ( triggerlar ) veya Input ( Bindings ) veriler alabilirler.Fonksiyon bir şekilde tetiklendiği zaman, http, storage queue, event grid vs. bu ‘run.ps1’ dosyayı çalışacaktır. Bu yüzden yapmak istediğiniz tüm işlemleri bu script içerisinde geliştirmelisiniz. İhtiyaca göre bu dosyanın adı veya path değiştirilebilir.
  • Function.json: Bu dosyanın içerisin baktığınız zaman Bindings detayları göreceksiniz. Hatırlarsanız, fonksiyonu oluştururken http trigger kullanmıştık ve bizim için gerekli yapılandırmaları bu json dosyasının içerisinde bulabilirsiniz.

Not: Her function bu dosyalara sahip olmalıdır. Belirttiğimiz gibi fonksiyonunuzun yapacağı işten ‘Run.ps1’ sorumlu olup, function için Trigger, Bindings ve diğer konfigurasyon ayarlarını barındırılması function bazında gereklidir.

Bir sonraki yazımızda ‘Run.ps1’ içerisinde nasıl bir Powershell Script kullanacağız bunun detaylarını konuşup testlerimizi yapacağız.