Tworzenie potoku ciągłej integracji i ciągłego wdrażania za pomocą dsc

Azure Pipelines | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018 | TFS 2017

Uwaga

W programie Microsoft Team Foundation Server (TFS) 2018 i poprzednich wersjach potoki kompilacji i wydania są nazywane definicjami, przebiegi są nazywane kompilacjami, połączenia z usługą są nazywane punktami końcowymi usługi, etapy są nazywane środowiskami , a zadania są nazywane fazami.

W tym przykładzie pokazano, jak utworzyć potok ciągłej integracji/ciągłego wdrażania (CI/CD) przy użyciu programu PowerShell, dsc i rozwiązania Sheller.

Po s zbudowaniu i skonfigurowaniu potoku można go użyć do pełnego wdrożenia, skonfigurowania i przetestowania serwera DNS i skojarzonych rekordów hosta. Ten proces symuluje pierwszą część potoku, która będzie używana w środowisku deweloperskim.

Zautomatyzowany potok cicha/cd pomaga w szybszym i bardziej niezawodnym aktualizowaniu oprogramowania, zapewniając, że cały kod jest testowany i że bieżąca kompilacja kodu jest dostępna przez cały czas.

Wymagania wstępne

Aby skorzystać z tego przykładu, należy zapoznać się z następującymi tematami:

Co jest potrzebne

Do skompilowania i uruchomienia tego przykładu potrzebne będzie środowisko z kilkoma komputerami i/lub maszynami wirtualnymi.

Klient

Jest to komputer, na którym będziesz wykonać całą pracę podczas konfigurowania i uruchamiania przykładu. Komputer kliencki musi być komputerem Windows z zainstalowanymi następującymi systemami:

Azure DevOps Subskrypcji

Organizacja Azure DevOps. Jeśli nie masz takiego konta, możesz je utworzyć bezpłatnie. (Organizacja Azure DevOps różni się od twojej GitHub organizacji. Nadaj im taką samą nazwę, jeśli chcesz wyrównać je).

TFSSrv

Komputer, który hostuje serwer TFS, na którym zostanie zdefiniowana kompilacja i wydanie. Na tym komputerze musi być Team Foundation Server 2017.

BuildAgent

Komputer z uruchomionym Windows kompilacji, który tworzy projekt. Ten komputer musi mieć zainstalowany i Windows kompilacji. Zobacz Wdrażanie agenta na Windows, aby uzyskać instrukcje dotyczące instalowania i uruchamiania agenta Windows kompilacji.

Należy również zainstalować moduły xDnsServer xNetworking DSC i na tym komputerze.

TestAgent1

Jest to komputer skonfigurowany jako serwer DNS przez konfigurację DSC w tym przykładzie. Na komputerze musi być uruchomiony Windows Server 2016.

TestAgent2

Jest to komputer, który hostuje witrynę internetową skonfigurowaną w tym przykładzie. Na komputerze musi być uruchomiony Windows Server 2016.

Dodawanie kodu do repozytorium

Zaczniemy od utworzenia repozytorium Git i zaimportowania kodu z repozytorium lokalnego na komputerze klienckim. Jeśli repozytorium danych nie zostało jeszcze sklonowane Demo_CI na komputer kliencki, zrób to teraz, uruchamiając następujące polecenie git:

git clone https://github.com/PowerShell/Demo_CI
  1. Na komputerze klienckim przejdź do serwera TFS w przeglądarce internetowej.

  2. Utwórz nowy projekt zespołowy o nazwie Demo_CI.

    Upewnij się, że dla ustawienia Kontrola wersji ustawiono wartość Git.

  3. Na komputerze klienckim dodaj repozytorium zdalne utworzone w programie TFS za pomocą następującego polecenia:

    git remote add tfs <YourTFSRepoURL>

    Gdzie <YourTFSRepoURL> to adres URL klonowania do repozytorium TFS utworzonego w poprzednim kroku.

    Jeśli nie wiesz, gdzie znaleźć ten adres URL, zobacz Clone an existing Git repo (Klonowanie istniejącego repozytorium Git).

  4. Wypchniesz kod z repozytorium lokalnego do repozytorium TFS za pomocą następującego polecenia:

    git push tfs --all

  5. Repozytorium TFS zostanie wypełnione Demo_CI kodu.

  1. Przejdź do subskrypcji Azure DevOps w przeglądarce internetowej.

  2. Utwórz nowy projekt zespołowy o nazwie Demo_CI. Upewnij się, że dla ustawienia Kontrola wersji ustawiono wartość Git.

  3. Na komputerze klienckim dodaj repozytorium zdalne, które właśnie utworzono, za pomocą następującego polecenia:

    git remote add devops <YourDevOpsRepoURL>

    Gdzie <YourDevOpsRepoURL> to sklonowany adres URL Azure DevOps repozytorium utworzonego w poprzednim kroku.

    Jeśli nie wiesz, gdzie znaleźć ten adres URL, zobacz Clone an existing Git repo (Klonowanie istniejącego repozytorium Git).

  4. Wypchniesz kod z repozytorium lokalnego do repozytorium TFS za pomocą następującego polecenia:

    git push devops --all

  5. Repozytorium Azure DevOps zostanie wypełnione kodem Demo_CI.

Uwaga

W tym przykładzie użyto kodu z ci-cd-example gałęzi repozytorium Git. Pamiętaj, aby określić tę gałąź jako gałąź domyślną w projekcie oraz dla wyzwalaczy ci/CD, które tworzysz.

Omówienie kodu

Zanim utworzymy potoki kompilacji i wdrażania, przyjrzyjmy się niektórym kodom, aby zrozumieć, co się dzieje. Na komputerze klienckim otwórz ulubiony edytor tekstów i przejdź do katalogu głównego repozytorium Demo_CI Git.

Konfiguracja DSC

Otwórz plik DNSServer.ps1 (z katalogu głównego lokalnego Demo_CI repozytorium , ./InfraDNS/Configs/DNSServer.ps1 ).

Ten plik zawiera konfigurację DSC, która konfiguruje serwer DNS. Tutaj jest w całości:

configuration DNSServer
{
    Import-DscResource -module 'xDnsServer','xNetworking', 'PSDesiredStateConfiguration'

    Node $AllNodes.Where{$_.Role -eq 'DNSServer'}.NodeName
    {
        WindowsFeature DNS
        {
            Ensure  = 'Present'
            Name    = 'DNS'
        }

        xDnsServerPrimaryZone $Node.zone
        {
            Ensure    = 'Present'
            Name      = $Node.Zone
            DependsOn = '[WindowsFeature]DNS'
        }

        foreach ($ARec in $Node.ARecords.keys) {
            xDnsRecord $ARec
            {
                Ensure    = 'Present'
                Name      = $ARec
                Zone      = $Node.Zone
                Type      = 'ARecord'
                Target    = $Node.ARecords[$ARec]
                DependsOn = '[WindowsFeature]DNS'
            }
        }

        foreach ($CName in $Node.CNameRecords.keys) {
            xDnsRecord $CName
            {
                Ensure    = 'Present'
                Name      = $CName
                Zone      = $Node.Zone
                Type      = 'CName'
                Target    = $Node.CNameRecords[$CName]
                DependsOn = '[WindowsFeature]DNS'
            }
        }
    }
}

Zwróć uwagę na Node instrukcje :

Node $AllNodes.Where{$_.Role -eq 'DNSServer'}.NodeName

Umożliwia znalezienie wszystkich węzłów, które zostały zdefiniowane jako mające rolę w danych DNSServer konfiguracji, które są tworzone przez DevEnv.ps1 skrypt.

Więcej informacji na temat metody Where można znaleźć w about_arrays

Używanie danych konfiguracji do definiowania węzłów jest ważne podczas wykonywania konfiguracji ci, ponieważ informacje o węźle prawdopodobnie zmienią się między środowiskami, a użycie danych konfiguracji pozwala łatwo wprowadzać zmiany w informacjach o węźle bez zmiany kodu konfiguracji.

W pierwszym bloku zasobów konfiguracja wywołuje funkcję WindowsFeature, aby upewnić się, że funkcja DNS jest włączona. Bloki zasobów, które są następujące po wywołaniu zasobów z modułu xDnsServer w celu skonfigurowania strefy podstawowej i rekordów DNS.

