Integrowanie usługi IoT Central z usługą Azure Pipelines w celu ciągłej integracji i ciągłego dostarczania

Ciągła integracja i ciągłe dostarczanie (CI/CD) odnosi się do procesu tworzenia i dostarczania oprogramowania w krótkim czasie, często używanych potoków automatyzacji. W tym artykule pokazano, jak zautomatyzować kompilację, testowanie i wdrażanie konfiguracji aplikacji usługi IoT Central. Ta automatyzacja umożliwia zespołom deweloperów częstsze dostarczanie niezawodnych wydań.

Ciągła integracja rozpoczyna się od zatwierdzenia kodu do gałęzi w repozytorium kodu źródłowego. Każde zatwierdzenie jest scalane z zatwierdzeniami od innych deweloperów, aby upewnić się, że nie wprowadzono konfliktów. Zmiany są dalej weryfikowane przez utworzenie kompilacji i uruchomienie testów automatycznych względem tej kompilacji. Ten proces ostatecznie powoduje utworzenie artefaktu lub pakietu wdrożenia w celu wdrożenia w środowisku docelowym. W takim przypadku obiektem docelowym jest aplikacja usługi Azure IoT Central.

Podobnie jak usługa IoT Central jest częścią większego rozwiązania IoT, usługa IoT Central jest częścią potoku ciągłej integracji/ciągłego wdrażania. Potok ciągłej integracji/ciągłego wdrażania powinien wdrożyć całe rozwiązanie IoT i wszystkie konfiguracje w każdym środowisku od programowania do środowiska produkcyjnego:

Diagram przedstawiający etapy typowego potoku ciągłej integracji/ciągłego wdrażania.

Usługa IoT Central to platforma aplikacji jako usługa , która ma różne wymagania dotyczące wdrażania od składników platformy jako usługi . W przypadku usługi IoT Central wdrażasz konfiguracje i szablony urządzeń. Te konfiguracje i szablony urządzeń są zarządzane i zintegrowane z potokiem wydania przy użyciu interfejsów API.

Chociaż istnieje możliwość zautomatyzowania tworzenia aplikacji usługi IoT Central, należy utworzyć aplikację w każdym środowisku przed opracowaniem potoku ciągłej integracji/ciągłego wdrażania.

Korzystając z interfejsu API REST usługi Azure IoT Central, możesz zintegrować konfiguracje aplikacji usługi IoT Central z potokiem wydania.

Ten przewodnik przeprowadzi Cię przez proces tworzenia nowego potoku, który aktualizuje aplikację usługi IoT Central na podstawie plików konfiguracji zarządzanych w usłudze GitHub. Ten przewodnik zawiera szczegółowe instrukcje dotyczące integracji z usługą Azure Pipelines, ale można je dostosować do uwzględnienia usługi IoT Central w dowolnym potoku wydania utworzonym przy użyciu narzędzi, takich jak Tekton, Jenkins, GitLab lub GitHub Actions.

W tym przewodniku utworzysz potok, który stosuje tylko konfigurację usługi IoT Central do pojedynczego wystąpienia aplikacji usługi IoT Central. Należy zintegrować kroki z większym potokiem, który wdraża całe rozwiązanie i promuje go od programowania do kontroli jakości do produkcji przedprodukcyjnej, wykonując wszystkie niezbędne testy po drodze.

Skrypty obecnie nie przesyłają następujących ustawień między wystąpieniami usługi IoT Central: pulpitami nawigacyjnymi, widokami, ustawieniami niestandardowymi w szablonach urządzeń, planem cenowym, dostosowaniami środowiska użytkownika, obrazem aplikacji, regułami, zaplanowanymi zadaniami, zapisanymi zadaniami i grupami rejestracji.

Skrypty obecnie nie usuwają ustawień z docelowej aplikacji usługi IoT Central, które nie są obecne w pliku konfiguracji.

Wymagania wstępne

Aby wykonać kroki opisane w tym przewodniku, potrzebne są następujące wymagania wstępne:

Pobieranie przykładowego kodu

Aby rozpocząć, rozwidlenie repozytorium GitHub ciągłej integracji/ciągłego wdrażania usługi IoT Central, a następnie sklonuj rozwidlenie na maszynę lokalną:

  1. Aby rozwidlić repozytorium GitHub, otwórz repozytorium GitHub ciągłej integracji/ciągłego wdrażania usługi IoT Central i wybierz pozycję Rozwidlenie.

  2. Sklonuj rozwidlenie repozytorium na komputer lokalny, otwierając okno konsoli lub powłoki bash i uruchamiając następujące polecenie.

    git clone https://github.com/{your GitHub username}/iot-central-CICD-sample
    

Tworzenie jednostki usługi

Chociaż usługa Azure Pipelines może integrować się bezpośrednio z magazynem kluczy, potok wymaga jednostki usługi dla niektórych dynamicznych interakcji magazynu kluczy, takich jak pobieranie wpisów tajnych dla miejsc docelowych eksportu danych.

Aby utworzyć jednostkę usługi w zakresie subskrypcji:

  1. Uruchom następujące polecenie, aby utworzyć nową jednostkę usługi:

    az ad sp create-for-rbac -n DevOpsAccess --scopes /subscriptions/{your Azure subscription Id} --role Contributor
    
  2. Zanotuj hasło, identyfikator appId i dzierżawę, ponieważ będą one potrzebne później.

  3. Dodaj hasło jednostki usługi jako wpis tajny wywoływany SP-Password do produkcyjnego magazynu kluczy:

    az keyvault secret set --name SP-Password --vault-name {your production key vault name} --value {your service principal password}
    
  4. Nadaj jednostce usługi uprawnienie do odczytywania wpisów tajnych z magazynu kluczy:

    az keyvault set-policy --name {your production key vault name} --secret-permissions get list --spn {the appId of the service principal}
    

Generowanie tokenów interfejsu API usługi IoT Central

W tym przewodniku potok używa tokenów interfejsu API do interakcji z aplikacjami usługi IoT Central. Można również użyć jednostki usługi.

Uwaga

Tokeny interfejsu API usługi IoT Central wygasają po roku.

Wykonaj poniższe kroki zarówno dla aplikacji deweloperskich, jak i produkcyjnych aplikacji usługi IoT Central.

  1. W aplikacji usługi IoT Central wybierz pozycję Uprawnienia , a następnie tokeny interfejsu API.

  2. Wybierz Nowy.

  3. Nadaj tokenowi nazwę, określ organizację najwyższego poziomu w aplikacji i ustaw rolę na App Administracja istrator.

  4. Zanotuj token interfejsu API z aplikacji usługi IoT Central. Będzie on używany później podczas uruchamiania skryptu IoTC-Config.ps1 .

  5. Zapisz wygenerowany token z produkcyjnej aplikacji usługi IoT Central jako wpis tajny wywoływany API-Token w magazynie kluczy produkcyjnych:

    az keyvault secret set --name API-Token --vault-name {your production key vault name} --value '{your production app API token}'
    

Generowanie pliku konfiguracji

Te kroki umożliwiają utworzenie pliku konfiguracji JSON dla środowiska deweloperskiego na podstawie istniejącej aplikacji usługi IoT Central. Wszystkie istniejące szablony urządzeń można również pobrać z aplikacji.

  1. Uruchom następujący skrypt programu PowerShell 7 w lokalnej kopii repozytorium ciągłej integracji/ciągłego wdrażania usługi IoT Central:

    cd .\iot-central-CICD-sample\PowerShell\
    .\IoTC-Config.ps1
    
  2. Postępuj zgodnie z instrukcjami, aby zalogować się do konta platformy Azure.

  3. Po zalogowaniu skrypt wyświetli menu opcji konfiguracji IoTC. Skrypt może wygenerować plik konfiguracji z istniejącej aplikacji usługi IoT Central i zastosować konfigurację do innej aplikacji usługi IoT Central.

  4. Wybierz opcję 1 , aby wygenerować plik konfiguracji.

  5. Wprowadź niezbędne parametry i naciśnij klawisz Enter:

    • Token interfejsu API wygenerowany na potrzeby programowania aplikacji usługi IoT Central.
    • Poddomena aplikacji deweloperskich usługi IoT Central.
    • Wprowadź ciąg .. \Config\Dev jako folder do przechowywania pliku konfiguracji i szablonów urządzeń.
    • Nazwa magazynu kluczy deweloperskich.
  6. Skrypt tworzy folder o nazwie IoTC Configuration w folderze Config\Dev w lokalnej kopii repozytorium. Ten folder zawiera plik konfiguracji i folder o nazwie Modele urządzeń dla wszystkich szablonów urządzeń w aplikacji.

Modyfikowanie pliku konfiguracji

Teraz, gdy masz plik konfiguracji reprezentujący ustawienia dla wystąpienia aplikacji usługi IoT Central, przed zastosowaniem tej konfiguracji do produkcyjnego wystąpienia aplikacji usługi IoT Central wprowadź niezbędne zmiany.

  1. Utwórz kopię utworzonego wcześniej folderu Dev i wywołaj go Production.

  2. Otwórz IoTC-Config.json w folderze Production przy użyciu edytora tekstów.

  3. Plik zawiera wiele sekcji. Jeśli jednak aplikacja nie używa określonego ustawienia, ta sekcja zostanie pominięta w pliku:

    {
      "APITokens": {
        "value": [
          {
            "id": "dev-admin",
            "roles": [
              {
                "role": "ca310b8d-2f4a-44e0-a36e-957c202cd8d4"
              }
            ],
            "expiry": "2023-05-31T10:47:08.53Z"
          }
        ]
      },
      "data exports": {
        "value": [
          {
            "id": "5ad278d6-e22b-4749-803d-db1a8a2b8529",
            "displayName": "All telemetry to blob storage",
            "enabled": false,
            "source": "telemetry",
            "destinations": [
              {
                "id": "393adfc9-0ed8-45f4-aa29-25b5c96ecf63"
              }
            ],
            "status": "notStarted"
          }
        ]
      },
      "device groups": {
        "value": [
          {
            "id": "66f41d29-832d-4a12-9e9d-18932bee3141",
            "displayName": "MXCHIP Getting Started Guide - All devices"
          },
          {
            "id": "494dc749-0963-4ec1-89ff-e1de2228e750",
            "displayName": "RS40 Occupancy Sensor - All devices"
          },
          {
            "id": "dd87877d-9465-410b-947e-64167a7a1c39",
            "displayName": "Cascade 500 - All devices"
          },
          {
            "id": "91ceac5b-f98d-4df0-9ed6-5465854e7d9e",
            "displayName": "Simulated devices"
          }
        ]
      },
      "organizations": {
        "value": []
      },
      "roles": {
        "value": [
          {
            "id": "344138e9-8de4-4497-8c54-5237e96d6aaf",
            "displayName": "Builder"
          },
          {
            "id": "ca310b8d-2f4a-44e0-a36e-957c202cd8d4",
            "displayName": "Administrator"
          },
          {
            "id": "ae2c9854-393b-4f97-8c42-479d70ce626e",
            "displayName": "Operator"
          }
        ]
      },
      "destinations": {
        "value": [
          {
            "id": "393adfc9-0ed8-45f4-aa29-25b5c96ecf63",
            "displayName": "Blob destination",
            "type": "blobstorage@v1",
            "authorization": {
              "type": "connectionString",
              "connectionString": "DefaultEndpointsProtocol=https;AccountName=yourexportaccount;AccountKey=*****;EndpointSuffix=core.windows.net",
              "containerName": "dataexport"
            },
            "status": "waiting"
          }
        ]
      },
      "file uploads": {
        "connectionString": "FileUpload",
        "container": "fileupload",
        "sasTtl": "PT1H"
      },
      "jobs": {
        "value": []
      }
    }
    
  4. Jeśli aplikacja używa przekazywania plików, skrypt tworzy wpis tajny w magazynie kluczy deweloperskich z wartością wyświetlaną connectionString we właściwości . Utwórz wpis tajny o tej samej nazwie w magazynie kluczy produkcyjnych, który zawiera parametry połączenia dla konta magazynu produkcyjnego. Na przykład:

    az keyvault secret set --name FileUpload --vault-name {your production key vault name} --value '{your production storage account connection string}'
    
  5. Jeśli aplikacja używa eksportów danych, dodaj wpisy tajne dla miejsc docelowych do produkcyjnego magazynu kluczy. Plik konfiguracji nie zawiera żadnych rzeczywistych wpisów tajnych dla miejsca docelowego. Wpisy tajne są przechowywane w magazynie kluczy.

  6. Zaktualizuj wpisy tajne w pliku konfiguracji przy użyciu nazwy wpisu tajnego w magazynie kluczy.

    Typ docelowy Właściwość do zmiany
    Kolejka usługi Service Bus Parametry połączenia
    Temat usługi Service Bus Parametry połączenia
    Azure Data Explorer clientSecret
    Azure Blob Storage Parametry połączenia
    Event Hubs Parametry połączenia
    Element webhook bez uwierzytelniania Nie dotyczy

    Na przykład:

    "destinations": {
      "value": [
        {
          "id": "393adfc9-0ed8-45f4-aa29-25b5c96ecf63",
          "displayName": "Blob destination",
          "type": "blobstorage@v1",
          "authorization": {
            "type": "connectionString",
            "connectionString": "Storage-CS",
            "containerName": "dataexport"
          },
          "status": "waiting"
        }
      ]
    }
    
  7. Aby przekazać folder Configuration do repozytorium GitHub, uruchom następujące polecenia z folderu IoTC-CICD-howto .

     git add Config
     git commit -m "Adding config directories and files"
     git push
    

Tworzenie potoku

  1. Otwórz organizację usługi Azure DevOps w przeglądarce internetowej, przechodząc do https://dev.azure.com/{your DevOps organization}
  2. Wybierz pozycję Nowy projekt , aby utworzyć nowy projekt.
  3. Nadaj projektowi nazwę i opcjonalny opis, a następnie wybierz pozycję Utwórz.
  4. Na stronie Witamy w projekcie wybierz pozycję Potoki, a następnie pozycję Utwórz potok.
  5. Wybierz pozycję GitHub jako lokalizację kodu.
  6. Wybierz pozycję Autoryzuj usługę AzurePipelines , aby autoryzować usługę Azure Pipelines w celu uzyskania dostępu do konta usługi GitHub.
  7. Na stronie Wybieranie repozytorium wybierz rozwidlenie repozytorium GitHub ciągłej integracji/ciągłego wdrażania usługi IoT Central.
  8. Po wyświetleniu monitu o zalogowanie się do usługi GitHub i udzieleniu uprawnień usłudze Azure Pipelines w celu uzyskania dostępu do repozytorium wybierz pozycję Zatwierdź i zainstaluj.
  9. Na stronie Konfigurowanie potoku wybierz pozycję Potok startowy, aby rozpocząć pracę. Zostanie wyświetlona azure-pipelines.yml do edycji.

Tworzenie grupy zmiennych

Łatwym sposobem integrowania wpisów tajnych magazynu kluczy z potokiem jest użycie grup zmiennych. Użyj grupy zmiennych, aby upewnić się, że odpowiednie wpisy tajne są dostępne dla skryptu wdrażania. Aby utworzyć grupę zmiennych:

  1. Wybierz pozycję Biblioteka w sekcji Potoki menu po lewej stronie.

  2. Wybierz pozycję + Grupa zmiennych.

  3. Wprowadź keyvault jako nazwę grupy zmiennych.

  4. Włącz przełącznik , aby połączyć wpisy tajne z magazynu kluczy platformy Azure.

  5. Wybierz subskrypcję platformy Azure i autoryzuj ją. Następnie wybierz nazwę produkcyjnego magazynu kluczy.

  6. Wybierz pozycję Dodaj , aby rozpocząć dodawanie zmiennych do grupy.

  7. Dodaj następujące wpisy tajne:

    • Klucz interfejsu API usługi IoT Central dla aplikacji produkcyjnej. Ten wpis tajny API-Token został wywołany podczas jego tworzenia.
    • Hasło utworzonej wcześniej jednostki usługi. Ten wpis tajny SP-Password został wywołany podczas jego tworzenia.
  8. Wybierz przycisk OK.

  9. Wybierz pozycję Zapisz , aby zapisać grupę zmiennych.

Konfigurowanie potoku

Teraz skonfiguruj potok do wypychania zmian konfiguracji do aplikacji usługi IoT Central:

  1. Wybierz pozycję Potoki w sekcji Potoki menu po lewej stronie.

  2. Zastąp zawartość potoku YAML następującym kodem YAML. W konfiguracji założono, że magazyn kluczy produkcyjnych zawiera następujące elementy:

    • Token interfejsu API dla produkcyjnej aplikacji usługi IoT Central w kluczu tajnym o nazwie API-Token.
    • Hasło jednostki usługi w kluczu tajnym o nazwie SP-Password.

    Zastąp wartości parametrów -AppName i -KeyVault odpowiednimi wartościami dla wystąpień produkcyjnych.

    Zanotuj wartości -AppId i -TenantId podczas tworzenia jednostki usługi.

    trigger:
    - master
    variables:
    - group: keyvault
    - name: buildConfiguration
      value: 'Release'
    steps:
    - task: PowerShell@2
      displayName: 'IoT Central'
      inputs:
        filePath: 'PowerShell/IoTC-Task.ps1'
        arguments: '-ApiToken "$(API-Token)" -ConfigPath "Config/Production/IoTC Configuration" -AppName "{your production IoT Central app name}" -ServicePrincipalPassword (ConvertTo-SecureString "$(SP-Password)" -AsPlainText -Force) -AppId "{your service principal app id}" -KeyVault "{your production key vault name}" -TenantId "{your tenant id}"'
        pwsh: true
        failOnStderr:  true
    
  3. Wybierz pozycję Zapisz i uruchom.

  4. Plik YAML jest zapisywany w repozytorium GitHub, dlatego musisz podać komunikat zatwierdzenia, a następnie wybrać pozycję Zapisz i uruchomić ponownie.

Potok jest kolejkowany. Zanim zostanie uruchomiona, może upłynąć kilka minut.

Przy pierwszym uruchomieniu potoku zostanie wyświetlony monit o nadanie potokowi uprawnień dostępu do subskrypcji i uzyskiwania dostępu do magazynu kluczy. Wybierz pozycję Zezwól, a następnie ponownie zezwól dla każdego zasobu.

Po pomyślnym zakończeniu zadania potoku zaloguj się do produkcyjnej aplikacji usługi IoT Central i sprawdź, czy konfiguracja została zastosowana zgodnie z oczekiwaniami.

Podwyższanie poziomu zmian z programowania do środowiska produkcyjnego

Teraz, gdy masz potok roboczy, możesz zarządzać wystąpieniami usługi IoT Central bezpośrednio przy użyciu zmian konfiguracji. Nowe szablony urządzeń można przekazać do folderu Modele urządzeń i wprowadzić zmiany bezpośrednio w pliku konfiguracji. Takie podejście umożliwia traktowanie konfiguracji aplikacji usługi IoT Central tak samo jak w przypadku każdego innego kodu.

Następny krok

Teraz, gdy wiesz, jak zintegrować konfiguracje usługi IoT Central z potokami ciągłej integracji/ciągłego wdrażania, sugerowanym następnym krokiem jest poznanie sposobu zarządzania aplikacjami usługi IoT Central i monitorowania ich.