Compartilhar via


Implantar um aplicativo Web em um pipeline e configurar a autenticação Serviço de Aplicativo

Este artigo descreve como configurar um pipeline no Azure Pipelines para criar e implantar um aplicativo Web no Azure e habilitar a autenticação interna do Serviço de Aplicativo do Azure.

Você aprenderá a:

  • Configurar recursos do Azure usando scripts no Azure Pipelines
  • Criar um aplicativo Web e implantar no Serviço de Aplicativo usando o Azure Pipelines
  • Criar um registro de aplicativo do Microsoft Entra no Azure Pipelines
  • Configure a autenticação interna do Serviço de Aplicativo no Azure Pipelines.

Pré-requisitos

Criar um aplicativo Web ASP.NET Core de amostra

Crie um aplicativo de exemplo e envie-o por push para o repositório GitHub.

Criar e clonar um repositório no GitHub

Crie um novo repositório no GitHub, especifique um nome como "PipelinesTest". Defina-o como Privado e adicione um arquivo .gitignore com .gitignore template: VisualStudio.

Abra uma janela do terminal e altere o diretório de trabalho atual para o local em que você deseja o diretório clonado:

cd c:\temp\

Insira o seguinte comando para clonar o repositório:

git clone https://github.com/YOUR-USERNAME/PipelinesTest
cd PipelinesTest

Criar um aplicativo Web ASP.NET Core

  1. Abra uma janela do terminal em seu computador para um diretório de trabalho. Crie um novo aplicativo Web ASP.NET Core usando o novo comando webapp dotnet e, em seguida, altere os diretórios para o aplicativo recém-criado.

    dotnet new webapp -n PipelinesTest --framework net7.0
    cd PipelinesTest
    dotnet new sln
    dotnet sln add .
    
  2. Na mesma sessão do terminal, execute o aplicativo localmente usando o comando de execução dotnet.

    dotnet run --urls=https://localhost:5001/
    
  3. Para verificar se o aplicativo Web está em execução, abra um navegador da Web e navegue até o aplicativo em https://localhost:5001.

Você verá o modelo do aplicativo Web ASP.NET Core exibido na página.

Captura de tela que mostra o aplicativo Web em execução localmente.

Insira CTRL-C na linha de comando para parar de executar o aplicativo Web.

Enviar o exemplo por push para o GitHub

Confirme suas alterações e envie por push para o GitHub:

git add .
git commit -m "Initial check-in"
git push origin main

Configurar seu ambiente do Azure DevOps

