Liberando agentes de build dinamicamente no firewall do ACR
Mais um post direto das trincheiras. Um de nossos clientes está usando Azure Container Registry com o firewall do registry ativado e por isso não estava conseguindo publicar suas imagens durante o build.
O problema
Isso porque, com o firewall ativado, o Azure Container Registry passa a recusar qualquer conexão direta feita via IP público. A ideia com isso é limitar o acesso ao Registry a uma rede privada virtual, impedindo o acesso através da internet pública.
O problema é que, dessa forma, os agentes do Azure Pipelines obviamente não conseguem mais acessar o Registry. A única maneira de permitir que os agentes façam “push” para o registry é incluindo seus IPs na lista de exclusões (“whitelist”) do firewall.
A solução
Como os IPs dos agentes de pipelines do Azure DevOps são dinâmicos, pré-cadastrar os IPs dos agentes no firewall não seria uma opção. E ainda que a Microsoft publique semanalmente os IPs dos serviços do Azure, ter que fazer essa manutenção (recadastrar todos os IPs semanalmente) seria muito trabalhoso e, ainda por cima, sujeito a erros.
A alternativa que propusemos ao cliente foi liberar os IPs sob demanda, no instante do build. Ou seja, teríamos um pipeline que, em alto nível, faria isto:
Para poder adicionar/remover o agente, precisamos:
- Pegar o IP público do agente atual; e
- Usar a Azure CLI para adicionar/remover esse IP.
Eis um exemplo da task Azure CLI obtendo o IP do agente atual (através de uma chamada de DNS usando a ferramenta de linha de comando dig
) e então a passando como parâmetro para o az acr network-rule add
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- task: AzureCLI@2
name:
displayName: 'Add agent IP to firewall whitelist'
inputs:
azureSubscription: $(azureSubscription)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
AGENT_IP="$(dig +short myip.opendns.com @resolver1.opendns.com)"
if [ -z "$(az acr network-rule list --name $(containerRegistry) | grep ${AGENT_IP})"]
then
echo "Adicionando IP '${AGENT_IP}' ao firewall do Azure Container Registry '$(containerRegistry)'"
az acr network-rule add --name $(containerRegistry) --ip-address $AGENT_IP
else
echo "Agent já está liberado; ignorando."
fi
Com isso, você já consegue usar a task do Docker para publicar a imagem no ACR desejado. Depois da publicação, é só remover o IP que acabamos de adicionar:
1
2
3
4
5
6
7
8
9
10
11
12
13
- task: AzureCLI@2
displayName: 'Remove agent IP from firewall whitelist'
condition: always()
inputs:
azureSubscription: $(azureSubscription)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
AGENT_IP="$(dig +short myip.opendns.com @resolver1.opendns.com)"
echo "Removing agent IP '${AGENT_IP}' from Azure Container Registry '$(containerRegistry)' firewall whitelist"
az acr network-rule remove --name $(containerRegistry) --ip-address $AGENT_IP --only-show-errors --output none
Note que colocamos nesta segunda task condition: always()
. Isso é importante, pois queremos que o IP seja removido do firewall em qualquer circunstância, mesmo quando por exemplo ocorrer um erro na publicação. Sem isso, esta tareja não seria executada em caso de erro na publicação e poderíamos acabar com um montão de IPs atulhando o firewall do ACR.
IMPORTANTE: No momento da publicação deste post o recurso de Firewall/VNet do Azure Container Registry ainda estava em preview, portanto pode ser que ele ainda sofra mudanças até o momento de ser finalmente disponibilizado.
Conclusão
O novo recurso de acesso restrito do Azure Container Registry, que oferece acesso exclusivo por VNet e/ou firewall é um importante mecanismo de segurança para seus registries de contêineres. Entretanto, diferentemente de outros serviços do Azure que oferecem uma “checkbox mágica” para liberar a passagem através do firewall para quaisquer serviços do Azure (incluindo o Azure Pipelines), o ACR Firewall ainda não suporta essa exceção automática. Por isso é que precisamos fazer isso em tempo de build, usando a ferramenta de linha de comando do Azure.
Para um exemplo completo de um pipeline fazendo esse processo, dê uma olhada neste gist.
Um abraço,
Igor
-
Tags:
- Azure
- Azure Container Registry
- Azure DevOps
- Azure Pipelines
- Build
- Cloud Computing
- DevOps
- Docker
29/04/2020 | Por Igor Abade V. Leite | Em Técnico | Tempo de leitura: 3 mins.