Jak szybko sprawdzić, ile zajmują Twoje dane w chmurze?

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? Challenge Accepted! - Challenge Accepted! Success Kid

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:)

  1. 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.

  1. Upewnij się, że masz poprawny ConnectionString 
  2. 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.

Ten wpis został opublikowany w kategorii PowerShell i oznaczony tagami . Dodaj zakładkę do bezpośredniego odnośnika.