Compartilhar via


Boas práticas do Gerenciador de Serviços do Operador do Azure para integrar e implantar funções de rede

A Microsoft desenvolveu muitas práticas testadas e comprovadas para gerenciar funções de rede (NFs) usando o Gerenciador de Serviços do Operador do Azure. Este artigo fornece diretrizes que os fornecedores de NF, operadores de telecomunicações e seus parceiros podem seguir para otimizar o design. Tenha essas práticas em mente ao integrar e implantar suas NFs.

Considerações gerais

Recomendamos que você, primeiro, integre e implante suas NFs mais simples (um ou dois gráficos) usando os guias de início rápido para se familiarizar com o fluxo geral. Você poderá adicionar os detalhes de configuração necessários em iterações subsequentes. Ao percorrer os guias de início rápido, leve em conta os seguintes pontos:

  • Estruture seus artefatos para alinhá-los ao uso planejado. Pense em separar os artefatos globais dos artefatos que você quer que variem por site ou por instância.
  • Garanta uma composição de serviço de várias NFs com um conjunto de parâmetros que corresponda às necessidades da rede. Por exemplo, você pode ter um gráfico que tenha 1.000 valores e personalizar apenas 100 deles. Certifique-se de que, na camada do Esquema de Grupo de Configuração (CGS) — descrita com mais detalhes nas seções a seguir — você exponha apenas 100.
  • Decida logo no início como você quer separar a infraestrutura (por exemplo, os clusters) ou os repositórios de artefatos do acesso entre fornecedores, em particular dentro de um único serviço. Faça com que seu conjunto de recursos de distribuidor corresponda a esse modelo.
  • O site do Gerenciador de Serviços do Operador do Azure é um conceito lógico, uma representação de um destino de implantação. Os exemplos são um cluster do Kubernetes para Funções de Rede Conteinerizadas (CNFs) ou um local personalizado estendido do Nexus do Operador do Azure para Funções de Rede Virtualizadas (VNFs). Não se trata de uma representação de um site de borda físico. Portanto, você tem casos de uso em que vários sites compartilham o mesmo local físico.
  • O Gerenciador de Serviços do Operador do Azure fornece várias APIs, simplificando a combinação com o ADO ou outras ferramentas de pipeline.

Considerações para o fornecedor

  • Recomendamos que você crie um único distribuidor por fornecedor de NF. Essa prática fornece uma experiência de suporte, manutenção e governança otimizada em todos os fornecedores e simplifica o design do seu serviço de rede quando composto por várias NFs de vários vendedores.

  • Após o conjunto desejado de recursos e artefatos do distribuidor do Gerenciador de Serviços do Operador do Azure for testado e aprovado para uso na produção, recomendamos marcar todo o conjunto como imutável para evitar alterações acidentais e garantir uma experiência de implantação consistente. Pense em depender de recursos de imutabilidade para distinguir entre os recursos e artefatos usados na produção e os que são usados para fins de teste e desenvolvimento. Você pode consultar o estado dos recursos do distribuidor e os manifestos do artefato para determinar quais estão marcados como imutáveis. Para obter mais informações, confira Locatários, assinaturas, regiões e gerenciamento de versões prévias do distribuidor.

    Tenha em mente a seguinte lógica:

    • Se a Versão de Design do Serviço de Rede (NSDV) estiver marcada como imutável, o CGS também precisa ser marcado como imutável. Caso contrário, a chamada de implantação falhará.
    • Se a Versão de Design de Função de Rede (NFDV) estiver marcada como imutável, o manifesto do artefato também precisa ser marcado como imutável. Caso contrário, a chamada de implantação falhará.
    • Se apenas o manifesto do artefato ou CGS estiverem marcados como imutáveis, a chamada de implantação será bem-sucedida, independentemente de a NFDV e a NSDV estarem marcadas como imutáveis.
    • Marcar um manifesto de artefato como imutável garante que todos os artefatos listados nesse manifesto (geralmente gráficos, imagens e modelos do Azure Resource Manager [modelos do ARM]) também sejam marcados como imutáveis ao aplicar as permissões necessárias no repositório de artefatos.
  • Pense em usar as convenções de nomenclatura aceitas de comum acordo e as técnicas de governança para ajudar a abordar quaisquer lacunas restantes.

Considerações sobre Grupo e Versão de Definição de Função de Rede

O Grupo de Definição de Função de Rede (NFDG) representa o menor componente que você planeja reutilizar de forma independente em vários serviços. Todas as partes de um NFDG são sempre implantadas juntas. Essas partes são chamadas networkFunctionApplications. Por exemplo, é natural integrar uma única NF composta de várias imagens e gráficos Helm como um único NFDG se você sempre implanta esses componentes juntos. Nos casos em que várias NFs são sempre implantadas juntas, é razoável ter um único NFDG para todas elas. Um único NFDG pode ter várias NFDVs.

Para Versões de Definição de Função de Rede Conteinerizadas (NFDVs de CNF), a lista de networkFunctionApplications só pode conter pacotes Helm. É razoável incluir vários pacotes Helm se forem sempre implantados e excluídos juntos.

Para Versões de Definição de Função de Rede Virtualizadas (NFDVs de VNF), a lista de networkFunctionApplications precisa conter pelo menos um VhdImageFile e um modelo do ARM. O modelo do ARM deve implantar uma única máquina virtual (VM). Para implantar várias VMs para uma única VNF, use modelos do ARM separados para cada VM.

O modelo do ARM só pode implantar recursos do Resource Manager dos seguintes provedores de recursos:

  • Microsoft.Compute
  • Microsoft.Network
  • Microsoft.NetworkCloud
  • Microsoft.Storage
  • Microsoft.NetworkFabric
  • Microsoft.Authorization
  • Microsoft.ManagedIdentity

Observação

Para modelos do ARM que contenham qualquer coisa além da lista anterior, todas as chamadas PUT e Re-PUT na VNF resultam em um erro de validação.

Casos de uso comuns que disparam a versão secundária ou principal da Versão do Design da Função de Rede

  • Atualizar o CGS/Valores de Grupo de Configuração (CGVs) para uma versão existente que dispara a alteração do deployParametersMappingRuleProfile.
  • Atualizar valores incluídos no código na NFDV.
  • Marcar componentes como inativos para impedir que sejam implantados por meio de applicationEnablement: Disabled.
  • Nova versão da NF, como gráficos e imagens.

Observação

Número mínimo de alterações necessárias sempre que o conteúdo de uma determinada NF for alterado. Um lançamento de versão secundária ou principal da NF sem expor novos parâmetros do CGS requer apenas atualizar o manifesto do artefato, enviar novas imagens e gráficos por push e aumentar a versão da NFDV.

Considerações sobre Versão e Grupo de Design de Serviço de Rede

O Grupo de Design de Serviço de Rede (NSDG) é uma composição de um ou mais NFDGs e quaisquer componentes de infraestrutura (como máquinas virtuais e clusters do Serviço do Kubernetes do Nexus do Azure [NAKS]/Serviço de Kubernetes do Azure [AKS]) implantados ao mesmo tempo. Um serviço de rede de site (SNS) se refere a uma única NSDV. Esse design garante uma implantação consistente e repetível do serviço de rede em um determinado site a partir de um único PUT de SNS.

Um exemplo de um NSDG é:

  • NF Função de Servidor de Autenticação (AUSF)
  • NF Gerenciamento de Dados Unificados (UDM)
  • VM administrativa que atua como apoio a AUSF/UDM
  • NF Função de Gerenciamento de Sessão (SMF) do Unity Cloud (UC)
  • Cluster do NAKS, no qual a AUSF, o UDM e o SMF são implantados

Esses cinco componentes formam um único NSDG. Um único NSDG pode ter várias NSDVs.

Casos de uso comuns que disparam uma atualização de versão principal ou secundária da Versão de Design de Serviço de Rede

  • Como criar ou excluir CGSs.
  • Alterações no modelo do ARM da NF associado a uma das NFs que estão sendo implantadas.
  • Alterações no modelo do ARM da infraestrutura, por exemplo, AKS/NAKS ou VM.

Observação

As alterações na NFDV não devem disparar uma atualização da NSDV. O valor da NFDV deve ser exposto como um parâmetro dentro do CGS, para que os operadores possam controlar o que implantar usando CGVs.

Considerações sobre o Esquema de Grupo de Configuração

Recomendamos que você sempre comece com um único CGS para toda a NF. Se houver parâmetros específicos de um site ou de uma instância, mesmo assim recomendamos mantê-los em um único CGS. Recomendamos dividir em vários CGSs quando existirem vários componentes (raramente NFs, mais comumente infraestrutura) ou configurações que sejam compartilhados entre várias NFs. O número de CGSs define o número de CGVs.

Cenário

  • FluentD, Kibana e Splunk (componentes comuns de terceiros) são sempre implantados para todas as NFs em um NSD. Recomendamos agrupar esses componentes em um único NFDG.
  • O NSD tem várias NFs que compartilham algumas configurações (local de implantação, nome do distribuidor e algumas configurações de gráfico).

Nesse cenário, recomendamos que você use um único CGS global para expor as configurações comuns da NF e de componentes de terceiros. Você pode definir um CGS específico para a NF conforme necessário.

Escolher parâmetros para expor

  • O CGS deve ter apenas parâmetros usados por NFs (configuração do Dia 0/N) ou componentes compartilhados.
  • Parâmetros que raramente são configurados devem ter os valores padrão definidos.
  • Se vários CGSs forem usados, recomendamos pouca ou nenhuma sobreposição entre os parâmetros. Se a sobreposição for necessária, certifique-se de que os nomes dos parâmetros sejam claramente distinguíveis entre os CGSs.
  • Você deve pensar no que pode ser definido por meio de API (Nexus do Operador do Azure, Gerenciador de Serviços do Operador do Azure) para ser usado no CGS. Em vez de, por exemplo, definir esses valores de configuração por meio de arquivos CloudInit.
  • Quando você não tiver certeza, um bom ponto de partida é expor o parâmetro e ter um valor padrão razoável especificado no CGS. O exemplo a seguir mostra a amostra do CGS e as cargas do CGV correspondentes.
  • Uma única identidade gerenciada atribuída pelo usuário deve ser usada em todos os modelos do ARM da NF e deve ser exposta por meio do CGS.

Conteúdo do CGS:

{ 
  "type": "object", 
  "properties": { 
    "abc": { 
    "type": "integer", 
    "default": 30
    }, 
    "xyz": { 
    "type": "integer", 
    "default": 40
    },
    "qwe": {
    "type": "integer" //doesn't have defaults
    }
  }
  "required": "qwe"
}

Conteúdo do CGV correspondente repassado pelo operador:

{
"qwe": 20
}

Conteúdo do CGV resultante gerado pelo Gerenciador de Serviços do Operador do Azure:

{
"abc": 30,
"xyz": 40,
"qwe": 20
}

Considerações sobre Valores do Grupo de Configuração

Antes de enviar a criação de recursos do CGV, você pode validar se o esquema e os valores do arquivo YAML ou JSON subjacentes correspondem ao que o CGS correspondente espera. Para fazer isso, uma opção é usar a extensão YAML do Visual Studio Code.

Considerações sobre a CLI

A extensão da CLI do Gerenciador de Serviços do Operador do Azure ajuda a publicar NFDs e NSDs. Use essa ferramenta como ponto de partida para criar novos NFDs e NSDs. Pense em usar a CLI para criar os arquivos iniciais. Em seguida, edite-os para incorporar componentes de infraestrutura antes de publicar.

Considerações sobre o serviço de rede de site

Recomendamos que você tenha um único SNS para todo o site, incluindo a infraestrutura. O SNS deve implantar qualquer infraestrutura necessária (por exemplo, máquinas virtuais e clusters do NAKS/AKS) e, em seguida, implantar as NFs necessárias sobre essa base. Esse design garante uma implantação consistente e repetível do serviço de rede em um determinado site a partir de um único PUT de SNS.

Recomendamos que cada SNS seja implantado com uma identidade gerenciada atribuída pelo usuário em vez de uma identidade gerenciada atribuída pelo sistema. Essa identidade gerenciada atribuída pelo usuário precisa ter permissões para acessar a NFDV e ter a função de Operador de Identidade Gerenciada em si própria. Para obter mais informações, confira Criar e atribuir uma identidade gerenciada atribuída pelo usuário.

Mapeamento de recursos do Gerenciador de Serviços do Operador do Azure por caso de uso

Os dois cenários a seguir ilustram o mapeamento de recursos do Gerenciador de Serviços do Operador do Azure.

Cenário: função de rede única

Uma NF com um ou dois componentes de aplicativo é implantada em um cluster do NAKS.

Detalhamento dos recursos:

  • NFDG: se os componentes puderem ser usados de forma independente, dois NFDGs, um por componente. Se os componentes forem sempre implantados juntos, então use um único NFDG.
  • NFDV: conforme necessário, com base nos casos de uso mencionados nas seções "Casos de uso comuns" anteriores que disparam atualizações de versão secundárias ou principais de NFDV.
  • NSDG: único. Combina as definições de NFs e de cluster do Kubernetes.
  • NSDV: conforme necessário com base nos casos de uso mencionados nas seções "Casos de uso comuns" anteriores que disparam atualizações de versão secundárias ou principais da NSDV.
  • CGS: único. Recomendamos que o CGS tenha subseções para cada componente e infraestrutura que sendo implantados para facilitar o gerenciamento e inclua as versões de NFDs.
  • CGV: único com base no número de CGSs.
  • SNS: um único por NSDV.

Cenário: várias funções de rede

Várias NFs com alguns componentes compartilhados e independentes são implantados em um cluster do NAKS.

Detalhamento dos recursos:

  • NFDG:
    • NFDG para todos os componentes compartilhados.
    • NFDG para cada NF ou componente independente.
  • NFDV: várias por cada NFDG por caso de uso mencionado nas seções "Casos de uso comuns" anteriores que disparam atualizações de versão secundárias ou principais da NFDV.
  • NSDG: único. Combina todas as NFs, componentes compartilhados e independentes e infraestrutura (cluster do Kubernetes ou quaisquer VMs de apoio).
  • NSDV: conforme necessário com base nos casos de uso mencionados nas seções "Casos de uso comuns" anteriores que disparam atualizações de versão secundárias ou principais da NSDV.
  • CGS:
    • Solteiro. Global para todos os componentes que têm valores de configuração compartilhados.
    • CGS de NF por NF, incluindo a versão de NFD.
    • Dependendo do número total de parâmetros, pense em combinar todos os CGSs em um único CGS.
  • CGV: igual ao número de CGSs.
  • SNS: um único por NSDV.

Considerações sobre upgrade de software

Supondo que as NFs sejam compatíveis com upgrades in-loco/no serviço para CNFs:

  • Se novos gráficos e imagens forem adicionados, o Gerenciador de Serviços do Operador do Azure instalará os novos gráficos.
  • Se alguns gráficos e imagens forem removidos, o Gerenciador de Serviços do Operador do Azure excluirá os gráficos que não são mais declarados na NFDV.
  • O Gerenciador de Serviços do Operador do Azure valida que a NFDV/NSDV se originou do mesmo NFDG/NSDG e, portanto, do mesmo distribuidor. Não há suporte para upgrades multidistribuidor.

Para VNFs:

  • Atualmente, não há suporte para upgrades in-loco. Você precisa criar uma instância de uma nova VNF com uma imagem atualizada lado a lado. Em seguida, exclua a VNF antiga excluindo o SNS.
  • Se a VNF for implantada como um par de VMs para alta disponibilidade, você poderá projetar o serviço de rede de modo que possa excluir e fazer o upgrade das VMs uma por uma. Recomendamos o design a seguir para permitir a exclusão e o upgrade de VMs individuais:
    • Cada VM é implantada usando um modelo do ARM dedicado.
    • No modelo do ARM, dois parâmetros precisam ser expostos por meio do CGS: o nome da VM, para permitir indicar qual instância é primária/secundária e a política de implantação, controlando se a implantação de VM é permitida ou não.
    • Na NFDV, deployParameters e templateParameters precisam ser parametrizados de modo que você possa fornecer os valores exclusivos usando CGVs para cada um.

Considerações sobre alta disponibilidade e recuperação de desastre

O Gerenciador de Serviços do Operador do Azure é um serviço regional implantado nas diversas zonas de disponibilidade em regiões que dão suporte a ele. Para todas as regiões em que o Gerenciador de Serviços do Operador do Azure estiver disponível, confira Produtos do Azure por região. Para obter a lista de regiões do Azure que têm zonas de disponibilidade, confira Escolha a região do Azure adequada para você.

