Öğretici: Windows kapsayıcılarını kullanarak C IoT Edge modülleri geliştirme

Şunlar için geçerlidir:evet simgesi IoT Edge 1.1

Önemli

IoT Edge 1.1 destek sonu tarihi 13 Aralık 2022'ydi. Bu ürünün, hizmetin, teknolojinin veya API’nin nasıl desteklendiği hakkında bilgi edinmek için Microsoft Ürün Yaşam Döngüsü’ne göz atın. IoT Edge en son sürümüne güncelleştirme hakkında daha fazla bilgi için bkz. Güncelleştirme IoT Edge.

Bu makalede, Visual Studio'yu kullanarak C kodu geliştirme ve Azure IoT Edge çalıştıran bir Windows cihazına dağıtma adımları gösterilmektedir.

Not

IoT Edge 1.1 LTS, Windows kapsayıcılarını destekleyen son sürüm kanalıdır. Sürüm 1.2'den itibaren Windows kapsayıcıları desteklenmez. Windows cihazlarında IoT Edge çalıştırmak için Windows üzerinde Linux için IoT Edge kullanmayı veya bu IoT Edge geçmeyi göz önünde bulundurun.

İş mantığınızı doğrudan IoT Edge cihazlarınızda uygulayan kodu dağıtmak için Azure IoT Edge modüllerini kullanabilirsiniz. Bu öğreticide, algılayıcı verilerini filtreleyen bir IoT Edge modülü oluşturma ve dağıtma işlemlerinin adımları açıklanmaktadır.

Bu öğreticide şunların nasıl yapıldığını öğreneceksiniz:

  • C SDK'sını temel alan bir IoT Edge modülü oluşturmak için Visual Studio'yu kullanın.
  • Visual Studio ve Docker kullanarak bir Docker görüntüsü oluşturun ve bunu kayıt defterinizde yayımlayın.
  • Modülü IoT Edge cihazınıza dağıtma.
  • Oluşturulan verileri görüntüleme.

Bu öğreticide oluşturacağınız IoT Edge modülü, cihazınız tarafından oluşturulan sıcaklık verilerini filtreler. Modül, yalnızca sıcaklık belirtilen eşiği aştığında yukarı akış iletileri gönderir. Bu tür bir analiz, buluta iletilen ve bulutta depolanan veri miktarını azaltmak için yararlıdır.

Azure aboneliğiniz yoksa başlamadan önce birücretsiz Azure hesabı oluşturun.

Önkoşullar

Bu öğreticide, Visual Studio 2019 kullanarak C'de modül geliştirme ve ardından bunu bir Windows cihazına dağıtma işlemleri gösterilmektedir. Linux kapsayıcılarını kullanarak modül geliştiriyorsanız Bunun yerine Linux kapsayıcılarını kullanarak C IoT Edge modülleri geliştirme bölümüne gidin.

Windows kapsayıcılarını kullanarak C modülleri geliştirme ve dağıtma seçeneklerinizi anlamak için aşağıdaki tabloya bakın:

C Visual Studio Code Visual Studio 2017 ve 2019
Windows AMD64 Visual Studio'da WinAMD64 için C modülleri geliştirme

Bu öğreticiye başlamadan önce, Windows kapsayıcılarını kullanarak IoT Edge modülleri geliştirme öğreticisindeki yönergeleri izleyerek geliştirme ortamınızı ayarlayın. Bunu tamamladıktan sonra ortamınız aşağıdaki önkoşulları içerir:

Aşağıdaki komutları çalıştırarak Windows x64 ile vcpkg arasında Azure IoT C SDK'sını yükleyin:

git clone https://github.com/Microsoft/vcpkg
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg install azure-iot-sdk-c:x64-windows
.\vcpkg --triplet x64-windows integrate install

İpucu

Visual Studio 2017 (sürüm 15.7 veya üzeri) kullanıyorsanız Visual Studio Market'ten Visual Studio 2017 için Azure IoT Edge Tools indirip yükleyin.

Modül projesi İçerik Oluşturucu

Bu bölümde, Visual Studio ve Azure IoT Edge Tools uzantısını kullanarak C SDK'sını temel alan bir IoT Edge modülü projesi oluşturacaksınız. Proje şablonu oluşturduktan sonra, modülün iletileri bildirilen özelliklerine göre filtrelemesi için yeni kod ekleyeceksiniz.