Zwróć uwagę, że xDnsRecord dwa bloki są opakowane w foreach pętle, które iterują po tablicach w danych konfiguracji. Ponownie dane konfiguracji są tworzone przez DevEnv.ps1 skrypt, który przyjrzymy się dalej.

Dane konfiguracji

Plik (z katalogu głównego lokalnego repozytorium Demo_CI ) określa dane konfiguracji specyficzne dla środowiska w tablicy skrótów, a następnie przekazuje tę tablicę skrótów do wywołania funkcji zdefiniowanej w pliku DevEnv.ps1 ./InfraDNS/DevEnv.ps1 ( New-DscConfigurationDataDocument DscPipelineTools.psm ./Assets/DscPipelineTools/DscPipelineTools.psm1 ).

Plik DevEnv.ps1 :

param(
    [parameter(Mandatory=$true)]
    [string]
    $OutputPath
)

Import-Module $PSScriptRoot\..\Assets\DscPipelineTools\DscPipelineTools.psd1 -Force

# Define Unit Test Environment
$DevEnvironment = @{
    Name                        = 'DevEnv';
    Roles = @(
        @{  Role                = 'DNSServer';
            VMName              = 'TestAgent1';
            Zone                = 'Contoso.com';
            ARecords            = @{'TFSSrv1'= '10.0.0.10';'Client'='10.0.0.15';'BuildAgent'='10.0.0.30';'TestAgent1'='10.0.0.40';'TestAgent2'='10.0.0.50'};
            CNameRecords        = @{'DNS' = 'TestAgent1.contoso.com'};
        }
    )
}

return New-DscConfigurationDataDocument -RawEnvData $DevEnvironment -OutputPath $OutputPath

Funkcja (zdefiniowana w pliku ) programowo tworzy dokument danych konfiguracji z tablicy skrótów (dane węzła) i tablicy (dane niewęzłowe), które są przekazywane jako New-DscConfigurationDataDocument \Assets\DscPipelineTools\DscPipelineTools.psm1 parametry i RawEnvData OtherEnvData .

W naszym przypadku używany jest RawEnvData tylko parametr .

Skrypt kompilacji psake

Skrypt kompilacji psake zdefiniowany w programie (w katalogu głównym Demo_CI repozytorium ) definiuje zadania, które są Build.ps1 częścią ./InfraDNS/Build.ps1 kompilacji. Definiuje również, od których innych zadań zależy każde zadanie. Po wywołaniu skrypt psake zapewnia uruchomienie określonego zadania (lub zadania o nazwie , jeśli nie określono żadnej) i że wszystkie zależności również są uruchamiane (jest to cykliczne, tak aby zostały uruchomione zależności Default itd.).

W tym przykładzie Default zadanie jest zdefiniowane jako:

Task Default -depends UnitTests

Zadanie Default nie ma samej implementacji, ale jest zależne od CompileConfigs zadania. Wynikowy łańcuch zależności zadań gwarantuje, że wszystkie zadania w skrypcie kompilacji są uruchamiane.

W tym przykładzie skrypt psake jest wywoływany przez wywołanie metody w pliku (znajduje się w katalogu głównym Invoke-PSake Initiate.ps1 Demo_CI repozytorium):

param(
    [parameter()]
    [ValidateSet('Build','Deploy')]
    [string]
    $fileName
)

#$Error.Clear()

Invoke-PSake $PSScriptRoot\InfraDNS\$fileName.ps1

<#if($Error.count)
{
    Throw "$fileName script failed. Check logs for failure details."
}
#>

Podczas tworzenia definicji kompilacji dla naszego przykładu podamy nasz plik skryptu psake jako fileName parametr dla tego skryptu.

Skrypt kompilacji definiuje następujące zadania:

GenerateEnvironmentFiles

Uruchamia DevEnv.ps1 plik , który generuje plik danych konfiguracji.

InstallModules

Instaluje moduły wymagane przez konfigurację DNSServer.ps1 .

ScriptAnalysis

Wywołuje program PSScriptAnalyzer.

UnitTests

Uruchamia testy jednostkowe Programu Testów.

CompileConfigs

Kompiluje konfigurację ( DNSServer.ps1 ) do pliku MOF przy użyciu danych konfiguracji wygenerowanych przez GenerateEnvironmentFiles zadanie.

Clean

Tworzy foldery używane na przykład i usuwa wszystkie wyniki testów, pliki danych konfiguracji i moduły z poprzednich przebiegów.

Skrypt wdrażania usługi psake

Skrypt wdrażania psake zdefiniowany w pliku (z katalogu głównego Demo_CI ) definiuje zadania, które wdrażają Deploy.ps1 i ./InfraDNS/Deploy.ps1 uruchamiają konfigurację.

Deploy.ps1 Definiuje następujące zadania:

DeployModules

Uruchamia sesję programu PowerShell TestAgent1 i instaluje moduły zawierające zasoby DSC wymagane dla konfiguracji.

DeployConfigs

Wywołuje polecenie cmdlet Start-DscConfiguration, aby uruchomić konfigurację w systemie TestAgent1 .

IntegrationTests

Uruchamia testy integracji z usługą Teser.

AcceptanceTests

Uruchamia testy akceptacyjne w uciekierach.

Clean

Usuwa wszystkie moduły zainstalowane w poprzednich przebiegach i zapewnia, że folder wyników testu istnieje.

Skrypty testowe

Testy akceptacyjne, integracji i jednostkowe są definiowane w skryptach w folderze (z katalogu głównego Demo_CI repozytorium ), każdy w plikach o nazwach w Tests ./InfraDNS/Tests odpowiednich DNSServer.tests.ps1 folderach.

Skrypty testowe używają składni PoshSpec i Basher.

Testy jednostkowe

Testy jednostkowe samodzielnie testują konfiguracje DSC, aby upewnić się, że konfiguracje będą działać w oczekiwany sposób po ich uruchomieniu. Skrypt testu jednostkowego używa MetodyKasera.

Testy integracji

Testy integracji testuje konfigurację systemu, aby upewnić się, że w przypadku integracji z innymi składnikami system jest skonfigurowany zgodnie z oczekiwaniami. Te testy są uruchamiane w węźle docelowym po skonfigurowaniu go przy użyciu konfiguracji DSC. W skrypcie testu integracji używana jest składnia Zespolona i PoshSpec.

Testy akceptacyjne

Testy akceptacyjne testuje system, aby upewnić się, że działa zgodnie z oczekiwaniami. Na przykład sprawdza, czy podczas zapytania strona internetowa zwraca odpowiednie informacje. Te testy są uruchamiane zdalnie z węzła docelowego w celu przetestowania rzeczywistych scenariuszy. W skrypcie testu integracji używana jest składnia Zespolona i PoshSpec.

Definiowanie kompilacji

Teraz, gdy kod został przekazany do repo i przyjrzeliśmy się temu, co robi, zdefiniujmy naszą kompilację.

W tym miejscu będziemy obejmować tylko kroki kompilacji, które dodasz do kompilacji. Aby uzyskać instrukcje dotyczące tworzenia definicji kompilacji w Azure DevOps, zobacz Tworzenie definicji kompilacji i kolejkowanie jej.

Utwórz nową definicję kompilacji (wybierz szablon potoku początkowego) o nazwie "InfraDNS". Dodaj następujące kroki do definicji kompilacji:

  • PowerShell
  • Publikowanie Wyniki testów
  • Kopiowanie plików
  • Publikowanie artefaktu

Po dodaniu tych kroków kompilacji edytuj właściwości każdego kroku w następujący sposób:

PowerShell

  1. Ustaw właściwość targetType na File Path wartość .
  2. Ustaw właściwość filePath na initiate.ps1 wartość .
  3. Dodaj -fileName build wartość do właściwości Arguments.

Ten krok kompilacji uruchamia initiate.ps1 plik , który wywołuje skrypt kompilacji psake.

Publikowanie Wyniki testów

  1. Ustaw wartość TestResultsFormat naNUnit
  2. Ustaw wartość TestResultsFiles naInfraDNS/Tests/Results/*.xml
  3. Dla ustawienia TestRunTitle ustaw wartość Unit .
  4. Upewnij się, że wybrano opcje Kontroluj włączone i Zawsze uruchamiaj.

W tym kroku kompilacji są uruchamiane testy jednostkowe w skrypcie Strukturyzator, który był wcześniej analizowany, i wyniki są przechowywane w InfraDNS/Tests/Results/*.xml folderze .

Kopiowanie plików

  1. Dodaj każdy z następujących wierszy do pola Zawartość:

    initiate.ps1
    **\deploy.ps1
    **\Acceptance\**
    **\Integration\**
    
  2. Ustaw element TargetFolder na$(Build.ArtifactStagingDirectory)\

Ten krok kopiuje skrypty kompilacji i testowania do katalogu przejściowego, aby można było opublikować go jako artefakty kompilacji w następnym kroku.

Publikowanie artefaktu

  1. Ustaw wartość TargetPath na $(Build.ArtifactStagingDirectory)\
  2. Ustaw parametr ArtifactName naDeploy
  3. Dla opcji Włączone ustaw wartość true .

Włączanie ciągłej integracji

Teraz skonfigurujemy wyzwalacz, który spowoduje skompilowanie projektu za każdym razem, gdy zmiana zostanie zaewidencjonowana w gałęzi ci-cd-example repozytorium git.

  1. W programie TFS kliknij kartę Build & Release (Kompilacja i wydanie)
  2. Wybierz DNS Infra definicję kompilacji, a następnie kliknij pozycję Edytuj
  3. Kliknij kartę Wyzwalacze
  4. Wybierz pozycję Ciągła integracja (CI) i wybierz refs/heads/ci-cd-example pozycję z listy rozwijanej gałęzi
  5. Kliknij pozycję Zapisz, a następnie przycisk OK.

Teraz każda zmiana w repozytorium git wyzwala zautomatyzowaną kompilację.

Tworzenie definicji wydania

Utwórzmy definicję wydania, aby projekt został wdrożony w środowisku dewelopera przy każdym zaewidencjonanym kodzie.

W tym celu dodaj nową definicję wydania skojarzoną z utworzoną InfraDNS wcześniej definicją kompilacji. Pamiętaj, aby wybrać pozycję Ciągłe wdrażanie, aby nowa wersja została wyzwolona za każdym razem, gdy nowa kompilacja zostanie ukończona. (Coto są potoki wydania?) i skonfiguruj je w następujący sposób:

Dodaj następujące kroki do definicji wydania:

  • PowerShell
  • Publikowanie Wyniki testów
  • Publikowanie Wyniki testów

Zedytuj kroki w następujący sposób:

PowerShell

  1. Ustaw pole TargetPath na wartość $(Build.DefinitionName)\Deploy\initiate.ps1"
  2. Ustaw pole Argumenty na -fileName Deploy

Pierwsze publikowanie Wyniki testów

  1. Wybierz NUnit dla pola TestResultsFormat
  2. Ustaw pole TestResultsFiles na wartość $(Build.DefinitionName)\Deploy\InfraDNS\Tests\Results\Integration*.xml
  3. Ustaw testRunTitle naIntegration
  4. Ustaw warunek na succeededOrFailed()

Drugi raport Wyniki testów

  1. Wybierz NUnit dla pola TestResultsFormat
  2. Ustaw pole TestResultsFiles na wartość $(Build.DefinitionName)\Deploy\InfraDNS\Tests\Results\Acceptance*.xml
  3. Ustaw testRunTitle naAcceptance
  4. Ustaw warunek na succeededOrFailed()

Weryfikowanie wyników

Teraz za każdym razem, gdy wypchniesz zmiany w ci-cd-example gałęzi, rozpocznie się nowa kompilacja. Jeśli kompilacja zakończy się pomyślnie, zostanie wyzwolone nowe wdrożenie.

Wynik wdrożenia można sprawdzić, otwierając przeglądarkę na komputerze klienckim i przechodząc do strony www.contoso.com .

Następne kroki

W tym przykładzie serwer DNS jest konfigurowane tak, aby adres URL był rozpoznany jako , ale w rzeczywistości nie wdrożono TestAgent1 www.contoso.com witryny TestAgent2 internetowej. W tym celu szkielet znajduje się w repo w WebApp folderze . Dostępne wycinki mogą być stosowane do tworzenia skryptów psake, testów Rozwiązania i konfiguracji DSC w celu wdrożenia własnej witryny internetowej.