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)

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

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)

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

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

(Cross-post de http://www.tshooter.com.br/2017/08/10/sobre-iis-web-deploy-e-winrm/)