Yeni proje oluşturma

Kendi yazacağınız kodla özelleştirebileceğiniz bir C çözüm şablonu oluşturun.

  1. Visual Studio 2019'ı açın ve yeni proje İçerik Oluşturucu seçin.

  2. Yeni bir proje İçerik OluşturucuIoT Edge arayın ve ardından sonuçlar listesinde Azure IoT Edge (Windows amd64) projesini seçin.

  3. İleri’yi seçin.

    Yeni projenizi yapılandırın bölmesi açılır.

  4. Yeni projenizi yapılandırın bölmesinde projeyi ve çözümü CTutorialApp gibi daha açıklayıcı bir şekilde yeniden adlandırın.

  5. Projeyi oluşturmak için Oluştur'u seçin.

    Modül Ekle bölmesi açılır.

    Projenizi yapılandırmak için

  6. Yeni projenizi yapılandırın sayfasında aşağıdakileri yapın:

    a. Sol bölmede C Modülü şablonunu seçin.
    b. Modül Adı kutusuna CModule girin.
    c. Depo Url'si kutusunda localhost:5000 değerini Azure kapsayıcı kayıt defterinizdeki Oturum açma sunucusu değeriyle aşağıdaki biçimde değiştirin:<registry name>.azurecr.io/cmodule

    Not

    Görüntü deposu, kapsayıcı kayıt defterinizin adını ve kapsayıcı görüntünüzün adını içerir. Kapsayıcı görüntünüz modül proje adı değerinden önceden doldurulur. Oturum açma sunucusunu Azure portal kapsayıcı kayıt defterinizin genel bakış sayfasından alabilirsiniz.

  7. Projeyi oluşturmak için Ekle'yi seçin.

Kayıt defteri kimlik bilgilerinizi ekleme

Dağıtım bildirimi, kapsayıcı kayıt defterinizin kimlik bilgilerini IoT Edge çalışma zamanıyla paylaşır. Çalışma zamanı, özel görüntülerinizi IoT Edge cihazına çekmek için bu kimlik bilgilerine ihtiyaç duyar. Azure kapsayıcı kayıt defterinizin Erişim anahtarları bölümündeki kimlik bilgilerini kullanın.

  1. Visual Studio Çözüm Gezgini'da deployment.template.json dosyasını açın.

  2. İstenen $edgeAgent özelliklerde registryCredentials özelliğini arayın. Özelliğin kayıt defteri adresi, projeyi oluştururken sağladığınız bilgilerle otomatik olarak doldurulmalıdır. Kullanıcı adı ve parola alanları değişken adları içermelidir. Örnek:

    "registryCredentials": {
      "<registry name>": {
        "username": "$CONTAINER_REGISTRY_USERNAME_<registry name>",
        "password": "$CONTAINER_REGISTRY_PASSWORD_<registry name>",
        "address": "<registry name>.azurecr.io"
      }
    }
    
  3. Modül çözümünüzde ortam (ENV) dosyasını açın. Varsayılan olarak, dosya Çözüm Gezgini gizlidir, bu nedenle görüntülemek için Tüm Dosyaları Göster düğmesini seçmeniz gerekebilir. ENV dosyası, deployment.template.json dosyasında gördüğünüz kullanıcı adı ve parola değişkenlerini içermelidir.

  4. Azure kapsayıcı kayıt defterinizden Kullanıcı adı ve Parola değerlerini ekleyin.

  5. Değişikliklerinizi ENV dosyasına kaydedin.

Modülü özel kodla güncelleştirme

