Azure: VNET integration for Functions

2023-10-21

Funkcje, czyli z grubsza rzecz biorąc, główni reprezentanci linii serverless w Azure (FunctionApp i LogicApp) mogą łączyć się z siecią w trzech płaszczyznach:

  • przez adres publiczny – jeśli aplikacja jest udostępniona publicznie
  • przez private endpoint – co jest wykorzystywane do połączenia się do funkcji (klient chce skorzystać z funkcjonalności funkcji, więc łączy się do jej endpointa
  • przez integration subnet – ten rodzaj połączenia jest wykorzystywany przez funkcję, kiedy chce ona „wyjść na zewnątrz”, np. w celu skorzystania z innych zasobów, które są potrzebne do działania tej funkcji.

Integration subnet nigdy nie jest wykorzystywane do połączenia się do funkcji. Nawet jeśli do integration subnet podłączysz NSG z regułami inbound, to zostaną one zignorowane, bo ruch przychodzący po prostu nie działa. Jedynym wyjątkiem są pakiety transferowane w ramach odpowiedzi na komunikację wychodzącą z funkcji, ale to zrozumiałe, bo bez tego komunikacja nie miałaby sensu.

Dzięki sprytnemu połączeniu ręcznie konfigurowanego routingu, NSG, integracji z Firewallem i innych mechanizmów konfiguracji sieci, administrator ma szeroki zakres możliwości definiowania jakie połączenia mogą być nawiązywane przez funkcje, np.: korzystanie z zasobów lokalnych sieci, połączenie do on-prem, połączenia z express route, innymi endpointami, wyjście do Internetu itd.

Do wykonania konfiguracji NSG może się przydać znajomość prywatnego adresu IP funkcji w integration subnet. Jest on zapisany w zmiennej środowiskowej WEBSITE_PRIVATE_IP.

Ruch sieciowy generowany przez funkcję podlega normalnym regułom. Jeśli np. chcesz przesłać pakiety do gateway’a, wystarczy odpowiednio zmodyfikować trasy routingu przypisane do podsieci.

Co ciekawe, application plan bazujący na windows, może się integrować z dwiema podsieciami, a na linux, tylko z jedną.

Sam routing to również ciekawa sprawa, bo można go konfigurować w trzech zakresach:

  • Routing aplikacyjny – określa, co ma sie stać z ruchem generowanym przez działającą aplikację. Może sięgać tylko do zasobów lokalnych, albo wychodzić na zewnątrz
  • Routing konfiguracyjny – określa, jak należy wykonywać routing przed uruchomieniem aplikacji, co jest wymagane np. do wykonania operacji pull image for container. Domyślnie komunikacja jest wykonywana przez połączenie publiczne, jeśli ma być inaczej, to wymagana jest zmiana. Jeśli funkcja ma sięgać do Key Vault po zapisane tam sekrety, które mają być np. używane w konfiguracji funkcji, to jeśli taka publiczna komunikacja jest zablokowana, to funkcja podejmuje próbę połączenia przez integration subnet
  • Routing sieciowy – pozwala na zdefiniowanie konkretnych tras. Generalnie, ruch wychodzący z funkcji podlega wszystkim normalnym zasadom routingu, które przynajmniej częściowo można tutaj zdefiniować.

Z drugiej strony private endpoint, pozwala na połączenie się do usługi. Endpoint jest podłączony do wybranej podsieci, otrzymuje swój adres IP, a ten adres powinien być zarejestrowany w DNS. Dzięki temu wybrane usługi będą mogły połączyć się do funkcji i skorzystać z jej funkcjonalności.

Integrate your app with an Azure virtual network – Azure App Service | Microsoft Learn

By Rafał Kraik in Azure

Terraform: Importowanie zasobu tworzonego przez for_each

2023-10-12

Opss. terraform się wywalił i w efekcie, część zasobów została utworzona w Azure, ale plik stanu nie został zaktualizowany. W takim przypadku otrzymsz błąd:

Error: A resource with the ID „/subscriptions/XXXX/resourceGroups/RG-TerraformLab/providers/Microsoft.Network/virtualNetworks/KRK-VNET/subnets/dev_subnet” already exists – to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for „azurerm_subnet_network_security_group_association” for more information.

No tak, to problemy mam dwa: 1 – zaimportowanie obiektu tworzonego przez for_each i 2 – próbuję utworzyć zasób azurerm_subnet_network_security_group_association, tymczasem brakujący obiekt to po prostu azurerm_subnet.

Na szczęście komunikat o błędzie zawiera już prawie wszystko, co trzeba. Rzeczywiście polecenie import oczekuje dwóch parameterów. Nazwy zasobu tak jak jest ona zdefiniowana dla Azure oraz identyfikatora zasobu. Na dodatek, to właśnie obiekt subnet zawiera w sobie informacje o association, więc w sumie, to problemu nie ma. No to jedziemy:

terraform import azurerm_subnet_network_security_group_association.sub_nsg["dev_subnet"] /subscriptions/XXXX/resourceGroups/RG-TerraformLab/providers/Microsoft.Network/virtualNetworks/KRK-VNET/subnets/dev_subnet

Niestety – komenda u mnie nie działa dobrze:

Index brackets must contain either a literal number or a literal string.

No jak to!? Przecież mam „literal string”. O co chodzi? Chodzi o to, że jestem fanem powershella i pracuję w powershellu. Tutaj poprawna komenda to:

terraform import azurerm_subnet_network_security_group_association.sub_nsg[\`"dev_subnet\`"] /subscriptions/XXXX/resourceGroups/RG-TerraformLab/providers/Microsoft.Network/virtualNetworks/KRK-VNET/subnets/dev_subnet

Uff – udało się!

By Rafał Kraik in Azure

Helpdesk: RDP: The credentials supplied to the package were not recognized

2023-10-04

Świeżo utworzona maszyna w Azure, z Windows na pokładzie. Błąd przy logowaniu:

An authentication error has occurred. The credentials supplied to the package were not recognized

No cóż… pamięć już nie taka, ale przecież hasło wprowadzam dobre! Okazuje się, że nazwę logowania podawałem po prostu w postaci <username>. W takim przypadku Azure czasami trochę wariuje i nie wie, w jakim kontekście zinterpretować nazwę użytkownika.

Zmień nazwę na:

AzureAD\username – jeśli to logowanie ma się wykonać w kontekście użytkownika Azure AD

lub

.\username – jeśli to logowanie na zwykłego użytkownika

I już!

By Rafał Kraik in Helpdesk

Git: Duplikacja repozytorium

2023-09-12

Zdarza się, że chcesz stworzyć kopię repozytorium, która ma zacząć żyć swoim własnym życiem. W takim przypadku:

1 – Sklonuj repozytorium na swój komputer:

git clone --bare https://github.com/my-user/old-repo.git

2 – Przejdź do katalogu ze skolonowanym repozytorium i wyślij je do nowego repozytorium:

cd old-repo.git
git push --mirror https://github.com/EXAMPLE-USER/NEW-REPOSITORY.git

3 – Repozytorium jest już na miejscu! Jeśli chcesz, to usuń kopię z lokalnego komputera

Jeśli oryginalne repozytorium jest duże (zawiera np. również pliki binarne to posłuż się metodą opisaną tutaj:
https://docs.github.com/en/repositories/creating-and-managing-repositories/duplicating-a-repository#mirroring-a-repository-that-contains-git-large-file-storage-objects

By Rafał Kraik in Git

Azure: Wygodne sprawdzenie tagów

2023-09-07

Ech ci księgowi… zawsze chcą wiedzieć co jest czyje, żeby dobrze rozliczyć koszty, a do tego są im potrzebne tagi. Oczywiście przy tagowaniu najlepiej sprawdzi się jakiś rodzaj automatyzacji, ale jeśli trzeba coś po prostu na szybko zobaczyć, to może się przydać wbudowana funkcjonalność portalu Azure.

Będąc w portalu przejdź do Manage view –> Edit columns:

Następnie w oknie dodaj kolumnę tags:

Jeśli miałoby się okazać, że jakiś zasób nie ma tagów, skorzystaj z przycisku z trzema kropeczkami przy tym zasobie. Jest tam polecenie Edit tags:

By Rafał Kraik in Azure

Helpdesk: Audacity: Skrót do polecenia w menu

2023-09-06

Pracuję intensywnie z Audacity i często korzystam z tych samych poleceń. Ponieważ Audacity jest sporym programem z wieloma opcjami, to wybór tej właściwej z menu nie jest wygodny. Za to można skonfigurować skróty klawiaturowe, które znacznie przyśpieszą pracę. Oto jak:

Przejdź do opcji programu wybierając Edit –> Preferences. Tutaj:

  • Kliknij na Keyboard [1]
  • Upewnij się, że masz wybrane View by: Tree [2]
  • Wyszukaj pozycji z menu lub wpisz fragment nazwy w polu Search [3]
  • Kliknij pozycję, dla której chcesz przypisać skrót [4]
  • Naciśnij kombinację klawiszy [5] i potwierdź klawiszem Set [6]. Jeśli wybrany skrót był już przypisany do innego polecenia, to zobaczysz ostrzeżenie i możliwość rezygnacji przy pomocy Cancel. Jeśli chcesz zmienić działanie skrótu, po prostu potwierdź decyzję.
  • Zamknij okno klawiszem OK [7]. I to wszystko!

By Rafał Kraik in Helpdesk

Terraform: „Error parsing Resource ID {resourceid} ID was missing the `resourcegroup` element”

2023-08-14

Zdarza sie, że do terraformowej definicji trzeba zaimportować istniejące już na Azure obiektu. Służy do tego polecenie import:

terraform import azurerm_recovery_services_vault.vault1 /subscriptions/XXX/resourcegroups/recovery-delme/providers/Microsoft.recoveryservices/vaults/recoservvault

Co zrobić jeśli komenda zakończy się błędem?

azurerm_recovery_services_vault.vault1: Importing from ID "/subscriptions/XXX/resourcegroups/recovery-delme/providers/Microsoft.recoveryservices/vaults/recoservvault"…
data.azurerm_resource_group.example: Reading…
data.azurerm_resource_group.example: Read complete after 0s [id=/subscriptions/XXX/resourceGroups/recovery-delme]

│ Error: parsing "/subscriptions/XXX/resourcegroups/recovery-delme/providers/Microsoft.recoveryservices/vaults/recoservvault": parsing segment "staticResourceGroups": parsing the Vault ID: the segment at position 2 didn't match

│ Expected a Vault ID that matched:

│ > /subscriptions/XXX/resourceGroups/example-resource-group/providers/Microsoft.RecoveryServices/vaults/vaultValue

│ However this value was provided:

│ > /subscriptions/XXX/resourcegroups/recovery-delme/providers/Microsoft.recoveryservices/vaults/recoservvault

│ The parsed Resource ID was missing a value for the segment at position 2
│ (which should be the literal value "resourceGroups").

O co chodzi? Pierwsza różnica, jaką widać dotyczy nazwy resourceGroups, raz napisaną przez małe, a raz przez wielkie „G”. Rzeczywiście. Terraform, a może dokładniej ARM jest czuły na wielkość liter. Wystarczy zapisać resourceGroups tak, jak chciałby Terraform i wszystko zadziała jak należy!

By Rafał Kraik in Azure