Pense nos seguintes requisitos de alta disponibilidade e recuperação de desastres:

  • Para fornecer redundância geográfica, verifique se você tem um distribuidor em cada uma das regiões em que estiver planejando implantar NFs. Pense em usar pipelines para se certificar de que os artefatos e recursos do distribuidor sejam mantidos em sincronia nas várias regiões.
  • O nome do distribuidor precisa ser exclusivo por região e por locatário do Microsoft Entra.

Observação

Se uma região ficar indisponível, você poderá implantar uma NF (mas não fazer um upgrade) usando recursos do distribuidor em outra região. Supondo que os artefatos e recursos sejam idênticos entre os distribuidores, você só precisa alterar o valor networkServiceDesignVersionOfferingLocation no conteúdo do recurso SNS.

resource sns 'Microsoft.HybridNetwork/sitenetworkservices@2023-09-01’ = {
 name: snsName
 location: location
 identity: {
  type: 'SystemAssigned'
 }
 properties: {
   publisherName: publisherName
   publisherScope: 'Private'
   networkServiceDesignGroupName: nsdGroup
   networkServiceDesignVersionName: nsdvName
   networkServiceDesignVersionOfferingLocation: location

Considerações sobre solução de problemas

Durante a instalação e o upgrade, por padrão, as opções atômicas e de espera são definidas como true e o tempo limite da operação é definido como 27 minutes. Durante a integração, recomendamos que você defina o sinalizador atômico como false para evitar a reversão do Helm após uma falha. A maneira ideal de fazer isso está no modelo do ARM da NF.

No modelo do ARM, adicione a seguinte seção:

"roleOverrideValues": [
    "{\"name\":\"NF_component_name>\",\"deployParametersMappingRuleProfile\":{\"helmMappingRuleProfile\":{\"options\":{\"installOptions\":{\"atomic\":\"false\",\"wait\":\"true\",\"timeout\":\"100\"},\"upgradeOptions\":{\"atomic\":\"true\",\"wait\":\"true\",\"timeout\":\"4\"}}}}}"
]

O nome do componente é definido na NFDV:

     networkFunctionTemplate: {
      nfviType: 'AzureArcKubernetes'
      networkFunctionApplications: [
        {
          artifactType: 'HelmPackage'
          name: 'fed-crds'
          dependsOnProfile: null
          artifactProfile: {
            artifactStore: {
              id: acrArtifactStore.id
            }

Considerações de limpeza

Exclua os recursos do operador na seguinte ordem, para garantir que nenhum recurso órfão seja deixado para trás:

  • SNS
  • Site
  • CGV

Importante

Certifique-se de que o SNS seja excluído antes de excluir a NFDV.

Exclua os recursos do distribuidor na seguinte ordem, para garantir que nenhum recurso órfão seja deixado para trás:

  • CGS
  • NSDV
  • NSDG
  • NFDV
  • NFDG
  • Manifesto do artefato
  • Armazenamento de artefatos
  • Editor

Considerações caso sua NF execute o cert-manager

Importante

Essas diretrizes se aplica apenas a determinadas versões. Verifique se a sua versão apresenta o comportamento adequado.

Da versão 1.0.2728-50 até a versão 2.0.2777-132, o AOSM usa o cert-manager para armazenar e alternar certificados. Como parte dessa alteração, o AOSM implanta um operador de cert-manager e associa CRDs no namespace azurehybridnetwork. Como, por ter vários operadores de cert-manager, mesmo implantados em namespaces separados, todos os namespaces serão observados, apenas um cert-manager pode ser executado efetivamente no cluster.

Qualquer usuário que tentar instalar o cert-manager no cluster, como parte de uma implantação de carga de trabalho, receberá uma falha de implantação com um erro afirmando que a CRD "existe e não pode ser importada para a versão atual". Para evitar esse erro, a recomendação é ignorar a instalação do cert-manager e, em vez disso, usar a dependência do operador do cert-manager e do CRD já instalados pelo AOSM.

Outras alterações de configuração a serem consideradas

Além de desabilitar o NfApp associado ao antigo cert-manager do usuário, descobrimos que outras alterações podem ser necessárias;

  1. Se um NfApp contiver o gerenciador de certificados e a instalação da AC, eles precisarão ser divididos em dois NfApps, para que o parceiro possa desabilitar o gerenciador de certificados, mas habilitar a instalação da AC.
  2. Se tiverem referências to tipo DependsOn ao NfApp do antigo cert-manager do usuário, todos os outros NfApps precisarão ser removidos.
  3. Se quaisquer outros NfApps fizerem referência ao valor do namespace do antigo cert-manager do usuário, esse valor precisará ser alterado para o novo valor do namespace azurehybridnetwork.

Gerenciamento e compatibilidade de versão do Cert-Manager

Para o operador do cert-manager, nossa versão atual implantada é 1.14.5. Os usuários devem testar a compatibilidade com essa versão. Futuros upgrades do operador do cert-manager terão suporte por meio do processo de upgrade da extensão do NFO.

Para os recursos de CRD, nossa versão atual implantada é 1.14.5. Os usuários devem testar a compatibilidade com essa versão. Como o gerenciamento de um CRD de cluster comum é algo que costuma ser realizado por um administrador de cluster, estamos trabalhando para habilitar os upgrades de recursos de CRD por meio do processo padrão de Complemento do Nexus.

Comportamento de ordenação sequencial de NfApp

Visão geral

Por padrão, os NfApps (aplicativos de função de rede em contêineres) são instalados ou atualizados com base na ordem sequencial na qual eles aparecem na NFDV (versão de design de função de rede). Para exclusão, os NfApps são excluídos na ordem inversa especificada. Quando um fornecedor precisa definir uma ordenação específica de NfApps diferente do padrão, um dependsOnProfile é usado para definir uma sequência exclusiva para operações de instalação, atualização e exclusão.

Como usar dependsOnProfile

Um fornecedor pode usar dependsOnProfile no NFDV para controlar a sequência de execuções do helm para NfApps. Dado o exemplo a seguir, na operação de instalação, o NfApps será implantado na seguinte ordem: dummyApplication1, dummyApplication2 e, em seguida, dummyApplication. Na operação de atualização, o NfApps será atualizado na seguinte ordem: dummyApplication2, dummyApplication1 e, em seguida, dummyApplication. Na operação de exclusão, o NfApps será excluído na seguinte ordem: dummyApplication2, dummyApplication1 e, em seguida, dummyApplication.

{
    "location": "eastus",
    "properties": {
        "networkFunctionTemplate": {
            "networkFunctionApplications": [
                {
                  "dependsOnProfile": {
                        "installDependsOn": [
                            "dummyApplication1",
                            "dummyApplication2"
                        ],
                        "uninstallDependsOn": [
                            "dummyApplication1"
                        ],
                        "updateDependsOn": [
                            "dummyApplication1"
                        ]
                    },
                    "name": "dummyApplication"
                },
                {
                  "dependsOnProfile": {
                        "installDependsOn": [
                        ],
                        "uninstallDependsOn": [
                            "dummyApplication2"
                        ],
                        "updateDependsOn": [
                            "dummyApplication2"
                        ]
                    },
                    "name": "dummyApplication1"
                },
                {
                    "dependsOnProfile": null,
                    "name": "dummyApplication2"
                }
            ],
            "nfviType": "AzureArcKubernetes"
        },
        "networkFunctionType": "ContainerizedNetworkFunction"
    }
}

Erros comuns

A partir de hoje, se dependsOnProfile fornecido no NFDV for inválido, a operação NF falhará com um erro de validação. A mensagem de erro de validação é mostrada no recurso de status da operação e é semelhante ao exemplo a seguir.

 {
  "id": "/providers/Microsoft.HybridNetwork/locations/EASTUS2EUAP/operationStatuses/ca051ddf-c8bc-4cb2-945c-a292bf7b654b*C9B39996CFCD97AB3A121AE136ED47F67BB13946C573EF90628C47628BC5EF5F",
  "name": "ca051ddf-c8bc-4cb2-945c-a292bf7b654b*C9B39996CFCD97AB3A121AE136ED47F67BB13946C573EF90628C47628BC5EF5F",
  "resourceId": "/subscriptions/4a0479c0-b795-4d0f-96fd-c7edd2a2928f/resourceGroups/xinrui-publisher/providers/Microsoft.HybridNetwork/networkfunctions/testnfDependsOn02",
  "status": "Failed",
  "startTime": "2023-07-17T20:48:01.4792943Z",
  "endTime": "2023-07-17T20:48:10.0191285Z",
  "error": {
    "code": "DependenciesValidationFailed",
    "message": "CyclicDependencies: Circular dependencies detected at hellotest."
  }
}