Entre na sua organização do Azure DevOps (https://dev.azure.com/{yourorganization}).

Crie um novo projeto:

  1. Selecione Novo projeto.
  2. Insira um nome de projeto, como "PipelinesTest".
  3. Selecione visibilidade privada .
  4. Selecione Criar.

Criar um novo pipeline

Depois que o projeto for criado, adicione um pipeline:

  1. No painel de navegação esquerdo, selecione Pipelines->Pipelines, e, em seguida, selecione Criar Pipeline.
  2. Selecione o YAML do GitHub.
  3. Na guia Conectar, selecioneGitHub YAML. Quando solicitado, insira suas credenciais do GitHub.
  4. Quando a lista de repositórios for exibida, selecione o seu repositório PipelinesTest.
  5. Você poderá ser redirecionado ao GitHub para instalar o aplicativo do Azure Pipelines. Em caso afirmativo, selecione Aprovar & instalar.
  6. Em Configurar o pipeline, selecione o Pipeline Inicial.
  7. Um novo pipeline com uma configuração básica é exibido. A configuração padrão usa um agente hospedado pela Microsoft.
  8. Quando estiver pronto, selecione Salvar e executar. Para confirmar suas alterações no GitHub e iniciar o pipeline, escolha Confirmar diretamente na ramificação principal e selecione Salvar e executar uma segunda vez. Se solicitado a conceder permissão com uma mensagem como Este pipeline precisa de permissão para acessar um recurso antes que essa execução possa continuar, escolha Exibir e siga os prompts para permitir o acesso.

Adicionar um estágio de build e criar tarefas ao pipeline

Agora que você tem um pipeline de trabalho, pode adicionar um estágio de build e criar tarefas para criar o aplicativo Web.

Atualize azure-pipelines.yml e substitua a configuração básica do pipeline pelo seguinte:

trigger:
- main

stages:
- stage: Build
  jobs: 
  - job: Build

    pool:
      vmImage: 'windows-latest'

    variables:
      solution: '**/*.sln'
      buildPlatform: 'Any CPU'      
      buildConfiguration: 'Release'      

    steps:
    - task: NuGetToolInstaller@1

    - task: NuGetCommand@2
      inputs:
        restoreSolution: '$(solution)'

    - task: VSBuild@1
      inputs:
        solution: '$(solution)'
        msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
        platform: '$(buildPlatform)'
        configuration: '$(buildConfiguration)'
        
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: 'drop'
        publishLocation: 'Container'

Salve suas alterações e execute o pipeline.

Um estágio Build é definido para criar o aplicativo Web. Na seção steps, você verá várias tarefas para criar o aplicativo Web e publicar artefatos no pipeline.

  • NuGetToolInstaller@1 adquire o NuGet e adiciona-o ao PATH.
  • NuGetCommand@2 restaura pacotes NuGet na solução.
  • VSBuild@1 cria a solução com o MSBuild e empacota os resultados de build do aplicativo (incluindo suas dependências) como um arquivo .zip em uma pasta.
  • PublishBuildArtifacts@1 publica o arquivo .zip no Azure Pipelines.

Criar uma conexão de serviço

Adicione uma conexão de serviço para que o pipeline possa se conectar e implantar recursos no Azure:

  1. Selecione as configurações do Projeto.
  2. No painel de navegação esquerdo, selecione Conexões de serviço e, em seguida, Crie conexão de serviço.
  3. Selecione o Azure Resource Manager e, em seguida, Avançar.
  4. Selecione Entidade de serviço (automático) e, em seguida, Avançar.
  5. Selecione Assinatura para o nível de escopo e selecione sua assinatura do Azure. Insira um nome de conexão de serviço, como "PipelinesTestServiceConnection" e selecione Avançar. O nome da conexão de serviço é usado nas etapas a seguir.

Um aplicativo também é criado em seu locatário do Microsoft Entra que fornece uma identidade para o pipeline. Você precisará do nome de exibição do registro do aplicativo em etapas posteriores. Para localizar o nome de exibição:

  1. Entre no Centro de administração do Microsoft Entra como pelo menos um Desenvolvedor de Aplicativos.
  2. Navegue até Entra ID>Registros de aplicativos>Todos os aplicativos.
  3. Localize o nome de exibição do registro do aplicativo, que é do formulário {organization}-{project}-{guid}.

Conceda a permissão de conexão de serviço para acessar o pipeline:

  1. No painel de navegação esquerdo, selecione as configurações do Project e, em seguida, as conexões de serviço.
  2. Selecione a conexão de serviço PipelinesTestServiceConnection, as Reticências e, em seguida, Segurança no menu suspenso.
  3. Na seção Permissões de pipeline , selecione Adicionar pipeline e selecione a conexão de serviço PipelinesTest na lista.

Adicionar um grupo de variáveis

O estágio DeployAzureResources criado na próxima seção usa vários valores para criar e implantar recursos no Azure:

  • A ID de locatário do Microsoft Entra ID (encontrada no centro de administração do Microsoft Entra).
  • A região ou o local em que os recursos são implantados.
  • Um nome de grupo de recursos.
  • O nome do plano de serviço do Serviço de Aplicativo.
  • O nome do aplicativo Web.
  • O nome da conexão de serviço usada para conectar o pipeline ao Azure. No pipeline, esse valor é usado para a assinatura do Azure.

Crie um grupo de variáveis e adicione valores a serem usados como variáveis no pipeline.

Selecione Biblioteca no painel de navegação esquerdo e crie um novo grupo variável. Dê a ele o nome "AzureResourcesVariableGroup".

Adicione as seguintes variáveis e valores:

Nome da variável Valor do exemplo
LOCALIZAÇÃO centralus
TENANTID {tenant-id}
RESOURCEGROUPNAME pipelinetestgroup
SVCPLANNAME pipelinetestplan
WEBAPPNAMETEST pipelinetestwebapp
AZURESUBSCRIPTION PipelinesTestServiceConnection

Selecione Salvar.

Conceda permissões de pipeline para acessar o grupo de variáveis. Na página do grupo de variáveis, selecione Permissões de pipeline, adicione seu pipeline e feche a janela.

Atualize azure-pipelines.yml e adicione o grupo de variáveis ao pipeline.

variables: 
- group: AzureResourcesVariableGroup
   
trigger:
- main

stages:
- stage: Build
  jobs: 
  - job: Build

    pool:
      vmImage: 'windows-latest'
  

Salve suas alterações e execute o pipeline.

Implantar recursos do Azure

Em seguida, adicione um estágio ao pipeline que implanta recursos do Azure. O pipeline usa um script embutido para criar a instância de Serviço de Aplicativo. Em uma etapa posterior, o script embutido cria um registro de aplicativo do Microsoft Entra para autenticação do Serviço de Aplicativo. Um script bash da CLI do Azure é usado porque o Azure Resource Manager (e as tarefas do Azure Pipelines) não podem criar um registro de aplicativo.

O script embutido é executado no contexto do pipeline, atribua a função Application.Administrator ao aplicativo para que o script possa criar registros de aplicativo:

  1. Entre no Centro de administração do Microsoft Entra.
  2. Navegue até o Entra ID>Funções & administradores.
  3. Selecione Administrador de Aplicativos na lista de funções internas e, em seguida, Adicione atribuição.
  4. Pesquise o registro do aplicativo de pipeline por nome de exibição.
  5. Selecione o registro do aplicativo na lista e selecione Adicionar.

Atualize azure-pipelines.yml para adicionar o script embutido, que cria um grupo de recursos no Azure, cria um plano do Serviço de Aplicativo e cria uma instância do Serviço de Aplicativo.

variables: 
- group: AzureResourcesVariableGroup
   
trigger:
- main

stages:
- stage: Build
  jobs: 
  - job: Build

    pool:
      vmImage: 'windows-latest'

    variables:
      solution: '**/*.sln'
      buildPlatform: 'Any CPU'
      buildConfiguration: 'Release'      

    steps:
    - task: NuGetToolInstaller@1

    - task: NuGetCommand@2
      inputs:
        restoreSolution: '$(solution)'

    - task: VSBuild@1
      inputs:
        solution: '$(solution)'
        msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
        platform: '$(buildPlatform)'
        configuration: '$(buildConfiguration)'
        
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: 'drop'
        publishLocation: 'Container'  
    
- stage: DeployAzureResources
  displayName: 'Deploy resources to Azure'
  dependsOn: Build
  condition: |
    succeeded()    
  jobs: 
  - job: DeployAzureResources
    pool: 
      vmImage: 'windows-latest'
    steps:
      - task: AzureCLI@2
        inputs:
          azureSubscription: $(AZURESUBSCRIPTION)
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: |
            # Create a resource group
            az group create --location $LOCATION --name $RESOURCEGROUPNAME
            echo "Created resource group $RESOURCEGROUPNAME"    

            # Create App Service plan
            az appservice plan create -g $RESOURCEGROUPNAME -n $SVCPLANNAME --sku FREE
            echo "Created App Service plan $SVCPLANNAME"
            
            ### Create Test resources
            # create and configure an Azure App Service web app
            az webapp create -g $RESOURCEGROUPNAME -p $SVCPLANNAME -n $WEBAPPNAMETEST -r "dotnet:7"
                        
        name: DeploymentScript

Salve suas alterações e execute o pipeline. No portal do Azure, navegue até grupos de recursos e verifique se um novo grupo de recursos e uma instância do Serviço de Aplicativo foram criados.

Implantar o aplicativo Web no Serviço de Aplicativo

Agora que o pipeline está criando recursos no Azure, uma fase de implantação para implantar o aplicativo Web no Serviço de Aplicativo.

Atualize azure-pipelines.yml para adicionar o estágio de implantação.

variables: 
- group: AzureResourcesVariableGroup
   
trigger:
- main

stages:
- stage: Build
  jobs: 
  - job: Build

    pool:
      vmImage: 'windows-latest'

    variables:
      solution: '**/*.sln'
      buildPlatform: 'Any CPU'
      buildConfiguration: 'Release'      

    steps:
    - task: NuGetToolInstaller@1

    - task: NuGetCommand@2
      inputs:
        restoreSolution: '$(solution)'

    - task: VSBuild@1
      inputs:
        solution: '$(solution)'
        msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
        platform: '$(buildPlatform)'
        configuration: '$(buildConfiguration)'
        
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: 'drop'
        publishLocation: 'Container'  
    
- stage: DeployAzureResources
  displayName: 'Deploy resources to Azure'
  dependsOn: Build
  condition: |
    succeeded()    
  jobs: 
  - job: DeployAzureResources
    pool: 
      vmImage: 'windows-latest'
    steps:
      - task: AzureCLI@2
        inputs:
          azureSubscription: $(AZURESUBSCRIPTION)
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: |
            # Create a resource group
            az group create --location $LOCATION --name $RESOURCEGROUPNAME
            echo "Created resource group $RESOURCEGROUPNAME"    

            # Create App Service plan
            az appservice plan create -g $RESOURCEGROUPNAME -n $SVCPLANNAME --sku FREE
            echo "Created App Service plan $SVCPLANNAME"
            
            ### Create Test resources
            # create and configure an Azure App Service web app
            az webapp create -g $RESOURCEGROUPNAME -p $SVCPLANNAME -n $WEBAPPNAMETEST -r "dotnet:7"
            
        name: DeploymentScript

- stage: DeployWebApp
  displayName: 'Deploy the web app'
  dependsOn: DeployAzureResources
  condition: |
    succeeded()    
  
  jobs: 
  - job: DeployWebApp
    displayName: 'Deploy Web App'
    pool: 
      vmImage: 'windows-latest'
    
    steps:
      
    - task: DownloadBuildArtifacts@0
      inputs:
        buildType: 'current'
        downloadType: 'single'
        artifactName: 'drop'
        downloadPath: '$(System.DefaultWorkingDirectory)'
    - task: AzureRmWebAppDeployment@4
      inputs:
        ConnectionType: 'AzureRM'
        azureSubscription: $(AZURESUBSCRIPTION)
        appType: 'webApp'
        WebAppName: '$(WEBAPPNAMETEST)'
        packageForLinux: '$(System.DefaultWorkingDirectory)/**/*.zip'

Salve suas alterações e execute o pipeline.

Um estágio DeployWebApp é definido com várias tarefas:

Exibir o site implantado no Serviço de Aplicativo. Navegue até o Serviço de Aplicativo e selecione o domínio Padrão da instância: https://pipelinetestwebapp.azurewebsites.net.

Captura de tela que mostra a URL de domínio padrão.

O pipelinetestwebapp foi implantado com sucesso no App Service.

Captura de tela que mostra o aplicativo Web em execução no Azure.

Configurar a autenticação do Serviço de Aplicativo

Agora que o pipeline está implantando o aplicativo web no App Service, você pode configurar a autenticação interna do App Service. Modifique o script embutido em DeployAzureResources para:

  1. Crie um registro de aplicativo do Microsoft Entra como uma identidade para seu aplicativo Web. Para criar um registro de aplicativo, a entidade de serviço que executa o pipeline precisa da função de administrador do aplicativo no diretório.
  2. Obtenha um segredo do aplicativo.
  3. Defina a configuração de segredo para o aplicativo Web do Serviço de Aplicativo.
  4. Defina o URI de redirecionamento, o URI da página inicial e as configurações do emissor para o aplicativo Web do Serviço de Aplicativo.
  5. Defina outras configurações no aplicativo Web.
variables: 
- group: AzureResourcesVariableGroup
   
trigger:
- main

stages:
- stage: Build
  jobs: 
  - job: Build

    pool:
      vmImage: 'windows-latest'

    variables:
      solution: '**/*.sln'
      buildPlatform: 'Any CPU'
      buildConfiguration: 'Release'      

    steps:
    - task: NuGetToolInstaller@1

    - task: NuGetCommand@2
      inputs:
        restoreSolution: '$(solution)'

    - task: VSBuild@1
      inputs:
        solution: '$(solution)'
        msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
        platform: '$(buildPlatform)'
        configuration: '$(buildConfiguration)'
        
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: 'drop'
        publishLocation: 'Container'  
    
- stage: DeployAzureResources
  displayName: 'Deploy resources to Azure'
  dependsOn: Build
  condition: |
    succeeded()    
  jobs: 
  - job: DeployAzureResources
    pool: 
      vmImage: 'windows-latest'
    steps:
      - task: AzureCLI@2
        inputs:
          azureSubscription: $(AZURESUBSCRIPTION)
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: |
            # Create a resource group
            az group create --location $LOCATION --name $RESOURCEGROUPNAME
            echo "Created resource group $RESOURCEGROUPNAME"    

            # Create App Service plan
            az appservice plan create -g $RESOURCEGROUPNAME -n $SVCPLANNAME --sku FREE
            echo "Created App Service plan $SVCPLANNAME"
            
            ### Create Test resources
            # create and configure an Azure App Service web app
            az webapp create -g $RESOURCEGROUPNAME -p $SVCPLANNAME -n $WEBAPPNAMETEST -r "dotnet:7"

            redirectUriTest="https://$WEBAPPNAMETEST.azurewebsites.net/.auth/login/aad/callback"
            homePageUrlTest="https://$WEBAPPNAMETEST.azurewebsites.net"
            issuerTest="https://sts.windows.net/$TENANTID"
            
            # Required resource access.  Access Microsoft Graph with delegated User.Read permissions.
            cat > manifest.json << EOF
            [
                {
                    "resourceAppId": "00000003-0000-0000-c000-000000000000",
                    "resourceAccess": [
                        {
                            "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
                            "type": "Scope"
                        }
                    ]
                }
            ]
            EOF
            
            # Create app registration for App Service authentication
            appIdTest=$(az ad app create --display-name $WEBAPPNAMETEST --sign-in-audience AzureADMyOrg --enable-id-token-issuance true --query appId --output tsv)
            echo "Created app registration $appIdTest"

            # Set identifier URI, homepage, redirect URI, and resource access
            az ad app update --id $appIdTest --identifier-uris api://$appIdTest --web-redirect-uris $redirectUriTest  --web-home-page-url $homePageUrlTest --required-resource-accesses @manifest.json
            echo "Updated app $appIdTest"

            # Get secret from the app for App Service authentication
            secretTest=$(az ad app credential reset --id $appIdTest --query password --output tsv)
            echo "Added secret to app $appIdTest"

            az config set extension.use_dynamic_install=yes_without_prompt
            az extension add --name authV2                      

            az webapp config appsettings set --name $WEBAPPNAMETEST --resource-group $RESOURCEGROUPNAME --slot-settings MICROSOFT_PROVIDER_AUTHENTICATION_SECRET=$secretTest
            echo "Updated settings for web app $WEBAPPNAMETEST"

            az webapp auth microsoft update --name $WEBAPPNAMETEST --resource-group $RESOURCEGROUPNAME --client-id $appIdTest --secret-setting MICROSOFT_PROVIDER_AUTHENTICATION_SECRET --allowed-audiences $redirectUriTest  --issuer $issuerTest
            echo "Updated authentication settings for $WEBAPPNAMETEST"
            
        name: DeploymentScript

- stage: DeployWebApp
  displayName: 'Deploy the web app'
  dependsOn: DeployAzureResources
  condition: |
    succeeded()    
  
  jobs: 
  - job: DeployWebApp
    displayName: 'Depoy Web App'
    pool: 
      vmImage: 'windows-latest'
    
    steps:
      
    - task: DownloadBuildArtifacts@0
      inputs:
        buildType: 'current'
        downloadType: 'single'
        artifactName: 'drop'
        downloadPath: '$(System.DefaultWorkingDirectory)'
    - task: AzureRmWebAppDeployment@4
      inputs:
        ConnectionType: 'AzureRM'
        azureSubscription: $(AZURESUBSCRIPTION)
        appType: 'webApp'
        WebAppName: '$(WEBAPPNAMETEST)'
        packageForLinux: '$(System.DefaultWorkingDirectory)/**/*.zip'

Salve suas alterações e execute o pipeline.

Verificar o acesso limitado ao aplicativo Web

Para verificar se o acesso ao seu aplicativo está limitado aos usuários em sua organização, navegue até o Serviço de Aplicativo e selecione o domínio Padrão da instância: https://pipelinetestwebapp.azurewebsites.net.

Você deverá ser direcionado para uma página de entrada segura, confirmando que os usuários não autenticados não têm permissão de acesso ao site. Entre como um usuário em sua organização para obter acesso ao site.

Você também pode iniciar um novo navegador e tentar entrar usando uma conta pessoal para confirmar se os usuários fora da organização não têm acesso.

Limpar os recursos

Limpe os recursos do Azure e o ambiente do Azure DevOps para que você não seja cobrado pelos recursos depois de terminar.

Exclua o grupo de recursos

Selecione grupos de recursos no menu e selecione o grupo de recursos que contém seu aplicativo Web implantado.

Selecione Excluir grupo de recursos para excluir o grupo de recursos e todos os recursos.

Desabilitar o pipeline ou excluir o projeto do Azure DevOps

Você criou um projeto que aponta para um repositório GitHub. O pipeline é disparado para ser executado sempre que você envia uma alteração por push para o repositório GitHub, consumindo minutos de build gratuitos ou seus recursos.

Opção 1: Desabilitar o pipeline

Escolha essa opção caso queira manter seu projeto e o pipeline de build para referência futura. Você poderá habilitar o pipeline novamente mais tarde se desejar.

  1. Em seu projeto do Azure DevOps, selecione Pipelines e selecione seu pipeline.
  2. Selecione o botão de reticências na extrema direita e escolha Configurações.
  3. Selecione Desabilitado e, em seguida, selecione Salvar. O pipeline não processará mais as novas solicitações de execução.

Opção 2: Excluir o projeto

Escolha essa opção se não precisar do projeto de DevOps para referência futura. Isso exclui o seu projeto do Azure DevOps.

  1. Navegue até seu projeto do Azure DevOps.
  2. Selecione as configurações do Project no canto inferior esquerdo.
  3. Em Visão geral, role para baixo até a parte inferior da página e selecione Excluir.
  4. Digite o nome do projeto na caixa de texto e selecione Excluir.

Excluir registros de aplicativo no Microsoft Entra ID

No Centro de administração do Microsoft Entra, selecione Entra ID>Registros de aplicativos>Todos os aplicativos.

Selecione o aplicativo para o pipeline, o nome de exibição tem o formulário {organization}-{project}-{guid}, e exclua-o.

Selecione o aplicativo para o aplicativo Web, pipelinetestwebapp, e exclua-o.

Próximas etapas

Saiba mais sobre: