Konfigurowanie bezpiecznego potoku CI/CD w prywatnej chmurze Amazon Virtual Private Cloud bez publicznego dostępu do Internetu
Wraz z rozwojem chmury i rosnącą świadomością bezpieczeństwa, gwałtownie wzrosło również wykorzystanie prywatnych VPC Amazon bez publicznego dostępu do Internetu. Ta konfiguracja jest zalecana, aby zapewnić odpowiednie bezpieczeństwo poprzez izolację. Wymóg izolacji dotyczy również potoków kodu, w których programiści wdrażają swoje moduły aplikacji, pakiety oprogramowania oraz inne zależności i pakiety w całym cyklu rozwoju. Odbywa się to bez konieczności „wypychania” większych pakietów z przestrzeni deweloperskiej do przestrzeni testowej lub środowiska docelowego. Co więcej, AWS CodeArtifact jest wykorzystywana jako usługa zarządzania artefaktami, która pomoże organizacjom dowolnej wielkości w bezpiecznym przechowywaniu, publikowaniu i udostępnianiu pakietów oprogramowania używanych w ich procesie tworzenia oprogramowania.
W dalszej części tekstu omówimy kroki wymagane do zbudowania bezpiecznego, prywatnego potoku ciągłej integracji/ciągłego rozwoju (CI/CD) bez publicznego dostępu do Internetu, przy jednoczesnym utrzymaniu przechowywania dzienników w Amazon CloudWatch. Wykorzystamy AWS CodeCommit jako źródło, CodeArtifact dla modułów i pakietów oprogramowania oraz Amazon Simple Storage Service (Amazon S3) jako miejsce do przechowywania artefaktów.
Wymagania wstępne
Warunkiem koniecznym, aby móc nadążyć za tym artykułem są:
- Konto AWS
- Wirtualna prywatna chmura (Amazon VPC)
- Potok CI/CD – może to być CodePipeline, Jenkins lub dowolne narzędzie CI/CD, z którym chcesz zintegrować CodeArtifact. W poniższym instruktażu użyto CodePipeline.
Opis rozwiązania
Główną usługą, na której się skupimy, jest CodeArtifact, w pełni zarządzana usługa repozytorium artefaktów, która ułatwia organizacjom dowolnej wielkości bezpieczne przechowywanie, publikowanie i udostępnianie pakietów oprogramowania używanych w ich procesie tworzenia oprogramowania. CodeArtifact współpracuje z powszechnie używanymi menedżerami pakietów i narzędziami do kompilacji, takimi jak Maven i Gradle (Java), npm i yarn (JavaScript), pip i twine (Python) lub NuGet (.NET).
Powyższy diagram pokazuje, w jaki sposób pozostają prywatne w VPC i nie przechodzą przez internetową bramę sieciową, przechodząc z CodeBuild przez prywatny punkt końcowy do usługi CodeArtifact, a wszystko to w prywatnej podsieci.
Żądania będą używać następujących punktów końcowych VPC do łączenia się z usługami AWS:
- CloudWatch Logs endpoint (aby CodeBuild umieścił logi w CloudWatch);
- CodeArtifact endpoints
- AWS Security Token Service (AWS STS) endpoint
- Amazon Simple Storage Service (Amazon S3) endpoint
Omówienie
- Utwórz repozytorium CodeCommit: a) Przejdź do konsoli CodeCommit, a następnie kliknij Utwórz repozytorium
b) Wpisz nazwę repozytorium, a następnie kliknij Utwórz
c) Przewiń w dół i kliknij Utwórz plik
d) Skopiuj przykładowy plik buildspec.yml i wklej go do edytora
Example buildspec.yml file:
e) Nazwij plik buildspec.yml, wpisz swoje imię i nazwisko oraz adres e-mail, a następnie zatwierdź zmiany
2.Utwórz artefakt kodu
a) Przejdź do konsoli CodeArtifact, a następnie kliknij Utwórz repozytorium
b) Nadaj mu nazwę i wybierz npm-store jako publiczne repozytorium upsteam
c) Dla domeny Wybierz to konto AWS i wprowadź nazwę domeny
d) Kliknij Dalej, a następnie Utwórz repozytorium
3. Utwórz CI/CD za pomocą CodePipeline
a) Przejdź do konsoli CodePipeline, a następnie kliknij Utwórz potok
b) Wpisz nazwę, pozostaw rolę usługi jako „Nowa rola usługi” i kliknij przycisk Dalej
c) Wybierz AWS CodeCommit jako dostawcę źródłowego
d) Następnie wybierz repozytorium CodeCommit, które utworzyłeś wcześniej, dla gałęzi wybierz główne, a następnie kliknij Dalej
e) Na etapie kompilacji wybierz AWS CodeBuild jako dostawcę kompilacji, a następnie kliknij Utwórz projekt
f) Spowoduje to otwarcie nowego okna w celu utworzenia nowego projektu. Nadaj temu projektowi nazwę
g) Przewiń w dół do sekcji Środowisko: wybierz opcję Zarządzany obraz,
h) W obszarze System operacyjny wybierz „Amazon Linux 2”,
i) Czas pracy „Standardowy”
j) Dla obrazu wybierz aws/codebuild/amazonlinux2-x86+64-standard:4.0 W przypadku wersji obrazu: Zawsze używaj najnowszego obrazu dla tej wersji środowiska uruchomieniowego
k) Wybierz Linux dla typu środowiska
l)Pozostaw opcję Uprzywilejowane niezaznaczoną i ustaw Rolę usługi na „Nowa rola usługi”
m) Rozwiń Dodatkowe konfiguracje i przewiń w dół do sekcji VPC, wybierz żądaną VPC, swoje podsieci (zaleca się wybranie wielu AZ, aby zapewnić wysoką dostępność) i grupę zabezpieczeń (reguły grupy zabezpieczeń muszą zezwalać zasobom, które będą używać punktu końcowego VPC do komunikacji z usługą AWS do komunikacji z interfejsem sieciowym punktu końcowego, jako przykład zostanie tu użyta domyślna grupa zabezpieczeń VPC)
n) Przewiń w dół do Buildspec i wybierz „Użyj pliku buildspec” i wpisz „buildspec.yml” jako nazwę Buildspec
o) Wybierz opcję dzienników CloudWatch, możesz pozostawić nazwę grupy i strumień pusty, co pozwoli usłudze użyć wartości domyślnych i kliknij Kontynuuj do CodePipeline
p) Spowoduje to utworzenie nowego projektu CodeBuild, zaktualizowanie strony CodePipeline. Teraz możesz kliknąć Dalej
r) Ponieważ nie wdrażasz tego w żadnym środowisku, możesz pominąć etap wdrażania i kliknąć „Pomiń etap wdrażania”
s) Po wyświetleniu wyskakującego okienka kliknij pomiń ponownie, zobaczysz stronę recenzji, przewiń do końca i kliknij Utwórz potok
4.Utwórz punkt końcowy VPC dla dzienników Amazon CloudWatch. Umożliwi to CodeBuild wysyłanie dzienników wykonania do CloudWatch:
a) Przejdź do konsoli VPC i z menu nawigacyjnego po lewej stronie wybierz „Punkty końcowe”.
b) kliknij przycisk Utwórz punkt końcowy.
c) Jako kategorię usługi wybierz „Usługi AWS”. Możesz ustawić nazwę nowego punktu końcowego i upewnij się, że używasz czegoś opisowego.
d) Z listy usług wyszukaj punkt końcowy, wpisując logi w pasku wyszukiwania i wybierając ten z com.amazonaws.us-west-2.logs.Ten przewodnik można wykonać w dowolnym regionie obsługującym usługi. Będziesz używać usługi us-west-2, wybierz odpowiedni region dla swojego obciążenia pracą.
e) Wybierz VPC, z którym chcesz powiązać punkt końcowy, i upewnij się, że opcja Włącz nazwę DNS jest zaznaczona w dodatkowych ustawieniach.
f) Wybierz podsieci, z którymi chcesz skojarzyć punkt końcowy i możesz pozostawić grupę zabezpieczeń jako domyślną, a zasady jako puste.
g) Wybierz Utwórz punkt końcowy.
- Utwórz punkt końcowy VPC dla CodeArtifact. W chwili pisania tego artykułu CodeArifact ma dwa punkty końcowe: jeden służy do operacji API, takich jak operacje na poziomie usług i uwierzytelnianie, a drugi służy do korzystania z usługi, takiej jak pobieranie modułów dla naszego kodu. Będziesz potrzebować obu punktów końcowych, aby zautomatyzować pracę z CodeArtifact. Dlatego utworzysz oba punkty końcowe z włączonym DNS.
Dodatkowo będziesz potrzebować punktu końcowego AWS Security Token Service (AWS STS) do wywołania API get-caller-identity:
Podążaj za krokami a-c z kroków, które zostały użyte podczas tworzenia punktu końcowego dzienników powyżej.
a) Z listy usług możesz wyszukać punkt końcowy, wpisując codeartifact w pasku wyszukiwania i wybierając ten z com.amazonaws.us-west-2.codeartifact.api.
Postępuj zgodnie z krokami e-g z części 4.
Następnie powtórz to samo dla usługi com.amazon.aws.us-west-2.codeartifact.repositories service.6. Włącz punkt końcowy VPC dla AWS STS:
Wykonaj czynności a-c z części 4
a) Z listy usług możesz wyszukać punkt końcowy, wpisując sts w pasku wyszukiwania i wybierając ten z com.amazonaws.us-west-2.sts.
Następnie wykonaj kroki e-g z części 4.
- Utwórz punkt końcowy VPC dla S3:
Wykonaj kroki a-c z części 4
a) Z listy usług możesz wyszukać punkt końcowy, wpisując sts w pasku wyszukiwania i wybierając ten z com.amazonaws.us-west-2.s3, wybierz ten z typem Gateway
Następnie wybierz swój VPC i wybierz tabele tras dla swoich podsieci. Spowoduje to automatyczną aktualizację tabeli tras o nowy punkt końcowy S3.8. Teraz mamy ustawione wszystkie punkty końcowe. Ostatnim krokiem jest zaktualizowanie potoku, aby wskazywał repozytorium CodeArtifact podczas ściągania zależności kodu. Jako przykładu użyję CodeBuild buildspec.yml.
Upewnij się, że Twoja rola CodeBuild AWS Identity and Access Management (IAM) posiada uprawnienia do wykonywania akcji STS i CodeArtifact.
Przejdź do konsoli IAM i kliknij Role w menu nawigacyjnym po lewej stronie, a następnie wyszukaj nazwę swojej roli IAM, w Twoim przypadku, ponieważ wybrałeś opcję „Nowa rola usługi” w kroku 2.k został utworzony z nazwą „codebuild-Private-service- rola” (codebuild--service-role)
W menu Dodaj uprawnienia kliknij Utwórz wbudowane zasady
Wyszukaj STS w usługach, a następnie wybierz STS
Wyszukaj „GetCallerIdentity” i wybierz akcję
Powtórz to samo z „GetServiceBearerToken”
Kliknij Przejrzyj, dodaj nazwę, a następnie kliknij Utwórz zasady
Powinieneś zobaczyć nową zasadę wewnętrzną dodaną do listy
W przypadku akcji CodeArtifact zrobisz to samo w tej roli, kliknij Utwórz zasady wbudowane
Wyszukaj CodeArtifact w usługach, a następnie wybierz CodeArtifact
Wyszukaj „GetAuthorizationToken” w akcjach i zaznacz tę akcję w polu wyboru
Powtórz dla „GetRepositoryEndpoint” i „ReadFromRepository”
Kliknij Zasoby, aby naprawić 2 ostrzeżenia, a następnie kliknij Dodaj ARN na pierwszym „Określ ARN zasobu domeny dla akcji GetAuthorizationToken”.
Otrzymasz wyskakujące okienko z polami dla regionu, konta i nazwy domeny, wpisz swój region, numer konta i nazwę domeny, której użyłeś jako „prywatna”, kiedy tworzyłeś swoją domenę wcześniej.
Następnie kliknij Dodaj
Powtórz ten sam proces dla „Określ ARN zasobu repozytorium dla ReadFromRepository i 1 więcej”, i tym razem autorzy podadzą Region, identyfikator konta, nazwę domeny i nazwę repozytorium, użyliśmy „Prywatne” dla repozytorium, które stworzyli wcześniej i „prywatnie” dla domeny
Pamiętaj, że najlepszą praktyką jest określenie zasobu, w który celujesz, możesz zaznaczyć pole wyboru „Dowolny”, ale Twoim celem jest jak najlepiej zawęzić zakres roli IAM.
9.Przejdź do CodeCommit, a następnie kliknij repozytorium utworzone wcześniej w kroku 1
Kliknij na listę rozwijaną Dodaj plik, a następnie przycisk Utwórz plik
Wklej następujące elementy w obszarze edytora:
{
"dependencies": {
"mathjs": "^11.2.0"
}
}
Nazwij plik „package.json”
Dodaj swoje imię i nazwisko, adres e-mail oraz opcjonalną wiadomość dotyczącą zatwierdzenia
Powtórz ten proces dla „index.js” i wklej następujące elementy w obszarze edytora:
const { sqrt } = require('mathjs')
console.log(sqrt(49).toString())
Spowoduje to uruchomienie potoku i rozpoczęcie budowania aplikacji
Jest to bardzo prosta aplikacja, która uzyskuje pierwiastek kwadratowy z 49 i loguje go na ekranie. Jeśli klikniesz link Szczegóły z etapu budowania potoku, zobaczysz wynik działania aplikacji NodeJS, dzienniki są przechowywane w CloudWatch i możesz tam nawigować, klikając link Wyświetl cały dziennik „Showing the last xx lines of the build log. View entire log”.
Użyliśmy przykładu npm w buildspec.yml powyżej, Podobna konfiguracja zostanie użyta dla pip i twine.
W przypadku Maven, Gradle i NuGet musisz ustawić zmienne środowiskowe i zmienić pliki settings.xml i build.gradle, a także zainstalować wtyczkę dla swojego środowiska IDE. Aby uzyskać więcej informacji, kliknij tutaj.
Porządkowanie
Przejdź do punktu końcowego VPC z konsoli AWS i usuń utworzone punkty końcowe.
Przejdź do CodePipeline i usuń utworzony potok.
Przejdź do CodeBuild i usuń utworzony projekt kompilacji.
Przejdź do CodeCommit i usuń utworzone repozytorium.
Przejdź do CodeArtifact i usuń repozytorium oraz utworzoną domenę.
Przejdź do IAM i usuń utworzone role:
W przypadku CodeBuild: codebuild--service-role
Dla CodePipeline: AWSCodePipelineServiceRole--
Podsumowanie
W tym artykule wdrożyliśmy pełny potok CI/CD z CodePipeline koordynującym CodeBuild w celu zbudowania i przetestowania małej aplikacji NodeJS przy użyciu CodeArtifact do pobrania zależności kodu aplikacji. Wszystko to miało miejsce bez wchodzenia do publicznego internetu i utrzymywania logów w CloudWatch.
Źródło: AWS