Como traduzir sua infraestrutura para um modelo de IaC
O Conector de Usuários ajuda os usuários a conectarem seus serviços de computação para direcionar serviços de backup em apenas alguns cliques ou comandos. Ao passar de um estágio inicial para um estágio de produção, os usuários também precisam fazer a transição do uso de configurações manuais para o uso de modelos de Infraestrutura como Código (IaC) nos seus pipelines de CI/CD. Nesta guia, mostramos como traduzir seus serviços do Azure conectados nos modelos de IaC.
Pré-requisitos
- Esta guia pressupõe que você esteja ciente das Limitações de IaC do Conector de Serviço.
Visão geral da solução
Geralmente, a tradução da infraestrutura para os modelos de IaC envolve duas partes principais: a lógica para fornecer serviços de origem e destino, e a lógica para criar conexões. Para implementar a lógica de provisionamento dos serviços de origem e destino, há duas opções:
- Criar um modelo do zero
- Exportar o modelo do Azure e poli-lo
Para implementar a lógica para criar conexões, há três opções:
- Usar o Conector de Serviço e a configuração do repositório na Configuração do Aplicativo
- Usar o Conector de Serviço no modelo
- Usar a lógica de modelo para configurar os serviços de origem e de destino diretamente
As combinações dessas diferentes opções podem produzir soluções diferentes. Por causa das Limitações de IaC no Conector de Serviço, recomendamos que você implemente as seguintes soluções na ordem apresentada abaixo. Para aplicar essas soluções, você deve entender as ferramentas de IaC e a gramática de criação de modelos.
Solução | Provisionar a origem e o destino | Conexão da compilação | Cenário aplicável | Vantagens | Desvantagens |
---|---|---|---|---|---|
1 | Criar do zero | Usar o Conector de Serviço e a configuração do repositório na Configuração do Aplicativo | Verifica a vivacidade dos recursos da nuvem antes de permitir o tráfego ativo | – O modelo é simples e legível – O Conector de Serviço traz valor adicional - Os problemas de IaC não são introduzidos pelo Conector de Serviço |
– Precisa de dependência extra para ler a configuração da Configuração do Aplicativo – Custo para verificar a dinâmica dos recursos de nuvem |
2 | Criar do zero | Usar o Conector de Serviço | Verifica a vivacidade dos recursos da nuvem antes de permitir o tráfego ativo | – O modelo é simples e legível – O Conector de Serviço traz valor adicional |
– Custo para verificar a dinâmica dos recursos de nuvem |
3 | Criar do zero | Configurar os serviços de origem e de destino diretamente no modelo | Não há verificação de vida útil nos recursos de nuvem | – O modelo é simples e legível | Alguns recursos do SQL Server não estão disponíveis. |
4 | Exportar e polir | Usar o Conector de Serviço e a configuração do repositório na Configuração do Aplicativo | Verifica a vivacidade dos recursos da nuvem antes de permitir o tráfego ativo | - Os recursos são exatamente iguais aos da nuvem – O Conector de Serviço traz valor adicional - Os problemas de IaC não são introduzidos pelo Conector de Serviço |
– Precisa de dependência extra para ler a configuração da Configuração do Aplicativo – Custo para verificar a dinâmica dos recursos de nuvem - Dá suporte apenas aos modelos do ARM - Esforços necessários para entender e polir o modelo |
5 | Exportar e polir | Usar o Conector de Serviço | Verifica a vivacidade dos recursos da nuvem antes de permitir o tráfego ativo | - Os recursos são exatamente iguais aos da nuvem – O Conector de Serviço traz valor adicional |
– Custo para verificar a dinâmica dos recursos de nuvem - Dá suporte apenas aos modelos do ARM - Esforços necessários para entender e polir o modelo |
6 | Exportar e polir | Configurar os serviços de origem e de destino diretamente no modelo | Não há verificação de vida útil nos recursos de nuvem | - Os recursos são exatamente iguais aos da nuvem | – Dar suporte apenas ao modelo do ARM - Esforços necessários para entender e polir o modelo Alguns recursos do SQL Server não estão disponíveis. |
Criação de modelos
As seções a seguir mostram como criar um aplicativo Web e uma conta de armazenamento e conectá-los a uma identidade atribuída pelo sistema usando o Bicep. Ele mostra como fazer isso usando o Conector de Serviço e usando a lógica do modelo.
Provisionar os serviços de origem e destino
Criar do zero
Criar o modelo do zero é a maneira preferida e recomendada de provisionar os serviços de origem e destino, pois é fácil de começar e torna o modelo simples e legível. Veja a seguir um exemplo, usando um conjunto mínimo de parâmetros para criar um aplicativo da Web e uma conta de armazenamento.
// This template creates a webapp and a storage account.
// In order to make it more readable, we use only the mininal set of parameters to create the resources.
param location string = resourceGroup().location
// App Service plan parameters
param planName string = 'plan_${uniqueString(resourceGroup().id)}'
param kind string = 'linux'
param reserved bool = true
param sku string = 'B1'
// Webapp parameters
param webAppName string = 'webapp-${uniqueString(resourceGroup().id)}'
param linuxFxVersion string = 'PYTHON|3.8'
param identityType string = 'SystemAssigned'
param appSettings array = []
// Storage account parameters
param storageAccountName string = 'account${uniqueString(resourceGroup().id)}'
// Create an app service plan
resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = {
name: planName
location: location
kind: kind
sku: {
name: sku
}
properties: {
reserved: reserved
}
}
// Create a web app
resource appService 'Microsoft.Web/sites@2022-09-01' = {
name: webAppName
location: location
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
linuxFxVersion: linuxFxVersion
appSettings: appSettings
}
}
identity: {
type: identityType
}
}
// Create a storage account
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
}
Exportar e polir
Se os recursos que você está provisionando forem exatamente os mesmos que você tem na nuvem, exportar o modelo do Azure pode ser outra opção. As duas premissas dessa abordagem são: os recursos existem no Azure e você está usando os modelos do ARM para sua IaC. Geralmente, o botão Export template
está na parte inferior da barra lateral no portal do Azure. O modelo do ARM exportado reflete os estados atuais do recurso, incluindo as configurações configuradas pelo Conector de Serviço. Geralmente, você precisa saber sobre as propriedades do recurso para polir o modelo exportado.
Criar a lógica de conexão
Usar o Conector de Serviço e a configuração do repositório na Configuração do Aplicativo
Usar a Configuração do Aplicativo para armazenar a configuração naturalmente dá suporte aos cenários de IaC. Portanto, recomendamos que você use esse método para criar seu modelo de IaC, se possível.
Para obter instruções simples do portal, você pode consultar este tutorial de Configuração do Aplicativo. Para adicionar esse recurso a um arquivo bicep, adicione a ID da Configuração do Aplicativo no conteúdo do Conector de Serviço.
resource webApp 'Microsoft.Web/sites@2022-09-01' existing = {
name: webAppName
}
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
name: storageAccountName
}
resource appConfiguration 'Microsoft.AppConfiguration/configurationStores@2023-03-01' existing = {
name: appConfigurationName
}
resource serviceConnector 'Microsoft.ServiceLinker/linkers@2022-05-01' = {
name: connectorName
scope: webApp
properties: {
clientType: 'python'
targetService: {
type: 'AzureResource'
id: storageAccount.id
}
authInfo: {
authType: 'systemAssignedIdentity'
}
configurationInfo: {
configurationStore: {
appConfigurationId: appConfiguration.id
}
}
}
}
Usar o Conector de Serviço
Criar conexões entre o serviço de origem e o de destino usando o Conector de ServiçoLimitação de IaC não for importante para o seu cenário. O Conector de Serviço simplifica o modelo e também fornece elementos adicionais, como a validação da integridade da conexão, que você não terá se estiver criando conexões diretamente pela lógica de modelo.
// The template builds a connection between a webapp and a storage account
// with a system-assigned identity using Service Connector
param webAppName string = 'webapp-${uniqueString(resourceGroup().id)}'
param storageAccountName string = 'account${uniqueString(resourceGroup().id)}'
param connectorName string = 'connector_${uniqueString(resourceGroup().id)}'
// Get an existing webapp
resource webApp 'Microsoft.Web/sites@2022-09-01' existing = {
name: webAppName
}
// Get an existig storage
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
name: storageAccountName
}
// Create a Service Connector resource for the webapp
// to connect to a storage account using system identity
resource serviceConnector 'Microsoft.ServiceLinker/linkers@2022-05-01' = {
name: connectorName
scope: webApp
properties: {
clientType: 'python'
targetService: {
type: 'AzureResource'
id: storageAccount.id
}
authInfo: {
authType: 'systemAssignedIdentity'
}
}
}
Para obter os formatos de propriedades e valores necessários ao criar um recurso do Conector de Serviço, verifique como fornecer parâmetros corretos. Você também pode visualizar e baixar um modelo do ARM para referência ao criar um recurso do Conector de Serviço no portal do Azure.
Usando a lógica de modelo
Quanto aos cenários em que o Conector de Serviço Limitação de IaC é importante, considere criar conexões usando diretamente a lógica de modelo. O modelo a seguir é um exemplo mostrando como conectar uma conta de armazenamento a um aplicativo Web usando uma identidade atribuída pelo sistema.
// The template builds a connection between a webapp and a storage account
// with a system-assigned identity without using Service Connector
param webAppName string = 'webapp-${uniqueString(resourceGroup().id)}'
param storageAccountName string = 'account${uniqueString(resourceGroup().id)}'
param storageBlobDataContributorRole string = 'ba92f5b4-2d11-453d-a403-e96b0029c9fe'
// Get an existing webapp
resource webApp 'Microsoft.Web/sites@2022-09-01' existing = {
name: webAppName
}
// Get an existing storage account
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
name: storageAccountName
}
// Operation: Enable system-assigned identity on the source service
// No action needed as this is enabled when creating the webapp
// Operation: Configure the target service's endpoint on the source service's app settings
resource appSettings 'Microsoft.Web/sites/config@2022-09-01' = {
name: 'appsettings'
parent: webApp
properties: {
AZURE_STORAGEBLOB_RESOURCEENDPOINT: storageAccount.properties.primaryEndpoints.blob
}
}
// Operation: Configure firewall on the target service to allow the source service's outbound IPs
// No action needed as storage account allows all IPs by default
// Operation: Create role assignment for the source service's identity on the target service
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount
name: guid(resourceGroup().id, storageBlobDataContributorRole)
properties: {
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', storageBlobDataContributorRole)
principalId: webApp.identity.principalId
}
}
Ao criar conexões usando diretamente a lógica de modelo, é fundamental entender o que o Conector de Serviço faz para cada tipo de autenticação, pois a lógica de modelo é equivalente às operações de back-end do Conector de Serviço. A tabela a seguir mostra os detalhes da operação que você precisa traduzir para a lógica de modelo de cada tipo de autenticação.
Tipo de autenticação | Operações do Conector de Serviço |
---|---|
Segredo/cadeia de conexão | - Definir a cadeia de conexão do serviço de destino nas configurações do aplicativo do serviço de origem – Configurar o firewall no serviço de destino para permitir os IPs de saída do serviço de origem |
Identidade gerenciada atribuída pelo sistema | - Definir o ponto de extremidade do serviço de destino nas configurações do aplicativo do serviço de origem – Configurar o firewall no serviço de destino para permitir os IPs de saída do serviço de origem - Habilitar a identidade atribuída pelo sistema no serviço de origem - Criar a atribuição de função para a identidade do serviço de origem no serviço de destino |
Identidade gerenciada atribuída pelo usuário | - Definir o ponto de extremidade do serviço de destino nas configurações do aplicativo do serviço de origem – Configurar o firewall no serviço de destino para permitir os IPs de saída do serviço de origem - Vincular a identidade atribuída pelo usuário ao serviço de origem - Criar a atribuição de função para a identidade atribuída ao usuário no serviço de destino |
Entidade de serviço | - Definir o ponto de extremidade do serviço de destino nas configurações do aplicativo do serviço de origem - Configurar o appId e o segredo da entidade de serviço nas configurações do aplicativo do serviço de origem – Configurar o firewall no serviço de destino para permitir os IPs de saída do serviço de origem - Criar a atribuição de função para a entidade de serviço no serviço de destino |