Cześć. Dzisiejszy post nie był absolutnie planowany i nie powstałby, gdyby nie dwaj koledzy: Karol i Kacper, którym przy tej okazji dziękuję.
A wszystko zaczęło się, kiedy na grupie Microsoft Azure User Group, padło proste pytanie: Jak sprawdzić ile zajmują dane w chmurze? A co gdybym chciał mieć historię i jeszcze do tego narysować wykres w czasie?
Koncepcja jest super prosta i do jej realizacji potrzebujemy:
1. Bazy, gdzie zapiszemy wielkość kont :na dziś” i dzięki której, narysujemy wykresy.
Wybrałem Azure SQL, może być dowolna, do której umiesz pisać i czytać. Azure SQL ma jeszcze jedną zaletę, najtańszy kosztuje 4.99$ za miesiąc (albo przy 32MB pojemności, dokładnie 0$).
2. Kawałek kodu, który uruchomi się raz dziennie, odczyta wielkość wszystkich kont i kontenerów a wynik zapisze do bazy.
Wybrałem Azure Automation i PowerShell, też dlatego, że miałem gotowy kod. No i Azure Automation do 500 minut wywołań w miesiącu jest za darmo a kolejne 1000 minut kosztuje 2$.
To samo można zrobić używając Azure Functions, które można uruchomić raz dziennie, używając ulubionego języka programowania. Za 31 wywołań w miesiącu też nie zapłacimy majątku.
Jeśli masz ochotę zobaczyć jak to zbudować krok po kroku – zapraszam:)
- Tworzymy prostą bazę Azure SQL, możesz wykorzystać taką, którą już masz. Potrzebna nam jest słownie jedna tabela.
2. W ramach bazy, musisz stworzyć tabelę, która będzie zbierała nasze dane. Możesz to zrobić wprost z portalu.
Moja propozycja tabeli wygląda tak, zbieram nazwę konta, nazwę kontenera, datę aktualizacji danych oraz wielkość. Koncepcję można dalej rozszerzać.
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[StorageAccountsMetrics]( [Name] [nvarchar](50) NOT NULL, [Id] [int] IDENTITY(1,1) NOT NULL, [Container] [nvarchar](50) NOT NULL, [Date] [datetime] NULL, [Size] [float] NOT NULL, CONSTRAINT [PK_StorageAccounts] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ) GO
Poprawnie wykonane polecenie powinno wyglądać tak:
3. Na koniec warto pobrać ConnectionString do bazy, którego użyjemy w swoim skrypcie.
Mamy już bazę danych, teraz czas na skrypt.
4. Jeśli jeszcze nie korzystasz z usługi Azure Automation to czas stworzyć sobie jedną z nich. Odszukaj na liście usług Automation Accounts, wybierz Add, podaj podstawowe parametry i gotowe.
5. Teraz czas na utworzenie nowego Runbook’a.
6. Kod runbooka nie jest specjalnie skomplikowany i bazuje na przykładzie, który pokazywałem w innym wpisie.
Gotowy skrypt niżej. Zwróć uwagę na dwa miejsce.
- Upewnij się, że masz poprawny ConnectionString
- Upewnij się, że Twoje polecenie INSERT zawiera poprawną nazwę tabeli i parametry podane w odpowiedniej kolejności
# # Connect to Azure Services # $connectionName = "AzureRunAsConnection" try { # Get the connection "AzureRunAsConnection " $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName "Logging in to Azure..." Add-AzureRmAccount ` -ServicePrincipal ` -TenantId $servicePrincipalConnection.TenantId ` -ApplicationId $servicePrincipalConnection.ApplicationId ` -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint } catch { if (!$servicePrincipalConnection) { $ErrorMessage = "Connection $connectionName not found." throw $ErrorMessage } else{ Write-Error -Message $_.Exception throw $_.Exception } } # # Get all the accounts size # # # TODO TODO TODO # $connectionString=<INSERT YOUR OWN CONNECTION STRING>' # # TODO TODO TODO # $DatabaseConnection = New-Object System.Data.SqlClient.SqlConnection $DatabaseConnection.ConnectionString = $connectionString try { $DatabaseConnection.Open(); } catch [System.Management.Automation.MethodInvocationException] { Write-Error -Message $($_.Exception.Message) } $sas=Get-AzureRmStorageAccount foreach ($sa in $sas) { $totalBlobSize=0 write-output "Storage Account: '$($sa.StorageAccountName)'" $containers = Get-AzureStorageContainer -Context $sa.Context If (!$containers.Name) { write-output "This storage account has no cotainers"} Else { $size=0 foreach ($container in $containers) { $listblobs = Get-AzureRmStorageAccount -ResourceGroupName $sa.ResourceGroupName -Name $sa.StorageAccountName -ErrorAction Ignore | Get-AzureStorageBlob -Container $container.Name foreach ($listblob in $listblobs) {$size = $size + $listblob.length} $size = $size/1024/1024 $totalBlobSize = $totalBlobSize + $size write-output "'$($container.Name)' -> container size: $size MB." $date = Get-Date -UFormat '%Y-%m-%d %H:%M' write-output $date $Query = "INSERT INTO StorageAccountsMetrics VALUES ( '$($sa.StorageAccountName)', '$($container.Name)', '$($date)', $size)" $DatabaseCommand = New-Object System.Data.SqlClient.SqlCommand $DatabaseCommand.Connection = $DatabaseConnection $DatabaseCommand.CommandText = $Query try { $DbResult = $DatabaseCommand.ExecuteNonQuery() } catch [System.Management.Automation.MethodInvocationException] { Write-Error -Message $($_.Exception.Message) } } } write-output "Total storage account size: $totalBlobSize MB" } $DatabaseConnection.Close()
Dodajemy kod do swojego runbook i czas na testy.
7. Jeśli coś ma się gdzieś popsuć, to właśnie tutaj.
Klikamy na Test pane a następnie na Run. Jeśli Wasz runbook poprawnie się uruchomi, zobaczycie efekt, zbliżony do tego.
8. Jeśli cały runbook wykonał się poprawnie, czas sprawdzić efekt w bazie. Możecie dalej to zrobić z portalu Azure.
Tutaj oglądamy wszystkie konta danych, kontenery, ich rozmiar i datę wpisu.
Możemy też pogrupować po koncie składowania danych oraz dacie z dokładnością co do dnia i wtedy to wygląda tak.
9. Jeśli Twój runbook działa poprawnie i nie masz zastrzeżeń do zapisywanych danych, to teraz czas na dodanie Schedule, który zapewni cykliczne jego wykonanie.
10. Wizualizację zostawiam Tobie, opcji masz wiele.
Możesz użyć darmowego konta na PowerBI i zbudować wykres, możesz równie dobrze użyć Zabbixa i kawałka kodu w PHP. Sam zapewne zrobię integrację z PRTG za pomocą skryptów PowerShell. Opcji jest wiele.