Рубрики
Uncategorized

Введение в проект Bicep — эволюция шаблонов руки

Возможно, вы слышали о шаблонах ARM. Возможно, вы слышали о проекте Bicep. Что они, как … помечены DevOps, Azure, Armtemplates, InfrastructuctureasCode.

Возможно, вы слышали о шаблонах ARM. Возможно, вы слышали о проекте Bicep. Что они, как они отличаются? Почему я использовал один над другим? Это именно то, что мы будем изучать на протяжении всего этого блога!

Представляем Azure Resource Manager (ARM) и шаблоны ARM

Независимо от того, работаете ли вы с Azure в течение некоторого времени, или только недавно начался — вы, скорее всего, слышали о шаблонах менеджера ресурсов Azure (ARM).

Давайте сделаем краткий уровень, на всякий случай, если вы не слышали о шаблонах ARM! Шаблоны ARM — это тип инфраструктуры в качестве кода. Они позволяют определить свою инфраструктуру Azure, используя код в декларативном порядке. А не говорить Как Вы хотите создавать вещи (например, Azure CLI/PowerShell), вы указываете что Вы хотите создать. Azure тогда «заставляет это случиться».

Менеджер ресурсов Azure не всегда был частью Azure. Azure (изначально известный как проект Red Dog) был впервые объявлен в октябре 2008 года и изначально выпущен в феврале 2010 года. Быстро вперед в/сборку 2014 года (как объяснено в этом Blog Post ), Microsoft объявила о предварительном просмотре Azure Portal (портал, который мы все они используются сейчас, известный как портал Ibiza в то время), а также лазурным порталом Диспетчер ресурсов.

Azure Resource Manager представил несколько больших преимуществ что мы сейчас принимаем как должное, в том числе —

  • Последовательный менеджмент на всех поставщиков ресурсов Azure
  • Группы ресурсов Azure
  • Лазурные замки
  • Политика Azure.
  • Azure Control Access Control
  • И последнее, но не в последнюю очередь — возможность декларивно определить ваши ресурсы в шаблонах, а не в состоянии в сценариях

В целом, Manager Azure Resource Manager значительно изменил игру от перспективы управления и управления управлением при работе с Azure Resources. (Может ли кто-нибудь оставить их разум на работу с отдельными ресурсами в классическом портале, без каких-либо групп ресурсов?)

Совет: Azure Resource Manager — это оказание услуг . Существует подразумеваемое преимущество использования шаблонов Manager Manager Resource Resource по сравнению с такими как террафом. Поскольку мы работаем через последовательный менеджмент, мы можем использовать тот факт, что рука может хранить текущее состояние нашей среды.

Поэтому — в отличие от террафора, нам не нужно управлять состоянием нашей инфраструктуры в качестве развертывания кода. Состояние обрабатывается для нас Manager Manager Azure (как это услуга) и уменьшает сложность управления и инфраструктуры в качестве развертывания кода.

Почему шаблоны ARM должны развиваться?

Шаблоны рычагов, безусловно, обратились к проблеме детерминированных и декларативных развертываний. Теперь мы можем написать код, который является представлением что Мы хотим развернуть, а не Как Отказ Это дает нам преимущество упрощенной логики развертывания и не требует, чтобы покрыть «все основы».

Сценарий : Рассмотрим, что мы создаем Azure Infrastructure, используя сценарий на основе скрипта PowerShell или Azure CLI. Возможно, нам понадобится серия услоев, разбросанных по всему сценарию (например, если этот ресурс уже существует, сделайте это, иначе сделать это …). С помощью шаблонов руки мы определяем желаемое состояние и обычно можно повторно запустить шаблон рычага, чтобы гарантировать, что конфигурация ресурсов не дрейфовала от ожидаемого результата.

Крис, что все звучит положительно — но вы намекаете, что шаблоны руки развиваются. Почему нам нужно что-то еще?

