Jak zbudować aplikację w chmurze i nie użyć ani jednego serwera?

To, co od zawsze mnie "kręciło" w "chmurach" to wcale nie oszczędności. Dużo potężniejsza jest chmura, gdy doświadczy się jej szybkości i łatwość korzystania z usług, z których można zbudować gotowe rozwiązanie. W świecie biznesu, który pędzi i będzie pędził coraz szybciej, możliwość szybszego zbudowania i wydania aplikacji jest kluczowa i może stanowić o realnej przewadze konkurencyjnej. Podkreślam, może. Jak dla mnie, dopiero wtedy można mówić o niższych, łącznych kosztach dostarczenia całości rozwiązania, a nie poszczególnych komponentów aplikacji. Właśnie w tym kontekście chciałbym przybliżyć Wam proces wykorzystania usług, które razem mogę i dla Was stanowić podstawę architektury Waszej aplikacji.

Zanim zacznę - potraktujcie ten wpis jako "spojrzenie z lotu ptaka" na te komponenty, których możecie użyć. Nie wejdziemy tutaj w szczegółowy opis każdego z nich, to zdarzy się w kolejnych wpisach. Nie opiszemy też takich tematów jak skalowanie, monitoring, utrzymanie ciągłości biznesowej czy analiza zdarzeń. Każdy z tych wątków to temat na oddzielny wpis i nie zawsze jeden.

Moim celem jest na dziś jest raczej pokazać Wam paletę możliwości, spróbować musicie już sami.

Serwer aplikacyjny

Zacznijmy od góry. Pierwszy element każdej aplikacji to serwer aplikacyjny.

Do dyspozycji macie Azure App Service albo Azure App Service Environment. Niezależnie od wyboru możecie pisać aplikację w ASP.NET, Node.js, Java, PHP, czy Python. Można też uruchamiać w ramach tego środowiska skrypty PowerShell czy CMD ale to nie jest ich najistotniejsza wartość. Oba te środowiska w warstwie niższej, niedostępnej dla użytkownika chmury, bazują na serwerze IIS zainstalowanym na maszynach z Windows. Natomiast już pojawiła się wersja App Service obsługiwana przez system Linux. Na dziś w tej wersji możecie skorzystać z gotowych kontenerów (i użyć środowisk PHP, Node.JS czy .Net Core), wybrać inny obraz z Docker Hub bądź swoje prywatne repo. App Service czy App Service Environment to nie wszystkie opcje, możecie pomyśleć o wykorzystaniu Service Fabric czy Azure Container Services,  ale te dwa tematy same w sobie wystarczają na wiele kolejnych wpisów na blogu.

O różnicach pomiędzy App Service i App Service Environment opowiadałem w czasie spotkania Microsoft Azure User Group. Bardzo robocze slajdy, które służyły tylko jako uzupełnienie, można zobaczyć na docs.com. Najważniejsze wyróżniki omawiane są tu ASE.

Z perspektywy architekta proponuję zapamiętać dwa kluczowe elementy: ASE używamy wtedy, gdy potrzebna jest nam duża wydajność oraz duża skala rozwiązania , a także wtedy, gdy chcemy mieć precyzyjny wpływ na ruch sieciowy w naszym środowisku. Dlaczego tak?

ASE bowiem zawsze jest uruchamiane w ramach dedykowanego VNET'u i wybranego subnet'u. Wy odpowiadacie za to, jaki ruch wejdzie do serwera aplikacyjnego a jaki nie i to na poziomie sieci. Co więcej, macie gwarancję publicznego stałego, adresu IP lub wielu publicznych adresów i możecie pokusić się o tzw. IP SSL Binding, co pozwala decydować o ruchu sieciowym per opublikowana usługa. Przy dużej ilości niepożądanego ruchu do Waszej strony, możecie go zablokować na warstwie sieci zanim jeszcze on dotrze do serwerów aplikacyjnych. W przypadku App Service jedynym ratunkiem jest wpisanie niepożądanych adresów w Web.config aplikacji, ale wtedy to serwer aplikacyjny blokuje takie połączenia a nie sieć, co zwiększa jego utylizację.

Element skalowalności również jest istotny. W ramach Azure App Service maksymalna liczba instancji, jaką możecie wykorzystać to 20, w przypadku ASE jest to 50, w tym dedykowane instancje na Load Balancer, które wstępują w tzw. Front End Pool. W oddzielnym poście postaram się pokazać moje wyniki testów wydajnościowych pomiędzy obiema platformami.