Varsayılan modül kodu, bir giriş kuyruğundaki iletileri alır ve bunları bir çıkış kuyruğu boyunca geçirir. Modülün iletileri IoT hub'ınıza iletmeden önce uçta işlemesi için biraz daha kod ekleyelim. Modülü güncelleştirerek her iletideki sıcaklık verilerini analiz eder ve yalnızca sıcaklık belirli bir eşiği aştığında iletiyi IoT hub'ına gönderir.

  1. Bu senaryoda sensörden alınan veriler JSON biçimindedir. JSON biçimindeki iletileri filtreleme amacıyla C için bir JSON kitaplığını içeri aktarın. Bu öğreticide Parson kullanılmıştır.

    a. Parson GitHub deposunu indirin.
    b. parson.c ve parson.h dosyalarını CModule projesine kopyalayın.
    c. Visual Studio'da, CModule proje klasöründen CMakeLists.txt dosyasını açın.
    d. Dosyanın en üstünde Parson dosyalarını my_parson adlı bir kitaplık olarak içeri aktarın.

    add_library(my_parson
        parson.c
        parson.h
    )
    

    e. CMakeLists.txt dosyasının "target_link_libraries" bölümündeki kitaplık listesine ekleyinmy_parson.
    f. CMakeLists.txt dosyasını kaydedin.
    g. CModule>main.c öğesini seçin. Include deyimleri listesinin en altına JSON desteği için eklenecek parson.h yeni bir deyim ekleyin:

    #include "parson.h"
    
  2. main.c dosyasına değişkeninin yanına messagesReceivedByInput1Queue adlı temperatureThreshold bir genel değişken ekleyin. Bu değişken, Verilerin IoT hub'ınıza gönderilmesi için ölçülen sıcaklığın aşması gereken değeri ayarlar.

    static double temperatureThreshold = 25;
    
  3. CreateMessageInstancemain.c dosyasında işlevini bulun. inner if-else deyimini aşağıdaki kodla değiştirin ve bu kod birkaç işlev satırı ekler:

    if ((messageInstance->messageHandle = IoTHubMessage_Clone(message)) == NULL)
    {
        free(messageInstance);
        messageInstance = NULL;
    }
    else
    {
        messageInstance->messageTrackingId = messagesReceivedByInput1Queue;
        MAP_HANDLE propMap = IoTHubMessage_Properties(messageInstance->messageHandle);
        if (Map_AddOrUpdate(propMap, "MessageType", "Alert") != MAP_OK)
        {
           printf("ERROR: Map_AddOrUpdate Failed!\r\n");
        }
    }
    

    else deyimindeki yeni kod satırları, iletiye iletiyi uyarı olarak etiketleyen yeni bir özellik ekler. Bu kod tüm iletileri uyarı olarak etiketler, çünkü ioT hub'ına yalnızca yüksek sıcaklıkları bildirdiklerinde ileti gönderen işlevler ekleyeceğiz.

  4. InputQueue1Callback işlevini bulun ve işlevin tamamını aşağıdaki kodla değiştirin. Bu işlev gerçek bir mesajlaşma filtresi uygular. İleti alındığında, bildirilen sıcaklığın eşiği aşıp aşmadığını denetler. Sıcaklık eşiği aşarsa işlev, iletiyi çıkış kuyruğu üzerinden iletir. Eşiği aşmazsa işlev iletiyi yoksayar.

    static unsigned char *bytearray_to_str(const unsigned char *buffer, size_t len)
    {
        unsigned char *ret = (unsigned char *)malloc(len + 1);
        memcpy(ret, buffer, len);
        ret[len] = '\0';
        return ret;
    }
    
    static IOTHUBMESSAGE_DISPOSITION_RESULT InputQueue1Callback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
    {
        IOTHUBMESSAGE_DISPOSITION_RESULT result;
        IOTHUB_CLIENT_RESULT clientResult;
        IOTHUB_MODULE_CLIENT_LL_HANDLE iotHubModuleClientHandle = (IOTHUB_MODULE_CLIENT_LL_HANDLE)userContextCallback;
    
        unsigned const char* messageBody;
        size_t contentSize;
    
        if (IoTHubMessage_GetByteArray(message, &messageBody, &contentSize) == IOTHUB_MESSAGE_OK)
        {
            messageBody = bytearray_to_str(messageBody, contentSize);
        } else
        {
            messageBody = "<null>";
        }
    
        printf("Received Message [%zu]\r\n Data: [%s]\r\n",
                messagesReceivedByInput1Queue, messageBody);
    
        // Check whether the message reports temperatures that exceed the threshold
        JSON_Value *root_value = json_parse_string(messageBody);
        JSON_Object *root_object = json_value_get_object(root_value);
        double temperature;
    
        // If temperature exceeds the threshold, send to output1
        if (json_object_dotget_value(root_object, "machine.temperature") != NULL && (temperature = json_object_dotget_number(root_object, "machine.temperature")) > temperatureThreshold)
        {
            printf("Machine temperature %f exceeds threshold %f\r\n", temperature, temperatureThreshold);
            // This message should be sent to next stop in the pipeline, namely "output1".  What happens at "outpu1" is determined
            // by the configuration of the Edge routing table setup.
            MESSAGE_INSTANCE *messageInstance = CreateMessageInstance(message);
            if (NULL == messageInstance)
            {
                result = IOTHUBMESSAGE_ABANDONED;
            }
            else
            {
                printf("Sending message (%zu) to the next stage in pipeline\n", messagesReceivedByInput1Queue);
    
                clientResult = IoTHubModuleClient_LL_SendEventToOutputAsync(iotHubModuleClientHandle, messageInstance->messageHandle, "output1", SendConfirmationCallback, (void *)messageInstance);
                if (clientResult != IOTHUB_CLIENT_OK)
                {
                    IoTHubMessage_Destroy(messageInstance->messageHandle);
                    free(messageInstance);
                    printf("IoTHubModuleClient_LL_SendEventToOutputAsync failed on sending msg#=%zu, err=%d\n", messagesReceivedByInput1Queue, clientResult);
                    result = IOTHUBMESSAGE_ABANDONED;
                }
                else
                {
                    result = IOTHUBMESSAGE_ACCEPTED;
                }
            }
        }
        // If message does not exceed the threshold, do not forward
        else
        {
            printf("Not sending message (%zu) to the next stage in pipeline.\r\n", messagesReceivedByInput1Queue);
            result = IOTHUBMESSAGE_ACCEPTED;
        }
    
        messagesReceivedByInput1Queue++;
        return result;
    }
    
  5. moduleTwinCallback işlevi ekleyin. Bu yöntem modül ikizinin istenen özellikleri üzerinde yapılan güncelleştirmeleri alır ve temperatureThreshold değişkenini buna göre güncelleştirir. Tüm modüllerin kendi modül ikizi vardır ve bu sayede doğrudan buluttan modülün içinde çalışan kodu yapılandırabilirsiniz.

    static void moduleTwinCallback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)
    {
        printf("\r\nTwin callback called with (state=%s, size=%zu):\r\n%s\r\n",
            MU_ENUM_TO_STRING(DEVICE_TWIN_UPDATE_STATE, update_state), size, payLoad);
        JSON_Value *root_value = json_parse_string(payLoad);
        JSON_Object *root_object = json_value_get_object(root_value);
        if (json_object_dotget_value(root_object, "desired.TemperatureThreshold") != NULL) {
            temperatureThreshold = json_object_dotget_number(root_object, "desired.TemperatureThreshold");
        }
        if (json_object_get_value(root_object, "TemperatureThreshold") != NULL) {
            temperatureThreshold = json_object_get_number(root_object, "TemperatureThreshold");
        }
    }
    
  6. işlevini arayın SetupCallbacksForModule . işlevini aşağıdaki kodla değiştirin. Bu kod, modül ikizinin güncelleştirilip güncelleştirilmediğini denetlemek için else-if deyimini ekler.

    static int SetupCallbacksForModule(IOTHUB_MODULE_CLIENT_LL_HANDLE iotHubModuleClientHandle)
    {
        int ret;
    
        if (IoTHubModuleClient_LL_SetInputMessageCallback(iotHubModuleClientHandle, "input1", InputQueue1Callback, (void*)iotHubModuleClientHandle) != IOTHUB_CLIENT_OK)
        {
            printf("ERROR: IoTHubModuleClient_LL_SetInputMessageCallback(\"input1\")..........FAILED!\r\n");
            ret = MU_FAILURE;
        }
        else if (IoTHubModuleClient_LL_SetModuleTwinCallback(iotHubModuleClientHandle, moduleTwinCallback, (void*)iotHubModuleClientHandle) != IOTHUB_CLIENT_OK)
        {
            printf("ERROR: IoTHubModuleClient_LL_SetModuleTwinCallback(default)..........FAILED!\r\n");
            ret = MU_FAILURE;
        }
        else
        {
            ret = 0;
        }
    
        return ret;
    }
    
  7. main.c dosyasını kaydedin.

  8. deployment.template.json dosyasını açın.

  9. Dağıtım bildirimine CModule modül ikizini ekleyin. Aşağıdaki JSON içeriğini moduleContent bölümünün en altına, $edgeHub modül ikizinin arkasına ekleyin:

    "CModule": {
        "properties.desired":{
            "TemperatureThreshold":25
        }
    }
    

    Dağıtım şablonuna eklenen modül ikizini gösteren ekran görüntüsü.

  10. deployment.template.json dosyasını kaydedin.

