Como traduzir sua infraestrutura para um modelo IaC

O Service Connector ajuda os usuários a conectar 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) em seus pipelines de CI/CD. Neste guia, mostramos como traduzir seus serviços conectados do Azure para modelos IaC.

Pré-requisitos

  • Este guia pressupõe que você esteja ciente das limitações do Service Connector IaC.

Descrição geral da solução

A tradução da infraestrutura para modelos IaC geralmente envolve duas partes principais: a lógica para provisionar serviços de origem e destino e a lógica para criar conexões. Para implementar a lógica de provisionamento de serviços de origem e destino, há duas opções:

  • Criação do modelo a partir do zero
  • Exportando o modelo do Azure e polindo-o

Para implementar a lógica para criar conexões, há três opções:

  • Usando o Service Connector e armazenando a configuração na Configuração do Aplicativo
  • Usando o Service Connector no modelo
  • Usando a lógica de modelo para configurar serviços de origem e destino diretamente

A combinação destas diferentes opções pode produzir soluções diferentes. Devido às limitações do IaC no Service Connector, recomendamos que você implemente as seguintes soluções na ordem apresentada abaixo. Para aplicar essas soluções, você deve entender as ferramentas IaC e a gramática de criação de modelos.

Solução Origem e destino do provisionamento Construir conexão Cenário aplicável Prós Contras
1 Criação a partir do zero Usar o Service Connector e armazenar a configuração na Configuração do Aplicativo Tem verificação de vivacidade nos recursos da nuvem antes de permitir o tráfego ao vivo - Modelo é simples e legível
- Service Connector traz valor adicional
- Nenhum problema IaC é introduzido pelo Service Connector
- Precisa de dependência extra para ler a configuração da Configuração do Aplicativo
- Custo para verificar a vivacidade dos recursos da nuvem
2 Criação a partir do zero Usar o Service Connector Tem verificação de vivacidade nos recursos da nuvem antes de permitir o tráfego ao vivo - Modelo é simples e legível
- Service Connector traz valor adicional
- Custo para verificar a vivacidade dos recursos da nuvem
3 Criação a partir do zero Configurar serviços de origem e destino diretamente no modelo Sem verificação de vivacidade nos recursos da nuvem - Modelo é simples e legível - Os recursos do Service Connector não estão disponíveis
4 Exportação e polimento Usar o Service Connector e armazenar a configuração na Configuração do Aplicativo Tem verificação de vivacidade nos recursos da nuvem antes de permitir o tráfego ao vivo - Os recursos são exatamente os mesmos que na nuvem
- Service Connector traz valor adicional
- Nenhum problema IaC é introduzido pelo Service Connector
- Precisa de dependência extra para ler a configuração da Configuração do Aplicativo
- Custo para verificar a vivacidade dos recursos da nuvem
- Suporta apenas modelos ARM
- Esforços necessários para compreender e polir o modelo
5 Exportação e polimento Usar o Service Connector Tem verificação de vivacidade nos recursos da nuvem antes de permitir o tráfego ao vivo - Os recursos são exatamente os mesmos que na nuvem
- Service Connector traz valor adicional
- Custo para verificar a vivacidade dos recursos da nuvem
- Suporta apenas modelos ARM
- Esforços necessários para compreender e polir o modelo
6 Exportação e polimento Configurar serviços de origem e destino diretamente no modelo Sem verificação de vivacidade nos recursos da nuvem - Os recursos são exatamente os mesmos que na nuvem - Suporte apenas modelo ARM
- Esforços para entender e polir o modelo
- Os recursos do Service Connector não estão disponíveis

Criar 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 ao sistema usando o Bicep. Ele mostra como fazer isso usando o Service Connector e usando a lógica do modelo.

Provisionar serviços de origem e de destino

Criação a partir do zero

Criar o modelo do zero é a maneira preferida e recomendada de provisionar serviços de origem e destino, pois é fácil de começar e torna o modelo simples e legível. A seguir está um exemplo, usando um conjunto mínimo de parâmetros para criar um webapp 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'
}

Exportação e polimento

Se os recursos que você está provisionando forem exatamente os mesmos que os 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 modelos ARM para seu IaC. O Export template botão geralmente está na parte inferior da barra lateral no portal do Azure. O modelo ARM exportado reflete os estados atuais do recurso, incluindo as configurações definidas pelo Service Connector. Normalmente, você precisa saber sobre as propriedades do recurso para polir o modelo exportado.

Captura de ecrã do portal do Azure, exportando modelo de braço de uma aplicação Web.

Construir lógica de conexão

Usando o Service Connector e armazenando a configuração na Configuração do Aplicativo

O uso da Configuração do Aplicativo para armazenar a configuração naturalmente oferece suporte a 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, consulte este tutorial de Configuração de Aplicativo. Para adicionar esse recurso a um arquivo bicep, adicione a ID de configuração do aplicativo na carga útil do Service Connector.

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
      }
    }
  }
}

Usando o Service Connector

Criar conexões entre o serviço de origem e de destino usando o Service Connector é a maneira preferida e recomendada se a limitação do Service Connector IaC não for importante para o seu cenário. O Service Connector 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 por meio da lógica do 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 Service Connector, verifique como fornecer parâmetros corretos. Você também pode visualizar e baixar um modelo ARM para referência ao criar um recurso do Service Connector no portal do Azure.

Captura de ecrã do portal do Azure, exportando modelo de braço de um recurso do conector de serviço.

Usando a lógica do modelo

Para os cenários em que a limitação do IaC do Service Connector é importante, considere a criação de conexões usando a lógica do modelo diretamente. O modelo a seguir é um exemplo que mostra 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 a lógica de modelo diretamente, é crucial entender o que o Service Connector faz para cada tipo de autenticação, pois a lógica do modelo é equivalente às operações de back-end do Service Connector. A tabela a seguir mostra os detalhes da operação que você precisa traduzir para a lógica do modelo para cada tipo de tipo de autenticação.

Tipo de autenticação Operações do Service Connector
Segredo / Cadeia de conexão - Configure 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 gerida atribuída pelo sistema - Configure 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
- Ativar a identidade atribuída ao sistema no serviço de origem
- Criar atribuição de função para a identidade do serviço de origem no serviço de destino
Identidade gerida atribuída pelo utilizador - Configure 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 atribuição de função para a identidade atribuída ao usuário no serviço de destino
Service principal (Principal de serviço) - Configure o ponto de extremidade do serviço de destino nas configurações do aplicativo do serviço de origem
- Configure 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 atribuição de função para a entidade de serviço no serviço de destino