Sobre IIS, Web Deploy e WinRM

Se você já precisou implantar um web site ASP.NET a partir do Release Management do TFS/VSTS, é possível que tenha usado a task Web App Deployment da extensão IIS Web App Deployment Using WinRM.

O que não te contaram é que talvez você tenha feito uma péssima escolha…

Que comece a polêmica!

O "problema" todo reside no WinRM – ou, mais especificamente, na decisão dos autores dessa extensão de usar o WinRM para fazer o deployment de um web site no IIS.

E por que o WinRM é um problema? É que ele torna muito complicado algo que podia ser muito mais simples!

Mas, afinal, o que é o WinRM?

Para entender o cerne da questão, precisamos começar entendendo o que é o WinRM, e o tipo de problema que ele se propõe a resolver.

De acordo com a documentação da Microsoft, "Windows Remote Management (WinRM) is the Microsoft implementation of WS-Management Protocol, a standard Simple Object Access Protocol (SOAP)-based, firewall-friendly protocol that allows hardware and operating systems, from different vendors, to interoperate."

Em outras palavras, o WinRM é um protocolo baseado em SOAP que permite a administração remota de sistemas que implementem o protocolo WS-Management. Dentre as várias coisas que o WinRM permite fazer, a mais comum é a conexão a um terminal remoto, tal como o SSH num sistema Linux. Com isso, é possível conectar num servidor remoto via linha de comando e executar instruções como se estivéssemos diretamente no console do servidor – como eu disse, tal qual uma sessão SSH.

Extensão de deployment via WinRM. Note que é preciso primeiramente usar uma task de cópia de arquivos (1) para transferir o conteúdo do web site para um diretório temporário no servidor remoto antes de fazer a instalação propriamente dita no IIS (2)
Extensão de deployment via WinRM. Note que é preciso primeiramente usar uma task de cópia de arquivos (1) para transferir o conteúdo do web site para um diretório temporário no servidor remoto antes de fazer a instalação propriamente dita no IIS (2)

A extensão de deployment de IIS que mencionei acima usa o WinRM para iniciar uma sessão remota (a la SSH) e executar o comando msdeploy.exe no servidor IIS para implantar a aplicação. Mas isso é desnecessariamente complicado! Senão, vejamos:

  1. Primeiramente é preciso copiar todos os arquivos do web site (o pacote de Web Deploy gerado durante o build de um site ASP.NET) para dentro do servidor de destino. Isso implica em usar alguma ferramenta de cópia de arquivos a partir do agente de release para o servidor de destino (FTP, Windows File Share ou algo que o valha);
  2. Depois, precisamos garantir que o Web Deploy esteja instalado no servidor de destino, pois a task depende de encontrar o arquivo msdeploy.exe lá no servidor onde está o IIS;
  3. Como se não bastasse, ainda precisamos configurar o WinRM no servidor IIS para aceitar chamadas remotas a partir do agente de release. E, acredite, isso pode dar um baita trabalho. É preciso se preocupar com credenciais, certificados, hosts confiáveis, HTTP vs. HTTPS… Sem contar que a configuração precisa ser feita nas duas pontas (agente e servidor). Ah, e boa sorte se seus servidores não estiverem num mesmo domínio!
  4. Tipicamente, o usuário precisa ter privilégios de administrador para se conectar ao servidor remoto. Ou seja, o agente de release vai ter mais privilégios do que deveria apenas para implantar um web site;
  5. Por fim, mas não menos importante: Você escancarou várias "portas" em seu servidor, que permitem inclusive acesso administrativo completo, quando tudo o que você queria era fazer deployment de um web site. É uma superfície de ataque desnecessariamente grande, principalmente se seu servidor Web estiver numa DMZ.

Ao invés disso, que tal usar um serviço que permita unicamente a implantação remota de uma aplicação Web num servidor IIS, sem o footprint gigante de uma solução baseada em WinRM?

Esse serviço já existe. Aliás, é bem provável que ele já esteja instalado em seu servidor IIS e você nem saiba.

A surpresa, para mim, é: Por que os autores da extensão não usaram este serviço desde o início?!

IIS Web Management Service

