Документация тут>>>.
Имеется шаблон для деплоя группы ресурсов – 2 VMSS, балансировщики, подсети и группы безопасности. Одна – для VMSS Docker Swarm-менеджеров, вторая – для Swarm-нод.
Задача – вынести описание групп безопасности в отдельные шаблоны, что бы подключать их в зависимости от окружения – для Dev свои, для Prod – свои и т.д.
Ресурс Network Security Group для нод выглядит так:
... { "apiVersion": "2015-06-15", "type": "Microsoft.Network/networkSecurityGroups", "name": "[variables('NodesNSGname')]", "location": "[resourceGroup().location]", "tags": { "displayName": "NSG - Remote Access" }, "properties": { "securityRules": [ { "name": "AllowSSHAll", "properties": { "description": "Allow SSH", "protocol": "Tcp", "sourcePortRange": "*", "destinationPortRange": "22", "sourceAddressPrefix": "*", "destinationAddressPrefix": "*", "access": "Allow", "priority": 100, "direction": "Inbound" } } ] } }, ...
Пробуем вложенность.
Создаём отдельный шаблон, например jm-website-nsg-dev.json
, копируем в него ресурс NSG:
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { }, "resources": [ { "apiVersion": "2015-06-15", "type": "Microsoft.Network/networkSecurityGroups", "name": "[variables('NodesNSGname')]", "location": "[resourceGroup().location]", "tags": { "displayName": "NSG - Remote Access" }, "properties": { "securityRules": [ { "name": "AllowSSHAll", "properties": { "description": "Allow SSH", "protocol": "Tcp", "sourcePortRange": "*", "destinationPortRange": "22", "sourceAddressPrefix": "*", "destinationAddressPrefix": "*", "access": "Allow", "priority": 100, "direction": "Inbound" } } ] } } ] }
Доступ к шаблонам – только по HTTP/S, поэтому – загружаем его в Storage Account:
[simterm]
$ export AZURE_STORAGE_ACCOUNT=utils $ export AZURE_STORAGE_ACCESS_KEY=tOkX***6Bw==
[/simterm]
Выполняем:
[simterm]
$ azure storage blob upload '/home/setevoy/Work/BER.JM/azure-infrastructure/jm-website/jm-website-nsg-dev.json' templates info: Executing command storage blob upload + Checking blob jm-website-nsg-dev.json in container templates + Uploading /home/setevoy/Work/BER.JM/azure-infrastructure/jm-website/jm-website-nsg-dev.json to blob jm-website-nsg-dev.json in container templates ...
[/simterm]
В главном шаблоне на место ресурса NSG вписываем ресурс деплоя:
... { "apiVersion": "2015-01-01", "name": "linkedTemplate", "type": "Microsoft.Resources/deployments", "properties": { "mode": "incremental", "templateLink": { "uri": "https://utils.blob.core.windows.net/templates/jm-website-nsg-dev.json", "contentVersion": "1.0.0.0" }, "parameters": { "StorageAccountName":{"value": "[parameters('storageAccountName')]"} } } }, ...
Пробуем:
[simterm]
$ azure group create -l westeurope -n jm-website-sw-nsg-test-1 -f jm-website-sw.json -e jm-website-sw.parameters.json info: Executing command group create + Getting resource group jm-website-sw-nsg-test-1 + Creating resource group jm-website-sw-nsg-test-1 info: Created resource group jm-website-sw-nsg-test-1 + Initializing template configurations and parameters + Creating a deployment error: InvalidContentLink : Unable to download deployment content from 'https://utils.blob.core.windows.net/templates/jm-website-nsg-dev.json'. The tracking Id is '7c85bd15-1377-417a-b6f1-4e08a64eb87a'. Please see https://aka.ms/arm-deploy for usage details. ...
[/simterm]
Странно – ARM при валидации не упал. Значит – в целом схема уже рабочая.
Авторизация.
Переходим в Portal > Storage accounts, генерируем SAS-токен:
Выносим его в параметр:
... "parameters": { "SAStoken": { "type": "string", "defaultValue": "?sv=2016-05-31&ss=bfqt&srt=sco&sp=ra&se=2018-03-17T20:31:25Z&st=2017-03-17T12:31:25Z&spr=https&sig=QWy2Sp***%3D" }, ...
Обновляем URI в главном шаблоне:
... "templateLink": { "uri": "[concat('https://utils.blob.core.windows.net/templates/jm-website-nsg-dev.json', parameters('SAStoken'))]", "contentVersion": "1.0.0.0" }, ...
Пробуем:
... error: InvalidContentLink : Unable to download deployment content from 'https://utils.blob.core.windows.net/templates/jm-website-nsg-dev.json?sv=2016-05-31&ss=bfqt&srt=sco&sp=ra&se=2018-03-17T20:31:25Z&st=2017-03-17T12:31:25Z&spr=https&sig=QWy2***U%3D'. The tracking Id is '6bad400b-6e1e-43cd-98c4-45b324500be5'. Please see https://aka.ms/arm-deploy for usage details. ...
Ну, ок. Ничего удивительного. Сделаем авторизацию позже, а пока – устанавливаем на контейнер права доступа Blob (пубичный доступ на чтение).
Пробуем снова:
[simterm]
$ azure group create -l westeurope -n jm-website-sw-nsg-test-1 -f jm-website-sw.json -e jm-website-sw.parameters.json info: Executing command group create + Getting resource group jm-website-sw-nsg-test-1 + Updating resource group jm-website-sw-nsg-test-1 info: Updated resource group jm-website-sw-nsg-test-1 + Initializing template configurations and parameters + Creating a deployment error: InvalidTemplate : Deployment template validation failed: 'The template parameters 'StorageAccountName' in the parameters file are not valid; they are not present in the original template and can therefore not be provided at deployment time. The only supported parameters for this template are 'adminPassword'. Please see https://aka.ms/arm-deploy/#parameter-file for usage details.'. ...
[/simterm]
Отлично! Уже ругается на параметры – StorageAccountName
, т.к. ресурс деплоя просто скопирован из документации.
В нашем шаблоне NSG мы используем переменную NodesNSGname
:
... "name": "[variables('NodesNSGname')]", ...
В файле шаблона – создаём параметр NodesNSGname
:
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "NodesNSGname": { "type": "string" } }, "resources": [ { "apiVersion": "2015-06-15", "type": "Microsoft.Network/networkSecurityGroups", "name": "[parameters('NodesNSGname')]", ...
Обновляем ресурс деплоя в основном шаблоне, передаём во вложенный шаблон переменную NodesNSGname
из главного шаблона:
... "nodesNSGname": "[concat(resourceGroup().name,'-nodes-nsg')]", ...
В ресурсе деплоя указываем:
... "parameters": { "NodesNSGname":{"value": "[variables('NodesNSGname')]"} ...
Полностью он сейчас выглядит так:
... { "apiVersion": "2015-01-01", "name": "linkedTemplate", "type": "Microsoft.Resources/deployments", "properties": { "mode": "incremental", "templateLink": { "uri": "https://utils.blob.core.windows.net/templates/jm-website-nsg-dev.json", "contentVersion": "1.0.0.0" }, "parameters": { "NodesNSGname":{"value": "[variables('NodesNSGname')]"} } } }, ...
Обновляем шаблон в Storage account-е:
[simterm]
$ azure storage blob upload '/home/setevoy/Work/BER.JM/azure-infrastructure/jm-website/jm-website-nsg-dev.json' templates info: Executing command storage blob upload + Checking blob jm-website-nsg-dev.json in container templates Do you want to overwrite the blob jm-website-nsg-dev.json in container templates? y ...
[/simterm]
Пробуем:
[simterm]
$ azure sazure group create -l westeurope -n jm-website-sw-nsg-test-1 -f jm-website-sw.json -e jm-website-sw.parameters.json info: Executing command group create + Getting resource group jm-website-sw-nsg-test-1 + Updating resource group jm-website-sw-nsg-test-1 info: Updated resource group jm-website-sw-nsg-test-1 + Initializing template configurations and parameters + Creating a deployment info: Created template deployment "jm-website-sw" data: Id: /subscriptions/0a4f2b9c-***-40b17ef8c3ab/resourceGroups/jm-website-sw-nsg-test-1 data: Name: jm-website-sw-nsg-test-1 data: Location: westeurope data: Provisioning State: Succeeded data: Tags: null data: info: group create command OK
[/simterm]
Проверяем:
[simterm]
$ azure group deployment show -g jm-website-sw-nsg-test-1 info: Executing command group deployment show + Getting deployments data: DeploymentName : jm-website-sw data: ResourceGroupName : jm-website-sw-nsg-test-1 data: ProvisioningState : Running ...
[/simterm]
В Portal-е, деплой главного шаблона:
Деплой вложенного шаблона:
Фиксим авторизацию.
Возвращаем права на контейнер – Private.
Пробуем curl
-ом:
[simterm]
$ curl https://utils.blob.core.windows.net/templates/jm-website-nsg-dev.json <?xml version="1.0" encoding="utf-8"?><Error><Code>ResourceNotFound</Code><Message>The specified resource does not exist. ...
[/simterm]
Пробуем с токеном:
$ curl "https://utils.blob.core.windows.net/templates/jm-website-nsg-dev.json/?sv=2016-05-31&ss=bfqt&srt=sco&sp=rwdlacup&se=2020-03-17T21:18:58Z&st=2017-03-17T13:18:58Z&spr=https,http&sig=QIN***%3D"
Ага, теперь видна ошибка:
Time:2017-03-17T11:23:58.3677617Z</Message><AuthenticationErrorDetail>Signature not valid in the specified time frame: Start [Fri, 17 Mar 2017 13:18:58 GMT] - Expiry [Tue, 17 Mar 2020 21:18:58 GMT] - Current [Fri, 17 Mar 2017 11:23:58 GMT]</AuthenticationErrorDetail></Error>
При деплое через ARM её не видел.
Вчитываемся в неё:
Time:2017-03-17T11:36:37.3456373Z</Message><AuthenticationErrorDetail>Signature not valid in the specified time frame: Start [Fri, 17 Mar 2017 13:33:28 GMT] – Expiry [Fri, 17 Mar 2017 21:33:28 GMT] – Current [Fri, 17 Mar 2017 11:36:37 GMT]</AuthenticationErrorDetail></Error>
Start 13:33:28
Expiry 21:33:28
Current 11:36:37
Current 11:36:37
Временная зона.
Генерируем токен заново, указываем зону UTC +2 (Киев):
Проверяем:
[simterm]
$ curl "https://utils.blob.core.windows.net/templates/jm-website-nsg-dev.json/?sv=2016-05-31&ss=bfqt&srt=sco&sp=rwdlacup&se=2020-03-17T19:37:37Z&st=2017-03-17T11:37:37Z&spr=https&sig=IlrsuM***0hk%3D"
[/simterm]
Теперь ошибка 404.
А через ARM – работает.
В основном шаблоне обновляем параметр SAStoken
:
"parameters": { "SAStoken": { "type": "string", "defaultValue": "?sv=2016-05-31&ss=bfqt&srt=sco&sp=rwdlacup&se=2020-03-17T19:37:37Z&st=2017-03-17T11:37:37Z&spr=https&sig=Ilr***k%3D" }, ...
И uri
:
... { "apiVersion": "2015-01-01", "name": "linkedTemplate", "type": "Microsoft.Resources/deployments", "properties": { "mode": "incremental", "templateLink": { "uri": "[concat('https://utils.blob.core.windows.net/templates/jm-website-nsg-dev.json', parameters('SAStoken'))]", "contentVersion": "1.0.0.0" ...
Выполняем, проверяем:
[simterm]
$ azure group create -l westeurope -n jm-website-sw-nsg-test-2 -f jm-website-sw.json -e jm-website-sw.parameters.json info: Executing command group create + Getting resource group jm-website-sw-nsg-test-2 + Creating resource group jm-website-sw-nsg-test-2 info: Created resource group jm-website-sw-nsg-test-2 + Initializing template configurations and parameters + Creating a deployment info: Created template deployment "jm-website-sw" ...
[/simterm]
С этим разобрались.
Последнее, что хотелось бы слделать – это выбор шаблона в зависимости от того, на какое окружение выполняется развёртывание группы ресурсов.
Проще всего – через добавление нового параметра:
... "environment": { "type": "string", "metadata": { "description": "dev, qa, staging, prod" }, "defaultValue": "dev", "allowedValues": [ "dev", "qa", "staging", "production" ] }, ...
И обновляем uri
:
... "uri": "[concat('https://utils.blob.core.windows.net/templates/jm-website-nsg-', parameters('environment'), '.json', parameters('SAStoken'))]", ...
Проверяем:
[simterm]
$ azure group create -l westeurope -n jm-website-sw-nsg-test-3 -f jm-website-sw.json -e jm-website-sw.parameters.json
[/simterm]
Готово.