Codefresh + Snyk = entregue com rapidez e segurança
Antoine Arlaud
11 de dezembro de 2018
0 minutos de leituraO desenvolvimento moderno de software é escrever código. Não é construir, nem entregar, mas desenvolver: escrevemos código, fazemos merge, a compilação acontece e a entrega também. É importante testar dos dois lados da fronteira do repositório, entre o código e a parte automatizada. A ideia é testar antes do merge para que as alterações passem pelo pipeline sem problemas.
Os pipelines não existem para nós, desenvolvedores, testarmos nossas alterações pela primeira vez. Eles servem para impedir a entrega quando nosso código não atende aos critérios da nova versão. É como uma lista de verificação final enquanto o foguete ainda está na plataforma de lançamento. No mundo ideal, corrigir problemas durante o pipeline já seria um pouco tarde demais. Preferimos fazer isso durante o desenvolvimento e/ou o merge. Mas, como nem sempre vivemos em um mundo ideal, devemos tentar manter as alterações na fase de desenvolvimento, como regra geral.
Para isso, teste mais cedo e obtenha feedback o mais à esquerda possível, por exemplo, na sua máquina ou no repositório de código. É claro que você ainda precisará criar o pipeline e integrar os testes necessários. É aí que entra o Codefresh. Com ele, você cria pipelines automatizados para entregar seus aplicativos em contêineres e implantações no Kubernetes.
Esses testes PRECISAM incluir segurança. Isso é indispensável. Se você não está convencido, pare de ler esta publicação e converse com sua equipe de segurança, um colega, seus pares, um grupo de meetup ou até mesmo com a gente. Vamos explicar por que isso deve ser importante para você... e é aí que entra o Snyk.
Vamos levar de 5 a 10 minutos para criar esse pipeline no Codefresh e integrar os testes de segurança com Snyk. Os testes serão rápidos e simples para podermos voltar a programar e, por fim, entregar funcionalidades. Codefresh e Snyk têm planos gratuitos, então você pode acompanhar sem pagar nada. Também participei de um webinar com o pessoal do Codefresh. Se preferir assistir ao vídeo, confira aqui.
Vamos criar um aplicativo Node de exemplo e empacotá-lo em um contêiner Docker, que enviaremos ao Docker Hub. Em seguida, outro pipeline será iniciado e implantará o resultado como um aplicativo Kubernetes. O Codefresh detectará as alterações integradas ao nosso repositório, criará as imagens Docker e executará os testes do Snyk para determinar se é seguro seguir com a entrega do resultado.
Antes, vamos fazer uma breve introdução a aplicativos e contêineres. A ilustração abaixo mostra a estrutura de um aplicativo típico executado em uma infraestrutura de contêineres.
O pipeline buscará o código-fonte do meu aplicativo no repositório do GitHub, criará um contêiner Docker e testará as dependências do aplicativo e do sistema operacional em busca de problemas de segurança antes de enviar a imagem ao Docker Hub. Se não houver vulnerabilidades, o pipeline não será interrompido.

Agora, vamos criar esse pipeline de verdade!
1. Crie contas no Codefresh e no Snyk.io.
2. Adicione um repositório no Codefresh.

Nesta demonstração, vamos usar o repositório https://github.com/snyk-playground/codefresh-pipeline-snyk-app-docker-scan.

3. Em seguida, selecione Start from template como método de build.

Aqui, vamos usar um aplicativo NodeJS. Selecione essa opção e clique em avançar.

Por enquanto, vamos usar o template padrão. Fique à vontade para ajustá-lo às suas necessidades.

Certo, adicionamos o novo repositório. Agora vamos definir o pipeline.

4. Agora, crie o repositório clicando em Create pipeline.
Primeiro, vamos definir algumas variáveis de ambiente necessárias. Não se esqueça de criptografar os segredos. Adicione uma variável chamada ‘SNYK_TOKEN’.

Você encontra o valor em https://app.snyk.io/account.