Oczywiście nie ma nic za darmo, bazowe środowisko ASE będzie Was kosztowało ok. 1100$ miesięcznie. Takie ASE ma dwie instancje do Load Balancingu (Front End Pool o wielkości P2, nie można ich zmniejszyć) oraz dwie instancje, na których jest aplikacja (Worker Pool 1, o wielkości P1). Co więcej, skalowanie środowiska App Service Enviroment jest dużo wolniejsze niż App Service, ponieważ jest to środowisko dedykowane, pracujące na maszynach, powołanych tylko dla Waszych potrzeb. Oficjalne blogi Microsoft'u powołują się na czas ok. 2 godzin, tyle samo czasu pokazuje portal Azure, efektywnie ostatnio jest to nie więcej niż 45 min. Oznacza to jednak, że proces skalowania nie może być dynamiczny, automatyczny, raczej polega na regułach i okresach, które sami ustalicie.

Aktualnie też na ASE nie można wdrażać Azure Functions i nie można wybrać Linux'a jako systemu operacyjnego (obie funkcje są na mapie rozwoju grupy produktowej, co więcej Chris Anderson, który opowiada za Functions i Christina Compy, która odpowiada za ASE są razem w grupie App Service). Poza tym, proces wdrażania rozwiązania, działania oraz monitorowania jest taki sam.

Jeśli skala, precyzyjna kontrola ruchu sieciowego czy wydajność nie jest Twoją potrzebą teraz ale również w przyszłości (czy na pewno?), wtedy wybierz App Service.  

Zmiana decyzji później jest możliwa. Wymaga nieco zaplanowania App Service Planów, zmian w tzw. Publishing Profiles oraz ustawienia App Settings ale poza tym różnic w działaniu samego rozwiązania nie ma.

Rozpoczęcie przygody z usługą jest proste i można zacząć ją przechodząc prosty tutorial lub oglądając Kamila Brzezińskiego, który pokazuje jak stworzyć prostą stronę.

Pojemniki na dane

Celowo napisałem pojemniki a nie bazy, bo nie zawsze Wasze rozwiązanie potrzebuje bazy danych. Być może wystarczy składowanie danych w postaci binarnej czy zwykła kolejka. Pomyślcie i o tych rozwiązania, mogą się okazać niezwykle tanie.

Jeśli jednak potrzebujecie bazy, to pierwszy dylemat architekta to wybór pomiędzy bazą relacyjną (np. Azure SQL, MySQL) a bazą nierelacyjną, typu NoSQL (np. DocumentDB, MongoDB). Pamiętajcie, że cały czas mówię tylko o usługach dostępnych w PaaS (Platform as a Service). Zakres dostępnych baz jest o wiele szerszy, ale wtedy musimy korzystać z baz instalowanych w ramach maszyn wirtualnych (IaaS).

Różnic pomiędzy typami baz jest wiele ale kilka należy podkreślić i zaznaczyć, szczególnie jest dopiero aplikację projektujecie.

1.Jeśli wybierasz bazę NoSQL nie oczekuj, że łatwo zbudujesz w niej relację.

Niby oczywiste, bazy NoSQL nie są od tego by projektować w nich relację. O tym jedna zdarza nam się zapominać na etapie projektowania i patrzymy tylko na wygodę zapisywania obiektów typu JSON, brak wymagań co do zawartości obiektów i potencjalnie, łatwe i nieograniczone skalowanie.

W jednym z projektów, klient zdecydował na początku, że dane o ofertach sklepu będzie trzymał w DocumentDB. Późniejsze wymagania biznesu jednak wymagały relacji pomiędzy sklepami, ofertami, kupującymi ect. wtedy plusy już nie przysłoniły minusów. Oczywiście budowanie tych relacji na poziomie soft'u nie jest niemożliwe, za to pojawiają się problemy doboru index'u, problem dużych zbiorów, powstałych przez iloczyn kartezjański i inne. Sama baza tych relacji nie zapewnia i developer musi o nie zadbać w procesie CRUD. Postaram się w jednym z postów pokazać podejście do nakładania indexów na bazę DocumentDB, które potrafią dla jednego zapytania zmniejszyć jego koszt ponad 40 krotnie. Więcje o indeksach w tym wpisie.

