Azure Storage jest jedną z najpopularniejszych usług wewnątrz chmury Azure. W przypadku rozwiązań analitycznych bez względu na dobór poszczególnych usług to właśnie Azure Storage zaimplementowany jako hierarchiczna struktura zoptymalizowana pod workload analityczny (Data Lake) niemal zawsze występuje na diagramach analitycznych tworzonych przez nas rozwiązań. Sposobów uwierzytelnienia do tej właśnie usługi jest kilka od tych najbardziej prefereowanych czyli takich które opierają się o Azure Active Directory jak i tych, które może nie są tak bezpieczne ale nadal znajdują zastosowanie jak chociażby Access Key. W ramach dzisiejszego artykułu powiemy sobie o tych mniej bezpiecznych rozwiązaniach czyli tych opartych o klucze dostępowe oraz o tym jak tego typu klucze odświeżać.
Access Key bardzo często kojarzy się nam z domyślnym sposobem uwierzytelnienia do rozwiązań storage’owych. Są bardzo proste w użyciu i raczej nikomu kto ma zacząć ich używać nie trzeba tłumaczyć w jaki sposób ich użyć i jakie jest ich przeznaczenie. Jak wspomniałem we wstępie preferowaną metodą mimo wszystko powinny być metody uwierzytelniające oparte o AAD jak np. Managed Identity jednakże zdarza się, iż musimy nadać dostęp spoza naszego tenanta lub po prostu musimy posłużyć się najprostszym z możliwych rozwiązań = wtedy też z pomocą przychodzą nam rzeczone Access Key lub sygnatury SAS. Jeśli zdecydowaliśmy się na to, że będziemy używać tego typu podejścia to obligatoryjną częścią nasze procesu utrzymania rozwiązania była regeneracja tych właśnie kluczy bo właśnie z kluczami jest jak z hasłami czyli cyklicznie powinny być zmieniane co według moich obserwacji wcale nie jest przestrzegane zawsze i wszędzie. Dlatego też postanowiłem dziś napisać kilka słów o tym w jaki sposób można podejść do zagadnienia przy wykorzystaniu REST API oraz Data Factory. Prewencyjnie chciałem zauważyć, że problem można rozwiązać na kilka różnych sposobów jak to bywa w Azure, a ja przedstawiam tylko jeden z nich.
Na samym początku powiedzmy sobie, że nasz klucz dostępowy będzie przechowywany w Azure Key Vault do którego będą się podłączać poszczególne usługi klienckie mają korzystać z Azure Storage przy pomocy Access Key. W tym właśnie AKV mamy sekret z właściwością naszego rozwiązania:
To właśnie do tego AKV będziemy wstawiać nowe, aktualizowane klucze i to właśnie tutaj będą łączyć się aplikacje klienckie mające do takiego storage mieć dostęp po kluczu. Powyższy sekret będzie ustawiany przez instancję ADF, którą wcześniej stworzyłem – musimy jedynie zadbać aby jej tożsamość (Managed Identity) była dodana do Access policies wewnątrz AKV czyli innymi słowy aby Data Factory mógł dostać się do Key Vaulta i ustawić tam wartość odświeżonego klucza. Aby nadać to uprawnienie należy w znaleźć interesujący nas AKV i tam pod Access Policy dodać naszego ADFa – potrzebne uprawnienia to:
- Get
- List
- Set
W ramach pipeline wewnątrz ADF nasz pierwszy krok będzie odpowiedzialny za pobranie obu kluczy związanych ze Storage Accountem – url tego requesta wygląda następująco:
https://management.azure.com/subscriptions/34a66411-9960-4c58-a9f2-ac157d5cc3d7/resourceGroups/myrg/providers/Microsoft.Storage/storageAccounts/mystorage/listKeys?api-version=2021-04-01
gdzie:
- 34a66411-9960-4c58-a9f2-ac157d5cc3d7 – identyfikator subskrypcji
- myrg – nazwa resource group
- mystorage – nazwa storage account
wykonywana operacja to listKeys.
Sam Web Activity wygląda następująco:
Na powyższym zrzucie warto zwrócić uwagę, że metodą jest POST, a Resource to https://management.azure.com.
Powyższa aktywność zwraca następującą informację:
{ "keys": [ { "creationTime": "2021-12-07T20:35:38.3729618Z", "keyName": "key1", "value": "zsoYu+UmVvyD8oLkHQjrOsgsme+sQ9ZrAOIywVIGzrgbC6F9Z+qp9HQ5DkNMwjJEz0ifMRFZyHR7/lzxSLSl6w==", "permissions": "FULL" }, { "creationTime": "2021-12-07T20:35:48.4667613Z", "keyName": "key2", "value": "ngHBpx46eLLC4AkW+WUICttksDfgyxfjPVpkvoZ5NjyJMnHW+LDlzf/8hh5poLU577I3VxXhweBoAN0tM7NRR5A==", "permissions": "FULL" } ],
Mamy oba klucze Access Key dostępne w ADF. Ogólnie dane zwrócone w ten sposób powodują, że w logach będziemy mieli informację o wartościach kluczy co nie powinno mieć miejsca. Aby temu zapobiec na każdej aktywności, która działa na wszelkiego rodzaju sekretach albo niejawnych wartościach powinniśmy zaznaczyć opcje Secure output oraz Secure input:
Przechodząc dalej kolejnym krokiem jest wstawienie do Key Vaulta wartości klucza Access Key nr 2 ponieważ w tym czasie Access Key nr 1 będzie odświeżany, a chcemy zapewnić ciągłość działania aplikacji. Wstawienie wartości do AKV również będzie polegać na wykonaniu requesta przez Web Activity. Url do wykonania tej czynności wygląda następująco:
https://keyvaultName.vault.azure.net/secrets/mysecret?api-version=7.2
gdzie:
- keyvaultname – nazwa key vaulta
- mysecret – nazwa sekretu
aby podmienić wartość w AKV musimy w Body wysyłanego przez nas żądania przekazać odpowiedniego JSONa, który w moim przypadku wygląda następująco:
@concat(‘{“value”:”‘,activity(‘Get Storage Access Keys’).output.keys[1].value,'”}’)
przekazujemy zatem wartość klucza zwróconego przez poprzedni krok. Sama konfiguracja aktywności wygląda następująco:
W tym momencie w AKV mamy podmienioną wartość sekretu na Access Key 2, możemy zatem przejść do rotacji klucza Access Key 1. Tą operację również wykonamy przez REST API – w tym wypadku URL przedstawia się następująco:
https://management.azure.com/subscriptions/34a66411-9960-4c58-a9f2-ac157d5cc3d7/resourceGroups/myrg/providers/Microsoft.Storage/storageAccounts/mystorage/regenerateKey?api-version=2021-04-01
gdzie:
- 34a66411-9960-4c58-a9f2-ac157d5cc3d7 – identyfikator subskrypcji
- myrg – nazwa resource groupy
- mystorage – nazwa storage account
W body przekazujemy informację, który klucz rotujemy:
{“keyName”:”key1″}
Po wykonaniu powyższych czynności mamy odświeżony klucz Access Key 1 dlatego też w dalszej części możemy podstawić do AKV jego wartość i przejść do odświeżenia klucza Access Key 2. Te operacje są już analogiczne do tego co wyż już przedstawiłem z tym, że podmieniamy klucz tym razem Access Key 2.Cały flow wygląda następująco:
Jeśli chcecie się upewnić, że wszystko poszło zgodnie z planem warto zajrzeć do Activity Loga określonego Storage Account gdzie powinniśmy zobaczyć informację o tym, że klucze były listowane oraz regenerowane:
Podobną informację możemy znaleźć w Key Vault gdzie widoczna jest informacja kiedy została wstawiona określona wersja sekretu:
Oczywiście analogiczny efekt możemy wykonać z poziomu innych narzędzi takich jak Azure Automation czy chociażby Logic Apps. Wybór tego w którym miejscu chcemy wykonać tego typu operację zależy od konkretnego scenariusza więc nie ma tutaj jakiejś złotej zasady. W moim przypadku nieco łatwiej obsłużyć jest monitorowanie oraz obsługę błędów w łaśnie w Azure Data Factory ale to wcale nie znaczy, że inne podejścia są złe.
Na ten moment to by było wszystko, do usłyszenia!
- Avoiding Issues: Monitoring Query Pushdowns in Databricks Federated Queries - October 27, 2024
- Microsoft Fabric: Using Workspace Identity for Authentication - September 25, 2024
- Executing SQL queries from Azure DevOps using Service Connection credentials - August 28, 2024
Last comments