Сложность и многообразие языка шаблона руки были общей областью обратной связи. Шаблоны ARM написаны как шаблоны JSON, а имеют Шаблон язык что слои на вершине этого. JSON, как правило, о представлять данные (например, XML или аналогичный), поэтому именно имеет смысл «представлять» наше развертывание в формате данных, чтобы мы могли добиться до развертывания желаемого состояния. Шаблоны ARM достигают этой цели, за счет легкого авторского использования/удобства использования возможности использования —

  • Инструменты для авторинга, как правило, не помогли автору ваших шаблонов. Это становилось лучше со временем, но восприятие сообщества в том, что он все еще был слишком тяжелым »
  • Использование возможностей языка шаблона ARM (например, функции шаблона ARM, переменные и параметры) не были интуитивно. С точки зрения читаемости, продвинутые сценарии могут легко стать сложным и многолетним
  • Это означало, что в целом, шаблоны руки могут стать очень долго и трудно разобраться (от перспективы человека)

Примечание: Visual Studio и Visual Studio Code Tooling оснащены лучше и лучше. Но иногда начинание с шаблонами руки может быть проблемой. Это где Галерея шаблонов Azure QuickStart приходит в. Это облегчает начало быстро. Эти шаблоны не обязательно являются готовыми к производству (поэтому вам нужно будет настроить их на ваш конкретный сценарий), но они дают вам отличную отправную точку через сотни (всерьез!) Сценариев.

В качестве примера, вот шаблон руки, который я написал ранее. Этот шаблон — Уровень развертывания штамп для администратора микровизора. Намерение состоит в том, что этот шаблон будет повторно использован по нескольким лазурным регионам и средам.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {             
        "aadClientId": {
            "type": "string",
            "metadata": {
              "description": "Client ID of the AAD B2C Application linked to the API Auth"
            }
          },            
          "aadB2cIssuer": {
              "type": "string",
              "metadata": {
                "description": "Link to the well known Open ID Configuration for the sign in policy."
              }
            },          
        "environmentName": {
            "type": "string",
            "allowedValues": [
                "dev",
                "test",
                "qa",
                "prod"
            ],
            "defaultValue": "dev",
            "metadata": {
                "description": "Define which environment is being deployed, this will affect naming convention of all resources"
            }
        },            
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "Location for all resources."
            }
        },   
        "servicePrincipalObjectId": {
            "type": "string",
            "metadata": {
                "description": "Object ID (not application ID) of the Azure DevOps service principal to be granted access to the KeyVault."
            }
        },        
        "tenantId": {
            "type": "string",
            "metadata": {
                "description": "GUID of the Azure AD Tenant associated with the Azure KeyVault"
            }
        },      
        "templateContainerUri": {
            "type": "string",
            "metadata": {
                "description": "URI of the Blob Storage Container containing the ARM Template building blocks"
            }
        },
        "templateContainerSasToken": {
            "type": "string",
            "metadata": {
                "description": "The SAS token of the container containing the ARM Template building blocks"
            }
        }
    },
    "variables": {
        "abbreviations": {
            "northeurope": "neu",
            "westeurope": "weu"
        },        
        "coreGlobalCogSvcSearchName": "[concat(variables('coreGlobalNamePrefix'), 'search')]",
        "coreGlobalResourceGroupName": "[concat(variables('coreGlobalNamePrefix'), 'rg')]",
        "coreGlobalNamePrefix": "[concat(variables('organisationPrefix'), '-core-', parameters('environmentName'), '-')]",
        "coreRegionalApimServiceName": "[concat(variables('coreRegionalNamePrefix'),'apim')]",
        "coreRegionalAppinsightsName": "[concat(variables('coreRegionalNamePrefix'), 'ai')]",
        "coreRegionalNamePrefix": "[concat(variables('organisationPrefix'), '-core-', parameters('environmentName'), '-', variables('abbreviations')[parameters('location')], '-')]",
        "coreRegionalResourceGroupName": "[concat(variables('coreRegionalNamePrefix'), 'rg')]",
        "serviceGlobalNamePrefix": "[concat(variables('organisationPrefix'),'-', variables('serviceName'), '-', parameters('environmentName'), '-')]",
        "serviceGlobalResourceGroupName": "[concat(variables('serviceGlobalNamePrefix'), 'rg')]",
        "serviceRegionalFunctionName": "[concat(variables('serviceRegionalNamePrefix'), 'func')]",
        "serviceRegionalKeyvaultName": "[concat(variables('serviceRegionalNamePrefix'), 'kv')]",
        "serviceRegionalNamePrefix": "[concat(variables('organisationPrefix'),'-', variables('serviceName'), '-', parameters('environmentName'),'-', variables('abbreviations')[parameters('location')], '-')]",
        "serviceRegionalNamePrefixWithoutDashes": "[replace(variables('serviceRegionalNamePrefix'), '-', '')]",
        "serviceResourceGroupName": "[concat(variables('serviceRegionalNamePrefix'), 'rg')]",
        "organisationPrefix": "th",
        "serviceName": "admin"
    },
    "resources": [
        {
            "apiVersion": "2017-05-10",
            "name": "functionDeployment",
            "type": "Microsoft.Resources/deployments",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "uri": "[concat(parameters('templateContainerUri'), 'function.json', parameters('templateContainerSasToken'))]",
                    "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "aadClientId": {
                        "value": "[parameters('aadClientId')]"
                    },
                    "aadB2cIssuer": {
                        "value": "[parameters('aadB2cIssuer')]"
                    },
                    "namePrefix": {
                        "value": "[variables('serviceRegionalNamePrefix')]"
                    },
                    "namePrefixWithoutDashes": {
                        "value": "[variables('serviceRegionalNamePrefixWithoutDashes')]"
                    },
                    "appInsightsResourceGroup": {
                        "value": "[variables('coreRegionalResourceGroupName')]"
                    },
                    "appInsightsName": {
                        "value": "[variables('coreRegionalAppinsightsName')]"
                    },
                    "cogSvcResourceGroup": {
                        "value": "[variables('coreGlobalResourceGroupName')]"
                    },
                    "cogSvcAccountName": {
                        "value": "[variables('coreGlobalCogSvcSearchName')]"
                    }
                }
            },
            "comments": "Downstream template to deploy an Azure Function (Function App, App Serivce Plan) and Storage Account, by using the Theatreers Azure Function Building Block."
        },
        {
            "apiVersion": "2017-05-10",
            "name": "[concat(variables('serviceRegionalFunctionName'), 'ServiceAPIsDeployment')]",
            "type": "Microsoft.Resources/deployments",
            "resourceGroup": "[variables('coreRegionalResourceGroupName')]",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "uri": "[concat(parameters('templateContainerUri'), 'apim-apis.json', parameters('templateContainerSasToken'))]",
                    "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "apimServiceName": {
                        "value": "[variables('coreRegionalApimServiceName')]"
                    },
                    "functionName": {
                        "value": "[variables('serviceRegionalFunctionName')]"
                    },
                    "serviceName": {
                        "value": "[variables('serviceName')]"
                    }
                }
            },
            "comments": "Downstream template to deploy an APIs for the given Microservice."
        },
        {
            "apiVersion": "2017-05-10",
            "name": "[concat(variables('serviceRegionalFunctionName'), 'BackendDeployment')]",
            "type": "Microsoft.Resources/deployments",
            "resourceGroup": "[variables('coreRegionalResourceGroupName')]",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "uri": "[concat(parameters('templateContainerUri'), 'apim-backend.json', parameters('templateContainerSasToken'))]",
                    "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "apimServiceName": {
                        "value": "[variables('coreRegionalApimServiceName')]"
                    },
                    "functionName": {
                        "value": "[variables('serviceRegionalFunctionName')]"
                    },
                    "functionResourceGroup": {
                        "value": "[variables('serviceResourceGroupName')]"
                    }
                }
            },
            "comments": "Downstream template to deploy an APIs for the given Microservice."
        },  
        {
            "apiVersion": "2017-05-10",
            "name": "keyVaultDeployment",
            "type": "Microsoft.Resources/deployments",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "uri": "[concat(parameters('templateContainerUri'), 'keyVault.json', parameters('templateContainerSasToken'))]",
                    "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "vaultName": {
                        "value": "[variables('serviceRegionalKeyvaultName')]"
                    },
                    "tenantId": {
                        "value": "[parameters('tenantId')]"
                    },
                    "objectId": {
                        "value": "[parameters('servicePrincipalObjectId')]"
                    }
                }
            },
            "comments": "Downstream template to deploy Azure KeyVault, associate it with a gievn tenant and assign a Service Principal Object with access to secrets. This uses the Theatreers Azure KeyVault Building Block."
        }
    ],
    "outputs": {}
}

Начиная понимать? Идеально. Давайте пойдем вперед и представим проект Bicep в историю!

Представляем проект Бицепс

