Numerownie buildów w AWS CodeBuild

Ostatnio zdarzyło mi się eksperymentować z AWS CodeBuild, CodeDeploy i CodePipeline jako alternatywy dla TeamCity/Jenkinsa. Konfiguracja i użycie tych narzędzi jest bardzo proste i wygodne, szczególnie jeśli cała infrastruktura jest umieszczona w AWS. Jednak brakowało mi prostej funkcjonalności, jaką jest numerowanie kolejnych buildów, tak żebym mógł użyć tego numeru przy releasowaniu biblioteki czy kontenera dockerowego.

Po krótkim researchu okazało się, że można taką numerację dość łatwo dodać, używając kolejnej usługi Amazona, jaką jest AWS System Manager Parameter Store (SSM). Możemy tam przechowywać własne parametry, które potem są udostępniane jako zmienne środowiskowe dla naszego buildu. Po ukończeniu budowania projektu możemy podbić numerek np. przy użyciu bashowego jednolinijkowca.

Tworzymy zmienną

Należy zacząć od stworzenia zmiennej. Bez tego build zakończy się niepowodzeniem z wiadomością:

[Container] 2019/07/22 09:40:18 Phase context status code: Decrypted Variables Error Message: parameter does not exist: /build-number/project-name

W zakładce services w konsoli Amazona wyszukujemy System Manager, następnie w menu po lewej wybieramy Parameter Store.

Wyszukujemy usługę System Manager
Następnie wybieramy Prameter Store

Dalej klikamy Create Parameter i wypełniamy pola. Jako schemat nazw wybrałem /build-number/project-name, dzięki temu potem można łatwiej nadać uprawnienia do parametrów (o tym będzie później). Jako typ parametru wybieramy String. Tier wystarczy standard. Value to początkowa wartość parametru, najlepiej 1. Po wypełnieniu pól klikamy create parameter.

Dalej klikamy create parameter

Mamy już zainicjowany parametr. Możemy przejść dalej.

Nadajemy uprawnienia w IAM

Projekt w CodeBuild ma przypisaną rolę, z którą się wykonuje. Musimy jej przypisać Policy, która zezwoli na pobranie wartości parametru oraz jej modyfikację. Może być to inline policy. Powinna wyglądać mniej więcej tak:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ssm:PutParameter",
                "ssm:GetParameters",
                "ssm:GetParameter"
            ],
            "Resource": "arn:aws:ssm:{region}:{account-id}:parameter/build-number/*"
        }
    ]
}

W przykładzie należy zmienić region i account-id na wasze wartości.

Przygotowanie buildu

Ostatnim krokiem jest dodanie odpowiednich parametrów w pliku konfiguracyjnym buildu.

version: 0.2

env:
  parameter-store:
     buildNumber: "/build-number/project-name" # 1

phases:
  install:
    runtime-versions:
      java: openjdk11
  build:
    commands:
      - echo Build number $buildNumber # 2
      - mvn versions:set -DnewVersion=1.$buildNumber # 3
      - mvn versions:update-child-modules # 4
  post_build:
    commands:
      - echo Incrementing build number
      - newBuildNumber=$(expr $buildNumber + 1) # 5
      - aws ssm put-parameter --name '/build-number/project-name' --overwrite --value $newBuildNumber --type String # 6

W miejscu oznaczonym jako # 1 definiujemy jakie zmienne środowiskowe mają być dostępne w skrypcie. Jeśli build posiada odpowiednie uprawnienia, zostaną one automatycznie pobrane z Parameter Store. Aby się upewnić, że wszystko jest ok, możemy wypisać do logów ten numer (#2). Używając version plugin z mavena, ustawiamy versję projektu (#3) i stosujemy ją tez do modułów potomnych (#4). Następnie inkrementujemy numer (#5) i nadpisujemy jego wartość w Parameter Storze (#6).

W przykładzie użyłem Mavena, ale tak samo możemy wykorzystać go do budowania kontenerów dockerowych czy innych narzędzi gdzie potrzebujemy ustawić jakąś konkretną wersję.

Podsumowanie

Pokazany sposób możemy wykorzystać w każdym projekcie Code Builda, niezależnie od użytego języka/narzędzia do budowania. Musimy jedynie pamiętać o ręcznym stworzeniu parametru, ponieważ bez tego nasz build zakończy się niepowodzeniem.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *