Criar ligações de serviço usando ferramentas IaC

O Service Connector ajuda-o a ligar rápida e facilmente os seus serviços de computação aos serviços de apoio alvo. Quando se move da fase inicial para a de produção, também precisa de mudar as suas ligações de serviço de configurações manuais para templates de Infraestrutura como Código (IaC) para usar nos seus pipelines de integração contínua/entrega contínua (CI/CD). Este artigo mostra como traduzir serviços Azure ligados para templates IaC.

Opções de solução

Os modelos Bicep neste artigo criam uma aplicação web e uma conta de armazenamento e ligam-nos através de uma identidade atribuída ao sistema, quer no Service Connector, quer usando lógica de templates. Para usar estes modelos, deve compreender as ferramentas IaC, a gramática de criação de modelos e as limitações conhecidas do Service Connector IaC.

A tradução da infraestrutura do Service Connector para templates IaC inclui as seguintes duas partes:

  1. Fornecer serviços de origem e destino. Para provisionar serviços de origem e destino, pode:

  2. Construa as ligações de serviço. Para construir uma ligação de serviço, pode:

Diferentes combinações destas opções produzem soluções distintas. A tabela seguinte apresenta as soluções do mais ao menos recomendado, com base em vários fatores.

Por exemplo, usar App Configuration elimina problemas conhecidos do Service Connector IaC, mas cria uma dependência para ler a partir da App Configuration. O Service Connector faz uma verificação da vivacidade dos recursos na cloud antes de permitir tráfego em tempo real, mas esta funcionalidade implica custos adicionais.

Solução Provisionamento de origem e destino Criação de ligação Verificação de funcionamento? Vantagens Desvantagens
1 Autor do zero Conector de Serviço /
App Configuration
Sim - Simplicidade e legibilidade do modelo
- Funcionalidades do Service Connector
- Sem problemas no conector de serviço IaC
- Dependência da Configuração da Aplicação
- Verificação de disponibilidade do custo dos recursos na cloud
2 Autor do zero Conector de Serviço Sim - Simplicidade e legibilidade do modelo
- Funcionalidades do Service Connector
- Verificação de disponibilidade do custo dos recursos na cloud
- Potenciais problemas com o Conector de Serviço IaC
3 Autor do zero Diretamente no modelo No - Simplicidade e legibilidade do modelo
- Sem problemas no conector de serviço IaC
- Sem funcionalidades do Conector de Serviço
4 Exportação e polimento Conector de Serviço /
App Configuration
Sim - Mesmos recursos que na cloud
- Funcionalidades do Service Connector
- Sem problemas no conector de serviço IaC
- Dependência da Configuração da Aplicação
- Verificação de atividade do custo dos recursos da nuvem
- Esforço para compreender e aperfeiçoar o modelo
5 Exportação e polimento Conector de Serviço Sim - Mesmos recursos que na cloud
- Funcionalidades do Service Connector
- Verificação de atividade do custo dos recursos da nuvem
- Potenciais problemas com o Conector de Serviço IaC
- Esforço para compreender e aperfeiçoar o modelo
6 Exportação e polimento Diretamente no modelo No - Mesmos recursos que na cloud
- Sem problemas no conector de serviço IaC
- Esforço para compreender e aperfeiçoar o modelo
- Sem funcionalidades do Conector de Serviço

Provisionamento de serviços de origem e de destino

Criar um modelo do zero é a forma preferida e recomendada de provisionar serviços de origem e de destino. Este método facilita o início e cria um modelo simples e legível.

Se estiveres a provisionar os mesmos recursos que tens na cloud, exportar um modelo do Azure é outra opção. Para exportar um modelo, o recurso deve já existir no Azure.

Crie um modelo do zero

O modelo de exemplo seguinte utiliza um conjunto mínimo de parâmetros para criar uma aplicação web do Azure e uma conta de armazenamento.

// This template uses a minimal set of parameters to create a web app and a storage account.

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 um modelo

Se os seus serviços já existem na cloud, exportar um modelo do Azure é outra opção. Para exportar um modelo de uma aplicação web Azure, selecione Exportar modelo em Automação no menu de navegação esquerdo da aplicação.

O modelo exportado reflete os estados atuais do recurso, incluindo as definições do Service Connector. Podes usar a informação de propriedades da aplicação para polir o modelo exportado.