Вы, возможно, уже слышали о Проект Бицепс прежде чем прочитать этот пост. Это было вокруг в течение некоторого времени (полагаю, поскольку вокруг зажига 2020 или немного раньше). В настоящее время он в версии 0.4, но был подтвержден как готов к производству, использующую с версии 0.3. Согласно репозиторию GitHub, все типы ресурсов, акавивеции и свойства, которые действительны в шаблоне рук, одинаково действительны на бицепсе в день (даже если BICEP предупреждает, что тип информации не доступен для ресурса, он все еще может быть развернут) Отказ

Примечание: Вот точная формулировка из Проект Bicep Github Repository

По состоянию на V0.3, BICEP теперь поддерживается планами поддержки Microsoft, а BICEP имеет 100% соотношение с тем, что может быть достигнуто с помощью шаблонов руки. По состоянию на это написание, в настоящее время не запланировано никаких изменений, но все еще возможно, что им нужно будет сделано в будущем.

Красота подхода Bicep проекта является то, что это строит существующие инвестиции в руки, которые у вас будут иметь.

Например, вы, возможно, развернули свои шаблоны руки, используя AZ Развертывание группы Создание -F {{TemplateFile}} -G {{ResourceGroup}} команда. Вместо того, чтобы пройти ссылку на ваш шаблон ARM (файл .json), вы передаете ссылку на шаблон бицепса (файл .bicep).

Наконечник: Надеюсь, теперь вы заметили игру на словах Рука (Менеджер ресурсов Azure) и Бицепс Отказ Вот где происходит имя:)

Но подожди — вы, наверное, задаетесь вопросом в этот момент — «Я должен выбрать либо или?» Нет! Шаблоны бицепсов на самом деле декомпилируют шаблоны руки.

Мысль: А как насчет ваших существующих шаблонов руки? Я не верю, что сейчас есть какие-либо функциональность транспилинга, чтобы вы могли легко перемещаться по шаблонам руки на бицепс. Шаблоны рук не собираются никуда нет! Вот некоторые дополнительный контекст из команды из Проект Bicep Github Repository Отказ

Обратите внимание, что, хотя мы хотим легко перейти к бицепсу, мы будем продолжать поддерживать и улучшить базовую руку шаблон JSON язык. Как упомянуто в том, что такое бицепс?, Шаблон ARM JSON остается бесплатным форматом, который будет отправлен на Azure для выполнения развертывания.

Итак, не волнуйтесь — шаблоны руки все еще будут рядом! BICEP Project BiCEP — это удельным языком домена (DSL), находящийся в верхней части языка шаблона ARM JSON. Это облегчает нам как людей автор и прочитать эти шаблоны.

Совет: Вам не нужно начинать с нуля! Галерея шаблонов Azure QuickStart постоянно растет, и не просто шаблоны ARM (JSON), но также содержит файлы BICEP. Смотрите пример здесь Отказ

Сравнение шаблонов руки (JSON) и бицепс

Мы не будем сравнивать и контрастировать языки шаблона в значительном количестве глубины, как Azure Docs Иметь некоторую отличную документацию, сравнивая синтаксис JSON с синтаксисом BICEP.

Однако для установки сцены — вот несколько сравнений по параметрам, переменным и ресурсам между шаблоном ARM JSON LANGUS и BICEP DSL.

Параметры

В JSON вы установили параметр следующим образом —

"parameters": {          
    "aadClientId": {
        "type": "string",
        "metadata": {
            "description": "Client ID of the AAD B2C Application linked to the API Auth"
        },
        "defaultValue": "DefaultValue",
    }
}

Тогда как с бицепсом —

@description('Client ID of the AAD B2C Application linked to the API Auth')
param aadClientId string = 'DefaultValue'

Переменные

В JSON вы установили переменную следующим образом —

    "variables": {
        "coreGlobalCogSvcSearchName": "[concat(variables('coreGlobalNamePrefix'), 'search')]"
    }

Тогда как с бицепсом —

var coreGlobalCogSvcSearchName = '${coreGlobalNamePrefix}search'

Определение ресурса

В JSON вы бы определили ресурс следующим образом —

