Azure: Blob Storage – static website hosting

Автор: | 18/05/2017
 

Аналогично хостингу сайтов в AWS S3Azure предоставляет аналогичную возможность размещения статичных сайтов используя Blob Storage Account.

У Azure (внезапно) есть два существенных отличия/недостатка:

  1. данные сайта загружаются в контейнер, расположенный в Storage Account, и имя контейнера потом видно в URL. Т.е. если есть аккаунт example, и контейнер website – то URL будет выглядеть как https://example.blob.core.windows.net/website/
  2. Azure не поддерживает указание документа по умолчанию. Т.е. если пользователь приходит на https://example.blob.core.windows.net/ без указания конкретного файла – он получает ошибку InvalidQueryParameterValue.

Если первая проблема решается с помощью контейнера с именем $root – то вторую придётся разруливать через NGINX.

Создаём Storage Account:

[simterm]

$ azure storage account create japanwebistedev -l westeurope -g jm-japan-webiste --sku-name RAGRS --kind BlobStorage --access-tier Hot
info:    Executing command storage account create
+ Checking availability of the storage account name                            
+ Creating storage account                                                     
info:    storage account create command OK

[/simterm]

Для дальнейшей работы – получаем ключи авторизации:

[simterm]

$ azure storage account keys list -g jm-japan-webiste japanwebistedev
info:    Executing command storage account keys list
+ Getting storage account keys                                                 
data:    Name  Key                                                                                       Permissions
data:    ----  ----------------------------------------------------------------------------------------  -----------
data:    key1  Gt7***t0g==  Full       
data:    key2  N6N***rJw==  Full       
info:    storage account keys list command OK

[/simterm]

Задаём переменные:

[simterm]

$ export AZURE_STORAGE_ACCESS_KEY=Gt7***t0g==
$ export AZURE_STORAGE_ACCOUNT=japanwebistedev

[/simterm]

Сейчас в аккаунте нет контейнеров:

[simterm]

$ azure storage container list
info:    Executing command storage container list
+ Getting storage containers                                                   
info:    No containers found
info:    storage container list command OK

[/simterm]

Создаём контейнер типа Blob с именем $root:

[simterm]

$ azure storage container create --container '$root' -p Blob
info:    Executing command storage container create
+ Creating storage container $root                                             
+ Getting storage container information                                        
data:    {
data:        name: '$root',
data:        metadata: {},
data:        etag: '"0x8D49DDED5CE94E1"',
data:        lastModified: 'Thu, 18 May 2017 11:12:56 GMT',
data:        lease: { status: 'unlocked', state: 'available' },
data:        requestId: '940648ea-0001-00cb-66c7-cfbc6c000000',
data:        publicAccessLevel: 'Blob'
data:    }
info:    storage container create command OK

[/simterm]

Загружаем индексный файл:

[simterm]

$ azure storage blob upload '/home/setevoy/index.html' '$root'
info:    Executing command storage blob upload
+ Checking blob index.html in container $root                                  
+ Uploading /home/setevoy/index.html to blob index.html in container $root     
Percentage: 100.0% (21.00B/21.00B) Average Speed: 21.00B/s Elapsed Time: 00:00:00 
+ Getting storage blob information                                             
data:    Property       Value                   
data:    -------------  ------------------------
data:    container      $root                   
data:    name           index.html              
data:    blobType       BlockBlob               
data:    contentLength  21                      
data:    contentType    text/html               
data:    contentMD5     TXAn2/9C+Sdw7AFDSI9Neg==
info:    storage blob upload command OK

[/simterm]

Проверяем:

[simterm]

$ curl https://japanwebistedev.blob.core.windows.net/index.html
Test Site index page

[/simterm]

Работает, без указания контейнера – ОК, хорошо.

Далее требуется подключить кастомный домен и настроить документ по умолчанию.

Как и везде в Azure – добавление кастомных доменов к сервисам выполняется через CNAME или *verify записи, а для того что бы решить проблему с индексным файлом – домен и его www субдомены направлены на прокси:

[simterm]

$ dig @ns1-07.azure-dns.com dev-jp.domain.tld +short
40.***.***.168
$ dig @ns1-07.azure-dns.com www.dev-jp.domain.tld +short
40.***.***.168

[/simterm]

Для подключения этих записей к Storage Account-у – требуется ещё две записи:

[simterm]

$ dig @ns1-07.azure-dns.com asverify.dev-jp.domain.tld +short
asverify.japanwebistedev.blob.core.windows.net.
$ dig @ns1-07.azure-dns.com asverify.www.dev-jp.domain.tld +short
asverify.japanwebistedev.blob.core.windows.net.

[/simterm]

Подробнее – тут>>>.

Подключаем к аккаунту:

[simterm]

$ azure storage account set japanwebistedev --subdomain asverify.dev-jp.domain.tld -g jm-japan-webiste
info:    Executing command storage account set
+ Updating storage account                                                     
error:   Request must specify an account property to update.
error:   Error information has been recorded to /home/setevoy/.azure/azure.err
error:   storage account set command failed

[/simterm]

#&%S&c#*&%8, Azure!!!!

Добавляем домен руками через Portal:

Настраиваем простой редирект на прокси/NGINX:

server {
    server_name dev-jp.domain.tld;
    rewrite ^ http://www.dev-jp.domain.tld$request_uri permanent;
}

server {

    server_name www.dev-jp.domain.tld;

    access_log /var/log/nginx/dev-jp.domain.tld-access.log;
    error_log /var/log/nginx/dev-jp.domain.tld-error.log;

    root /usr/share/nginx/html;

    location / {
        proxy_redirect          off;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass https://japanwebistedev.blob.core.windows.net$request_uri;
    }
}

Проверяем:

[simterm]

$ curl -L dev-jp.domain.tld/index.html
Test Site index page
$ curl -L www.dev-jp.domain.tld/index.html
Test Site index page

[/simterm]

И последнее, что надо сделать – проверять наличие $request_uri: если URI присутсвует – использовать его, если нет – то дописывать index.html.

Обновляем конфиг NGINX:

server {
    server_name dev-jp.domain.tld;
    rewrite ^ http://www.dev-jp.domain.tld$request_uri permanent;
}

server {

    server_name www.dev-jp.domain.tld;

    access_log /var/log/nginx/dev-jp.domain.tld-access.log;
    error_log /var/log/nginx/dev-jp.domain.tld-error.log;

    root /usr/share/nginx/html;

    rewrite ^(/)$ /index.html permanent;

    resolver 8.8.8.8;

    location ~ / {
        proxy_redirect          off;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass https://japanwebistedev.blob.core.windows.net$request_uri;
    }

}

Проверяем:

[simterm]

$ curl -L dev-jp.domain.tld
Test Site index page
$ curl -L dev-jp.domain.tld/
Test Site index page
$ curl -L www.dev-jp.domain.tld
Test Site index page
$ curl -L www.dev-jp.domain.tld/
Test Site index page

[/simterm]

Готово.