Aproveite e adicione outra variável chamada SNYK_ORG. Use como valor a parte final do seu URL: https://app.snyk.io/org/. No meu caso, é aarlaud-snyk-demo.

Isso é tudo no Snyk.
Agora, precisaremos de mais algumas variáveis de ambiente para buscar a imagem no registro do Codefresh e também enviar a imagem final ao Docker Hub.
Para que o Codefresh acesse nosso registro privado de imagens, adicione as variáveis a seguir (veja mais detalhes aqui: https://codefresh.io/docs/docs/docker-registries/codefresh-registry/#generate-cfcr-login-token):
CF_USER_NAME- meu nome de usuário do Codefresh (por exemplo, aarlaud no meu caso)CFCR_ACCOUNT- no meu caso, é igual ao meu nome de usuário: aarlaudCFCR_LOGIN_TOKEN- gere um token em https://g.codefresh.io/user/settings e criptografe-o!
Para integrar com o Docker Hub, vamos armazenar o nome da imagem que queremos enviar ao Hub:
IMAGE_NAME - por exemplo, no meu caso: aarlaudsnyk/trainingapp
O conjunto de variáveis deve ficar parecido com este:

Por fim, precisamos configurar o Docker na seção Integrations do Codefresh:

Você precisa ter uma conta no Docker Hub (https://hub.docker.com/). Crie uma, caso ainda não tenha, e configure a integração com o registro Docker:

Certo, agora podemos continuar! Se você conferir os gatilhos, verá que cada commit inicia um build. Como criamos este pipeline a partir do branch master, somente os commits no master vão iniciar o build. Por enquanto, isso é suficiente e é fácil alterar ou duplicar a configuração para outros branches e ambientes.

Ao analisar o fluxo de trabalho, reconhecemos o template Docker que vimos antes. Talvez, em algum momento, seja melhor transferi-lo para um Dockerfile.

Agora, vamos tentar fazer o build para verificar se tudo funciona como esperado antes de prosseguir.

Você verá o build começar:

E agora o build do meu aplicativo foi concluído.

O Codefresh agora coloca automaticamente essa imagem no seu próprio registro privado do Docker, na sua conta do Codefresh. Na seção Images, vejo a imagem Docker que acabei de criar:

Além disso, antes de simplesmente enviar essa imagem ao Docker Hub, quero garantir que ela não tenha vulnerabilidades de segurança.
5. Voltando ao pipeline, vamos adicionar um comando snyk test para verificar as dependências em busca de vulnerabilidades de segurança.
Primeiro, vamos instalar o Snyk e executá-lo com comandos simples, configurados para interromper o pipeline se houver problemas de alta gravidade. Por enquanto, não quero interrompê-lo por problemas de gravidade baixa ou média, até entender melhor meu fluxo de trabalho.

Clique em Save e faça o build novamente para executá-lo. Você verá uma etapa extra no pipeline, chamada Running Unit Tests. Provavelmente, ela vai falhar devido a alguns problemas. Vamos corrigi-los depois. Agora, vamos analisar a própria imagem Docker em busca de problemas no componente de sistema operacional do aplicativo.
Quando o Codefresh cria o aplicativo, ele envia a imagem ao nosso registro privado. Depois, busca a imagem para executar os testes unitários. Vamos repetir esse processo para executar um segundo teste do Snyk, desta vez direcionado à imagem Docker.
Para isso, vamos usar uma composição do Codefresh. Consulte a documentação para mais detalhes. Vamos mudar para YAML para ter mais recursos.

Agora, no modo YAML, vamos adicionar estas três linhas logo depois de “version: ‘1.0’”: stages:
Essa alteração é puramente visual: ela cria uma seção parecida com uma categoria na interface. Vamos ajustar a seção RunningUnitTests que já temos para usar a seção SnykAppScan. Além de mudar os títulos, adicionamos uma seção de estágio para colocar essa etapa na categoria correta da interface e passamos as variáveis de ambiente de forma mais direta, simplificando algumas coisas.
Agora, vamos adicionar uma seção SnykScanImage para analisar nossa imagem Docker. O estágio também é scan, então essa etapa fica na mesma categoria da análise das dependências do aplicativo. A documentação sobre composições explica como executar vários serviços para realizar testes.
No nosso caso, BuildingDockerImage será a imagem gerada pelo estágio de build. Queremos testar essa imagem externamente, então vamos compor nosso teste com um serviço de análise que executa outra imagem que criei anteriormente: aarlaudsnyk/snyk-container-scan-docker. Essa imagem reúne os componentes necessários para que o Snyk teste uma imagem Docker. Você encontra o código-fonte aqui:
O trecho relevante do arquivo YAML acima é:
Usamos essa imagem para executar um comando Python que faz principalmente duas coisas:
Baixa a imagem para testá-la localmente
Executa ‘snyk test --docker ’
Essa imagem foi criada para buscar a imagem no registro do Codefresh quando as variáveis de ambiente a seguir estiverem definidas:
CFCR_ACCOUNT
CF_USER_NAME
CFCR_LOGIN_TOKEN
Assim, podemos testar a imagem recém-criada. Caso contrário, ela tentará buscar uma imagem no Docker Hub.
Por fim, vamos adicionar ao final o envio ao registro do Docker Hub, para que a imagem seja enviada se os testes forem aprovados:
Nada de complicado por aqui: o Codefresh facilita o envio para o Docker Hub, desde que a integração esteja configurada (veja um pouco antes). Observe que o estágio se chama promote, para diferenciá-lo dos testes de análise.
No conjunto, deve ficar mais ou menos assim:
6. Vamos fazer um build para estabelecer uma referência inicial. Nossa organização parece estar bem limpa:

Depois de um momento, temos este resultado:

Ops, parece que há alguns problemas no nosso aplicativo — o pipeline foi interrompido com segurança antes de entregar algo com problemas de segurança. Vamos corrigir isso seguindo as etapas de remediação indicadas no resultado. Atualizar o pacote qs para a versão 6.0.4 no package.json resolve o problema.
Vamos executar novamente.

Corrigimos a vulnerabilidade do qs, eba! Mas agora há um problema com as dependências do sistema operacional na nossa imagem Docker.

A recomendação de remediação indica que atualizar a imagem pode resolver o problema (consulte a seção sobre Docker em snyk.io/docs). Então, vamos atualizar para node:10-alpine e tentar novamente.

Salvar => Fazer build => Fazer flexões enquanto o build acontece!

Ótimo! Agora temos uma nova referência inicial e um pipeline totalmente funcional que entrega nosso aplicativo e contêiner ao Docker Hub.
Agora podemos voltar a programar. Lembre-se de executar snyk test nas suas alterações antes do merge e/ou testá-las usando a integração do Snyk com pull requests do GitHub. Depois disso, as alterações serão entregues automaticamente. E tem mais: um recurso recém-adicionado!
Use snyk monitor para acompanhar suas dependências ao longo do tempo. Ninguém gosta de ficar cuidando de projetos o tempo todo. Ao executar snyk monitor, o Snyk avisa você automaticamente se uma nova vulnerabilidade for divulgada em qualquer dependência do projeto ou da imagem Docker. Basta adicionar snyk monitor depois da seção snyk test.

O URL do snapshot de monitoramento aparecerá no resultado:

A etapa do Docker será executada automaticamente se o snyk test for aprovado (ou seja, se não houver problemas conhecidos). Os links para os snapshots de monitoramento também serão exibidos.

Você também pode ver os projetos monitorados na interface do Snyk, na sua organização do Snyk:

Acesse o pipeline do Codefresh clicando no selo do repositório (https://github.com/snyk-playground/codefresh-pipeline-snyk-app-docker-scan).
É isso, pessoal! Mantenha-se seguro!
Comece a participar de desafios de Capture the Flag
Aprenda a resolver desafios de Capture the Flag assistindo sob demanda ao nosso workshop virtual introdutório.