O IIS Web Management Service (WMSVC) é um recurso do IIS que permite a administração remota do servidor. O Web Deploy, por sua vez, oferece integração nativa a esse serviço e permite a implantação remota de aplicações Web.

Diagrama de operação do Web Deploy com o WMSVC. Um cliente remoto se conecta ao serviço de gerenciamento remoto do IIS, que por sua vez transfere o controle para o serviço remoto do Web Deploy a fim de implantar a aplicação Web
Diagrama de operação do Web Deploy com o WMSVC. Um cliente remoto se conecta ao serviço de gerenciamento remoto do IIS, que por sua vez transfere o controle para o serviço remoto do Web Deploy a fim de implantar a aplicação Web

O primeiro passo é configurar o WMSVC no servidor IIS de destino.

Agora, a partir de um computador remoto (que pode ser a máquina do desenvolvedor ou um agente de build/release) já é possível executar o msdeploy.exe localmente. Este, por sua vez, conecta-se ao WMSVC no servidor de destino, copiando os arquivos e efetuando as configurações necessárias no IIS, sem depender do WinRM para isso.

Para usar esta nova abordagem, é preciso instalar o Web Deploy tanto no agente de build/release quanto no servidor IIS de destino. Agora, uma dica importante:

  1. No agente de build/release, você irá selecionar a opção Typical durante a instalação do Web Deploy;
  2. Já no servidor IIS de destino, selecione a opção Complete.

Por fim, no seu pipeline de release no TFS/VSTS remova as tasks de IIS+WinRM. Nós vamos, ao invés disso, usar o arquivo batch criado durante o processo de empacotamento de uma aplicação Web no build. Sabe quando você coloca no seu build os parâmetros abaixo? Então, ele está empacotando seu site no formato necessário para o Web Deploy.

/p:DeployOnBuild=true /p:WebPublishMethod=Package
/p:SkipInvalidConfigurations=true
/p:PackageLocation=$(build.artifactstagingdirectory)

Por acaso você já reparou que, quando você faz isso, ele gera um arquivo .deploy.cmd junto aos arquivos do seu site? É esse arquivo que usaremos no nosso release.

Build de uma aplicação ASP.NET, com os arquivos de publicação do Web Deploy (em destaque, o script de implantação com a extensão ".deploy.cmd", gerado automaticamente)
Build de uma aplicação ASP.NET, com os arquivos de publicação do Web Deploy (em destaque, o script de implantação com a extensão ".deploy.cmd", gerado automaticamente)

Agora, tudo o que nos resta é criar/alterar a definição de release, colocando apenas uma simples task de Batch Script. Nela, iremos chamar o arquivo CMD com os devidos parâmetros para informar detalhes como nome do servidor IIS de destino e credenciais do usuário com permissão para fazer um deploy no servidor:

Task de Batch Script com a chamada ao script de Web Deploy. Note o argumento /M, com a indicação do URL apontando para o Web Deployment Handler no servidor de destino
Task de Batch Script com a chamada ao script de Web Deploy. Note o argumento /M, com a indicação do URL apontando para o Web Deployment Handler no servidor de destino

Conclusão

O WinRM é uma ferramenta extremamente poderosa e, por isso mesmo, pode não ser a melhor opção quando se quer fazer uma simples publicação de um site ASP.NET. Ao invés disso, o Web Deployment Handler do Web Deploy oferece uma solução mais simples, leve e segura de se obter o mesmo resultado.

Um abraço,
    Igor

Autor: Igor Abade

Igor Abade V. Leite ([email protected]) é Microsoft MVP (Most Valuable Professional) de Visual Studio ALM desde 2006. Palestrante em diversos eventos da comunidade de desenvolvimento de software (TechEd Brasil, The Developers’ Conference, DevOps Summit Brasil, Agile Brazil, Visual Studio Summit, QCON e outros), é também autor de artigos em revistas e sites como o MSDN Brasil. Desde março de 2011 é um dos sócios da Lambda3, uma consultoria especializada em ALM, desenvolvimento de software e treinamentos. Visite seu blog sobre VS ALM em http://www.tshooter.com.br/ e siga-o no Twitter @igorabade.

Deixe seu comentário!