"resources": [
    {
        "apiVersion": "2017-05-10",
        "name": "functionDeployment",
        "type": "Microsoft.Resources/deployments",
        ...
    },

Тогда как в бицепсе —

resource functionDeployment 'Microsoft.Resources/deployments@2017-05-10' = {
  ...
}

Надеюсь, что дает вам пик в простоту конкретного языка домена Bicep проекта. Это меньше многословного. Для меня это дает знакомое ощущение подобных подобных языках Hashicorp (HCl) (если вы использовали Hashicorp Terraform ранее).

Переработка шаблона руки в бицепс DSL

Я забрал некоторое время, чтобы переписать вышеуказанный шаблон как шаблон Azure Bicep. Я использовал Visual Studio Code и VSCODE BICEP расширение Отказ Мне потребовалось около 20 минут от начала до конца, не зная большого количества нового языка шаблона, чтобы получить завершенный шаблон. Это было с благодаря удивительной функциональности Intellisense, которая встроена в расширение.

Вот пример шаблона, используя BICEP DSL —

@description('Client ID of the AAD B2C Application linked to the API Auth')
param aadClientId string 

@description('Link to the well known Open ID Configuration for the sign in policy.')
param aadB2cIssuer string

@description('Define which environment is being deployed, this will affect naming convention of all resources')
@allowed([
  'dev'
  'test'
  'qa'
  'prod'
])
param environmentName string = 'dev'

@description('Location for all resources.')
param location string = resourceGroup().location

@description('Object ID (not application ID) of the Azure DevOps service principal to be granted access to the KeyVault.')
param servicePrincipalObjectId string

@description('GUID of the Azure AD Tenant associated with the Azure KeyVault')
param tenantId string

@description('URI of the Blob Storage Container containing the ARM Template building blocks')
param templateContainerUri string

@description('The SAS token of the container containing the ARM Template building blocks')
param templateContainerSasToken string

var abbreviations = {
  northeurope: 'neu'
  westeurope: 'weu'
}
var coreGlobalCogSvcSearchName = '${coreGlobalNamePrefix}search'
var coreGlobalResourceGroupName = '${coreGlobalNamePrefix}rg'
var coreGlobalNamePrefix = '${organisationPrefix}-core-${environmentName}-'
var coreRegionalApimServiceName = '${coreGlobalNamePrefix}apim'
var coreRegionalAppInsightsName = '${coreGlobalNamePrefix}ai'
var coreRegionalNamePrefix = '${organisationPrefix}-core-${environmentName}-${abbreviations[location]}-'
var coreRegionalResourceGroupName = '${coreRegionalNamePrefix}rg'
var serviceGlobalNamePrefix = '${organisationPrefix}-${serviceName}-${environmentName}-'
var serviceGlobalResourceGroupName = '${serviceGlobalNamePrefix}rg'
var serviceRegionalFunctionName = '${serviceGlobalNamePrefix}func'
var serviceRegionalKeyvaultName = '${serviceGlobalNamePrefix}kv'
var serviceRegionalNamePrefix = '${organisationPrefix}-${serviceName}'
var serviceRegionalNamePrefixWithoutDashes = replace(serviceRegionalNamePrefix, '-', '')
var serviceResourceGroupName ='${serviceRegionalNamePrefix}rg'
var organisationPrefix = 'th'
var serviceName = 'admin'

/ Downstream template to deploy an Azure Function (Function App, App Serivce Plan) and Storage Account,
/ by using the Theatreers Azure Function Building Block.
resource functionDeployment 'Microsoft.Resources/deployments@2017-05-10' = {
  name: 'functionDeployment'
  properties: {
    mode: 'Incremental'
    templateLink: {
      uri: '${templateContainerUri}function.json${templateContainerSasToken}'
      contentVersion: '1.0.0.0'
    }
    parameters: {
      aadClientId: aadClientId
      aadB2cIssuer: aadB2cIssuer
      namePrefix: serviceRegionalNamePrefix
      namePrefixWithoutDashes: serviceRegionalNamePrefixWithoutDashes
      appInsightsResourceGroup: coreRegionalResourceGroupName
      appInsightsName: coreRegionalAppInsightsName
      cogSvcResourceGroup: coreGlobalResourceGroupName
      cogSvcAccountName: coreGlobalCogSvcSearchName
    }
  }
}

/ Downstream template to deploy an APIs for the given Microservice.
resource serviceAPIsDeployment 'Microsoft.Resources/deployments@2017-05-10' = {
  name: 'ServiceAPIsDeployment'
  resourceGroup: coreRegionalResourceGroupName
  properties: {
    mode: 'Incremental'
    templateLink: {
      uri: '${templateContainerUri}apim-apis.json${templateContainerSasToken}'
      contentVersion: '1.0.0.0'
    }
    parameters: {
      apimServiceName: coreRegionalApimServiceName
      functionName: serviceRegionalFunctionName
      serviceName: serviceName
    }
  }
}

/ Downstream template to deploy an APIs for the given Microservice.
resource backendDeployment 'Microsoft.Resources/deployments@2017-05-10' = {
  name: 'backendDeployment'
  resourceGroup: coreRegionalResourceGroupName
  properties: {
    mode: 'Incremental'
    templateLink: {
      uri: '${templateContainerUri}apim-backend.json${templateContainerSasToken}'
      contentVersion: '1.0.0.0'
    }
    parameters: {
      apimServiceName: coreRegionalApimServiceName
      functionName: serviceRegionalFunctionName
      functionResourceGroup: serviceResourceGroupName
    }
  }
}

/ Downstream template to deploy Azure KeyVault, associate it with a gievn tenant and assign a Service Principal Object with access to secrets. 
/ This uses the Theatreers Azure KeyVault Building Block.
resource keyVaultDeployment 'Microsoft.Resources/deployments@2017-05-10' = {
  name: 'keyVaultDeployment'
  properties: {
    mode: 'Incremental'
    templateLink: {
      uri: '${templateContainerUri}keyVault.json${templateContainerSasToken}'
      contentVersion: '1.0.0.0'
    }
    parameters: {
      value: serviceRegionalKeyvaultName
      tenantId: tenantId
      objectId: servicePrincipalObjectId
    }
  }
}

Это совсем разница, не так ли? Я лично легче прочитать подход Бицепса. Это гораздо более лаконично по сравнению с шаблоном ARM на основе JSON. С благодарностью улучшенной инструментации я даже обнаружил, что у меня была одна переменная, которую я не использовал ( ServiceGlobalresourceGroupname ) — так что может сделать некоторую дополнительную оптимизацию моего шаблона!

Я заинтригован. Как мне продолжить путешествие с бицепсом?

Здорово! Вот несколько ресурсов, чтобы вы пойти —

  • Некоторые коллеги в Microsoft (включая людей из моей предыдущей команды) вытащили вместе Microsoft изучает путь обучения на бицепс Отказ Это отличный ресурс для начала вашего бицепного обучения.
  • Когда вы начинаете понимать BICEP DSL, вы, вероятно, захотите просмотреть Документация BICEP Чтобы понять некоторые из основных языковых особенностей и лучших практик.
  • Как вы начинаете авторские собственные шаблоны, используя DSL BICEP, вы можете использовать Visual Studio Code Bicep Расширение Отказ Это дает вам IntelliSense на свойства Dot-Properties, имена ресурсов и значений свойств, а также как фрагменты и другие трюки, которые помогут вам легко авторуйте ваши шаблоны!
  • Наконец, вы, возможно, использовали Ссылка на лазурных шаблонах Если вы авторитетные шаблоны Azure Resource Manager (ARM) в прошлом. Эти эталонные документы указывают дополнительные/обязательные свойства для каждого поставщика ресурсов и типа ресурса. Теперь они включают информацию о схемы BICEP DSL для каждого типа ресурса.

Закрытие мыслей

Я взволнован возможностью, чтобы проектировать бицепс подарки. Как вы можете видеть из вышеперечисленного шаблона, существует много простота по сравнению с шаблонами руки — как из читаемости, так и влагоподъемности. Инструменты поправляются, и есть очень активное и процветающее сообщество. Если вы заинтересованы в принятии участия, я рекомендую вам рассмотреть Azure Bicep Github Repository Где вы также можете найти дополнительные ссылки и проекты сообщества вокруг Бицепа.

Итак, каковы ваши мысли на проекте Бицепс? Будете ли вы использовать BICEP DSL в своих собственных развертываемых? Давайте продолжим обсуждение на Twitter, @reddobowen .

Спасибо за чтение этого. Если вы хотите увидеть больше на проекте Bicep, и определенные реализации/сценарии — Пожалуйста, дайте мне знать! В противном случае до следующего поста — спасибо за чтение и пока!

Оригинал: «https://dev.to/cloudwithchris/introduction-to-project-bicep-the-evolution-of-arm-templates-3676»