Modülünüzü derleme ve gönderme

Önceki bölümde bir IoT Edge çözümü oluşturdunuz ve bildirilen makine sıcaklığının kabul edilebilir eşiğin altında olduğu iletileri filtrelemek için CModule'e kod eklediniz. Şimdi çözümü kapsayıcı görüntüsü olarak derlemeniz ve kapsayıcı kayıt defterine göndermeniz gerekiyor.

Docker'da oturum açma

Kapsayıcı görüntünüzü kayıt defterinde depolanmak üzere gönderebilmesi için geliştirme makinenizdeki Docker'a kapsayıcı kayıt defteri kimlik bilgilerinizi sağlayın.

  1. PowerShell'i veya Komut İstemi penceresini açın.

  2. Kayıt defterini oluşturduktan sonra kaydettiğiniz Azure kapsayıcı kayıt defteri kimlik bilgileriyle Docker'da oturum açın.

    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    kullanılmasını --password-stdinöneren bir güvenlik uyarısı alabilirsiniz. Bunu üretim senaryoları için en iyi yöntem olarak önersek de, bu öğreticinin kapsamı dışındadır. Daha fazla bilgi için bkz. docker oturum açma başvurusu.

Derleme ve gönderme

Geliştirme makinenizin artık kapsayıcı kayıt defterinize erişimi vardır ve IoT Edge cihazlarınız da erişecektir. Proje kodunu kapsayıcı görüntüsüne dönüştürmenin zamanı geldi.

  1. Visual Studio Çözüm Gezgini'da, oluşturmak istediğiniz projenin adına sağ tıklayın. Varsayılan ad AzureIotEdgeApp1'dir. Bu öğretici için CTutorialApp adını seçtik ve bir Windows modülü derlediğiniz için uzantı Windows.Amd64 olmalıdır.

  2. IoT Edge Modülleri Oluştur ve Gönder'i seçin.

    Derleme ve gönderme komutu üç işlem başlatır:

    • İlk olarak, çözümde tam dağıtım bildirimini tutan config adlı yeni bir klasör oluşturur. Dağıtım şablonundaki ve diğer çözüm dosyalarındaki bilgilerden oluşturulur.
    • İkinci olarak, hedef mimariniz için uygun Dockerfile'ı temel alarak kapsayıcı görüntüsünü derlemek için çalışır docker build .
    • Son olarak, görüntü deposunu kapsayıcı kayıt defterinize göndermek için çalışır docker push .

    Bu işlem ilk kez birkaç dakika sürebilir, ancak komutları bir sonraki çalıştırmanızda daha hızlı olacaktır.