2.Jeśli w Twojej aplikacji, istotne jest dla Ciebie struktura danych i chcesz, by sam silnik bazy o nią dbał, to wybierz bazę typu SQL. Bazy NoSQL dają Ci wolność, nie musisz zachowywać struktury, nie dotyczą Ciebie żmudne migracje ale właśnie kosztem tego, jest fakt, że o strukturę musisz zadbać sam.

Ma to oczywiście potem konsekwencje przy raportowaniu danych z takiej bazy. Jest to możliwe ale ani zakres dostępnych narzędzi ani ich metoda wykorzystania nie są jeszcze bardzo dojrzałe. Niektórzy eksportują dane z baz dokumentowy do silników typu Hadoop i tam budują raporty. Drugim elementem, związanym z schematem są funkcje agregujące. Na teraz ich zestaw jest nieco ograniczony, można pisać własne za pomocą JavaScript, ale nie skalują się jeszcze idealnie. Jeśli ktoś z Was będzie miał tutaj wyzwania, pomogę. Dwie ważne referencje: raporty w PowerBI dla DocumentDB, funkcje agregujące w DocumentDB.

3. Piszesz "grę dla całego świata" i potrzebujesz silnika danych, który ją będzie wspierał? Bazy dokumentowe z reguły łatwiej dzielić na małe kawałki i skalować. Warto poczytać o metodzie "partycjonowania" czy "sharding'u" dla Document DB oraz dla Azure SQL. Sam "sharding" nie jest domeną tylko baz NoSQL ale skalowanie i działanie w ramach wielu regionów świata już tak. Co więcej, dla baz typu DocumentDB, jest to praktycznie jedyny model osiągania dużej skali, więc wybierając taką bazą od razu planuj jak korzystać z shardów. Pojedyncza kolekcja DocumentDB bez shardów portafi dostarczyć maksymalnie 10 000 RU/s.

Jeśli nadal po przeczytaniu tych różnic nie wiesz, co wybrać, generalna reguła mogłaby być taka. Jeśli Twoje dane, które będziesz przechowywał w aplikacji, silnie od siebie zależą a co więcej, nie piszesz aplikacji dla "całego świata" i nie umiesz wyobrazić sobie architektury z wieloma niewielkimi bazami danych, najprawdopodobniej baza typu Azure SQL jest dla Ciebie. Jeśli jednak, przechowywane dane są mocno niezależne, mogą szybko zmieniać swoją strukturę (budujesz drugiego Twittera lub Facebook'a albo grę), będzie mógł łatwo wprowadzić koncepcję, jedna kolekcji danych per klient czy grupa klientów, to wtedy raczej szukasz bazy dokumentowej.

"Who is who" czyli co zrobić z tożsamością

Jeśli już uporaliśmy się z wyborem serwera aplikacyjnego, środowiska, języka, i wiecie, gdzie będziecie trzymać dane, to przyszedł czas na kolejny, kluczowy do rozstrzygnięcia element. Gdzie i jak będziesz przechowywał użytkowników swojej aplikacji, nimi zarządzał i jakie możliwości samoobsługi zaproponujesz. I tu wybór jest ciekawy.

Co mamy w menu:

1) Azure Active Directory 

2) Azure Active Directory Services

3) Azure Active Directory B2C

4) Azure Active Directory B2B

5) Usługa Active Directory na Azure VM 

A mówią, że od przybytku głowa nie boli a tu nagle pojawia się 5 sposobów na przechowywanie tożsamości użytkownika. Prawdą jest, że każda ma nieco inne przeznaczenia i postaram się je tutaj omówić.

Jeśli Wasza aplikacja nie powstała w chmurze, swój żywot poczęła w lokalnych DC i korzystała standardowego Active Directory, to teraz w świecie chmury, może nadal korzystać z tego typu katalogu. Taka aplikacja rozumie Windows Authenticaion ale już nie koniecznie wie czym jest OAuth2.0. Wtedy przyda Wam się standardowy katalog zainstalowany na maszynie wirtualnej, patrz pkt. 5. Jedną z takich aplikacji jest np. SharePoint 2013. Co prawda, może równie dobrze pracować z Azure AD dzięki dodatkowemu komponentowi  ale jednak pełen katalog jest jego naturalnym przeznaczaniem.