Captura de ecrã da exportação de um modelo Bicep de uma aplicação web no portal Azure.

Criar a conexão de serviço

Pode construir a ligação de serviço usando apenas o Service Connector, Service Connector com App Configuration, ou diretamente em lógica de templates.

Usar o Service Connector

Criar ligações entre serviços de origem e destino usando o Service Connector é preferível e recomendado, desde que as limitações conhecidas do Service Connector não afetem o seu cenário. Usar o Service Connector simplifica o template e fornece funcionalidades como validação da saúde da ligação que não estão disponíveis quando se constrói ligações diretamente através da lógica do template.

O modelo seguinte cria uma ligação Service Connector entre uma aplicação web e uma conta de armazenamento, usando uma identidade atribuída pelo sistema.

// This template builds a Service Connector connection between a web app and a storage account using a system-assigned identity.

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 existing storage
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
  name: storageAccountName
}

// Create a Service Connector resource for the web app 
// 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 mais informações sobre as propriedades necessárias para criar um recurso de Conector de Serviço, consulte Fornecer parâmetros corretos ao Conector de Serviço. Também pode pré-visualizar e descarregar um modelo ARM para referência quando criar um recurso Service Connector no portal do Azure.

Captura de ecrã da exportação de um modelo Bicep de um recurso de conector de serviço no portal do Azure.

Use o Service Connector com a Configuração da Aplicação

A Configuração de Aplicações é a forma recomendada de armazenar a configuração da ligação, porque não está sujeita às limitações do Service Connector IaC. Para criar uma loja de Configuração de Aplicações usando o portal Azure, consulte Connect Azure serviços e configuração de armazenamento numa loja de Configuração de Aplicações.

Para adicionar a Configuração da Aplicação a um modelo Bicep, adicione o ID de Configuração da Aplicação na carga útil do Conector de Serviço. O modelo de exemplo seguinte cria uma ligação Service Connector entre uma aplicação web e uma conta de armazenamento, e armazena a informação de configuração da ligação na Configuração da Aplicaçã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
      }
    }
  }
}

Escrever lógica de modelo

Se as limitações do Service Connector IaC afetarem o seu cenário, considere construir ligações diretamente usando lógica de templates. A seguinte lógica modelo liga uma conta de armazenamento diretamente a uma aplicação web, usando uma identidade atribuída pelo sistema.

// This template builds a connection between a web app and a storage account with a system-assigned identity directly

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

Operações de autenticação para lógica de modelos

Usar lógica de templates diretamente é equivalente a usar operações de backend do Service Connector. Quando constrói ligações usando lógica modelo diretamente, deve implementar as mesmas operações de autenticação que o Service Connector faria. A tabela seguinte lista as operações que deve traduzir para lógica modelo para cada tipo de tipo de autenticação.

Tipo de autenticação Operações obrigatórias
Secret ou connection string - Configurar a cadeia de conexão do serviço de destino nas definições de configuração da aplicação de serviço de origem.
- Configurar firewall no serviço alvo para permitir IPs de saída do serviço de origem.
Identidade atribuída gerida pelo sistema - Configurar o endpoint do serviço de destino nas definições da aplicação de serviço de origem.
- Configurar firewall no serviço alvo para permitir que o serviço de origem tenha IPs de saída.
- Ativar a identidade atribuída ao sistema no serviço de origem.
- Criar atribuição de funções para a identidade do serviço de origem no serviço de destino.
Identidade gerida atribuída pelo utilizador - Configurar o endpoint do serviço de destino nas definições da aplicação de serviço de origem.
- Configurar firewall no serviço alvo para permitir que o serviço de origem tenha IPs de saída.
- Associar a identidade atribuída pelo utilizador ao serviço de origem.
- Criar atribuição de funções para a identidade atribuída pelo utilizador no serviço alvo.
Service principal (Principal de serviço) - Configurar o endpoint do serviço de destino nas definições da aplicação de serviço de origem.
- Configurar a identificação de aplicativo principal do serviço e o segredo nas configurações da aplicação de serviço de origem.
- Configurar firewall no serviço alvo para permitir que o serviço de origem tenha IPs de saída.
- Criar atribuição de funções para o principal de serviço no serviço-alvo.