Cihaza modül dağıtma

Modül projesini IoT Edge cihazınıza dağıtmak için Visual Studio Bulut Gezgini'ni ve Azure IoT Edge Tools uzantısını kullanın. Yapılandırma klasöründekideployment.windows-amd64.json dosyası olan senaryonuz için zaten bir dağıtım bildirimi hazırladınız. Tek yapmanız gereken dağıtımı almak üzere bir cihaz seçmek.

IoT Edge cihazınızın çalışır durumda olduğundan emin olun.

  1. Visual Studio Bulut Gezgini'nde IoT cihazları listenizi görüntülemek için kaynakları genişletin.

  2. Dağıtımı almak istediğiniz IoT Edge cihazının adına sağ tıklayın.

  3. İçerik Oluşturucu Dağıtım'ı seçin.

  4. Visual Studio Dosya Gezgini'da çözümünüzün yapılandırma klasöründeki deployment.windows-amd64.json dosyasını seçin.

  5. Cihazınızın altında listelenen dağıtılan modülleri görüntülemek için Bulut Gezgini'ni yenileyin.

Oluşturulan verileri görüntüleme

Dağıtım bildirimini IoT Edge cihazınıza uyguladıktan sonra, cihazdaki IoT Edge çalışma zamanı yeni dağıtım bilgilerini toplar ve üzerinde yürütmeye başlar. Cihazda çalışan ancak dağıtım bildirimine dahil olmayan tüm modüller durdurulur. Cihazda eksik olan tüm modüller başlatılır.

ioT hub'ınıza ulaşan iletileri görüntülemek için IoT Edge Araçları uzantısını kullanabilirsiniz.

  1. Visual Studio Bulut Gezgini'nde IoT Edge cihazınızın adını seçin.

  2. Eylemler listesinde Yerleşik Olay Uç Noktasını İzlemeyi Başlat'ı seçin.

  3. IoT hub'ınıza gelen iletileri görüntüleyin. IoT Edge cihazının yeni dağıtımını alması ve tüm modülleri başlatması gerektiğinden iletilerin gelmesi biraz zaman alabilir. İletilerin gönderebilmesi için CModule kodundaki değişikliklerin makine sıcaklığı 25 dereceye ulaşana kadar beklemesi gerekir. Kod ayrıca, bu sıcaklık eşiğine ulaşan iletilere Uyarı ileti türünü ekler.

    IoT hub'ına gelen iletileri görüntüleyen Çıkış penceresinin ekran görüntüsü.

Modül ikizini düzenleme

Sıcaklık eşiğini 25 derece olarak ayarlamak için CModule modül ikizini kullandınız. Modül kodunu güncelleştirmek zorunda kalmadan işlevselliği değiştirmek için modül ikizini kullanabilirsiniz.

  1. Visual Studio'da deployment.windows-amd64.json dosyasını açın.

    deployment.templatedosyasını açmayın. Çözüm Gezgini'daki yapılandırma dosyasında dağıtım bildirimini görmüyorsanız Çözüm Gezgini araç çubuğundaki Tüm dosyaları göster simgesini seçin.

  2. CModule ikizini arayın ve temperatureThreshold parametresinin değerini bildirilen en son sıcaklığa göre 5-10 derece daha yüksek olan yeni bir sıcaklıkla değiştirin.

  3. deployment.windows-amd64.json dosyasını kaydedin.

  4. Güncelleştirilmiş dağıtım bildirimini cihazınıza uygulamak için dağıtım yönergelerini yeniden izleyin.

  5. Gelen cihazdan buluta iletileri izleyin. İletiler, yeni sıcaklık eşiğine ulaşılana kadar durmalıdır.

Kaynakları temizleme

Bir sonraki önerilen makaleye devam etmek istiyorsanız, bu öğreticide oluşturduğunuz kaynakları ve yapılandırmaları tutabilir ve yeniden kullanabilirsiniz. Aynı IoT Edge cihazını test cihazı olarak kullanmaya devam edebilirsiniz.

Aksi takdirde, ücret yansıtılmasını önlemek için burada kullandığınız yerel yapılandırmaları ve Azure kaynaklarını silebilirsiniz.

Azure kaynaklarını silme

Azure kaynaklarını ve kaynak gruplarını silme işlemi geri alınamaz. Yanlış kaynak grubunu veya kaynakları yanlışlıkla silmediğinizden emin olun. IoT hub'ını tutmak istediğiniz kaynakların bulunduğu mevcut bir kaynak grubunda oluşturduysanız, kaynak grubunu değil yalnızca IoT hub kaynağını silin.

Kaynakları silmek için:

  1. Azure portalında oturum açın ve Kaynak grupları’nı seçin.

  2. IoT Edge test kaynaklarınızı içeren kaynak grubunun adını seçin.

  3. Kaynak grubunuzda bulunan kaynakların listesini gözden geçirin. Tümünü silmek isterseniz Kaynak grubunu sil'i seçebilirsiniz. Kaynakların yalnızca bazılarını silmek istiyorsanız tek tek tıklayarak silebilirsiniz.

Sonraki adımlar

Bu öğreticide IoT Edge cihazınız tarafından üretilen ham verileri filtreleme kodunu içeren bir IoT Edge modülü oluşturdunuz.

Azure IoT Edge'in uçta verileri işlemek ve analiz etmek üzere Azure bulut hizmetlerini dağıtmanıza nasıl yardımcı olabileceğini öğrenmek için sonraki öğreticilere geçin.