Co więc zrobić maszynami wirtualnym w Azure, do których dostęp powinny mieć osoby tylko z katalogu Azure AD? Czy można nie korzystać z kont lokalnych? Z pomocą przychodzi pkt. 2 czyli usługa Domain Services, która w wybranych przez Was VNET'ach pozwoli Wam podłączyć maszyny do Azure AD. Otrzymacie usługi katalogowe zgodne z LDAP i możliwości wykorzystania Kerberosa. Efektywnie chmura w danym VNET rezerwuje sobie pewien zakres adresów i wdroży maszynę wirtualną, do której użytkownik usługi nie ma żadnego dostępu i za działanie usługi odpowiada Microsoft.

Co innego, jeśli Wasza aplikacja powstaje w chmurze i będzie prezentowana w Internecie, wtedy naturalnym miejsce składowania tożsamości jest Azure Active Directory, które z tradycyjnym Active Directory ma wspólną nazwę. Jest to katalog użytkowników, grup ale też kont usługowych, przeznaczonych do wykonywania konkretnych czynności w Azure (Azure Automation). Nie jest to miejsce na składowanie polityk, wszystkich komputerów czy drukarek. Azure Active Directory jest katalogiem skierowanym na użytkownika aplikacji. Dokładnie o możliwościach, które są nie małe, postara się napisać Piotr Boniński w innym poście.

I teraz dochodzimy do dwóch odmian Azure AD czyli B2C oraz B2B. Różnica między nimi jest zasadnicza i można ją sprowadzić do stwierdzenia: jeśli wszyscy użytkownicy, korzystający z Twojej aplikacji w chmurze znajdują się w Twoim katalogu i nie robisz integracji z kontami sieci społecznościowych, to wtedy odmiany B2C czy B2B w ogóle Cię nie interesują.
Jeśli jednak chcesz pozwolić użytkownikowi na zakładanie konta i logowanie się jego tożsamością z LinkedIn, Facebook, Google czy Amazon wtedy Azure AD B2C jest Twoim przyjacielem. Tak naprawdę Azure AD B2C jest swego rodzaju proxy, Twoja aplikacja integruje się tylko z B2C, a B2C już martwi się oto, jak tożsamość z  innego katalogu, traktować w jeden i ten sam sposób. I to jest chyba największa zaleta katalogu, że integracja jest po stronie dostawcy. Możesz napisać też własnego dostawcę tożsamości (custom IdP) i zintegrować aplikację biznesową. Co więcej B2C dzięki tzw. politykom (singin, signup policy) daje wiele gotowych ekranów od razu, takich jak choćby ekran utworzenia konta, logowania czy resetu hasła. Na dziś te ekrany można w dużej mierze dostosowywać poprzez elementy graficzne oraz CSS, w przyszłości pojawi się też JavaScript. Są też biblioteki na platformy mobilne, iOS oraz Android, co pozwala na natywną integrację aplikacji mobilnej.

B2C załatwia jeszcze jeden, bardzo istotny a chętnie pomijany przez twórców aplikacji element. B2C jest gotową i dobrą implementacją OAuth2.0 oraz OpenID. I jest to bardzo istotne jeśli zależy nam na branżowym standardzie zaimplementowanym w bezpieczny sposób, który np. dba o wymianę i odświeżanie tokenów czy utworzenie nowego tokena, jeśli poprzedni wygasł. Implementacja integracji z każdym z tych dostawców tożsamości wcale nie jest trywialną zabawą, jeśli chcieć to pisać samemu.
O Azure AD B2C mówiłem w trakcie spotkania Microsoft Azure User Group. Temu rozwiązaniu też przyda się oddzielny wpis, pokazujący co i jak warto wykorzystać na bazie dwóch moich wdrożeń. Pierwszy tips&trick o B2C pojawił się na moim blogu. Będzie ich więcej.

I na koniec zostało B2B, które tak naprawdę nie jest innym typem katalogu. Jeśli zależy Ci na wykorzystaniu tożsamości z różnych katalogów Azure AD aby przyznawać dostęp do aplikacji to rozwiązanie B2B może okazać się dla Ciebie. Nie mam praktycznych doświadczeń z wykorzystaniem tego, więc znowu poproszę Piotra Bonińskiego, by ten świat nam przybliżył.

Wybaczcie długość. Przy następnym wpisie postanawiam poprawę! Będziemy kontynuować wątek usług PaaS.