<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR">
	<id>https://wiki.brasilpeeringforum.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Renato.Oliveira</id>
	<title>Wiki BPF - Contribuições do(a) usuário(a) [pt-br]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.brasilpeeringforum.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Renato.Oliveira"/>
	<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/w/Especial:Contribui%C3%A7%C3%B5es/Renato.Oliveira"/>
	<updated>2026-06-01T21:48:15Z</updated>
	<subtitle>Contribuições do(a) usuário(a)</subtitle>
	<generator>MediaWiki 1.35.14</generator>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Conteudos&amp;diff=1944</id>
		<title>Conteudos</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Conteudos&amp;diff=1944"/>
		<updated>2020-01-10T11:18:02Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: /* Infraestrutura */ Adição de tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Conteúdos para os Operadores de Redes ==&lt;br /&gt;
[[Arquivo:Content-BW.png|commoldura]]&lt;br /&gt;
Nesta página você encontrará os links para os diversos artigos, how-tos, tutoriais e vídeos produzidos no âmbito do BPF e direcionados à Comunidade de Internet Brasileira. O intuito é que eles sejam úteis para o dia a dia de operação de redes, infraestrutura, boas práticas e assuntos relacionados.&lt;br /&gt;
&lt;br /&gt;
Para escrever um novo artigo, how-to ou tutorial e compartilhá-lo é necessário criar antes um usuário na Wiki. Existe um artigo com orientações gerais sobre [[Como Escrever na Wiki]]. Após finalizar o artigo não esqueça de indexá-lo nesta página como também compartilhar conosco na lista de emails.&lt;br /&gt;
&lt;br /&gt;
Caso haja interesse em publicar algum material mais completo ou algum projeto envie um email para a lista de discussão geral abordando o assunto de interesse para verificar se já existe alguém o alguma Task Force trabalhando neste assunto ou ainda verifique se já existe algo mais específico em alguma das Task Forces temáticas. Toda contribuição da comunidade é bem vinda e incentivada.&lt;br /&gt;
&lt;br /&gt;
Para facilitar os artigos e materiais publicados abaixo são separados por assuntos.&lt;br /&gt;
== Direitos Autorais, Licença de Uso e Termo de Responsabilidade ==&lt;br /&gt;
Todos os conteúdos, contribuições e obras publicados pelo Brasil Peering Forum (BPF) estão licenciados com uma '''Licença Creative Commons Atribuição-NãoComercial 4.0 Internacional'''. Consulte o nosso [[Direitos Autorais Licenca de Uso|Termo de Responsabilidade]] para verificar a licença, os direitos e restrições de uso, assim como as devidas isenções de responsabilidades.&lt;br /&gt;
&lt;br /&gt;
== Artigos ==&lt;br /&gt;
&lt;br /&gt;
=== Geral ===&lt;br /&gt;
* [[Como Escrever na Wiki]] - Passo a Passo de como criar um novo artigo e contribuir com a Wiki do BPF.&lt;br /&gt;
* [[Assinatura MoU BPF]] - Assinatura do Memorando de Entendimento entre os membros da Board e Comitê de Programa do BPF.&lt;br /&gt;
* [[Enciclopedia e desciclopedia da telecom|Enciclopédia e &amp;quot;Desciclopédia&amp;quot; da Telecom]] - Aqui reunimos expressões, acrônimos e termos conhecidos referentes ao universo de telecomunicações e ISPs.&lt;br /&gt;
&lt;br /&gt;
=== BCOPs ===&lt;br /&gt;
* [[Boas Praticas para Melhorar a Seguranca de seu Provedor]]‎‎ - Boas práticas a serem seguidas para melhorar a segurança de seu Provedor.&lt;br /&gt;
* [[Boas Praticas para Protecao de Roteadores e Switches|Boas Práticas para a Proteção de Roteadores e Switches]] - Artigo que dissemina várias áreas de atenção e práticas para o aumento da segurança da rede do Provedor.&lt;br /&gt;
* [[Boas Praticas para Politicas de Manutencao de Software de Ativos de Rede|Boas Práticas para Políticas de Manutenção de Software de Ativos de Rede]] - Artigo dissertativo sobre boas práticas para a escolha, adoção e manutenção de software de equipamentos de redes.&lt;br /&gt;
* [[Boas Praticas para a Documentacao de Infraestruturas de Redes e Servicos do Provedor|Boas Práticas para a Documentação de Infraestruturas de Redes e Serviços do Provedor]] - Artigo que apresenta boas práticas e sugestões para a documentação de ambientes de redes.&lt;br /&gt;
* [[Boas praticas para a implantacao do ospf em ambientes de isp|Boas praticas para a implantacão do OSPF em ambientes de ISP]] - Artigo discorrendo sobre 12 boas práticas em situações envolvendo OSPF em ambientes ISP.&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
* [[Porque usar um DNS local e algumas dicas para isto]] - Artigo explicativo das razões porque é uma boa prática para um ISP possuir servidores DNS Recursivos próprios do que direcionar o usuário para um servidor público.&lt;br /&gt;
&lt;br /&gt;
=== Infraestrutura ===&lt;br /&gt;
* [[Compatibilidade de GBICs e Cabos Twinax|Compatibilidade de GBICs e cabos Twinax]] - Banco de dados colaborativo sobre experiências de uso de GBICs e cabos Twinax em Roteadores e Switches&lt;br /&gt;
&lt;br /&gt;
=== Interconexão ===&lt;br /&gt;
* [[Modelos Interconexão]] - Artigo sobre os modelos de interconexão Peering e Trânsito&lt;br /&gt;
* [[Looking Glass]] - Artigo com uma lista de Looking Glass nacionais e internacionais&lt;br /&gt;
* [[CDN Peering e PNI - Brasil]] - Lista com as principais CDNs, instruções de como solicitar Servidores, Sessões Bilaterias no IX e PNIs.&lt;br /&gt;
&lt;br /&gt;
=== Roteamento ===&lt;br /&gt;
* [[Dimensionando Roteador para BGP]] - Considerações a serem levadas em conta ao adquirir um novo Roteador para BGP&lt;br /&gt;
* [[Engenharia de Trafego com MPLS TE]]‎ - Artigo explicando o funcionamento do MPLS com Traffic Engineering&lt;br /&gt;
* [[Balanceamento de Trafego em Redes MPLS]] - Artigo explicando o funcionamento de distribuição de tráfego em redes MPLS&lt;br /&gt;
* [[Redes MPLS para Provedores]] - Artigo explicando as vantagens e benefícios de infraestruturas do provedor baseadas no MPLS&lt;br /&gt;
* [[Fundamentos de Roteamento para Provedores]] - Artigo explorando os fundamentos de funções de Camadas 2 e 3, comutação e roteamento, em redes Ethernet IP para provedores&lt;br /&gt;
* [[Protecao e Resiliencia em Redes L2 de Provedores|Proteção e Resiliência em Redes L2 de Provedores]] - Artigo explicando as necessidades e opções para a proteção e resiliência de redes Ethernet para provedores&lt;br /&gt;
* [[Introducao ao IPv6 Provider Edge over MPLS e 6VPE|Introdução ao IPv6 Provider Edge over MPLS (6PE) e 6VPE]] - Artigo abordando as tecnologias 6PE e 6VPE em regime BGP Free Core com MPLS TE. Inclui vídeos demonstrativos&lt;br /&gt;
* [[Introducao ao Unified MPLS|Introdução ao Unified MPLS]] - Artigo explicando a adoção do MPLS em infraestruturas de redes de grandes operadores. Inclui vídeo demonstrativo&lt;br /&gt;
* [[Lista de Communities BGP]] - Listagem com as Communities disponibilizadas pelos principais Operadores de Trânsito IP e Internet Exchanges&lt;br /&gt;
* [[Diferenca entre AS-OVERRIDE e ALLOWAS-IN]] - Explicação básica sobre a diferença entre os dois mecanismos anti-loop do protocolo BGP&lt;br /&gt;
* [[Construção de Redes de Gerenciamento OOB para o ISP]] - Artigo dissertativo sobre conceitos de gerenciamento e redes Fora-de-Banda (OOB)&lt;br /&gt;
* [[Transicao de Solucoes L2VPN MPLS Tradicionais para o EVPN|Transição de Soluções L2VPN MPLS Tradicionais para o Ethernet VPN (EVPN)]] - Artigo explicando muitas das diferenças entre as soluções L2VPN MPLS tradicionais e o Ethernet VPN. Inclui vídeos demonstrativos&lt;br /&gt;
* [[O Minimo que Voce precisa saber sobre o BGP|O Mínimo que Você precisa saber sobre o BGP]] - Artigo bem dissertativo de conceitos fundamentais que todo profissional de ISP precisa saber a respeito do BGP&lt;br /&gt;
* [[Adocao de Quality of Service em Ambientes de Operadores de Redes|Adoção de Quality of Service (QoS) em Ambientes de Operadores de Rede]] - Artigo bastante didático e esclarecedor sobre as tecnologias e ferramentas para o QoS.&lt;br /&gt;
* [[O Minimo que voce precisa saber sobre DDoS]] - Artigo explicando diferenças entre ataques DDoS e maneiras de se prevenir e mitigar.&lt;br /&gt;
* [[Redes que descartam RPKI Invalidos]] - Uma introdução rápida ao RPKI além de listar as operadoras e provedores de trânsito Internet que já implementam o descarte de prefixos inválidos.&lt;br /&gt;
* [[O Minimo que Voce precisa saber sobre IRR]] - Artigo explicando o que é IRR, a importância do uso, principais bases e com um tutorial de como adicionar informações em uma base.&lt;br /&gt;
&lt;br /&gt;
=== Transmissão ===&lt;br /&gt;
* [[Sistemas DWDM de Baixo Custo]] - Artigo explicado sobre como projetar um sistema DWDM de baixo custo&lt;br /&gt;
&lt;br /&gt;
=== Capacitação ===&lt;br /&gt;
* [[Abordagens para o Troubleshooting Eficaz de Problemas Tipicos na Rede do ISP|Abordagens para o Troubleshooting Eficaz de Problemas Típicos na Rede do ISP]] - Artigo didático que comenta boas práticas para ações de suporte na rede do ISP&lt;br /&gt;
* [[Aprimorando a Disponibilidade da rede do ISP]] - Artigo com vídeo explicando os fundamentos de disponibilidade das infraestruturas de redes do provedor&lt;br /&gt;
* [[Frameworks de industria para a reestuturacao e profissionalizacao do isp|Frameworks de Indústria para a Reestruturação e Profissionalização do ISP]] - Artigo que destaca positivamente o eTOM BPF do Frameworx como conceito de remodelagem de operação e de negócios de ISPs&lt;br /&gt;
&lt;br /&gt;
== How-tos e Tutoriais ==&lt;br /&gt;
&lt;br /&gt;
=== Geral ===&lt;br /&gt;
* [[Como reportar abusos ao Google]] - Instruções sobre como reportar servidores com conteúdos maliciosos hospedados pelo Google&lt;br /&gt;
&lt;br /&gt;
=== DNS ===&lt;br /&gt;
* [[Melhorando a performance e resiliencia da rede com Recursive DNS Anycast|Melhorando a performance e resiliência da rede com Recursive DNS Anycast]] - Tutorial que apresenta uma técnica interessante para maior disponibilidade e desempenho dos servidores DNS para os provedores&lt;br /&gt;
&lt;br /&gt;
=== Boas Práticas ===&lt;br /&gt;
* [[Boas práticas de segurança para roteadores Mikrotik]] - How-to com orientações de segurança e regras a serem aplicadas em roteadores Mikrotik rodando RouterOS.&lt;br /&gt;
* [[Como consultar e corrigir a geolocalizacao de seus IPs|Como Consultar e Corrigir a Geolocalização de IPs]] - Tutorial explicando como consultar e corrigir as informações de geolocalização de alocações de um ASN.&lt;br /&gt;
* [[MANRS]] - Passo a passo de como cumprir todos os requisitos do MANRS e para se ter um Sistema Autônomo e uma Internet mais segura&lt;br /&gt;
* [[PeeringDB - como se cadastrar e atualizar seus dados|PeeringDB - Como se cadastrar e atualizar seus dados]] - Passo a passo de como realizar o cadastro no PeeringDB e preencher as informações necessárias&lt;br /&gt;
&lt;br /&gt;
=== Edge ===&lt;br /&gt;
* [[Concentradores PPPoE com IPv6]] - Como habilitar suporte a IPv6 e distribuição de prefixos para usuários finais em diferentes concentradores.&lt;br /&gt;
&lt;br /&gt;
=== Infraestrutura ===&lt;br /&gt;
* [[Log de Portas de Origem em Servidores Web]] - Como adicionar a porta de origem ao log dos Servidores Web e ser capaz de identificar usuários atrás de CGNAT.&lt;br /&gt;
* [[CGNAT na pratica|CGNAT na prática]] - Tutorial sobre como configurar um servidor Linux com netfilter para CGNAT com ajustes de configurações voltadas para performance.&lt;br /&gt;
* [[Tutorial DNS Hyperlocal]] - Tutorial descrevendo como hospedar uma cópia da zona raiz de DNS para que os servidores Recursivos locais possam consultar com maior performance e eficiência.&lt;br /&gt;
* [[Monitoramento-telegraf|Monitoramento Telegraf]] - Como configurar uma solução Telegraf + InfluxDB + Grafana para monitoramento via ICMP de destinos desde diferentes endereços de origem.&lt;br /&gt;
* [[Como Ter Seu Proprio Looking Glass|Como Ter Seu Próprio Looking Glass]] - Tutorial ensinando como o ISP poderá facilmente disponibilizar seu próprio Looking Glass para visibilidade e suporte à problemas com o BGP.&lt;br /&gt;
* [[Como capturar pacotes no Mikrotik]] - Tutorial ensinando como realizar captura de pacotes no Mikrotik visando a análise e depuração de protocolos e conversações.&lt;br /&gt;
* [[Orquestrando sua rede com Ansible e Gitlab]] - Tutorial ensinando a utilizar modelos de dados, em uma estrutura CI/CD com Ansible e GitLab.&lt;br /&gt;
&lt;br /&gt;
=== IPv6 ===&lt;br /&gt;
* [[IPv6 no TPLink WR840N v2]] - Como ativar IPv6 na CPE TPLink WR840N v2&lt;br /&gt;
* [[IPv6 na ONU Huawei HS8546 v2]] - Como ativar IPv6 na ONU Huawei HS8546 v2&lt;br /&gt;
* [[IPv6 no Mikrotik CPE]] - Como ativar IPv6 em uma CPE Mikrotik (RouterOS)&lt;br /&gt;
* [[IPV6 no Ubiquiti AirOS6|IPv6 no Ubiquiti AirOS6]] - Como ativar IPv6 em uma CPE Ubiquiti com AirOS6&lt;br /&gt;
* [[IPV6 no Ubiquiti AirOS8|IPv6 no Ubiquiti AirOS8]] - Como ativar IPv6 em uma CPE Ubiquiti com AirOS8&lt;br /&gt;
* [[Ipv6-TL-WRN849N|IPv6 no TPLink WRN849N]] - Como ativar IPv6 em uma CPE TPLink WRN849N&lt;br /&gt;
* [[IPV6 no Intelbras Wom|IPv6 no Intelbras WOM]] - Como ativar IPv6 em uma CPE Intelbras WOM 500, WOM 5000 MIMO, WOM 5a-23 e WOM 5a MIMO&lt;br /&gt;
* [[IPv6 no Dlink Dir-615|IPv6 no Dlink DIR 615]] - Como ativar IPv6 em uma CPE Dlink DIR 615, DIR 608, DIR 610 e DIR 611&lt;br /&gt;
* [[IPV6 no DLINK DIR-882|IPv6 no D-Link DIR-882]] - Como ativar IPv6 em uma CPE D-Link DIR-882&lt;br /&gt;
* [[Acesso via IPv6 Link-Local]] - Uma maneira de acessar equipamentos via IPv6 Link-Local em caso de perda de conectividade por IPv4&lt;br /&gt;
* [[Como Ativar IPv6 em Servicos de Hosting e CDN]] - Tutorial sobre como ativar IPv6 nos serviços de Hosting e CDN mais utilizados&lt;br /&gt;
* [[Servidor DNS Recursivo com IPV6 e DNSsec]]- Mini tutorial sobre IPv6 e DNSsec em DNS recursivo Unbound.&lt;br /&gt;
* [[Gerando Log de IPv6 Delegation no Mikrotik]] - How to explicando como registrar em um servidor Syslog o Prefixo IPv6 entregue para o usuário em concentradores Mikrotik&lt;br /&gt;
&lt;br /&gt;
=== Roteamento ===&lt;br /&gt;
* [[Como fazer com que um determinado conteudo saia por um link especifico|Como fazer com que um determinado conteúdo saia por um link específico]] - Tutorial bem objetivo ensinando como manipular o roteamento para o recebimento de tráfego em seu AS&lt;br /&gt;
* [[Configuracao de filtros BGP usando Extended Routing Policy Language (XPL) no Huawei|Configuração de filtros BGP usando Extended Routing Policy Language (XPL) no Huawei]] - Tutorial sobre como configurar filtros usando XPL em Huawei&lt;br /&gt;
&lt;br /&gt;
== Tech Notes ==&lt;br /&gt;
Esta seção contém contribuições fornecidas por fabricantes (&amp;quot;''vendors''&amp;quot;) acerca de suas soluções, tecnologias disponíveis, diferenciais de mercado e afins.&lt;br /&gt;
* [[Otimizacao de balanceamento de tráfego em Link Aggregation utilizando DLB e FAT em switches Datacom|Otimização de balanceamento de tráfego em Link Aggregation utilizando DLB &amp;amp; FAT em switches Datacom]] - Artigo dissertativo acerca das soluções DLB e FAT do portfólio de switches da Datacom&lt;br /&gt;
&lt;br /&gt;
== Informativos ==&lt;br /&gt;
Os informativos do Brasil Peering Forum são editados de forma quinzenal, dependendo do conteúdo e relevância e contém as principais notícias e novidades do mercado  de Infraestrutura de Telecom e Internet.Todos eles são também enviados para a [https://listas.brasilpeeringforum.org/mailman/listinfo/bpf Lista Pública de Discussão] do BPF. Inscreva-se para receber as notificações.&lt;br /&gt;
* [[Informativo Infra 01]] - 16/09/2019&lt;br /&gt;
* [[Informativo Infra 02]] - 22/09/2019&lt;br /&gt;
* [[Informativo Infra 03]] - 25/10/2019&lt;br /&gt;
* [[Informativo Infra 04]] - 04/11/2019&lt;br /&gt;
* [[Informativo Infra 05]] - 17/11/2019&lt;br /&gt;
* [[Informativo Infra 06]] - 02/12/2019&lt;br /&gt;
* [[Informativo Infra 07]] - 29/12/2019&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
=== Eventos ===&lt;br /&gt;
* [https://www.youtube.com/watch?v=KG2JZ0A_9yY Painel sobre Peering ocorrido durante o Future ISP em Maio de 2018]&lt;br /&gt;
* [https://www.youtube.com/watch?v=8GVHB52qu5k Apresentação do Brasil Peering Forum feita por Uesley Correa]&lt;br /&gt;
* [https://www.youtube.com/watch?v=SE8YEuVXMWQ Dever de Casa e o Impacto da Negligência Técnica e Administrativa de Participantes do IX-BR], por Elizandro Pacheco no IX Forum 12&lt;br /&gt;
* [https://www.youtube.com/watch?v=2oq7pMBF7Oc Tudo que você gostaria de saber sobre transmissões ópticas e WDM], por Tiago Setti no IX Forum 12&lt;br /&gt;
* [https://www.youtube.com/watch?v=Obh98S5xyQA Automatização de Listas de Prefixos em Peering BGP - Como fazer e sua importância], por Douglas Fischer no GTER 46&lt;br /&gt;
* [https://www.youtube.com/watch?v=hbEC2Sf5o20 BIER: Evolução do IP Multicast, por Tiago Setti] no GTER 46&lt;br /&gt;
* [https://www.youtube.com/watch?v=H-m0sKr8I0Q Problemas e soluções na identificação de usuário IPv6 usando RouterOS], por Uesley Correa no GTER 46&lt;br /&gt;
* [https://www.youtube.com/watch?v=WjSps5huDGU Painel - Trânsito Burstable com 95th] percentil, por Fernando Frediani, Fábio Monteiro, Edivan Silva e Tiago Setti no GTER 46&lt;br /&gt;
* [https://www.youtube.com/watch?v=4-77r2PGKB4 BSDRP - Uma opção de softrouter com FRR], por Antonio Donizeti Corazza Jr no GTER 46&lt;br /&gt;
* [https://www.youtube.com/watch?v=CjTcI0-UApI Ataques DDoS como ação anti-competitiva: prevenção, mitigação e reação], por Thiago Ayub no GTER 46&lt;br /&gt;
* [https://youtu.be/qBD7zCnbTF4 Automatização de Listas de Prefixos em peering BGP], por Douglas Fischer no LACNIC 31/FTL&lt;br /&gt;
* [https://youtu.be/8DdtN_fj_uQ BSDRP - Uma opção de sofftrouter com FRR], por Junior Corazza no LACNIC 31/FTL&lt;br /&gt;
* [https://www.youtube.com/watch?v=utPs-sXsOZg A importância de um CGNAT bem feito], por Fernando Frediani no GTER 47&lt;br /&gt;
* [https://www.youtube.com/watch?v=l2tVyz1Ba1A Entrevista sobre ataques e mitigação DDoS], com Thiago Ayub&lt;br /&gt;
&lt;br /&gt;
=== Hangouts ===&lt;br /&gt;
[https://www.youtube.com/watch?v=fy4efZZ-yvg Desmistificando o CGNAT] - Hangout realizado para debater o assunto e desmistificar esta necessidade dos ISPs. Durante a conversa foram abordadas boas práticas, diferentes modelos de CGNAT, problemas com Jogos e um case prático.&lt;br /&gt;
&lt;br /&gt;
[https://www.youtube.com/watch?v=ePMfMv3UVOs Boas Práticas de DNS] - Hangout realizado que debateu as melhores práticas para se ter um bom serviço de DNS rodando no seu provedor, a importância de ter seu DNS Reverso configurado corretamente, quando é necessário ter um servidor Autoritativo, DNSSEC e assuntos relacionados.&lt;br /&gt;
&lt;br /&gt;
=== Roteamento e MPLS ===&lt;br /&gt;
* [https://youtu.be/OWI4ndstx-o Demonstração do BGP-Free Core em Redes MPLS para Provedores], por Leonardo Furtado&lt;br /&gt;
* [https://www.youtube.com/watch?v=5Eg5jC2AMaQ Demonstração de Soluções de Conectividade para Redes MPLS de Provedores - Parte 1] (Introdução), [https://www.youtube.com/watch?v=W8HS_y7REiM Parte 2] (Introdução ao L3VPN), [https://www.youtube.com/watch?v=TqdZYK_9rlY Parte 3] (Demonstração de Interconexões com L3VPN MPLS), [https://www.youtube.com/watch?v=bmgWGOPbkfw Parte 4] (Demonstração da Solução Carrier Supporting Carrier - (CsC)), [https://www.youtube.com/watch?v=H4SyKiGBOXM Parte 5] (Demonstração de L3VPN MPLS com VPNs &amp;quot;Complex Overlapping&amp;quot;), [https://www.youtube.com/watch?v=6fQ34nnk-Dk Parte 6] (Demonstração de L2VPN MPLS com AToM/EoMPLS/VPWS), por [[Usuário:Leonardo.Furtado|Leonardo Furtado]].&lt;br /&gt;
* [https://youtu.be/W4tmhK4tJEQ Demonstração de Túneis de Engenharia de Tráfego com MPLS TE], por Leonardo Furtado.&lt;br /&gt;
* [https://youtu.be/zkv2Q3lOiKI Introdução ao IPv6 Provider Edge over MPLS (6PE) e 6VPE, Parte 1] e [https://youtu.be/0N-ejxGncSU Parte 2], por Leonardo Furtado.&lt;br /&gt;
* [https://youtu.be/NqC9nGFVkUU Introdução ao Unified MPLS], por Leonardo Furtado.&lt;br /&gt;
* [https://youtu.be/gNUevLCPgxA Demonstração de Tecnologias L2VPN com EVPN], por Leonardo Furtado.&lt;br /&gt;
* [https://community.cisco.com/t5/eventos-de-routing-switching/evento-webcast-troubleshooting-de-border-gateway-protocol-bgp/bc-p/3104885 Evento Webcast Troubleshooting de BGP, da Comunidade de Suporte Cisco em Português], por Leonardo Furtado.&lt;br /&gt;
* [https://youtu.be/zSiFtIgT1Ig Palestra de Evoluções de Tecnologias MPLS com Segment Routing e EVPN] - Future ISP 2018, por Leonardo Furtado.&lt;br /&gt;
* [https://community.cisco.com/t5/routing-switching-v%C3%ADdeos/webcast-video-redes-mpls-de-%C3%BAltima-gera%C3%A7%C3%A3o-com-evpn-e-segment/ba-p/3880397 Evento Webcast Redes MPLS de Última Geração com EVPN e Segment Routing, da Comunidade de Suporte Cisco em Português], por Leonardo Furtado&lt;br /&gt;
* [https://youtu.be/9aQaCo_yDkU Construção de Redes de Gerenciamento Fora-de-Banda (OOB) para o ISP], por Leonardo Furtado&lt;br /&gt;
* [https://youtu.be/B6Et9MFU7cA Boas Praticas para a Proteção da Infraestrutura de Redes do ISP], por Leonardo Furtado&lt;br /&gt;
* [https://youtu.be/dZvzuCMyxDg Demonstração da Transição de Soluções L2VPN MPLS Tradicionais para o Ethernet VPN (EVPN)], por Leonardo Furtado&lt;br /&gt;
=== Capacitação ===&lt;br /&gt;
* [https://youtu.be/e00Qs1H26Zo Aprimorando a Disponibilidade da rede do ISP], por Leonardo Furtado&lt;br /&gt;
* [https://youtu.be/8yAGzNuerFg Conceitos e Análises de Investimentos Tecnológicos para o ISP], por Leonardo Furtado&lt;br /&gt;
* [https://youtu.be/rnABNk26pZk Caracterização das Funcionalidades e Recursos para Projetos de Redes no ISP], por Leonardo Furtado&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1943</id>
		<title>Orquestrando sua rede com Ansible e Gitlab</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1943"/>
		<updated>2020-01-10T11:09:11Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: /* Criando templates com Jinja2 */  Correção na identação&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Introdução ===&lt;br /&gt;
Neste artigo será apresentado uma metodologia de automação de redes baseada em GitLab e Ansible, onde, utilizando templates em Jinja2, será possível entregar ao operador uma estrutura de configurações baseada em modelos de dados. As peculiaridades de cada fabricante estarão encapsuladas através de templates que podem abstrair desde a CLI específica o equipamento até modelos YANG. Este artigo será divido em 5 seções, sendo elas:&lt;br /&gt;
* A instalação do ambiente que para simplificação será monolítica, com o Ansible e o GitLab instalado no mesmo servidor;&lt;br /&gt;
&lt;br /&gt;
* A apresentação da metodologia CI/CD com o GitLab e a criação de um workflow de implantação, com sua respectiva configuração no GitLab-Runner;&lt;br /&gt;
&lt;br /&gt;
* A descrição do funcionamento do Ansible-playbook, em conjunto com uma proposta de estrutura de diretório.&lt;br /&gt;
&lt;br /&gt;
* A criação uma abstração de modelos de dados utilizando Jinja2.&lt;br /&gt;
&lt;br /&gt;
* Integrando a solução e realização de testes.&lt;br /&gt;
&lt;br /&gt;
=== Instalação ===&lt;br /&gt;
O ambiente que será demostrado neste artigo utiliza como sistema operacional o CentOS 7&amp;lt;!-- Atenção o CentoOS 7 é a versão mais recente suportada pelo GitLab --&amp;gt;, instalado a partir da imagem: CentOS-7-x86_64-DVD-1908, que pode ser encontrada no repositório da distribuição. Neste ambiente, todos os componentes foram instalados em conjunto, porém, para um ambiente de produção, pode ser recomendado separar os componentes GitLab-Runner e Ansible em outro servidor.&lt;br /&gt;
&lt;br /&gt;
Para realizar a instalação dos componentes pode-se utilizar o script fornecido ou realizar a instalação via repositórios, devendo tomar o cuidado de atualizar a versão do git padrão da distribuição pois ela é incompatível com git-fetch que é utilizado pelo gitlab-runner, realizar a instalação via pip do ncclient e netmiko e criar um domínio em DNS para o gitlab. Caso deseje utilizar o script fornecido, atualize a url “gitlab.local” para o domínio registrado.&lt;br /&gt;
&lt;br /&gt;
Finalizado o processo de instalação das ferramentas, execute o procedimento de registro do gitlab-runner conforme esta url da referência [1] .&lt;br /&gt;
&lt;br /&gt;
=== GitLab ===&lt;br /&gt;
O GitLab é um gerenciador de repositório de software baseado em git com suporte à Wiki, gerenciamento de tarefas e CI/CD. GitLab é similar ao GitHub, mas o GitLab permite que os desenvolvedores armazenem o código em seus próprios servidores, ao invés de servidores de terceiros. Ele é um software livre, distribuído pela Licença MIT. (Wikipedia)&lt;br /&gt;
&lt;br /&gt;
E com todas essas funcionalidades pode agregar valor à operação, sendo capaz de prover uma base de conhecimento com sua wiki e, através do gitlab-runner, é possível criar um ciclo onde o técnico escreve a configuração desejada e faz um commit no repositório, que automaticamente executa as tarefas de compilação e validação de sintaxe, podendo inclusive realizar o deploy das configurações em um ambiente de laboratório como o EVE-NG.&lt;br /&gt;
&lt;br /&gt;
=== Configurando a pipeline ===&lt;br /&gt;
Uma vez que o gitlab-runner foi instalado e configurado, é necessário adicionar no repositório o arquivo .gitlab-ci.yml que irá descrever todo o fluxo da pipeline [2].&lt;br /&gt;
&lt;br /&gt;
Durante a execução de cada tarefa, o gitlab-runner executa uma operação ''git fetch'' dentro da sua pasta home o que, para o contexto deste artigo e outras aplicações, pode ser problemático, já que todo os arquivos gerados pelas tarefas anteriores serão perdidos.&lt;br /&gt;
&lt;br /&gt;
Para a solução deste problema é necessário realizar um cache dos arquivos de configuração compilados, conforme sintaxe abaixo:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cache:&lt;br /&gt;
key: ${CI_COMMIT_REF_SLUG}&lt;br /&gt;
paths:&lt;br /&gt;
 - cfg/tmp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ao término da configuração do .gitlab-ci.yml, a cada commit realizado pelo técnico será executada a pipeline que, para este tutorial, terá a forma da Figura 1:&lt;br /&gt;
[[Arquivo:Ciclo de execução.png|centro|miniaturadaimagem|800x800px|Figura 1. Ciclo de execução]]&lt;br /&gt;
&lt;br /&gt;
=== Ansible ===&lt;br /&gt;
O Ansible é uma ferramenta open-source para gerenciamento de configuração e provisionamento, que utiliza uma comunicação com os nós baseadas em SSH sem a necessidade da instalação de agentes.&lt;br /&gt;
&lt;br /&gt;
Para a utilização da ferramenta é necessário criar um arquivo ansible.cfg, que contém as configurações básicas do ansible, criar um arquivo contendo a relação dos dispositivos, e criar um arquivo contendo as instruções a serem executadas.&lt;br /&gt;
&lt;br /&gt;
Com os três arquivos citados anteriormente já é possível realizar alguns testes de acesso com o Ansible, porém para aplicações mais complexas é conveniente utilizar uma estrutura de diretórios para dois propósitos, o primeiro é melhorar a usabilidade e semântica da automação, e a segunda é criar um ambiente flexível e que possa ser reutilizado para diversos propósitos.&lt;br /&gt;
&lt;br /&gt;
Com este propósito a partir da versão 1.2 o Ansible introduziu o conceito de Roles, que através de uma estrutura de diretórios possibilita o carregamento automático de diversos arquivos e o agrupamento de configurações conforme sua semelhança e necessidade específica, a documentação a respeito de roles pode ser encontrada no link da referência [4], outra vantagem da utilização de roles reside no seu compartilhamento, onde pelo link da referência [5] podem ser encontrados diversos roles prontos para uso.&lt;br /&gt;
&lt;br /&gt;
Neste tutorial iremos criar roles de acordo com o software que roda nos equipamentos, por exemplo RouterOS, IOS, IOS-XR, Junos e etc, pois cada software possui uma sintaxe própria que ao final da implementação devem ser encapsuladas, outra vantagem desta escolha reside na possibilidade de separação de equipes de modo que a equipe com experiencia em RouteOS, não precisa se preocupar com particularidades do IOS, ou seja a única preocupação dessa equipe é considerando o modelo de dados de entrada que é padrão para todas as implementações gerar a configuração correspondente, conforme Figura 2.&lt;br /&gt;
[[Arquivo:Roles.png|centro|miniaturadaimagem|800x800px|Figura 2. Metologia de utilização dos Roles]]&lt;br /&gt;
Com a estrutura de diretórios pronta é necessário criar as abstrações das configurações o que é dependente de cada modelo e dos módulos disponíveis, para esse tutorial como configuraremos um mikrotik (RouterOS), e um cisco (IOS) iremos utilizar os seguintes módulos routeros_command [6] ios_config [7], e a linguagem de template Jinja2 para criar as abstrações, e devido as diferenças entre os módulos do ios_config e do routeros_command as etapas para a configuração serão diferentes conforme Figuras 3 e 4 &lt;br /&gt;
[[Arquivo:RoleCisco.png|centro|miniaturadaimagem|795x795px|Figura 3. Implementação de um Role para IOS]]&lt;br /&gt;
[[Arquivo:Renato-MikrotikRoles.png|centro|miniaturadaimagem|800x800px|Figura 4. Implementação de um Role para RouterOS]]&lt;br /&gt;
&lt;br /&gt;
=== Criando templates com Jinja2 ===&lt;br /&gt;
Neste tutorial irei demonstrar a criação dos templates apenas para o IOS, mas para o RouterOS a implementação é análoga.&lt;br /&gt;
&lt;br /&gt;
O primeiro passo é conceber a estrutura de dados do modelo, será utilizado uma interface como base. Abstraindo toda a sintaxe os dados que são inseridos em uma interface em geral são nome da interface, endereço IP, máscara, estado ( shut ou no shut), velocidade, encapsulamento e etc, um exemplo de modelo seria o apresentado abaixo: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Interfaces:&lt;br /&gt;
    - interface:&lt;br /&gt;
    name: Loopback0&lt;br /&gt;
    address: 10.0.0.1&lt;br /&gt;
    description: LDP Loopback&lt;br /&gt;
    mask: 255.255.255.255&lt;br /&gt;
    enabled: True&lt;br /&gt;
    - interface:&lt;br /&gt;
    name: GigabitEthernet0/0&lt;br /&gt;
    address: 10.0.1.1&lt;br /&gt;
    mask: 255.255.255.252&lt;br /&gt;
    enabled: True&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Os arquivos contendo estes modelos seriam armazenados dentro da pasta ''roles/models/files/interfaces/&amp;lt;hostname&amp;gt;.yml''. Percebe que neste momento estamos fazendo duas associações implícitas, a primeira é utilizar a palavra '''interfaces''' no caminho que será utilizada posteriormente para acessar todos os arquivos de configuração relativos a configuração das interfaces, e a segunda associação está no nome do arquivo '''&amp;lt;hostname&amp;gt;.yml''', que será utilizado em tempo de execução para associar dada configuração ao ativo.&lt;br /&gt;
&lt;br /&gt;
Com o modelo pronto precisamos escrever o template, que no caso do IOS ficará em ''roles/ios/templates/interfaces.j2'', e iremos criar um template para cada funcionalidade que desejarmos automatizar.&lt;br /&gt;
&lt;br /&gt;
Para a criação do template é necessário conhecer algumas estruturas de controle que nos permitirão realizar testes, e executar laços dentro da execução. A primeira estrutura que será apresentada é o laço '''{% for iterador in variável %} ... {% endfor %}'''. Ao observar o modelo que criamos acima pode se perceber que ele forma uma lista de interfaces, e será carregado dentro do Ansible como uma variável de nome interfaces, então para montar o laço iremos utilizar:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{% for interface in interfaces %}&lt;br /&gt;
{% endfor %}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
E para acessar as variáveis basta utilizar a seguinte sintaxe &amp;lt;nowiki&amp;gt;{{ nome da variável }}&amp;lt;/nowiki&amp;gt;.  O próximo passo é escrever a configuração que se deseja aplicar tomando muito cuidado com espaços, e sem a necessidade de se utilizar end ao final, pois o módulo executa uma comparação textual com a configuração em produção antes de configurar, no final a configuração do template será semelhando a abaixo:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{% for interface in interfaces %}&lt;br /&gt;
interface {{ interface.name }}&lt;br /&gt;
{% if interface.description is defined %}&lt;br /&gt;
 description {{ interface.description}}&lt;br /&gt;
{% endif %}&lt;br /&gt;
{% if (interface.address is defined ) and (interface.mask is defined ) %}&lt;br /&gt;
 ip address {{ interface.address }} {{ interface.mask }}&lt;br /&gt;
{% endif %}&lt;br /&gt;
{% if interface.enabled == True %}&lt;br /&gt;
 no shutdown&lt;br /&gt;
{% endif %}&lt;br /&gt;
{% if interface.enabled == False %}&lt;br /&gt;
 shutdown&lt;br /&gt;
{% endif %}&lt;br /&gt;
exit&lt;br /&gt;
{% endfor %}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integrando a solução ===&lt;br /&gt;
Com os modelos prontos e todos os templates está na hora de criar os playbooks, que serão utilizados pelo Ansible para guiar a automação. O primeiro playbook a ser criado fica na raiz do diretório e será responsável por “chamar” os playbooks de cada role, o que é entregue automaticamente, bastando se incluir o role no playbook, para esse primeiro playbook que chamarei de principal, será necessário criar um “Play” para cada grupo de ativos e neste play será incluído a role desejada, conforme exemplo abaixo:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: Cisco&lt;br /&gt;
  hosts: cisco&lt;br /&gt;
  roles:&lt;br /&gt;
   - cisco&lt;br /&gt;
- name: MikroTik&lt;br /&gt;
  hosts: routeros&lt;br /&gt;
  roles:&lt;br /&gt;
   - routeros&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
A relação de hosts para cada grupo é definida dentro do arquivo hosts, que tem a seguinte sintaxe:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[cisco]&lt;br /&gt;
CPE7 ansible_host=192.168.237.206&lt;br /&gt;
PE4 ansible_host=192.168.237.202&lt;br /&gt;
P2  ansible_host=192.168.237.203&lt;br /&gt;
P1  ansible_host=192.168.237.205&lt;br /&gt;
PE5 ansible_host=192.168.237.207&lt;br /&gt;
CPE6 ansible_host=192.168.237.204&lt;br /&gt;
[routeros]&lt;br /&gt;
P3  ansible_host=192.168.237.183&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Neste arquivo os grupos são definidos dentro dos colchetes, [cisco] e [routeros], enquanto os membros do grupo são definidos individualmente abaixo com a seguinte sintaxe: HOSTNAME  ansible_host=&amp;lt;endereço IP&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Adicionalmente ao endereço é necessário prover as credenciais de acesso ao equipamento e o sistema que roda em cada um conforme [3], neste tutorial será utilizado a mesma credencial de acesso a todos os equipamentos e tal configuração ficará dentro do arquivo group_vars/all.yml que tem a seguinte forma:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ansible_connection: network_cli&lt;br /&gt;
ansible_become: yes&lt;br /&gt;
ansible_become_method: enable&lt;br /&gt;
ansible_user: 'renato'&lt;br /&gt;
ansible_ssh_pass: '123456'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note que nesse tutorial estou usando uma senha em claro dentro de um arquivo de configuração o que não é uma boa prática, para encriptar esta senha utilize os procedimentos descritos em [8].&lt;br /&gt;
&lt;br /&gt;
E para as configurações específicas de cada plataforma será criado um arquivo com o mesmo nome do groupo na pasta group_vars, estas configurações podem ser visualizadas em [9].&lt;br /&gt;
&lt;br /&gt;
Finalizado estas configurações, criação do playbook principal, do inventário e das variáveis, vamos aos arquivos específicos de cada modelo. Para isso deverá ser criado um arquivo com o nome main.yml na pasta roles/&amp;lt;role&amp;gt;/tasks. Para a configuração no cisco, conforme Figura 3 precisamos primeiro ler o arquivo com o modelo e transformar ele em variável, porém é importante notar que cada tarefa é executada para todos os equipamentos do grupo, assim para evitar erros de execução iremos pesquisar pelo modelo na sua pasta respectiva:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: List interface directory&lt;br /&gt;
  find:&lt;br /&gt;
    paths: roles/models/files/interfaces&lt;br /&gt;
    patterns: &amp;quot;*{{ inventory_hostname }}.yml&amp;quot;&lt;br /&gt;
    recurse: yes&lt;br /&gt;
    file_type: file&lt;br /&gt;
  register: Files&lt;br /&gt;
  delegate_to: localhost&lt;br /&gt;
&amp;lt;/pre&amp;gt;              &lt;br /&gt;
Perceba que a tarefa acima pesquisa na pasta /roles/models/files/interfaces todos os arquivos com o seguinte padrão ''&amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;'', note a sintaxe ''&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;'', vista anteriormente nos templates em jinja2, que  faz referência ao equipamento que está sendo processado, registra o resultado de sua busca na variável Files e por fim executa esse procedimento localmente, sem a necessidade de se conectar via ssh no host.&lt;br /&gt;
&lt;br /&gt;
Com os arquivos identificados o próximo passo é importar as variáveis que será feito utilizando o módulo template, conforme descrito abaixo:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: Include interface vars&lt;br /&gt;
  include_vars:&lt;br /&gt;
    file: roles/models/files/interfaces/{{ inventory_hostname }}.yml&lt;br /&gt;
  when: Files.files != []&lt;br /&gt;
  delegate_to: localhost&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Com o modelo importado o próximo passo é a criação dos arquivos de configuração, nesta etapa é fundamental que na sua estrutura de diretórios já exista uma pasta destinada a estes arquivos, e para a sua configuração basta seguir o modelo abaixo:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: Make Config&lt;br /&gt;
  template:&lt;br /&gt;
    src: interface.j2&lt;br /&gt;
    dest: cfg/interfaces/{{ inventory_hostname }}.cfg&lt;br /&gt;
    mode: 0777&lt;br /&gt;
  when: Files.files != []&lt;br /&gt;
  delegate_to: localhost&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Finalmente com todos os arquivos de configuração prontos, está na hora de aplicar as configurações nos equipamentos que no caso do ios é feito utilizando o módulo ios_config, conforme sintaxe abaixo:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- name: Configure&lt;br /&gt;
  ios_config:&lt;br /&gt;
    src:  “cfg/interfaces/{{ inventory_hostname }}.cfg”&lt;br /&gt;
  when: configFiles.files != []&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Finalizadas estas configurações basta repetir o processo para cada funcionalidade que se deseja implementar em sua automação, e caso seja de interesse é possível simplificar ainda mais a criação dos playbooks, realizando a separação da configuração das tarefas por escopos, ou seja dentro da pasta roles/&amp;lt;role&amp;gt;/tasks existirá um arquivo main.yml que é responsável por importar as tarefas de cada uma das funcionalidades e cada funcionalidade terá um arquivo próprio como por exemplor interfaces.yml, ospf.yml , mpls.yml e etc, desta forma as configurações apresentadas acima residirão dentro de cada um dos playbooks de funcionalidades e o playbook main.yml irá apenas instanciar usando a seguinte sintaxe:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
- import_tasks: interfaces.yml&lt;br /&gt;
  vars:&lt;br /&gt;
    scope: interfaces&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Observe no código acima que foi introduzido uma variável durante a inclusão, e ao observar as configurações realizadas anteriormente é possível perceber que em nenhum momento foi utilizado alguma especificidade de alguma funcionalidade, portanto com é possível apenas com a alteração da variável scope, recém introduzida, replicar todo o código que criamos sem a necessidade de escreve-lo novamente.&lt;br /&gt;
&lt;br /&gt;
Finalizado as configurações dos outros roles, para executar a automação basta executar o comando ansible-playbook &amp;lt;playbook).yaml na pasta raiz do projeto, comando este que deve ser inserido no .gitlab-ci.yml para que o gitlab execute a configuração sempre que o usuário realizar um commit.&lt;br /&gt;
&lt;br /&gt;
=== Conclusão ===&lt;br /&gt;
Neste tutorial foi apresentado uma metodologia de automação de redes baseada na integração de ferramentas open source, Ansible e gitlab. Onde através da utilização da abstração de modelos de dados e roles, é possível entregar ao administrador de redes uma interface de configuração agnóstica a fabricantes e com um mecanismo de aprovação característico de metodologias de desenvolvimento de software, com commits e processos de aprovação.&lt;br /&gt;
&lt;br /&gt;
Por fim toda a configuração demonstrada neste artigo pode ser acessada no seguinte repositório do github [10], e a demonstração deste cenário poderá ser assistido em um vídeo no YouTube que será publicado em breve.&lt;br /&gt;
&lt;br /&gt;
Muito obrigado pela atenção, espero que tenham gostado do conteúdo, e assim que possível estarei disponibilizando um vídeo no YouTube demonstrando e dando maiores explicações sobre a metodologia&lt;br /&gt;
&lt;br /&gt;
=== Referências ===&lt;br /&gt;
[1]     (https://docs.gitlab.com/runner/register&amp;lt;nowiki/&amp;gt;/)&lt;br /&gt;
&lt;br /&gt;
[2]     (https://docs.gitlab.com/ee/ci/quick_start/README.html#creating-a-gitlab-ciyml-file)&lt;br /&gt;
&lt;br /&gt;
[3]     (https://docs.gitlab.com/ee/ci/yaml/)&lt;br /&gt;
&lt;br /&gt;
[4]     (https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html)&lt;br /&gt;
&lt;br /&gt;
[5]     (https://galaxy.ansible.com/)&lt;br /&gt;
&lt;br /&gt;
[6]     (https://docs.ansible.com/ansible/latest/modules/routeros_command_module.html#routeros-command-module)&lt;br /&gt;
&lt;br /&gt;
[7]     (https://docs.ansible.com/ansible/latest/modules/ios_config_module.html#ios-config-module)&lt;br /&gt;
&lt;br /&gt;
[8]     (https://docs.ansible.com/ansible/latest/user_guide/vault.html)&lt;br /&gt;
&lt;br /&gt;
[9]     (https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html)&lt;br /&gt;
&lt;br /&gt;
[10]   (https://github.com/renatoalmeidaoliveira/TutorialAnsible)&lt;br /&gt;
&lt;br /&gt;
'''AUTOR:''' [[Usuário:Renato.Oliveira|Renato.Oliveira]]&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Usu%C3%A1rio:Renato.Oliveira&amp;diff=1940</id>
		<title>Usuário:Renato.Oliveira</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Usu%C3%A1rio:Renato.Oliveira&amp;diff=1940"/>
		<updated>2020-01-10T00:20:29Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Perfil do Profissional ===&lt;br /&gt;
Renato Almeida de Oliveira é um engenheiro de telecomunicações formado pelo instituto militar de engenharia (IME).&lt;br /&gt;
&lt;br /&gt;
Atua como engenheiro militar no Exército Brasileiro tendo contribuído com os seguintes projetos:&lt;br /&gt;
* Criação do NOC do 2º CTA situado no Rio de Janeiro, responsável pelo monitoramento da a infraestrutura de redes dedica aos centros de operações em atuação nos jogos olímpicos Rio 2016;&lt;br /&gt;
&lt;br /&gt;
* Desenvolvimento de software para autenticação e registro de usuários da rede coorporativa do exército, entregando as unidades da área do Rio de Janeiro uma plataforma self-service com provimento automático de serviços;&lt;br /&gt;
&lt;br /&gt;
* Mapeamento da infraestrutura legada de Brasília para a realização do moving entre o datacenter antigo para o recém construído data center Ricardo Franco (TIER III);&lt;br /&gt;
&lt;br /&gt;
* Configuração da infraestrutura de redes do backbone nacional do Exército Brasileiro, e integração da rede MPLS legada com a novo backbone;&lt;br /&gt;
&lt;br /&gt;
=== Contato ===&lt;br /&gt;
Para contatos referentes a serviços de consultoria técnica especializada, fornecimento de soluções, projetos, suporte e treinamentos:&lt;br /&gt;
&lt;br /&gt;
'''Linkedin: https://www.linkedin.com/in/renato-oliveira-2b5b4094/'''&lt;br /&gt;
&lt;br /&gt;
'''Telegram''': https://t.me/RenatoAOliveira&lt;br /&gt;
&lt;br /&gt;
=== Artigos escritos ===&lt;br /&gt;
* [[Orquestrando sua rede com Ansible e Gitlab|https://wiki.brasilpeeringforum.org/w/Orquestrando_sua_rede_com_Ansible_e_Gitlab]]&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1939</id>
		<title>Orquestrando sua rede com Ansible e Gitlab</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1939"/>
		<updated>2020-01-10T00:18:35Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: /* Referências */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Introdução ===&lt;br /&gt;
Neste artigo será apresentado uma metodologia de automação de redes baseada em GitLab e Ansible, onde, utilizando templates em Jinja2, será possível entregar ao operador uma estrutura de configurações baseada em modelos de dados. As peculiaridades de cada fabricante estarão encapsuladas através de templates que podem abstrair desde a CLI específica o equipamento até modelos YANG. Este artigo será divido em 5 seções, sendo elas:&lt;br /&gt;
* A instalação do ambiente que para simplificação será monolítica, com o Ansible e o GitLab instalado no mesmo servidor;&lt;br /&gt;
&lt;br /&gt;
* A apresentação da metodologia CI/CD com o GitLab e a criação de um workflow de implantação, com sua respectiva configuração no GitLab-Runner;&lt;br /&gt;
&lt;br /&gt;
* A descrição do funcionamento do Ansible-playbook, em conjunto com uma proposta de estrutura de diretório.&lt;br /&gt;
&lt;br /&gt;
* A criação uma abstração de modelos de dados utilizando Jinja2.&lt;br /&gt;
&lt;br /&gt;
* Integrando a solução e realização de testes.&lt;br /&gt;
&lt;br /&gt;
=== Instalação ===&lt;br /&gt;
O ambiente que será demostrado neste artigo utiliza como sistema operacional o CentOS 7 &amp;lt;!-- Atenção o CentoOS 7 é a versão mais recente suportada pelo GitLab --&amp;gt;, instalado a partir da imagem: CentOS-7-x86_64-DVD-1908, que pode ser encontrada no repositório da distribuição. Neste ambiente, todos os componentes foram instalados em conjunto, porém, para um ambiente de produção, pode ser recomendado separar os componentes GitLab-Runner e Ansible em outro servidor.&lt;br /&gt;
&lt;br /&gt;
             Para realizar a instalação dos componentes pode-se utilizar o script fornecido ou realizar a instalação via repositórios, devendo tomar o cuidado de atualizar a versão do git padrão da distribuição pois ela é incompatível com git-fetch que é utilizado pelo gitlab-runner, realizar a instalação via pip do ncclient e netmiko e criar um domínio em DNS para o gitlab. Caso deseje utilizar o script fornecido, atualize a url “gitlab.local” para o domínio registrado.&lt;br /&gt;
&lt;br /&gt;
             Finalizado o processo de instalação das ferramentas, execute o procedimento de registro do gitlab-runner conforme esta url da referência [1] .&lt;br /&gt;
&lt;br /&gt;
=== GitLab ===&lt;br /&gt;
O GitLab é um gerenciador de repositório de software baseado em git com suporte à Wiki, gerenciamento de tarefas e CI/CD. GitLab é similar ao GitHub, mas o GitLab permite que os desenvolvedores armazenem o código em seus próprios servidores, ao invés de servidores de terceiros. Ele é um software livre, distribuído pela Licença MIT. (wikipedia)&lt;br /&gt;
&lt;br /&gt;
             E com todas essas funcionalidades pode agregar valor à operação, sendo capaz de prover uma base de conhecimento com sua wiki e, através do gitlab-runner, é possível criar um ciclo onde o técnico escreve a configuração desejada e faz um commit no repositório, que automaticamente executa as tarefas de compilação e validação de sintaxe, podendo inclusive realizar o deploy das configurações em um ambiente de laboratório como o EVE-NG.&lt;br /&gt;
&lt;br /&gt;
=== Configurando a pipeline ===&lt;br /&gt;
Uma vez que o gitlab-runner foi instalado e configurado, é necessário adicionar no repositório o arquivo .gitlab-ci.yml que irá descrever todo o fluxo da pipeline [2].&lt;br /&gt;
&lt;br /&gt;
             Durante a execução de cada tarefa, o gitlab-runner executa uma operação ''git fetch'' dentro da sua pasta home o que, para o contexto deste artigo e outras aplicações, pode ser problemático, já que todo os arquivos gerados pelas tarefas anteriores serão perdidos.&lt;br /&gt;
&lt;br /&gt;
             Para a solução deste problema é necessário realizar um cache dos arquivos de configuração compilados, conforme sintaxe abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;''cache:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  key: ${CI_COMMIT_REF_SLUG}''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  paths:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  - cfg/tmp''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Após a configuração do cache, pode ser configurado os estágios da automação onde o gitlab-runner irá executar todas as suas tarefas em paralelo, porém,  somente irá executar as tarefas do próximo estágio, quando todas as tarefas anteriores forem concluídas com êxito. Para a configuração dos estágios, basta adicionar uma seção os relacionando conforme sintaxe abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;''stages:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- deploy''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Por fim, são configuradas as tarefas que cada estágio executa, para o cenário apresentado nesse tutorial iremos configurar apenas o script a ser executado, o estágio que a tarefa pertence e quando ela deve ser executada, conforme script abaixo, porém existem diversas opções de configuração e customizações que podem ser feitas e estão documentadas no link da referência [3] &amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;''Setup:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  stage: build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''script:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''  - ansible-playbook parse.yaml''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''when: always''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Ao término da configuração do .gitlab-ci.yml, a cada commit realizado pelo técnico será executada a pipeline que, para este tutorial, terá a forma da Figura 1:&lt;br /&gt;
[[Arquivo:Ciclo de execução.png|centro|miniaturadaimagem|800x800px|Figura 1. Ciclo de execução]]&lt;br /&gt;
&lt;br /&gt;
=== Ansible ===&lt;br /&gt;
O Ansible é uma ferramenta open-source para gerenciamento de configuração e provisionamento, que utiliza uma comunicação com os nós baseadas em SSH sem a necessidade da instalação de agentes.&lt;br /&gt;
&lt;br /&gt;
             Para a utilização da ferramenta é necessário criar um arquivo ansible.cfg, que contém as configurações básicas do ansible, criar um arquivo contendo a relação dos dispositivos, e criar um arquivo contendo as instruções a serem executadas.&lt;br /&gt;
&lt;br /&gt;
              Com os três arquivos citados anteriormente já é possível realizar alguns testes de acesso com o Ansible, porém para aplicações mais complexas é conveniente utilizar uma estrutura de diretórios para dois propósitos, o primeiro é melhorar a usabilidade e semântica da automação, e a segunda é criar um ambiente flexível e que possa ser reutilizado para diversos propósitos.&lt;br /&gt;
&lt;br /&gt;
             Com este propósito a partir da versão 1.2 o Ansible introduziu o conceito de Roles, que através de uma estrutura de diretórios possibilita o carregamento automático de diversos arquivos e o agrupamento de configurações conforme sua semelhança e necessidade específica, a documentação a respeito de roles pode ser encontrada no link da referência [4], outra vantagem da utilização de roles reside no seu compartilhamento, onde pelo link da referência [5] podem ser encontrados diversos roles prontos para uso.&lt;br /&gt;
&lt;br /&gt;
             Neste tutorial iremos criar roles de acordo com o software que roda nos equipamentos, por exemplo RouterOS, IOS, IOS-XR, Junos e etc, pois cada software possui uma sintaxe própria que ao final da implementação devem ser encapsuladas, outra vantagem desta escolha reside na possibilidade de separação de equipes de modo que a equipe com experiencia em RouteOS, não precisa se preocupar com particularidades do IOS, ou seja a única preocupação dessa equipe é considerando o modelo de dados de entrada que é padrão para todas as implementações gerar a configuração correspondente, conforme Figura 2.&lt;br /&gt;
[[Arquivo:Roles.png|centro|miniaturadaimagem|800x800px|Figura 2. Metologia de utilização dos Roles]]&lt;br /&gt;
Com a estrutura de diretórios pronta é necessário criar as abstrações das configurações o que é dependente de cada modelo e dos módulos disponíveis, para esse tutorial como configuraremos um mikrotik (RouterOS), e um cisco (IOS) iremos utilizar os seguintes módulos routeros_command [6] ios_config [7], e a linguagem de template Jinja2 para criar as abstrações, e devido as diferenças entre os módulos do ios_config e do routeros_command as etapas para a configuração serão diferentes conforme Figuras 3 e 4 &lt;br /&gt;
[[Arquivo:RoleCisco.png|centro|miniaturadaimagem|795x795px|Figura 3. Implementação de um Role para IOS]]&lt;br /&gt;
[[Arquivo:Renato-MikrotikRoles.png|centro|miniaturadaimagem|800x800px|Figura 4. Implementação de um Role para RouterOS]]&lt;br /&gt;
&lt;br /&gt;
=== Criando templates com Jinja2 ===&lt;br /&gt;
Neste tutorial irei demonstrar a criação dos templates apenas para o IOS, mas para o RouterOS a implementação é análoga.&lt;br /&gt;
&lt;br /&gt;
             O primeiro passo é conceber a estrutura de dados do modelo, será utilizado uma interface como base. Abstraindo toda a sintaxe os dados que são inseridos em uma interface em geral são nome da interface, endereço IP, máscara, estado ( shut ou no shut), velocidade, encapsulamento e etc, um exemplo de modelo seria o apresentado abaixo: &amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;Interfaces:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: Loopback0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.0.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description: LDP Loopback&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.255&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: GigabitEthernet0/0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.1.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.252&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Os arquivos contendo estes modelos seriam armazenados dentro da pasta ''roles/models/files/interfaces/&amp;lt;hostname&amp;gt;.yml''. Percebe que neste momento estamos fazendo duas associações implícitas, a primeira é utilizar a palavra '''interfaces''' no caminho que será utilizada posteriormente para acessar todos os arquivos de configuração relativos a configuração das interfaces, e a segunda associação está no nome do arquivo '''&amp;lt;hostname&amp;gt;.yml''', que será utilizado em tempo de execução para associar dada configuração ao ativo.&lt;br /&gt;
&lt;br /&gt;
             Com o modelo pronto precisamos escrever o template, que no caso do IOS ficará em ''roles/ios/templates/interfaces.j2'', e iremos criar um template para cada funcionalidade que desejarmos automatizar.&lt;br /&gt;
&lt;br /&gt;
             Para a criação do template é necessário conhecer algumas estruturas de controle que nos permitirão realizar testes, e executar laços dentro da execução. A primeira estrutura que será apresentada é o laço '''{% for iterador in variável %} ... {% endfor %}'''. Ao observar o modelo que criamos acima pode se perceber que ele forma uma lista de interfaces, e será carregado dentro do Ansible como uma variável de nome interfaces, então para montar o laço iremos utilizar:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Outra estrutura que será usada extensivamente é condicional IF que possui a seguinte estrutura: &amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;{% if confição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;..&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% elif condição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% else %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             E para acessar as variáveis basta utilizar a seguinte sintaxe &amp;lt;nowiki&amp;gt;{{ nome da variável }}&amp;lt;/nowiki&amp;gt;.  O próximo passo é escrever a configuração que se deseja aplicar tomando muito cuidado com espaços, e sem a necessidade de se utilizar end ao final, pois o módulo executa uma comparação textual com a configuração em produção antes de configurar, no final a configuração do template será semelhando a abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;interface &amp;lt;nowiki&amp;gt;{{ interface.name }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.description is defined %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description &amp;lt;nowiki&amp;gt;{{ interface.description}}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if (interface.address is defined ) and (interface.mask is defined ) %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ip address &amp;lt;nowiki&amp;gt;{{ interface.address }}&amp;lt;/nowiki&amp;gt; &amp;lt;nowiki&amp;gt;{{ interface.mask }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == True %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;no shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == False %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;exit&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integrando a solução ===&lt;br /&gt;
Com os modelos prontos e todos os templates está na hora de criar os playbooks, que serão utilizados pelo Ansible para guiar a automação. O primeiro playbook a ser criado fica na raiz do diretório e será responsável por “chamar” os playbooks de cada role, o que é entregue automaticamente, bastando se incluir o role no playbook, para esse primeiro playbook que chamarei de principal, será necessário criar um “Play” para cada grupo de ativos e neste play será incluído a role desejada, conforme exemplo abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: Cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- name: MikroTik&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: routeros&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - routeros&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;A relação de hosts para cada grupo é definida dentro do arquivo hosts, que tem a seguinte sintaxe:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;[cisco]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE7 ansible_host=192.168.237.206&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE4 ansible_host=192.168.237.202&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P2  ansible_host=192.168.237.203&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P1  ansible_host=192.168.237.205&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE5 ansible_host=192.168.237.207&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE6 ansible_host=192.168.237.204&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;[routeros]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P3  ansible_host=192.168.237.183&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Neste arquivo os grupos são definidos dentro dos colchetes, [cisco] e [routeros], enquanto os membros do grupo são definidos individualmente abaixo com a seguinte sintaxe: HOSTNAME  ansible_host=&amp;lt;endereço IP&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
             Adicionalmente ao endereço é necessário prover as credenciais de acesso ao equipamento e o sistema que roda em cada um conforme [3], neste tutorial será utilizado a mesma credencial de acesso a todos os equipamentos e tal configuração ficará dentro do arquivo group_vars/all.yml que tem a seguinte forma:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;ansible_connection: network_cli&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become_method: enable&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_user: 'renato'&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_ssh_pass: '123456'&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Note que nesse tutorial estou usando uma senha em claro dentro de um arquivo de configuração o que não é uma boa prática, para encriptar esta senha utilize os procedimentos descritos em [8].&lt;br /&gt;
&lt;br /&gt;
E para as configurações específicas de cada plataforma será criado um arquivo com o mesmo nome do groupo na pasta group_vars, estas configurações podem ser visualizadas em [9].&lt;br /&gt;
&lt;br /&gt;
             Finalizado estas configurações, criação do playbook principal, do inventário e das variáveis, vamos aos arquivos específicos de cada modelo. Para isso deverá ser criado um arquivo com o nome main.yml na pasta roles/&amp;lt;role&amp;gt;/tasks. Para a configuração no cisco, conforme Figura 3 precisamos primeiro ler o arquivo com o modelo e transformar ele em variável, porém é importante notar que cada tarefa é executada para todos os equipamentos do grupo, assim para evitar erros de execução iremos pesquisar pelo modelo na sua pasta respectiva:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: List interface directory&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;find:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  paths: roles/models/files/interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  patterns: &amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  recurse: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file_type: file&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;register: Files&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              &lt;br /&gt;
&lt;br /&gt;
Perceba que a tarefa acima pesquisa na pasta /roles/models/files/interfaces todos os arquivos com o seguinte padrão ''&amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;'', note a sintaxe ''&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;'', vista anteriormente nos templates em jinja2, que  faz referência ao equipamento que está sendo processado, registra o resultado de sua busca na variável Files e por fim executa esse procedimento localmente, sem a necessidade de se conectar via ssh no host.&lt;br /&gt;
&lt;br /&gt;
Com os arquivos identificados o próximo passo é importar as variáveis que será feito utilizando o módulo template, conforme descrito abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: Include interface vars&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  include_vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file: roles/models/files/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             Com o modelo importado o próximo passo é a criação dos arquivos de configuração, nesta etapa é fundamental que na sua estrutura de diretórios já exista uma pasta destinada a estes arquivos, e para a sua configuração basta seguir o modelo abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: Make Config&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;template:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  src: interface.j2&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  dest: cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  mode: 0777&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             Finalmente com todos os arquivos de configuração prontos, está na hora de aplicar as configurações nos equipamentos que no caso do ios é feito utilizando o módulo ios_config, conforme sintaxe abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;  - name: Configure&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  ios_config:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;    src:  “cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg”&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: configFiles.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Finalizadas estas configurações basta repetir o processo para cada funcionalidade que se deseja implementar em sua automação, e caso seja de interesse é possível simplificar ainda mais a criação dos playbooks, realizando a separação da configuração das tarefas por escopos, ou seja dentro da pasta roles/&amp;lt;role&amp;gt;/tasks existirá um arquivo main.yml que é responsável por importar as tarefas de cada uma das funcionalidades e cada funcionalidade terá um arquivo próprio como por exemplor interfaces.yml, ospf.yml , mpls.yml e etc, desta forma as configurações apresentadas acima residirão dentro de cada um dos playbooks de funcionalidades e o playbook main.yml irá apenas instanciar usando a seguinte sintaxe:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- import_tasks: interfaces.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  scope: interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Observe no código acima que foi introduzido uma variável durante a inclusão, e ao observar as configurações realizadas anteriormente é possível perceber que em nenhum momento foi utilizado alguma especificidade de alguma funcionalidade, portanto com é possível apenas com a alteração da variável scope, recém introduzida, replicar todo o código que criamos sem a necessidade de escreve-lo novamente.&lt;br /&gt;
&lt;br /&gt;
             Finalizado as configurações dos outros roles, para executar a automação basta executar o comando ansible-playbook &amp;lt;playbook).yaml na pasta raiz do projeto, comando este que deve ser inserido no .gitlab-ci.yml para que o gitlab execute a configuração sempre que o usuário realizar um commit.&lt;br /&gt;
&lt;br /&gt;
=== Conclusão ===&lt;br /&gt;
             Neste tutorial foi apresentado uma metodologia de automação de redes baseada na integração de ferramentas open source, Ansible e gitlab. Onde através da utilização da abstração de modelos de dados e roles, é possível entregar ao administrador de redes uma interface de configuração agnóstica a fabricantes e com um mecanismo de aprovação característico de metodologias de desenvolvimento de software, com commits e processos de aprovação.&lt;br /&gt;
&lt;br /&gt;
Por fim toda a configuração demonstrada neste artigo pode ser acessada no seguinte repositório do github [10], e a demonstração deste cenário poderá ser assistido em um vídeo no YouTube que será publicado em breve.&lt;br /&gt;
&lt;br /&gt;
Muito obrigado pela atenção, espero que tenham gostado do conteúdo, e assim que possível estarei disponibilizando um vídeo no YouTube demonstrando e dando maiores explicações sobre a metodologia&lt;br /&gt;
&lt;br /&gt;
=== Referências ===&lt;br /&gt;
[1]     (https://docs.gitlab.com/runner/register&amp;lt;nowiki/&amp;gt;/)&lt;br /&gt;
&lt;br /&gt;
[2]     (https://docs.gitlab.com/ee/ci/quick_start/README.html#creating-a-gitlab-ciyml-file)&lt;br /&gt;
&lt;br /&gt;
[3]     (https://docs.gitlab.com/ee/ci/yaml/)&lt;br /&gt;
&lt;br /&gt;
[4]     (https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html)&lt;br /&gt;
&lt;br /&gt;
[5]     (https://galaxy.ansible.com/)&lt;br /&gt;
&lt;br /&gt;
[6]     (https://docs.ansible.com/ansible/latest/modules/routeros_command_module.html#routeros-command-module)&lt;br /&gt;
&lt;br /&gt;
[7]     (https://docs.ansible.com/ansible/latest/modules/ios_config_module.html#ios-config-module)&lt;br /&gt;
&lt;br /&gt;
[8]     (https://docs.ansible.com/ansible/latest/user_guide/vault.html)&lt;br /&gt;
&lt;br /&gt;
[9]     (https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html)&lt;br /&gt;
&lt;br /&gt;
[10]   (https://github.com/renatoalmeidaoliveira/TutorialAnsible)&lt;br /&gt;
&lt;br /&gt;
'''AUTOR:''' [[Usuário:Renato.Oliveira]]&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1938</id>
		<title>Orquestrando sua rede com Ansible e Gitlab</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1938"/>
		<updated>2020-01-09T22:51:08Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: /* Referências */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Introdução ===&lt;br /&gt;
Neste artigo será apresentado uma metodologia de automação de redes baseada em GitLab e Ansible, onde, utilizando templates em Jinja2, será possível entregar ao operador uma estrutura de configurações baseada em modelos de dados. As peculiaridades de cada fabricante estarão encapsuladas através de templates que podem abstrair desde a CLI específica o equipamento até modelos YANG. Este artigo será divido em 5 seções, sendo elas:&lt;br /&gt;
* A instalação do ambiente que para simplificação será monolítica, com o Ansible e o GitLab instalado no mesmo servidor;&lt;br /&gt;
&lt;br /&gt;
* A apresentação da metodologia CI/CD com o GitLab e a criação de um workflow de implantação, com sua respectiva configuração no GitLab-Runner;&lt;br /&gt;
&lt;br /&gt;
* A descrição do funcionamento do Ansible-playbook, em conjunto com uma proposta de estrutura de diretório.&lt;br /&gt;
&lt;br /&gt;
* A criação uma abstração de modelos de dados utilizando Jinja2.&lt;br /&gt;
&lt;br /&gt;
* Integrando a solução e realização de testes.&lt;br /&gt;
&lt;br /&gt;
=== Instalação ===&lt;br /&gt;
O ambiente que será demostrado neste artigo utiliza como sistema operacional o CentOS 7 &amp;lt;!-- Atenção o CentoOS 7 é a versão mais recente suportada pelo GitLab --&amp;gt;, instalado a partir da imagem: CentOS-7-x86_64-DVD-1908, que pode ser encontrada no repositório da distribuição. Neste ambiente, todos os componentes foram instalados em conjunto, porém, para um ambiente de produção, pode ser recomendado separar os componentes GitLab-Runner e Ansible em outro servidor.&lt;br /&gt;
&lt;br /&gt;
             Para realizar a instalação dos componentes pode-se utilizar o script fornecido ou realizar a instalação via repositórios, devendo tomar o cuidado de atualizar a versão do git padrão da distribuição pois ela é incompatível com git-fetch que é utilizado pelo gitlab-runner, realizar a instalação via pip do ncclient e netmiko e criar um domínio em DNS para o gitlab. Caso deseje utilizar o script fornecido, atualize a url “gitlab.local” para o domínio registrado.&lt;br /&gt;
&lt;br /&gt;
             Finalizado o processo de instalação das ferramentas, execute o procedimento de registro do gitlab-runner conforme esta url da referência [1] .&lt;br /&gt;
&lt;br /&gt;
=== GitLab ===&lt;br /&gt;
O GitLab é um gerenciador de repositório de software baseado em git com suporte à Wiki, gerenciamento de tarefas e CI/CD. GitLab é similar ao GitHub, mas o GitLab permite que os desenvolvedores armazenem o código em seus próprios servidores, ao invés de servidores de terceiros. Ele é um software livre, distribuído pela Licença MIT. (wikipedia)&lt;br /&gt;
&lt;br /&gt;
             E com todas essas funcionalidades pode agregar valor à operação, sendo capaz de prover uma base de conhecimento com sua wiki e, através do gitlab-runner, é possível criar um ciclo onde o técnico escreve a configuração desejada e faz um commit no repositório, que automaticamente executa as tarefas de compilação e validação de sintaxe, podendo inclusive realizar o deploy das configurações em um ambiente de laboratório como o EVE-NG.&lt;br /&gt;
&lt;br /&gt;
=== Configurando a pipeline ===&lt;br /&gt;
Uma vez que o gitlab-runner foi instalado e configurado, é necessário adicionar no repositório o arquivo .gitlab-ci.yml que irá descrever todo o fluxo da pipeline [2].&lt;br /&gt;
&lt;br /&gt;
             Durante a execução de cada tarefa, o gitlab-runner executa uma operação ''git fetch'' dentro da sua pasta home o que, para o contexto deste artigo e outras aplicações, pode ser problemático, já que todo os arquivos gerados pelas tarefas anteriores serão perdidos.&lt;br /&gt;
&lt;br /&gt;
             Para a solução deste problema é necessário realizar um cache dos arquivos de configuração compilados, conforme sintaxe abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;''cache:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  key: ${CI_COMMIT_REF_SLUG}''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  paths:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  - cfg/tmp''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Após a configuração do cache, pode ser configurado os estágios da automação onde o gitlab-runner irá executar todas as suas tarefas em paralelo, porém,  somente irá executar as tarefas do próximo estágio, quando todas as tarefas anteriores forem concluídas com êxito. Para a configuração dos estágios, basta adicionar uma seção os relacionando conforme sintaxe abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;''stages:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- deploy''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Por fim, são configuradas as tarefas que cada estágio executa, para o cenário apresentado nesse tutorial iremos configurar apenas o script a ser executado, o estágio que a tarefa pertence e quando ela deve ser executada, conforme script abaixo, porém existem diversas opções de configuração e customizações que podem ser feitas e estão documentadas no link da referência [3] &amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;''Setup:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  stage: build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''script:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''  - ansible-playbook parse.yaml''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''when: always''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Ao término da configuração do .gitlab-ci.yml, a cada commit realizado pelo técnico será executada a pipeline que, para este tutorial, terá a forma da Figura 1:&lt;br /&gt;
[[Arquivo:Ciclo de execução.png|centro|miniaturadaimagem|800x800px|Figura 1. Ciclo de execução]]&lt;br /&gt;
&lt;br /&gt;
=== Ansible ===&lt;br /&gt;
O Ansible é uma ferramenta open-source para gerenciamento de configuração e provisionamento, que utiliza uma comunicação com os nós baseadas em SSH sem a necessidade da instalação de agentes.&lt;br /&gt;
&lt;br /&gt;
             Para a utilização da ferramenta é necessário criar um arquivo ansible.cfg, que contém as configurações básicas do ansible, criar um arquivo contendo a relação dos dispositivos, e criar um arquivo contendo as instruções a serem executadas.&lt;br /&gt;
&lt;br /&gt;
              Com os três arquivos citados anteriormente já é possível realizar alguns testes de acesso com o Ansible, porém para aplicações mais complexas é conveniente utilizar uma estrutura de diretórios para dois propósitos, o primeiro é melhorar a usabilidade e semântica da automação, e a segunda é criar um ambiente flexível e que possa ser reutilizado para diversos propósitos.&lt;br /&gt;
&lt;br /&gt;
             Com este propósito a partir da versão 1.2 o Ansible introduziu o conceito de Roles, que através de uma estrutura de diretórios possibilita o carregamento automático de diversos arquivos e o agrupamento de configurações conforme sua semelhança e necessidade específica, a documentação a respeito de roles pode ser encontrada no link da referência [4], outra vantagem da utilização de roles reside no seu compartilhamento, onde pelo link da referência [5] podem ser encontrados diversos roles prontos para uso.&lt;br /&gt;
&lt;br /&gt;
             Neste tutorial iremos criar roles de acordo com o software que roda nos equipamentos, por exemplo RouterOS, IOS, IOS-XR, Junos e etc, pois cada software possui uma sintaxe própria que ao final da implementação devem ser encapsuladas, outra vantagem desta escolha reside na possibilidade de separação de equipes de modo que a equipe com experiencia em RouteOS, não precisa se preocupar com particularidades do IOS, ou seja a única preocupação dessa equipe é considerando o modelo de dados de entrada que é padrão para todas as implementações gerar a configuração correspondente, conforme Figura 2.&lt;br /&gt;
[[Arquivo:Roles.png|centro|miniaturadaimagem|800x800px|Figura 2. Metologia de utilização dos Roles]]&lt;br /&gt;
Com a estrutura de diretórios pronta é necessário criar as abstrações das configurações o que é dependente de cada modelo e dos módulos disponíveis, para esse tutorial como configuraremos um mikrotik (RouterOS), e um cisco (IOS) iremos utilizar os seguintes módulos routeros_command [6] ios_config [7], e a linguagem de template Jinja2 para criar as abstrações, e devido as diferenças entre os módulos do ios_config e do routeros_command as etapas para a configuração serão diferentes conforme Figuras 3 e 4 &lt;br /&gt;
[[Arquivo:RoleCisco.png|centro|miniaturadaimagem|795x795px|Figura 3. Implementação de um Role para IOS]]&lt;br /&gt;
[[Arquivo:Renato-MikrotikRoles.png|centro|miniaturadaimagem|800x800px|Figura 4. Implementação de um Role para RouterOS]]&lt;br /&gt;
&lt;br /&gt;
=== Criando templates com Jinja2 ===&lt;br /&gt;
Neste tutorial irei demonstrar a criação dos templates apenas para o IOS, mas para o RouterOS a implementação é análoga.&lt;br /&gt;
&lt;br /&gt;
             O primeiro passo é conceber a estrutura de dados do modelo, será utilizado uma interface como base. Abstraindo toda a sintaxe os dados que são inseridos em uma interface em geral são nome da interface, endereço IP, máscara, estado ( shut ou no shut), velocidade, encapsulamento e etc, um exemplo de modelo seria o apresentado abaixo: &amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;Interfaces:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: Loopback0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.0.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description: LDP Loopback&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.255&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: GigabitEthernet0/0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.1.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.252&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Os arquivos contendo estes modelos seriam armazenados dentro da pasta ''roles/models/files/interfaces/&amp;lt;hostname&amp;gt;.yml''. Percebe que neste momento estamos fazendo duas associações implícitas, a primeira é utilizar a palavra '''interfaces''' no caminho que será utilizada posteriormente para acessar todos os arquivos de configuração relativos a configuração das interfaces, e a segunda associação está no nome do arquivo '''&amp;lt;hostname&amp;gt;.yml''', que será utilizado em tempo de execução para associar dada configuração ao ativo.&lt;br /&gt;
&lt;br /&gt;
             Com o modelo pronto precisamos escrever o template, que no caso do IOS ficará em ''roles/ios/templates/interfaces.j2'', e iremos criar um template para cada funcionalidade que desejarmos automatizar.&lt;br /&gt;
&lt;br /&gt;
             Para a criação do template é necessário conhecer algumas estruturas de controle que nos permitirão realizar testes, e executar laços dentro da execução. A primeira estrutura que será apresentada é o laço '''{% for iterador in variável %} ... {% endfor %}'''. Ao observar o modelo que criamos acima pode se perceber que ele forma uma lista de interfaces, e será carregado dentro do Ansible como uma variável de nome interfaces, então para montar o laço iremos utilizar:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Outra estrutura que será usada extensivamente é condicional IF que possui a seguinte estrutura: &amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;{% if confição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;..&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% elif condição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% else %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             E para acessar as variáveis basta utilizar a seguinte sintaxe &amp;lt;nowiki&amp;gt;{{ nome da variável }}&amp;lt;/nowiki&amp;gt;.  O próximo passo é escrever a configuração que se deseja aplicar tomando muito cuidado com espaços, e sem a necessidade de se utilizar end ao final, pois o módulo executa uma comparação textual com a configuração em produção antes de configurar, no final a configuração do template será semelhando a abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;interface &amp;lt;nowiki&amp;gt;{{ interface.name }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.description is defined %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description &amp;lt;nowiki&amp;gt;{{ interface.description}}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if (interface.address is defined ) and (interface.mask is defined ) %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ip address &amp;lt;nowiki&amp;gt;{{ interface.address }}&amp;lt;/nowiki&amp;gt; &amp;lt;nowiki&amp;gt;{{ interface.mask }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == True %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;no shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == False %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;exit&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integrando a solução ===&lt;br /&gt;
Com os modelos prontos e todos os templates está na hora de criar os playbooks, que serão utilizados pelo Ansible para guiar a automação. O primeiro playbook a ser criado fica na raiz do diretório e será responsável por “chamar” os playbooks de cada role, o que é entregue automaticamente, bastando se incluir o role no playbook, para esse primeiro playbook que chamarei de principal, será necessário criar um “Play” para cada grupo de ativos e neste play será incluído a role desejada, conforme exemplo abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: Cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- name: MikroTik&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: routeros&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - routeros&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;A relação de hosts para cada grupo é definida dentro do arquivo hosts, que tem a seguinte sintaxe:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;[cisco]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE7 ansible_host=192.168.237.206&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE4 ansible_host=192.168.237.202&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P2  ansible_host=192.168.237.203&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P1  ansible_host=192.168.237.205&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE5 ansible_host=192.168.237.207&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE6 ansible_host=192.168.237.204&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;[routeros]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P3  ansible_host=192.168.237.183&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Neste arquivo os grupos são definidos dentro dos colchetes, [cisco] e [routeros], enquanto os membros do grupo são definidos individualmente abaixo com a seguinte sintaxe: HOSTNAME  ansible_host=&amp;lt;endereço IP&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
             Adicionalmente ao endereço é necessário prover as credenciais de acesso ao equipamento e o sistema que roda em cada um conforme [3], neste tutorial será utilizado a mesma credencial de acesso a todos os equipamentos e tal configuração ficará dentro do arquivo group_vars/all.yml que tem a seguinte forma:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;ansible_connection: network_cli&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become_method: enable&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_user: 'renato'&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_ssh_pass: '123456'&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Note que nesse tutorial estou usando uma senha em claro dentro de um arquivo de configuração o que não é uma boa prática, para encriptar esta senha utilize os procedimentos descritos em [8].&lt;br /&gt;
&lt;br /&gt;
E para as configurações específicas de cada plataforma será criado um arquivo com o mesmo nome do groupo na pasta group_vars, estas configurações podem ser visualizadas em [9].&lt;br /&gt;
&lt;br /&gt;
             Finalizado estas configurações, criação do playbook principal, do inventário e das variáveis, vamos aos arquivos específicos de cada modelo. Para isso deverá ser criado um arquivo com o nome main.yml na pasta roles/&amp;lt;role&amp;gt;/tasks. Para a configuração no cisco, conforme Figura 3 precisamos primeiro ler o arquivo com o modelo e transformar ele em variável, porém é importante notar que cada tarefa é executada para todos os equipamentos do grupo, assim para evitar erros de execução iremos pesquisar pelo modelo na sua pasta respectiva:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: List interface directory&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;find:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  paths: roles/models/files/interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  patterns: &amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  recurse: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file_type: file&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;register: Files&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              &lt;br /&gt;
&lt;br /&gt;
Perceba que a tarefa acima pesquisa na pasta /roles/models/files/interfaces todos os arquivos com o seguinte padrão ''&amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;'', note a sintaxe ''&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;'', vista anteriormente nos templates em jinja2, que  faz referência ao equipamento que está sendo processado, registra o resultado de sua busca na variável Files e por fim executa esse procedimento localmente, sem a necessidade de se conectar via ssh no host.&lt;br /&gt;
&lt;br /&gt;
Com os arquivos identificados o próximo passo é importar as variáveis que será feito utilizando o módulo template, conforme descrito abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: Include interface vars&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  include_vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file: roles/models/files/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             Com o modelo importado o próximo passo é a criação dos arquivos de configuração, nesta etapa é fundamental que na sua estrutura de diretórios já exista uma pasta destinada a estes arquivos, e para a sua configuração basta seguir o modelo abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: Make Config&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;template:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  src: interface.j2&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  dest: cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  mode: 0777&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             Finalmente com todos os arquivos de configuração prontos, está na hora de aplicar as configurações nos equipamentos que no caso do ios é feito utilizando o módulo ios_config, conforme sintaxe abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;  - name: Configure&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  ios_config:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;    src:  “cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg”&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: configFiles.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Finalizadas estas configurações basta repetir o processo para cada funcionalidade que se deseja implementar em sua automação, e caso seja de interesse é possível simplificar ainda mais a criação dos playbooks, realizando a separação da configuração das tarefas por escopos, ou seja dentro da pasta roles/&amp;lt;role&amp;gt;/tasks existirá um arquivo main.yml que é responsável por importar as tarefas de cada uma das funcionalidades e cada funcionalidade terá um arquivo próprio como por exemplor interfaces.yml, ospf.yml , mpls.yml e etc, desta forma as configurações apresentadas acima residirão dentro de cada um dos playbooks de funcionalidades e o playbook main.yml irá apenas instanciar usando a seguinte sintaxe:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- import_tasks: interfaces.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  scope: interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Observe no código acima que foi introduzido uma variável durante a inclusão, e ao observar as configurações realizadas anteriormente é possível perceber que em nenhum momento foi utilizado alguma especificidade de alguma funcionalidade, portanto com é possível apenas com a alteração da variável scope, recém introduzida, replicar todo o código que criamos sem a necessidade de escreve-lo novamente.&lt;br /&gt;
&lt;br /&gt;
             Finalizado as configurações dos outros roles, para executar a automação basta executar o comando ansible-playbook &amp;lt;playbook).yaml na pasta raiz do projeto, comando este que deve ser inserido no .gitlab-ci.yml para que o gitlab execute a configuração sempre que o usuário realizar um commit.&lt;br /&gt;
&lt;br /&gt;
=== Conclusão ===&lt;br /&gt;
             Neste tutorial foi apresentado uma metodologia de automação de redes baseada na integração de ferramentas open source, Ansible e gitlab. Onde através da utilização da abstração de modelos de dados e roles, é possível entregar ao administrador de redes uma interface de configuração agnóstica a fabricantes e com um mecanismo de aprovação característico de metodologias de desenvolvimento de software, com commits e processos de aprovação.&lt;br /&gt;
&lt;br /&gt;
Por fim toda a configuração demonstrada neste artigo pode ser acessada no seguinte repositório do github [10], e a demonstração deste cenário poderá ser assistido em um vídeo no YouTube que será publicado em breve.&lt;br /&gt;
&lt;br /&gt;
Muito obrigado pela atenção, espero que tenham gostado do conteúdo, e assim que possível estarei disponibilizando um vídeo no YouTube demonstrando e dando maiores explicações sobre a metodologia&lt;br /&gt;
&lt;br /&gt;
=== Referências ===&lt;br /&gt;
[1]     (https://docs.gitlab.com/runner/register&amp;lt;nowiki/&amp;gt;/)&lt;br /&gt;
&lt;br /&gt;
[2]     (https://docs.gitlab.com/ee/ci/quick_start/README.html#creating-a-gitlab-ciyml-file)&lt;br /&gt;
&lt;br /&gt;
[3]     (https://docs.gitlab.com/ee/ci/yaml/)&lt;br /&gt;
&lt;br /&gt;
[4]     (https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html)&lt;br /&gt;
&lt;br /&gt;
[5]     (https://galaxy.ansible.com/)&lt;br /&gt;
&lt;br /&gt;
[6]     (https://docs.ansible.com/ansible/latest/modules/routeros_command_module.html#routeros-command-module)&lt;br /&gt;
&lt;br /&gt;
[7]     (https://docs.ansible.com/ansible/latest/modules/ios_config_module.html#ios-config-module)&lt;br /&gt;
&lt;br /&gt;
[8]     (https://docs.ansible.com/ansible/latest/user_guide/vault.html)&lt;br /&gt;
&lt;br /&gt;
[9]     (https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html)&lt;br /&gt;
&lt;br /&gt;
'''AUTOR:''' [[Usuário:Renato.Oliveira]]&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1937</id>
		<title>Orquestrando sua rede com Ansible e Gitlab</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1937"/>
		<updated>2020-01-09T22:04:42Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Introdução ===&lt;br /&gt;
Neste artigo será apresentado uma metodologia de automação de redes baseada em GitLab e Ansible, onde, utilizando templates em Jinja2, será possível entregar ao operador uma estrutura de configurações baseada em modelos de dados. As peculiaridades de cada fabricante estarão encapsuladas através de templates que podem abstrair desde a CLI específica o equipamento até modelos YANG. Este artigo será divido em 5 seções, sendo elas:&lt;br /&gt;
* A instalação do ambiente que para simplificação será monolítica, com o Ansible e o GitLab instalado no mesmo servidor;&lt;br /&gt;
&lt;br /&gt;
* A apresentação da metodologia CI/CD com o GitLab e a criação de um workflow de implantação, com sua respectiva configuração no GitLab-Runner;&lt;br /&gt;
&lt;br /&gt;
* A descrição do funcionamento do Ansible-playbook, em conjunto com uma proposta de estrutura de diretório.&lt;br /&gt;
&lt;br /&gt;
* A criação uma abstração de modelos de dados utilizando Jinja2.&lt;br /&gt;
&lt;br /&gt;
* Integrando a solução e realização de testes.&lt;br /&gt;
&lt;br /&gt;
=== Instalação ===&lt;br /&gt;
O ambiente que será demostrado neste artigo utiliza como sistema operacional o CentOS 7 &amp;lt;!-- Atenção o CentoOS 7 é a versão mais recente suportada pelo GitLab --&amp;gt;, instalado a partir da imagem: CentOS-7-x86_64-DVD-1908, que pode ser encontrada no repositório da distribuição. Neste ambiente, todos os componentes foram instalados em conjunto, porém, para um ambiente de produção, pode ser recomendado separar os componentes GitLab-Runner e Ansible em outro servidor.&lt;br /&gt;
&lt;br /&gt;
             Para realizar a instalação dos componentes pode-se utilizar o script fornecido ou realizar a instalação via repositórios, devendo tomar o cuidado de atualizar a versão do git padrão da distribuição pois ela é incompatível com git-fetch que é utilizado pelo gitlab-runner, realizar a instalação via pip do ncclient e netmiko e criar um domínio em DNS para o gitlab. Caso deseje utilizar o script fornecido, atualize a url “gitlab.local” para o domínio registrado.&lt;br /&gt;
&lt;br /&gt;
             Finalizado o processo de instalação das ferramentas, execute o procedimento de registro do gitlab-runner conforme esta url da referência [1] .&lt;br /&gt;
&lt;br /&gt;
=== GitLab ===&lt;br /&gt;
O GitLab é um gerenciador de repositório de software baseado em git com suporte à Wiki, gerenciamento de tarefas e CI/CD. GitLab é similar ao GitHub, mas o GitLab permite que os desenvolvedores armazenem o código em seus próprios servidores, ao invés de servidores de terceiros. Ele é um software livre, distribuído pela Licença MIT. (wikipedia)&lt;br /&gt;
&lt;br /&gt;
             E com todas essas funcionalidades pode agregar valor à operação, sendo capaz de prover uma base de conhecimento com sua wiki e, através do gitlab-runner, é possível criar um ciclo onde o técnico escreve a configuração desejada e faz um commit no repositório, que automaticamente executa as tarefas de compilação e validação de sintaxe, podendo inclusive realizar o deploy das configurações em um ambiente de laboratório como o EVE-NG.&lt;br /&gt;
&lt;br /&gt;
=== Configurando a pipeline ===&lt;br /&gt;
Uma vez que o gitlab-runner foi instalado e configurado, é necessário adicionar no repositório o arquivo .gitlab-ci.yml que irá descrever todo o fluxo da pipeline [2].&lt;br /&gt;
&lt;br /&gt;
             Durante a execução de cada tarefa, o gitlab-runner executa uma operação ''git fetch'' dentro da sua pasta home o que, para o contexto deste artigo e outras aplicações, pode ser problemático, já que todo os arquivos gerados pelas tarefas anteriores serão perdidos.&lt;br /&gt;
&lt;br /&gt;
             Para a solução deste problema é necessário realizar um cache dos arquivos de configuração compilados, conforme sintaxe abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;''cache:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  key: ${CI_COMMIT_REF_SLUG}''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  paths:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  - cfg/tmp''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Após a configuração do cache, pode ser configurado os estágios da automação onde o gitlab-runner irá executar todas as suas tarefas em paralelo, porém,  somente irá executar as tarefas do próximo estágio, quando todas as tarefas anteriores forem concluídas com êxito. Para a configuração dos estágios, basta adicionar uma seção os relacionando conforme sintaxe abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;''stages:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- deploy''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Por fim, são configuradas as tarefas que cada estágio executa, para o cenário apresentado nesse tutorial iremos configurar apenas o script a ser executado, o estágio que a tarefa pertence e quando ela deve ser executada, conforme script abaixo, porém existem diversas opções de configuração e customizações que podem ser feitas e estão documentadas no link da referência [3] &amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;''Setup:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  stage: build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''script:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''  - ansible-playbook parse.yaml''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''when: always''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Ao término da configuração do .gitlab-ci.yml, a cada commit realizado pelo técnico será executada a pipeline que, para este tutorial, terá a forma da Figura 1:&lt;br /&gt;
[[Arquivo:Ciclo de execução.png|centro|miniaturadaimagem|800x800px|Figura 1. Ciclo de execução]]&lt;br /&gt;
&lt;br /&gt;
=== Ansible ===&lt;br /&gt;
O Ansible é uma ferramenta open-source para gerenciamento de configuração e provisionamento, que utiliza uma comunicação com os nós baseadas em SSH sem a necessidade da instalação de agentes.&lt;br /&gt;
&lt;br /&gt;
             Para a utilização da ferramenta é necessário criar um arquivo ansible.cfg, que contém as configurações básicas do ansible, criar um arquivo contendo a relação dos dispositivos, e criar um arquivo contendo as instruções a serem executadas.&lt;br /&gt;
&lt;br /&gt;
              Com os três arquivos citados anteriormente já é possível realizar alguns testes de acesso com o Ansible, porém para aplicações mais complexas é conveniente utilizar uma estrutura de diretórios para dois propósitos, o primeiro é melhorar a usabilidade e semântica da automação, e a segunda é criar um ambiente flexível e que possa ser reutilizado para diversos propósitos.&lt;br /&gt;
&lt;br /&gt;
             Com este propósito a partir da versão 1.2 o Ansible introduziu o conceito de Roles, que através de uma estrutura de diretórios possibilita o carregamento automático de diversos arquivos e o agrupamento de configurações conforme sua semelhança e necessidade específica, a documentação a respeito de roles pode ser encontrada no link da referência [4], outra vantagem da utilização de roles reside no seu compartilhamento, onde pelo link da referência [5] podem ser encontrados diversos roles prontos para uso.&lt;br /&gt;
&lt;br /&gt;
             Neste tutorial iremos criar roles de acordo com o software que roda nos equipamentos, por exemplo RouterOS, IOS, IOS-XR, Junos e etc, pois cada software possui uma sintaxe própria que ao final da implementação devem ser encapsuladas, outra vantagem desta escolha reside na possibilidade de separação de equipes de modo que a equipe com experiencia em RouteOS, não precisa se preocupar com particularidades do IOS, ou seja a única preocupação dessa equipe é considerando o modelo de dados de entrada que é padrão para todas as implementações gerar a configuração correspondente, conforme Figura 2.&lt;br /&gt;
[[Arquivo:Roles.png|centro|miniaturadaimagem|800x800px|Figura 2. Metologia de utilização dos Roles]]&lt;br /&gt;
Com a estrutura de diretórios pronta é necessário criar as abstrações das configurações o que é dependente de cada modelo e dos módulos disponíveis, para esse tutorial como configuraremos um mikrotik (RouterOS), e um cisco (IOS) iremos utilizar os seguintes módulos routeros_command [6] ios_config [7], e a linguagem de template Jinja2 para criar as abstrações, e devido as diferenças entre os módulos do ios_config e do routeros_command as etapas para a configuração serão diferentes conforme Figuras 3 e 4 &lt;br /&gt;
[[Arquivo:RoleCisco.png|centro|miniaturadaimagem|795x795px|Figura 3. Implementação de um Role para IOS]]&lt;br /&gt;
[[Arquivo:Renato-MikrotikRoles.png|centro|miniaturadaimagem|800x800px|Figura 4. Implementação de um Role para RouterOS]]&lt;br /&gt;
&lt;br /&gt;
=== Criando templates com Jinja2 ===&lt;br /&gt;
Neste tutorial irei demonstrar a criação dos templates apenas para o IOS, mas para o RouterOS a implementação é análoga.&lt;br /&gt;
&lt;br /&gt;
             O primeiro passo é conceber a estrutura de dados do modelo, será utilizado uma interface como base. Abstraindo toda a sintaxe os dados que são inseridos em uma interface em geral são nome da interface, endereço IP, máscara, estado ( shut ou no shut), velocidade, encapsulamento e etc, um exemplo de modelo seria o apresentado abaixo: &amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;Interfaces:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: Loopback0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.0.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description: LDP Loopback&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.255&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: GigabitEthernet0/0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.1.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.252&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Os arquivos contendo estes modelos seriam armazenados dentro da pasta ''roles/models/files/interfaces/&amp;lt;hostname&amp;gt;.yml''. Percebe que neste momento estamos fazendo duas associações implícitas, a primeira é utilizar a palavra '''interfaces''' no caminho que será utilizada posteriormente para acessar todos os arquivos de configuração relativos a configuração das interfaces, e a segunda associação está no nome do arquivo '''&amp;lt;hostname&amp;gt;.yml''', que será utilizado em tempo de execução para associar dada configuração ao ativo.&lt;br /&gt;
&lt;br /&gt;
             Com o modelo pronto precisamos escrever o template, que no caso do IOS ficará em ''roles/ios/templates/interfaces.j2'', e iremos criar um template para cada funcionalidade que desejarmos automatizar.&lt;br /&gt;
&lt;br /&gt;
             Para a criação do template é necessário conhecer algumas estruturas de controle que nos permitirão realizar testes, e executar laços dentro da execução. A primeira estrutura que será apresentada é o laço '''{% for iterador in variável %} ... {% endfor %}'''. Ao observar o modelo que criamos acima pode se perceber que ele forma uma lista de interfaces, e será carregado dentro do Ansible como uma variável de nome interfaces, então para montar o laço iremos utilizar:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Outra estrutura que será usada extensivamente é condicional IF que possui a seguinte estrutura: &amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;{% if confição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;..&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% elif condição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% else %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             E para acessar as variáveis basta utilizar a seguinte sintaxe &amp;lt;nowiki&amp;gt;{{ nome da variável }}&amp;lt;/nowiki&amp;gt;.  O próximo passo é escrever a configuração que se deseja aplicar tomando muito cuidado com espaços, e sem a necessidade de se utilizar end ao final, pois o módulo executa uma comparação textual com a configuração em produção antes de configurar, no final a configuração do template será semelhando a abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;interface &amp;lt;nowiki&amp;gt;{{ interface.name }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.description is defined %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description &amp;lt;nowiki&amp;gt;{{ interface.description}}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if (interface.address is defined ) and (interface.mask is defined ) %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ip address &amp;lt;nowiki&amp;gt;{{ interface.address }}&amp;lt;/nowiki&amp;gt; &amp;lt;nowiki&amp;gt;{{ interface.mask }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == True %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;no shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == False %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;exit&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integrando a solução ===&lt;br /&gt;
Com os modelos prontos e todos os templates está na hora de criar os playbooks, que serão utilizados pelo Ansible para guiar a automação. O primeiro playbook a ser criado fica na raiz do diretório e será responsável por “chamar” os playbooks de cada role, o que é entregue automaticamente, bastando se incluir o role no playbook, para esse primeiro playbook que chamarei de principal, será necessário criar um “Play” para cada grupo de ativos e neste play será incluído a role desejada, conforme exemplo abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: Cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- name: MikroTik&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: routeros&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - routeros&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;A relação de hosts para cada grupo é definida dentro do arquivo hosts, que tem a seguinte sintaxe:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;[cisco]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE7 ansible_host=192.168.237.206&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE4 ansible_host=192.168.237.202&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P2  ansible_host=192.168.237.203&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P1  ansible_host=192.168.237.205&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE5 ansible_host=192.168.237.207&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE6 ansible_host=192.168.237.204&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;[routeros]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P3  ansible_host=192.168.237.183&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Neste arquivo os grupos são definidos dentro dos colchetes, [cisco] e [routeros], enquanto os membros do grupo são definidos individualmente abaixo com a seguinte sintaxe: HOSTNAME  ansible_host=&amp;lt;endereço IP&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
             Adicionalmente ao endereço é necessário prover as credenciais de acesso ao equipamento e o sistema que roda em cada um conforme [3], neste tutorial será utilizado a mesma credencial de acesso a todos os equipamentos e tal configuração ficará dentro do arquivo group_vars/all.yml que tem a seguinte forma:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;ansible_connection: network_cli&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become_method: enable&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_user: 'renato'&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_ssh_pass: '123456'&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Note que nesse tutorial estou usando uma senha em claro dentro de um arquivo de configuração o que não é uma boa prática, para encriptar esta senha utilize os procedimentos descritos em [8].&lt;br /&gt;
&lt;br /&gt;
E para as configurações específicas de cada plataforma será criado um arquivo com o mesmo nome do groupo na pasta group_vars, estas configurações podem ser visualizadas em [9].&lt;br /&gt;
&lt;br /&gt;
             Finalizado estas configurações, criação do playbook principal, do inventário e das variáveis, vamos aos arquivos específicos de cada modelo. Para isso deverá ser criado um arquivo com o nome main.yml na pasta roles/&amp;lt;role&amp;gt;/tasks. Para a configuração no cisco, conforme Figura 3 precisamos primeiro ler o arquivo com o modelo e transformar ele em variável, porém é importante notar que cada tarefa é executada para todos os equipamentos do grupo, assim para evitar erros de execução iremos pesquisar pelo modelo na sua pasta respectiva:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: List interface directory&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;find:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  paths: roles/models/files/interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  patterns: &amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  recurse: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file_type: file&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;register: Files&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              &lt;br /&gt;
&lt;br /&gt;
Perceba que a tarefa acima pesquisa na pasta /roles/models/files/interfaces todos os arquivos com o seguinte padrão ''&amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;'', note a sintaxe ''&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;'', vista anteriormente nos templates em jinja2, que  faz referência ao equipamento que está sendo processado, registra o resultado de sua busca na variável Files e por fim executa esse procedimento localmente, sem a necessidade de se conectar via ssh no host.&lt;br /&gt;
&lt;br /&gt;
Com os arquivos identificados o próximo passo é importar as variáveis que será feito utilizando o módulo template, conforme descrito abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: Include interface vars&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  include_vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file: roles/models/files/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             Com o modelo importado o próximo passo é a criação dos arquivos de configuração, nesta etapa é fundamental que na sua estrutura de diretórios já exista uma pasta destinada a estes arquivos, e para a sua configuração basta seguir o modelo abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- name: Make Config&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;template:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  src: interface.j2&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  dest: cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  mode: 0777&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             Finalmente com todos os arquivos de configuração prontos, está na hora de aplicar as configurações nos equipamentos que no caso do ios é feito utilizando o módulo ios_config, conforme sintaxe abaixo:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;  - name: Configure&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  ios_config:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;    src:  “cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg”&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: configFiles.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Finalizadas estas configurações basta repetir o processo para cada funcionalidade que se deseja implementar em sua automação, e caso seja de interesse é possível simplificar ainda mais a criação dos playbooks, realizando a separação da configuração das tarefas por escopos, ou seja dentro da pasta roles/&amp;lt;role&amp;gt;/tasks existirá um arquivo main.yml que é responsável por importar as tarefas de cada uma das funcionalidades e cada funcionalidade terá um arquivo próprio como por exemplor interfaces.yml, ospf.yml , mpls.yml e etc, desta forma as configurações apresentadas acima residirão dentro de cada um dos playbooks de funcionalidades e o playbook main.yml irá apenas instanciar usando a seguinte sintaxe:&amp;lt;div style=&amp;quot;padding-left: 40%; border-style: solid;&amp;quot;&amp;gt; &amp;lt;blockquote&amp;gt;- import_tasks: interfaces.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  scope: interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Observe no código acima que foi introduzido uma variável durante a inclusão, e ao observar as configurações realizadas anteriormente é possível perceber que em nenhum momento foi utilizado alguma especificidade de alguma funcionalidade, portanto com é possível apenas com a alteração da variável scope, recém introduzida, replicar todo o código que criamos sem a necessidade de escreve-lo novamente.&lt;br /&gt;
&lt;br /&gt;
             Finalizado as configurações dos outros roles, para executar a automação basta executar o comando ansible-playbook &amp;lt;playbook).yaml na pasta raiz do projeto, comando este que deve ser inserido no .gitlab-ci.yml para que o gitlab execute a configuração sempre que o usuário realizar um commit.&lt;br /&gt;
&lt;br /&gt;
=== Conclusão ===&lt;br /&gt;
             Neste tutorial foi apresentado uma metodologia de automação de redes baseada na integração de ferramentas open source, Ansible e gitlab. Onde através da utilização da abstração de modelos de dados e roles, é possível entregar ao administrador de redes uma interface de configuração agnóstica a fabricantes e com um mecanismo de aprovação característico de metodologias de desenvolvimento de software, com commits e processos de aprovação.&lt;br /&gt;
&lt;br /&gt;
Por fim toda a configuração demonstrada neste artigo pode ser acessada no seguinte repositório do github [10], e a demonstração deste cenário poderá ser assistido em um vídeo no YouTube que será publicado em breve.&lt;br /&gt;
&lt;br /&gt;
Muito obrigado pela atenção, espero que tenham gostado do conteúdo, e assim que possível estarei disponibilizando um vídeo no YouTube demonstrando e dando maiores explicações sobre a metodologia&lt;br /&gt;
&lt;br /&gt;
=== Referências ===&lt;br /&gt;
[1]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/runner/register/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[2]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/quick_start/README.html#creating-a-gitlab-ciyml-file&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[3]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/yaml/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[4]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[5]     (&amp;lt;nowiki&amp;gt;https://galaxy.ansible.com/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[6]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/routeros_command_module.html#routeros-command-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[7]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/ios_config_module.html#ios-config-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[8]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/vault.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[9]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
'''AUTOR:''' [[Usuário:Renato.Oliveira]]&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1936</id>
		<title>Orquestrando sua rede com Ansible e Gitlab</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1936"/>
		<updated>2020-01-09T22:03:00Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Introdução ===&lt;br /&gt;
Neste artigo será apresentado uma metodologia de automação de redes baseada em GitLab e Ansible, onde, utilizando templates em Jinja2, será possível entregar ao operador uma estrutura de configurações baseada em modelos de dados. As peculiaridades de cada fabricante estarão encapsuladas através de templates que podem abstrair desde a CLI específica o equipamento até modelos YANG. Este artigo será divido em 5 seções, sendo elas:&lt;br /&gt;
* A instalação do ambiente que para simplificação será monolítica, com o Ansible e o GitLab instalado no mesmo servidor;&lt;br /&gt;
&lt;br /&gt;
* A apresentação da metodologia CI/CD com o GitLab e a criação de um workflow de implantação, com sua respectiva configuração no GitLab-Runner;&lt;br /&gt;
&lt;br /&gt;
* A descrição do funcionamento do Ansible-playbook, em conjunto com uma proposta de estrutura de diretório.&lt;br /&gt;
&lt;br /&gt;
* A criação uma abstração de modelos de dados utilizando Jinja2.&lt;br /&gt;
&lt;br /&gt;
* Integrando a solução e realização de testes.&lt;br /&gt;
&lt;br /&gt;
=== Instalação ===&lt;br /&gt;
O ambiente que será demostrado neste artigo utiliza como sistema operacional o CentOS 7 &amp;lt;!-- Atenção o CentoOS 7 é a versão mais recente suportada pelo GitLab --&amp;gt;, instalado a partir da imagem: CentOS-7-x86_64-DVD-1908, que pode ser encontrada no repositório da distribuição. Neste ambiente, todos os componentes foram instalados em conjunto, porém, para um ambiente de produção, pode ser recomendado separar os componentes GitLab-Runner e Ansible em outro servidor.&lt;br /&gt;
&lt;br /&gt;
             Para realizar a instalação dos componentes pode-se utilizar o script fornecido ou realizar a instalação via repositórios, devendo tomar o cuidado de atualizar a versão do git padrão da distribuição pois ela é incompatível com git-fetch que é utilizado pelo gitlab-runner, realizar a instalação via pip do ncclient e netmiko e criar um domínio em DNS para o gitlab. Caso deseje utilizar o script fornecido, atualize a url “gitlab.local” para o domínio registrado.&lt;br /&gt;
&lt;br /&gt;
             Finalizado o processo de instalação das ferramentas, execute o procedimento de registro do gitlab-runner conforme esta url da referência [1] .&lt;br /&gt;
&lt;br /&gt;
=== GitLab ===&lt;br /&gt;
O GitLab é um gerenciador de repositório de software baseado em git com suporte à Wiki, gerenciamento de tarefas e CI/CD. GitLab é similar ao GitHub, mas o GitLab permite que os desenvolvedores armazenem o código em seus próprios servidores, ao invés de servidores de terceiros. Ele é um software livre, distribuído pela Licença MIT. (wikipedia)&lt;br /&gt;
&lt;br /&gt;
             E com todas essas funcionalidades pode agregar valor à operação, sendo capaz de prover uma base de conhecimento com sua wiki e, através do gitlab-runner, é possível criar um ciclo onde o técnico escreve a configuração desejada e faz um commit no repositório, que automaticamente executa as tarefas de compilação e validação de sintaxe, podendo inclusive realizar o deploy das configurações em um ambiente de laboratório como o EVE-NG.&lt;br /&gt;
&lt;br /&gt;
=== Configurando a pipeline ===&lt;br /&gt;
Uma vez que o gitlab-runner foi instalado e configurado, é necessário adicionar no repositório o arquivo .gitlab-ci.yml que irá descrever todo o fluxo da pipeline [2].&lt;br /&gt;
&lt;br /&gt;
             Durante a execução de cada tarefa, o gitlab-runner executa uma operação ''git fetch'' dentro da sua pasta home o que, para o contexto deste artigo e outras aplicações, pode ser problemático, já que todo os arquivos gerados pelas tarefas anteriores serão perdidos.&lt;br /&gt;
&lt;br /&gt;
             Para a solução deste problema é necessário realizar um cache dos arquivos de configuração compilados, conforme sintaxe abaixo:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;''cache:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  key: ${CI_COMMIT_REF_SLUG}''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  paths:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  - cfg/tmp''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Após a configuração do cache, pode ser configurado os estágios da automação onde o gitlab-runner irá executar todas as suas tarefas em paralelo, porém,  somente irá executar as tarefas do próximo estágio, quando todas as tarefas anteriores forem concluídas com êxito. Para a configuração dos estágios, basta adicionar uma seção os relacionando conforme sintaxe abaixo:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;''stages:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- deploy''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Por fim, são configuradas as tarefas que cada estágio executa, para o cenário apresentado nesse tutorial iremos configurar apenas o script a ser executado, o estágio que a tarefa pertence e quando ela deve ser executada, conforme script abaixo, porém existem diversas opções de configuração e customizações que podem ser feitas e estão documentadas no link da referência [3] &amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;''Setup:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  stage: build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''script:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''  - ansible-playbook parse.yaml''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''when: always''&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Ao término da configuração do .gitlab-ci.yml, a cada commit realizado pelo técnico será executada a pipeline que, para este tutorial, terá a forma da Figura 1:&lt;br /&gt;
[[Arquivo:Ciclo de execução.png|centro|miniaturadaimagem|800x800px|Figura 1. Ciclo de execução]]&lt;br /&gt;
&lt;br /&gt;
=== Ansible ===&lt;br /&gt;
O Ansible é uma ferramenta open-source para gerenciamento de configuração e provisionamento, que utiliza uma comunicação com os nós baseadas em SSH sem a necessidade da instalação de agentes.&lt;br /&gt;
&lt;br /&gt;
             Para a utilização da ferramenta é necessário criar um arquivo ansible.cfg, que contém as configurações básicas do ansible, criar um arquivo contendo a relação dos dispositivos, e criar um arquivo contendo as instruções a serem executadas.&lt;br /&gt;
&lt;br /&gt;
              Com os três arquivos citados anteriormente já é possível realizar alguns testes de acesso com o Ansible, porém para aplicações mais complexas é conveniente utilizar uma estrutura de diretórios para dois propósitos, o primeiro é melhorar a usabilidade e semântica da automação, e a segunda é criar um ambiente flexível e que possa ser reutilizado para diversos propósitos.&lt;br /&gt;
&lt;br /&gt;
             Com este propósito a partir da versão 1.2 o Ansible introduziu o conceito de Roles, que através de uma estrutura de diretórios possibilita o carregamento automático de diversos arquivos e o agrupamento de configurações conforme sua semelhança e necessidade específica, a documentação a respeito de roles pode ser encontrada no link da referência [4], outra vantagem da utilização de roles reside no seu compartilhamento, onde pelo link da referência [5] podem ser encontrados diversos roles prontos para uso.&lt;br /&gt;
&lt;br /&gt;
             Neste tutorial iremos criar roles de acordo com o software que roda nos equipamentos, por exemplo RouterOS, IOS, IOS-XR, Junos e etc, pois cada software possui uma sintaxe própria que ao final da implementação devem ser encapsuladas, outra vantagem desta escolha reside na possibilidade de separação de equipes de modo que a equipe com experiencia em RouteOS, não precisa se preocupar com particularidades do IOS, ou seja a única preocupação dessa equipe é considerando o modelo de dados de entrada que é padrão para todas as implementações gerar a configuração correspondente, conforme Figura 2.&lt;br /&gt;
[[Arquivo:Roles.png|centro|miniaturadaimagem|800x800px|Figura 2. Metologia de utilização dos Roles]]&lt;br /&gt;
Com a estrutura de diretórios pronta é necessário criar as abstrações das configurações o que é dependente de cada modelo e dos módulos disponíveis, para esse tutorial como configuraremos um mikrotik (RouterOS), e um cisco (IOS) iremos utilizar os seguintes módulos routeros_command [6] ios_config [7], e a linguagem de template Jinja2 para criar as abstrações, e devido as diferenças entre os módulos do ios_config e do routeros_command as etapas para a configuração serão diferentes conforme Figuras 3 e 4 &lt;br /&gt;
[[Arquivo:RoleCisco.png|centro|miniaturadaimagem|795x795px|Figura 3. Implementação de um Role para IOS]]&lt;br /&gt;
[[Arquivo:Renato-MikrotikRoles.png|centro|miniaturadaimagem|800x800px|Figura 4. Implementação de um Role para RouterOS]]&lt;br /&gt;
&lt;br /&gt;
=== Criando templates com Jinja2 ===&lt;br /&gt;
Neste tutorial irei demonstrar a criação dos templates apenas para o IOS, mas para o RouterOS a implementação é análoga.&lt;br /&gt;
&lt;br /&gt;
             O primeiro passo é conceber a estrutura de dados do modelo, será utilizado uma interface como base. Abstraindo toda a sintaxe os dados que são inseridos em uma interface em geral são nome da interface, endereço IP, máscara, estado ( shut ou no shut), velocidade, encapsulamento e etc, um exemplo de modelo seria o apresentado abaixo: &amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;Interfaces:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: Loopback0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.0.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description: LDP Loopback&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.255&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: GigabitEthernet0/0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.1.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.252&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Os arquivos contendo estes modelos seriam armazenados dentro da pasta ''roles/models/files/interfaces/&amp;lt;hostname&amp;gt;.yml''. Percebe que neste momento estamos fazendo duas associações implícitas, a primeira é utilizar a palavra '''interfaces''' no caminho que será utilizada posteriormente para acessar todos os arquivos de configuração relativos a configuração das interfaces, e a segunda associação está no nome do arquivo '''&amp;lt;hostname&amp;gt;.yml''', que será utilizado em tempo de execução para associar dada configuração ao ativo.&lt;br /&gt;
&lt;br /&gt;
             Com o modelo pronto precisamos escrever o template, que no caso do IOS ficará em ''roles/ios/templates/interfaces.j2'', e iremos criar um template para cada funcionalidade que desejarmos automatizar.&lt;br /&gt;
&lt;br /&gt;
             Para a criação do template é necessário conhecer algumas estruturas de controle que nos permitirão realizar testes, e executar laços dentro da execução. A primeira estrutura que será apresentada é o laço '''{% for iterador in variável %} ... {% endfor %}'''. Ao observar o modelo que criamos acima pode se perceber que ele forma uma lista de interfaces, e será carregado dentro do Ansible como uma variável de nome interfaces, então para montar o laço iremos utilizar:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Outra estrutura que será usada extensivamente é condicional IF que possui a seguinte estrutura: &amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;{% if confição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;..&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% elif condição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% else %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             E para acessar as variáveis basta utilizar a seguinte sintaxe &amp;lt;nowiki&amp;gt;{{ nome da variável }}&amp;lt;/nowiki&amp;gt;.  O próximo passo é escrever a configuração que se deseja aplicar tomando muito cuidado com espaços, e sem a necessidade de se utilizar end ao final, pois o módulo executa uma comparação textual com a configuração em produção antes de configurar, no final a configuração do template será semelhando a abaixo:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;interface &amp;lt;nowiki&amp;gt;{{ interface.name }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.description is defined %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description &amp;lt;nowiki&amp;gt;{{ interface.description}}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if (interface.address is defined ) and (interface.mask is defined ) %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ip address &amp;lt;nowiki&amp;gt;{{ interface.address }}&amp;lt;/nowiki&amp;gt; &amp;lt;nowiki&amp;gt;{{ interface.mask }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == True %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;no shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == False %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;exit&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integrando a solução ===&lt;br /&gt;
Com os modelos prontos e todos os templates está na hora de criar os playbooks, que serão utilizados pelo Ansible para guiar a automação. O primeiro playbook a ser criado fica na raiz do diretório e será responsável por “chamar” os playbooks de cada role, o que é entregue automaticamente, bastando se incluir o role no playbook, para esse primeiro playbook que chamarei de principal, será necessário criar um “Play” para cada grupo de ativos e neste play será incluído a role desejada, conforme exemplo abaixo:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;- name: Cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- name: MikroTik&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: routeros&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - routeros&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;A relação de hosts para cada grupo é definida dentro do arquivo hosts, que tem a seguinte sintaxe:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;[cisco]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE7 ansible_host=192.168.237.206&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE4 ansible_host=192.168.237.202&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P2  ansible_host=192.168.237.203&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P1  ansible_host=192.168.237.205&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE5 ansible_host=192.168.237.207&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE6 ansible_host=192.168.237.204&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;[routeros]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P3  ansible_host=192.168.237.183&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              Neste arquivo os grupos são definidos dentro dos colchetes, [cisco] e [routeros], enquanto os membros do grupo são definidos individualmente abaixo com a seguinte sintaxe: HOSTNAME  ansible_host=&amp;lt;endereço IP&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
             Adicionalmente ao endereço é necessário prover as credenciais de acesso ao equipamento e o sistema que roda em cada um conforme [3], neste tutorial será utilizado a mesma credencial de acesso a todos os equipamentos e tal configuração ficará dentro do arquivo group_vars/all.yml que tem a seguinte forma:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;ansible_connection: network_cli&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become_method: enable&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_user: 'renato'&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_ssh_pass: '123456'&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;Note que nesse tutorial estou usando uma senha em claro dentro de um arquivo de configuração o que não é uma boa prática, para encriptar esta senha utilize os procedimentos descritos em [8].&lt;br /&gt;
&lt;br /&gt;
E para as configurações específicas de cada plataforma será criado um arquivo com o mesmo nome do groupo na pasta group_vars, estas configurações podem ser visualizadas em [9].&lt;br /&gt;
&lt;br /&gt;
             Finalizado estas configurações, criação do playbook principal, do inventário e das variáveis, vamos aos arquivos específicos de cada modelo. Para isso deverá ser criado um arquivo com o nome main.yml na pasta roles/&amp;lt;role&amp;gt;/tasks. Para a configuração no cisco, conforme Figura 3 precisamos primeiro ler o arquivo com o modelo e transformar ele em variável, porém é importante notar que cada tarefa é executada para todos os equipamentos do grupo, assim para evitar erros de execução iremos pesquisar pelo modelo na sua pasta respectiva:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;- name: List interface directory&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;find:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  paths: roles/models/files/interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  patterns: &amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  recurse: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file_type: file&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;register: Files&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;              &lt;br /&gt;
&lt;br /&gt;
Perceba que a tarefa acima pesquisa na pasta /roles/models/files/interfaces todos os arquivos com o seguinte padrão ''&amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;'', note a sintaxe ''&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;'', vista anteriormente nos templates em jinja2, que  faz referência ao equipamento que está sendo processado, registra o resultado de sua busca na variável Files e por fim executa esse procedimento localmente, sem a necessidade de se conectar via ssh no host.&lt;br /&gt;
&lt;br /&gt;
Com os arquivos identificados o próximo passo é importar as variáveis que será feito utilizando o módulo template, conforme descrito abaixo:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;- name: Include interface vars&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  include_vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file: roles/models/files/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             Com o modelo importado o próximo passo é a criação dos arquivos de configuração, nesta etapa é fundamental que na sua estrutura de diretórios já exista uma pasta destinada a estes arquivos, e para a sua configuração basta seguir o modelo abaixo:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;- name: Make Config&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;template:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  src: interface.j2&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  dest: cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  mode: 0777&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             Finalmente com todos os arquivos de configuração prontos, está na hora de aplicar as configurações nos equipamentos que no caso do ios é feito utilizando o módulo ios_config, conforme sintaxe abaixo:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;  - name: Configure&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  ios_config:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;    src:  “cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg”&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: configFiles.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Finalizadas estas configurações basta repetir o processo para cada funcionalidade que se deseja implementar em sua automação, e caso seja de interesse é possível simplificar ainda mais a criação dos playbooks, realizando a separação da configuração das tarefas por escopos, ou seja dentro da pasta roles/&amp;lt;role&amp;gt;/tasks existirá um arquivo main.yml que é responsável por importar as tarefas de cada uma das funcionalidades e cada funcionalidade terá um arquivo próprio como por exemplor interfaces.yml, ospf.yml , mpls.yml e etc, desta forma as configurações apresentadas acima residirão dentro de cada um dos playbooks de funcionalidades e o playbook main.yml irá apenas instanciar usando a seguinte sintaxe:&amp;lt;div style='padding-left: 40%; border-style: solid;'&amp;gt; &amp;lt;blockquote&amp;gt;- import_tasks: interfaces.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  scope: interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;/div&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Observe no código acima que foi introduzido uma variável durante a inclusão, e ao observar as configurações realizadas anteriormente é possível perceber que em nenhum momento foi utilizado alguma especificidade de alguma funcionalidade, portanto com é possível apenas com a alteração da variável scope, recém introduzida, replicar todo o código que criamos sem a necessidade de escreve-lo novamente.&lt;br /&gt;
&lt;br /&gt;
             Finalizado as configurações dos outros roles, para executar a automação basta executar o comando ansible-playbook &amp;lt;playbook).yaml na pasta raiz do projeto, comando este que deve ser inserido no .gitlab-ci.yml para que o gitlab execute a configuração sempre que o usuário realizar um commit.&lt;br /&gt;
&lt;br /&gt;
=== Conclusão ===&lt;br /&gt;
             Neste tutorial foi apresentado uma metodologia de automação de redes baseada na integração de ferramentas open source, Ansible e gitlab. Onde através da utilização da abstração de modelos de dados e roles, é possível entregar ao administrador de redes uma interface de configuração agnóstica a fabricantes e com um mecanismo de aprovação característico de metodologias de desenvolvimento de software, com commits e processos de aprovação.&lt;br /&gt;
&lt;br /&gt;
Por fim toda a configuração demonstrada neste artigo pode ser acessada no seguinte repositório do github [10], e a demonstração deste cenário poderá ser assistido em um vídeo no YouTube que será publicado em breve.&lt;br /&gt;
&lt;br /&gt;
Muito obrigado pela atenção, espero que tenham gostado do conteúdo, e assim que possível estarei disponibilizando um vídeo no YouTube demonstrando e dando maiores explicações sobre a metodologia&lt;br /&gt;
&lt;br /&gt;
=== REFERÊNCIAS ===&lt;br /&gt;
[1]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/runner/register/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[2]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/quick_start/README.html#creating-a-gitlab-ciyml-file&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[3]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/yaml/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[4]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[5]     (&amp;lt;nowiki&amp;gt;https://galaxy.ansible.com/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[6]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/routeros_command_module.html#routeros-command-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[7]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/ios_config_module.html#ios-config-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[8]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/vault.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[9]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
'''AUTOR:''' [[Usuário:Renato.Oliveira]]&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1935</id>
		<title>Orquestrando sua rede com Ansible e Gitlab</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1935"/>
		<updated>2020-01-09T21:46:37Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Introdução ===&lt;br /&gt;
Neste artigo será apresentado uma metodologia de automação de redes baseada em GitLab e Ansible, onde, utilizando templates em Jinja2, será possível entregar ao operador uma estrutura de configurações baseada em modelos de dados. As peculiaridades de cada fabricante estarão encapsuladas através de templates que podem abstrair desde a CLI específica o equipamento até modelos YANG. Este artigo será divido em 5 seções, sendo elas:&lt;br /&gt;
* A instalação do ambiente que para simplificação será monolítica, com o Ansible e o GitLab instalado no mesmo servidor;&lt;br /&gt;
&lt;br /&gt;
* A apresentação da metodologia CI/CD com o GitLab e a criação de um workflow de implantação, com sua respectiva configuração no GitLab-Runner;&lt;br /&gt;
&lt;br /&gt;
* A descrição do funcionamento do Ansible-playbook, em conjunto com uma proposta de estrutura de diretório.&lt;br /&gt;
&lt;br /&gt;
* A criação uma abstração de modelos de dados utilizando Jinja2.&lt;br /&gt;
&lt;br /&gt;
* Integrando a solução e realização de testes.&lt;br /&gt;
&lt;br /&gt;
=== Instalação ===&lt;br /&gt;
O ambiente que será demostrado neste artigo utiliza como sistema operacional o CentOS 7 &amp;lt;!-- Atenção o CentoOS 7 é a versão mais recente suportada pelo GitLab --&amp;gt;, instalado a partir da imagem: CentOS-7-x86_64-DVD-1908, que pode ser encontrada no repositório da distribuição. Neste ambiente, todos os componentes foram instalados em conjunto, porém, para um ambiente de produção, pode ser recomendado separar os componentes GitLab-Runner e Ansible em outro servidor.&lt;br /&gt;
&lt;br /&gt;
             Para realizar a instalação dos componentes pode-se utilizar o script fornecido ou realizar a instalação via repositórios, devendo tomar o cuidado de atualizar a versão do git padrão da distribuição pois ela é incompatível com git-fetch que é utilizado pelo gitlab-runner, realizar a instalação via pip do ncclient e netmiko e criar um domínio em DNS para o gitlab. Caso deseje utilizar o script fornecido, atualize a url “gitlab.local” para o domínio registrado.&lt;br /&gt;
&lt;br /&gt;
             Finalizado o processo de instalação das ferramentas, execute o procedimento de registro do gitlab-runner conforme esta url da referência [1] .&lt;br /&gt;
&lt;br /&gt;
=== GitLab ===&lt;br /&gt;
O GitLab é um gerenciador de repositório de software baseado em git com suporte à Wiki, gerenciamento de tarefas e CI/CD. GitLab é similar ao GitHub, mas o GitLab permite que os desenvolvedores armazenem o código em seus próprios servidores, ao invés de servidores de terceiros. Ele é um software livre, distribuído pela Licença MIT. (wikipedia)&lt;br /&gt;
&lt;br /&gt;
             E com todas essas funcionalidades pode agregar valor à operação, sendo capaz de prover uma base de conhecimento com sua wiki e, através do gitlab-runner, é possível criar um ciclo onde o técnico escreve a configuração desejada e faz um commit no repositório, que automaticamente executa as tarefas de compilação e validação de sintaxe, podendo inclusive realizar o deploy das configurações em um ambiente de laboratório como o EVE-NG.&lt;br /&gt;
&lt;br /&gt;
=== Configurando a pipeline ===&lt;br /&gt;
Uma vez que o gitlab-runner foi instalado e configurado, é necessário adicionar no repositório o arquivo .gitlab-ci.yml que irá descrever todo o fluxo da pipeline [2].&lt;br /&gt;
&lt;br /&gt;
             Durante a execução de cada tarefa, o gitlab-runner executa uma operação ''git fetch'' dentro da sua pasta home o que, para o contexto deste artigo e outras aplicações, pode ser problemático, já que todo os arquivos gerados pelas tarefas anteriores serão perdidos.&lt;br /&gt;
&lt;br /&gt;
             Para a solução deste problema é necessário realizar um cache dos arquivos de configuração compilados, conforme sintaxe abaixo:&amp;lt;blockquote&amp;gt;''cache:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  key: ${CI_COMMIT_REF_SLUG}''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  paths:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  - cfg/tmp''&amp;lt;/blockquote&amp;gt;Após a configuração do cache, pode ser configurado os estágios da automação onde o gitlab-runner irá executar todas as suas tarefas em paralelo, porém,  somente irá executar as tarefas do próximo estágio, quando todas as tarefas anteriores forem concluídas com êxito. Para a configuração dos estágios, basta adicionar uma seção os relacionando conforme sintaxe abaixo:&amp;lt;blockquote&amp;gt;''stages:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- deploy''&amp;lt;/blockquote&amp;gt;Por fim, são configuradas as tarefas que cada estágio executa, para o cenário apresentado nesse tutorial iremos configurar apenas o script a ser executado, o estágio que a tarefa pertence e quando ela deve ser executada, conforme script abaixo, porém existem diversas opções de configuração e customizações que podem ser feitas e estão documentadas no link da referência [3]&amp;lt;blockquote&amp;gt;''Setup:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  stage: build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''script:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''  - ansible-playbook parse.yaml''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''when: always''&amp;lt;/blockquote&amp;gt;              Ao término da configuração do .gitlab-ci.yml, a cada commit realizado pelo técnico será executada a pipeline que, para este tutorial, terá a forma da Figura 1:&lt;br /&gt;
[[Arquivo:Ciclo de execução.png|centro|miniaturadaimagem|800x800px|Figura 1. Ciclo de execução]]&lt;br /&gt;
&lt;br /&gt;
=== Ansible ===&lt;br /&gt;
O Ansible é uma ferramenta open-source para gerenciamento de configuração e provisionamento, que utiliza uma comunicação com os nós baseadas em SSH sem a necessidade da instalação de agentes.&lt;br /&gt;
&lt;br /&gt;
             Para a utilização da ferramenta é necessário criar um arquivo ansible.cfg, que contém as configurações básicas do ansible, criar um arquivo contendo a relação dos dispositivos, e criar um arquivo contendo as instruções a serem executadas.&lt;br /&gt;
&lt;br /&gt;
              Com os três arquivos citados anteriormente já é possível realizar alguns testes de acesso com o Ansible, porém para aplicações mais complexas é conveniente utilizar uma estrutura de diretórios para dois propósitos, o primeiro é melhorar a usabilidade e semântica da automação, e a segunda é criar um ambiente flexível e que possa ser reutilizado para diversos propósitos.&lt;br /&gt;
&lt;br /&gt;
             Com este propósito a partir da versão 1.2 o Ansible introduziu o conceito de Roles, que através de uma estrutura de diretórios possibilita o carregamento automático de diversos arquivos e o agrupamento de configurações conforme sua semelhança e necessidade específica, a documentação a respeito de roles pode ser encontrada no link da referência [4], outra vantagem da utilização de roles reside no seu compartilhamento, onde pelo link da referência [5] podem ser encontrados diversos roles prontos para uso.&lt;br /&gt;
&lt;br /&gt;
             Neste tutorial iremos criar roles de acordo com o software que roda nos equipamentos, por exemplo RouterOS, IOS, IOS-XR, Junos e etc, pois cada software possui uma sintaxe própria que ao final da implementação devem ser encapsuladas, outra vantagem desta escolha reside na possibilidade de separação de equipes de modo que a equipe com experiencia em RouteOS, não precisa se preocupar com particularidades do IOS, ou seja a única preocupação dessa equipe é considerando o modelo de dados de entrada que é padrão para todas as implementações gerar a configuração correspondente, conforme Figura 2.&lt;br /&gt;
[[Arquivo:Roles.png|centro|miniaturadaimagem|800x800px|Figura 2. Metologia de utilização dos Roles]]&lt;br /&gt;
Com a estrutura de diretórios pronta é necessário criar as abstrações das configurações o que é dependente de cada modelo e dos módulos disponíveis, para esse tutorial como configuraremos um mikrotik (RouterOS), e um cisco (IOS) iremos utilizar os seguintes módulos routeros_command [6] ios_config [7], e a linguagem de template Jinja2 para criar as abstrações, e devido as diferenças entre os módulos do ios_config e do routeros_command as etapas para a configuração serão diferentes conforme Figuras 3 e 4 &lt;br /&gt;
[[Arquivo:RoleCisco.png|centro|miniaturadaimagem|795x795px|Figura 3. Implementação de um Role para IOS]]&lt;br /&gt;
[[Arquivo:Renato-MikrotikRoles.png|centro|miniaturadaimagem|800x800px|Figura 4. Implementação de um Role para RouterOS]]&lt;br /&gt;
&lt;br /&gt;
=== Criando templates com Jinja2 ===&lt;br /&gt;
Neste tutorial irei demonstrar a criação dos templates apenas para o IOS, mas para o RouterOS a implementação é análoga.&lt;br /&gt;
&lt;br /&gt;
             O primeiro passo é conceber a estrutura de dados do modelo, será utilizado uma interface como base. Abstraindo toda a sintaxe os dados que são inseridos em uma interface em geral são nome da interface, endereço IP, máscara, estado ( shut ou no shut), velocidade, encapsulamento e etc, um exemplo de modelo seria o apresentado abaixo: &amp;lt;blockquote&amp;gt;Interfaces:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: Loopback0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.0.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description: LDP Loopback&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.255&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: GigabitEthernet0/0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.1.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.252&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;Os arquivos contendo estes modelos seriam armazenados dentro da pasta ''roles/models/files/interfaces/&amp;lt;hostname&amp;gt;.yml''. Percebe que neste momento estamos fazendo duas associações implícitas, a primeira é utilizar a palavra '''interfaces''' no caminho que será utilizada posteriormente para acessar todos os arquivos de configuração relativos a configuração das interfaces, e a segunda associação está no nome do arquivo '''&amp;lt;hostname&amp;gt;.yml''', que será utilizado em tempo de execução para associar dada configuração ao ativo.&lt;br /&gt;
&lt;br /&gt;
             Com o modelo pronto precisamos escrever o template, que no caso do IOS ficará em ''roles/ios/templates/interfaces.j2'', e iremos criar um template para cada funcionalidade que desejarmos automatizar.&lt;br /&gt;
&lt;br /&gt;
             Para a criação do template é necessário conhecer algumas estruturas de controle que nos permitirão realizar testes, e executar laços dentro da execução. A primeira estrutura que será apresentada é o laço '''{% for iterador in variável %} ... {% endfor %}'''. Ao observar o modelo que criamos acima pode se perceber que ele forma uma lista de interfaces, e será carregado dentro do Ansible como uma variável de nome interfaces, então para montar o laço iremos utilizar:&amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;              Outra estrutura que será usada extensivamente é condicional IF que possui a seguinte estrutura: &amp;lt;blockquote&amp;gt;{% if confição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;..&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% elif condição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% else %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;             E para acessar as variáveis basta utilizar a seguinte sintaxe &amp;lt;nowiki&amp;gt;{{ nome da variável }}&amp;lt;/nowiki&amp;gt;.  O próximo passo é escrever a configuração que se deseja aplicar tomando muito cuidado com espaços, e sem a necessidade de se utilizar end ao final, pois o módulo executa uma comparação textual com a configuração em produção antes de configurar, no final a configuração do template será semelhando a abaixo:&amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;interface &amp;lt;nowiki&amp;gt;{{ interface.name }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.description is defined %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description &amp;lt;nowiki&amp;gt;{{ interface.description}}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if (interface.address is defined ) and (interface.mask is defined ) %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ip address &amp;lt;nowiki&amp;gt;{{ interface.address }}&amp;lt;/nowiki&amp;gt; &amp;lt;nowiki&amp;gt;{{ interface.mask }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == True %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;no shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == False %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;exit&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integrando a solução ===&lt;br /&gt;
Com os modelos prontos e todos os templates está na hora de criar os playbooks, que serão utilizados pelo Ansible para guiar a automação. O primeiro playbook a ser criado fica na raiz do diretório e será responsável por “chamar” os playbooks de cada role, o que é entregue automaticamente, bastando se incluir o role no playbook, para esse primeiro playbook que chamarei de principal, será necessário criar um “Play” para cada grupo de ativos e neste play será incluído a role desejada, conforme exemplo abaixo:&amp;lt;blockquote&amp;gt;- name: Cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- name: MikroTik&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: routeros&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - routeros&amp;lt;/blockquote&amp;gt;A relação de hosts para cada grupo é definida dentro do arquivo hosts, que tem a seguinte sintaxe:&amp;lt;blockquote&amp;gt;[cisco]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE7 ansible_host=192.168.237.206&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE4 ansible_host=192.168.237.202&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P2  ansible_host=192.168.237.203&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P1  ansible_host=192.168.237.205&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE5 ansible_host=192.168.237.207&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE6 ansible_host=192.168.237.204&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;[routeros]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P3  ansible_host=192.168.237.183&amp;lt;/blockquote&amp;gt;              Neste arquivo os grupos são definidos dentro dos colchetes, [cisco] e [routeros], enquanto os membros do grupo são definidos individualmente abaixo com a seguinte sintaxe: HOSTNAME  ansible_host=&amp;lt;endereço IP&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
             Adicionalmente ao endereço é necessário prover as credenciais de acesso ao equipamento e o sistema que roda em cada um conforme [3], neste tutorial será utilizado a mesma credencial de acesso a todos os equipamentos e tal configuração ficará dentro do arquivo group_vars/all.yml que tem a seguinte forma:&amp;lt;blockquote&amp;gt;ansible_connection: network_cli&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become_method: enable&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_user: 'renato'&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_ssh_pass: '123456'&amp;lt;/blockquote&amp;gt;Note que nesse tutorial estou usando uma senha em claro dentro de um arquivo de configuração o que não é uma boa prática, para encriptar esta senha utilize os procedimentos descritos em [8].&lt;br /&gt;
&lt;br /&gt;
E para as configurações específicas de cada plataforma será criado um arquivo com o mesmo nome do groupo na pasta group_vars, estas configurações podem ser visualizadas em [9].&lt;br /&gt;
&lt;br /&gt;
             Finalizado estas configurações, criação do playbook principal, do inventário e das variáveis, vamos aos arquivos específicos de cada modelo. Para isso deverá ser criado um arquivo com o nome main.yml na pasta roles/&amp;lt;role&amp;gt;/tasks. Para a configuração no cisco, conforme Figura 3 precisamos primeiro ler o arquivo com o modelo e transformar ele em variável, porém é importante notar que cada tarefa é executada para todos os equipamentos do grupo, assim para evitar erros de execução iremos pesquisar pelo modelo na sua pasta respectiva:&amp;lt;blockquote&amp;gt;- name: List interface directory&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;find:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  paths: roles/models/files/interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  patterns: &amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  recurse: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file_type: file&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;register: Files&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;              &lt;br /&gt;
&lt;br /&gt;
Perceba que a tarefa acima pesquisa na pasta /roles/models/files/interfaces todos os arquivos com o seguinte padrão ''&amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;'', note a sintaxe ''&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;'', vista anteriormente nos templates em jinja2, que  faz referência ao equipamento que está sendo processado, registra o resultado de sua busca na variável Files e por fim executa esse procedimento localmente, sem a necessidade de se conectar via ssh no host.&lt;br /&gt;
&lt;br /&gt;
Com os arquivos identificados o próximo passo é importar as variáveis que será feito utilizando o módulo template, conforme descrito abaixo:&amp;lt;blockquote&amp;gt;- name: Include interface vars&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  include_vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file: roles/models/files/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;             Com o modelo importado o próximo passo é a criação dos arquivos de configuração, nesta etapa é fundamental que na sua estrutura de diretórios já exista uma pasta destinada a estes arquivos, e para a sua configuração basta seguir o modelo abaixo:&amp;lt;blockquote&amp;gt;- name: Make Config&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;template:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  src: interface.j2&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  dest: cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  mode: 0777&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;             Finalmente com todos os arquivos de configuração prontos, está na hora de aplicar as configurações nos equipamentos que no caso do ios é feito utilizando o módulo ios_config, conforme sintaxe abaixo:&amp;lt;blockquote&amp;gt;  - name: Configure&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  ios_config:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;    src:  “cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg”&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: configFiles.files != []&amp;lt;/blockquote&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Finalizadas estas configurações basta repetir o processo para cada funcionalidade que se deseja implementar em sua automação, e caso seja de interesse é possível simplificar ainda mais a criação dos playbooks, realizando a separação da configuração das tarefas por escopos, ou seja dentro da pasta roles/&amp;lt;role&amp;gt;/tasks existirá um arquivo main.yml que é responsável por importar as tarefas de cada uma das funcionalidades e cada funcionalidade terá um arquivo próprio como por exemplor interfaces.yml, ospf.yml , mpls.yml e etc, desta forma as configurações apresentadas acima residirão dentro de cada um dos playbooks de funcionalidades e o playbook main.yml irá apenas instanciar usando a seguinte sintaxe:&amp;lt;blockquote&amp;gt;- import_tasks: interfaces.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  scope: interfaces&amp;lt;/blockquote&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Observe no código acima que foi introduzido uma variável durante a inclusão, e ao observar as configurações realizadas anteriormente é possível perceber que em nenhum momento foi utilizado alguma especificidade de alguma funcionalidade, portanto com é possível apenas com a alteração da variável scope, recém introduzida, replicar todo o código que criamos sem a necessidade de escreve-lo novamente.&lt;br /&gt;
&lt;br /&gt;
             Finalizado as configurações dos outros roles, para executar a automação basta executar o comando ansible-playbook &amp;lt;playbook).yaml na pasta raiz do projeto, comando este que deve ser inserido no .gitlab-ci.yml para que o gitlab execute a configuração sempre que o usuário realizar um commit.&lt;br /&gt;
&lt;br /&gt;
=== Conclusão ===&lt;br /&gt;
             Neste tutorial foi apresentado uma metodologia de automação de redes baseada na integração de ferramentas open source, Ansible e gitlab. Onde através da utilização da abstração de modelos de dados e roles, é possível entregar ao administrador de redes uma interface de configuração agnóstica a fabricantes e com um mecanismo de aprovação característico de metodologias de desenvolvimento de software, com commits e processos de aprovação.&lt;br /&gt;
&lt;br /&gt;
Por fim toda a configuração demonstrada neste artigo pode ser acessada no seguinte repositório do github [10], e a demonstração deste cenário poderá ser assistido em um vídeo no YouTube que será publicado em breve.&lt;br /&gt;
&lt;br /&gt;
Muito obrigado pela atenção, espero que tenham gostado do conteúdo, e assim que possível estarei disponibilizando um vídeo no YouTube demonstrando e dando maiores explicações sobre a metodologia&lt;br /&gt;
&lt;br /&gt;
=== REFERÊNCIAS ===&lt;br /&gt;
[1]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/runner/register/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[2]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/quick_start/README.html#creating-a-gitlab-ciyml-file&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[3]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/yaml/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[4]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[5]     (&amp;lt;nowiki&amp;gt;https://galaxy.ansible.com/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[6]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/routeros_command_module.html#routeros-command-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[7]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/ios_config_module.html#ios-config-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[8]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/vault.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[9]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
'''AUTOR:''' [[Usuário:Renato.Oliveira]]&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1934</id>
		<title>Orquestrando sua rede com Ansible e Gitlab</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1934"/>
		<updated>2020-01-09T21:43:17Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: Edição de forma&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== '''Introdução''' ===&lt;br /&gt;
Neste artigo será apresentado uma metodologia de automação de redes baseada em GitLab e Ansible, onde, utilizando templates em Jinja2, será possível entregar ao operador uma estrutura de configurações baseada em modelos de dados. As peculiaridades de cada fabricante estarão encapsuladas através de templates que podem abstrair desde a CLI específica o equipamento até modelos YANG. Este artigo será divido em 5 seções, sendo elas:&lt;br /&gt;
* A instalação do ambiente que para simplificação será monolítica, com o Ansible e o GitLab instalado no mesmo servidor;&lt;br /&gt;
&lt;br /&gt;
* A apresentação da metodologia CI/CD com o GitLab e a criação de um workflow de implantação, com sua respectiva configuração no GitLab-Runner;&lt;br /&gt;
&lt;br /&gt;
* A descrição do funcionamento do Ansible-playbook, em conjunto com uma proposta de estrutura de diretório.&lt;br /&gt;
&lt;br /&gt;
* A criação uma abstração de modelos de dados utilizando Jinja2.&lt;br /&gt;
&lt;br /&gt;
* Integrando a solução e realização de testes.&lt;br /&gt;
&lt;br /&gt;
=== '''Instalação''' ===&lt;br /&gt;
O ambiente que será demostrado neste artigo utiliza como sistema operacional o CentOS 7 &amp;lt;!-- Atenção o CentoOS 7 é a versão mais recente suportada pelo GitLab --&amp;gt;, instalado a partir da imagem: CentOS-7-x86_64-DVD-1908, que pode ser encontrada no repositório da distribuição. Neste ambiente, todos os componentes foram instalados em conjunto, porém, para um ambiente de produção, pode ser recomendado separar os componentes GitLab-Runner e Ansible em outro servidor.&lt;br /&gt;
&lt;br /&gt;
             Para realizar a instalação dos componentes pode-se utilizar o script fornecido ou realizar a instalação via repositórios, devendo tomar o cuidado de atualizar a versão do git padrão da distribuição pois ela é incompatível com git-fetch que é utilizado pelo gitlab-runner, realizar a instalação via pip do ncclient e netmiko e criar um domínio em DNS para o gitlab. Caso deseje utilizar o script fornecido, atualize a url “gitlab.local” para o domínio registrado.&lt;br /&gt;
&lt;br /&gt;
             Finalizado o processo de instalação das ferramentas, execute o procedimento de registro do gitlab-runner conforme esta url da referência [1] .&lt;br /&gt;
&lt;br /&gt;
=== '''GitLab''' ===&lt;br /&gt;
O GitLab é um gerenciador de repositório de software baseado em git com suporte à Wiki, gerenciamento de tarefas e CI/CD. GitLab é similar ao GitHub, mas o GitLab permite que os desenvolvedores armazenem o código em seus próprios servidores, ao invés de servidores de terceiros. Ele é um software livre, distribuído pela Licença MIT. (wikipedia)&lt;br /&gt;
&lt;br /&gt;
             E com todas essas funcionalidades pode agregar valor à operação, sendo capaz de prover uma base de conhecimento com sua wiki e, através do gitlab-runner, é possível criar um ciclo onde o técnico escreve a configuração desejada e faz um commit no repositório, que automaticamente executa as tarefas de compilação e validação de sintaxe, podendo inclusive realizar o deploy das configurações em um ambiente de laboratório como o EVE-NG.&lt;br /&gt;
&lt;br /&gt;
=== '''Configurando a pipeline''' ===&lt;br /&gt;
Uma vez que o gitlab-runner foi instalado e configurado, é necessário adicionar no repositório o arquivo .gitlab-ci.yml que irá descrever todo o fluxo da pipeline [2].&lt;br /&gt;
&lt;br /&gt;
             Durante a execução de cada tarefa, o gitlab-runner executa uma operação ''git fetch'' dentro da sua pasta home o que, para o contexto deste artigo e outras aplicações, pode ser problemático, já que todo os arquivos gerados pelas tarefas anteriores serão perdidos.&lt;br /&gt;
&lt;br /&gt;
             Para a solução deste problema é necessário realizar um cache dos arquivos de configuração compilados, conforme sintaxe abaixo:&amp;lt;blockquote&amp;gt;''cache:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  key: ${CI_COMMIT_REF_SLUG}''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  paths:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  - cfg/tmp''&amp;lt;/blockquote&amp;gt;Após a configuração do cache, pode ser configurado os estágios da automação onde o gitlab-runner irá executar todas as suas tarefas em paralelo, porém,  somente irá executar as tarefas do próximo estágio, quando todas as tarefas anteriores forem concluídas com êxito. Para a configuração dos estágios, basta adicionar uma seção os relacionando conforme sintaxe abaixo:&amp;lt;blockquote&amp;gt;''stages:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- deploy''&amp;lt;/blockquote&amp;gt;Por fim, são configuradas as tarefas que cada estágio executa, para o cenário apresentado nesse tutorial iremos configurar apenas o script a ser executado, o estágio que a tarefa pertence e quando ela deve ser executada, conforme script abaixo, porém existem diversas opções de configuração e customizações que podem ser feitas e estão documentadas no link da referência [3]&amp;lt;blockquote&amp;gt;''Setup:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  stage: build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''script:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''  - ansible-playbook parse.yaml''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''when: always''&amp;lt;/blockquote&amp;gt;              Ao término da configuração do .gitlab-ci.yml, a cada commit realizado pelo técnico será executada a pipeline que, para este tutorial, terá a forma da Figura 1:&lt;br /&gt;
[[Arquivo:Ciclo de execução.png|centro|miniaturadaimagem|800x800px|Figura 1. Ciclo de execução]]&lt;br /&gt;
&lt;br /&gt;
=== '''Ansible''' ===&lt;br /&gt;
O Ansible é uma ferramenta open-source para gerenciamento de configuração e provisionamento, que utiliza uma comunicação com os nós baseadas em SSH sem a necessidade da instalação de agentes.&lt;br /&gt;
&lt;br /&gt;
             Para a utilização da ferramenta é necessário criar um arquivo ansible.cfg, que contém as configurações básicas do ansible, criar um arquivo contendo a relação dos dispositivos, e criar um arquivo contendo as instruções a serem executadas.&lt;br /&gt;
&lt;br /&gt;
              Com os três arquivos citados anteriormente já é possível realizar alguns testes de acesso com o Ansible, porém para aplicações mais complexas é conveniente utilizar uma estrutura de diretórios para dois propósitos, o primeiro é melhorar a usabilidade e semântica da automação, e a segunda é criar um ambiente flexível e que possa ser reutilizado para diversos propósitos.&lt;br /&gt;
&lt;br /&gt;
             Com este propósito a partir da versão 1.2 o Ansible introduziu o conceito de Roles, que através de uma estrutura de diretórios possibilita o carregamento automático de diversos arquivos e o agrupamento de configurações conforme sua semelhança e necessidade específica, a documentação a respeito de roles pode ser encontrada no link da referência [4], outra vantagem da utilização de roles reside no seu compartilhamento, onde pelo link da referência [5] podem ser encontrados diversos roles prontos para uso.&lt;br /&gt;
&lt;br /&gt;
             Neste tutorial iremos criar roles de acordo com o software que roda nos equipamentos, por exemplo RouterOS, IOS, IOS-XR, Junos e etc, pois cada software possui uma sintaxe própria que ao final da implementação devem ser encapsuladas, outra vantagem desta escolha reside na possibilidade de separação de equipes de modo que a equipe com experiencia em RouteOS, não precisa se preocupar com particularidades do IOS, ou seja a única preocupação dessa equipe é considerando o modelo de dados de entrada que é padrão para todas as implementações gerar a configuração correspondente, conforme Figura 2.&lt;br /&gt;
[[Arquivo:Roles.png|centro|miniaturadaimagem|800x800px|Figura 2. Metologia de utilização dos Roles]]&lt;br /&gt;
Com a estrutura de diretórios pronta é necessário criar as abstrações das configurações o que é dependente de cada modelo e dos módulos disponíveis, para esse tutorial como configuraremos um mikrotik (RouterOS), e um cisco (IOS) iremos utilizar os seguintes módulos routeros_command [6] ios_config [7], e a linguagem de template Jinja2 para criar as abstrações, e devido as diferenças entre os módulos do ios_config e do routeros_command as etapas para a configuração serão diferentes conforme Figuras 3 e 4 &lt;br /&gt;
[[Arquivo:RoleCisco.png|centro|miniaturadaimagem|795x795px|Figura 3. Implementação de um Role para IOS]]&lt;br /&gt;
[[Arquivo:Renato-MikrotikRoles.png|centro|miniaturadaimagem|800x800px|Figura 4. Implementação de um Role para RouterOS]]&lt;br /&gt;
&lt;br /&gt;
=== '''Criando templates com Jinja2''' ===&lt;br /&gt;
Neste tutorial irei demonstrar a criação dos templates apenas para o IOS, mas para o RouterOS a implementação é análoga.&lt;br /&gt;
&lt;br /&gt;
             O primeiro passo é conceber a estrutura de dados do modelo, será utilizado uma interface como base. Abstraindo toda a sintaxe os dados que são inseridos em uma interface em geral são nome da interface, endereço IP, máscara, estado ( shut ou no shut), velocidade, encapsulamento e etc, um exemplo de modelo seria o apresentado abaixo: &amp;lt;blockquote&amp;gt;Interfaces:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: Loopback0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.0.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description: LDP Loopback&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.255&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: GigabitEthernet0/0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.1.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.252&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;Os arquivos contendo estes modelos seriam armazenados dentro da pasta ''roles/models/files/interfaces/&amp;lt;hostname&amp;gt;.yml''. Percebe que neste momento estamos fazendo duas associações implícitas, a primeira é utilizar a palavra '''interfaces''' no caminho que será utilizada posteriormente para acessar todos os arquivos de configuração relativos a configuração das interfaces, e a segunda associação está no nome do arquivo '''&amp;lt;hostname&amp;gt;.yml''', que será utilizado em tempo de execução para associar dada configuração ao ativo.&lt;br /&gt;
&lt;br /&gt;
             Com o modelo pronto precisamos escrever o template, que no caso do IOS ficará em ''roles/ios/templates/interfaces.j2'', e iremos criar um template para cada funcionalidade que desejarmos automatizar.&lt;br /&gt;
&lt;br /&gt;
             Para a criação do template é necessário conhecer algumas estruturas de controle que nos permitirão realizar testes, e executar laços dentro da execução. A primeira estrutura que será apresentada é o laço '''{% for iterador in variável %} ... {% endfor %}'''. Ao observar o modelo que criamos acima pode se perceber que ele forma uma lista de interfaces, e será carregado dentro do Ansible como uma variável de nome interfaces, então para montar o laço iremos utilizar:&amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;              Outra estrutura que será usada extensivamente é condicional IF que possui a seguinte estrutura: &amp;lt;blockquote&amp;gt;{% if confição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;..&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% elif condição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% else %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;             E para acessar as variáveis basta utilizar a seguinte sintaxe &amp;lt;nowiki&amp;gt;{{ nome da variável }}&amp;lt;/nowiki&amp;gt;.  O próximo passo é escrever a configuração que se deseja aplicar tomando muito cuidado com espaços, e sem a necessidade de se utilizar end ao final, pois o módulo executa uma comparação textual com a configuração em produção antes de configurar, no final a configuração do template será semelhando a abaixo:&amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;interface &amp;lt;nowiki&amp;gt;{{ interface.name }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.description is defined %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description &amp;lt;nowiki&amp;gt;{{ interface.description}}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if (interface.address is defined ) and (interface.mask is defined ) %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ip address &amp;lt;nowiki&amp;gt;{{ interface.address }}&amp;lt;/nowiki&amp;gt; &amp;lt;nowiki&amp;gt;{{ interface.mask }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == True %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;no shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == False %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;exit&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== '''Integrando a solução''' ===&lt;br /&gt;
Com os modelos prontos e todos os templates está na hora de criar os playbooks, que serão utilizados pelo Ansible para guiar a automação. O primeiro playbook a ser criado fica na raiz do diretório e será responsável por “chamar” os playbooks de cada role, o que é entregue automaticamente, bastando se incluir o role no playbook, para esse primeiro playbook que chamarei de principal, será necessário criar um “Play” para cada grupo de ativos e neste play será incluído a role desejada, conforme exemplo abaixo:&amp;lt;blockquote&amp;gt;- name: Cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- name: MikroTik&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: routeros&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - routeros&amp;lt;/blockquote&amp;gt;A relação de hosts para cada grupo é definida dentro do arquivo hosts, que tem a seguinte sintaxe:&amp;lt;blockquote&amp;gt;[cisco]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE7 ansible_host=192.168.237.206&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE4 ansible_host=192.168.237.202&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P2  ansible_host=192.168.237.203&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P1  ansible_host=192.168.237.205&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE5 ansible_host=192.168.237.207&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE6 ansible_host=192.168.237.204&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;[routeros]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P3  ansible_host=192.168.237.183&amp;lt;/blockquote&amp;gt;              Neste arquivo os grupos são definidos dentro dos colchetes, [cisco] e [routeros], enquanto os membros do grupo são definidos individualmente abaixo com a seguinte sintaxe: HOSTNAME  ansible_host=&amp;lt;endereço IP&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
             Adicionalmente ao endereço é necessário prover as credenciais de acesso ao equipamento e o sistema que roda em cada um conforme [3], neste tutorial será utilizado a mesma credencial de acesso a todos os equipamentos e tal configuração ficará dentro do arquivo group_vars/all.yml que tem a seguinte forma:&amp;lt;blockquote&amp;gt;ansible_connection: network_cli&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become_method: enable&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_user: 'renato'&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_ssh_pass: '123456'&amp;lt;/blockquote&amp;gt;Note que nesse tutorial estou usando uma senha em claro dentro de um arquivo de configuração o que não é uma boa prática, para encriptar esta senha utilize os procedimentos descritos em [8].&lt;br /&gt;
&lt;br /&gt;
E para as configurações específicas de cada plataforma será criado um arquivo com o mesmo nome do groupo na pasta group_vars, estas configurações podem ser visualizadas em [9].&lt;br /&gt;
&lt;br /&gt;
             Finalizado estas configurações, criação do playbook principal, do inventário e das variáveis, vamos aos arquivos específicos de cada modelo. Para isso deverá ser criado um arquivo com o nome main.yml na pasta roles/&amp;lt;role&amp;gt;/tasks. Para a configuração no cisco, conforme Figura 3 precisamos primeiro ler o arquivo com o modelo e transformar ele em variável, porém é importante notar que cada tarefa é executada para todos os equipamentos do grupo, assim para evitar erros de execução iremos pesquisar pelo modelo na sua pasta respectiva:&amp;lt;blockquote&amp;gt;- name: List interface directory&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;find:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  paths: roles/models/files/interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  patterns: &amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  recurse: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file_type: file&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;register: Files&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;              &lt;br /&gt;
&lt;br /&gt;
Perceba que a tarefa acima pesquisa na pasta /roles/models/files/interfaces todos os arquivos com o seguinte padrão ''&amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;'', note a sintaxe ''&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;'', vista anteriormente nos templates em jinja2, que  faz referência ao equipamento que está sendo processado, registra o resultado de sua busca na variável Files e por fim executa esse procedimento localmente, sem a necessidade de se conectar via ssh no host.&lt;br /&gt;
&lt;br /&gt;
Com os arquivos identificados o próximo passo é importar as variáveis que será feito utilizando o módulo template, conforme descrito abaixo:&amp;lt;blockquote&amp;gt;- name: Include interface vars&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  include_vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file: roles/models/files/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;             Com o modelo importado o próximo passo é a criação dos arquivos de configuração, nesta etapa é fundamental que na sua estrutura de diretórios já exista uma pasta destinada a estes arquivos, e para a sua configuração basta seguir o modelo abaixo:&amp;lt;blockquote&amp;gt;- name: Make Config&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;template:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  src: interface.j2&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  dest: cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  mode: 0777&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;             Finalmente com todos os arquivos de configuração prontos, está na hora de aplicar as configurações nos equipamentos que no caso do ios é feito utilizando o módulo ios_config, conforme sintaxe abaixo:&amp;lt;blockquote&amp;gt;  - name: Configure&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  ios_config:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;    src:  “cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg”&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: configFiles.files != []&amp;lt;/blockquote&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Finalizadas estas configurações basta repetir o processo para cada funcionalidade que se deseja implementar em sua automação, e caso seja de interesse é possível simplificar ainda mais a criação dos playbooks, realizando a separação da configuração das tarefas por escopos, ou seja dentro da pasta roles/&amp;lt;role&amp;gt;/tasks existirá um arquivo main.yml que é responsável por importar as tarefas de cada uma das funcionalidades e cada funcionalidade terá um arquivo próprio como por exemplor interfaces.yml, ospf.yml , mpls.yml e etc, desta forma as configurações apresentadas acima residirão dentro de cada um dos playbooks de funcionalidades e o playbook main.yml irá apenas instanciar usando a seguinte sintaxe:&amp;lt;blockquote&amp;gt;- import_tasks: interfaces.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  scope: interfaces&amp;lt;/blockquote&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Observe no código acima que foi introduzido uma variável durante a inclusão, e ao observar as configurações realizadas anteriormente é possível perceber que em nenhum momento foi utilizado alguma especificidade de alguma funcionalidade, portanto com é possível apenas com a alteração da variável scope, recém introduzida, replicar todo o código que criamos sem a necessidade de escreve-lo novamente.&lt;br /&gt;
&lt;br /&gt;
             Finalizado as configurações dos outros roles, para executar a automação basta executar o comando ansible-playbook &amp;lt;playbook).yaml na pasta raiz do projeto, comando este que deve ser inserido no .gitlab-ci.yml para que o gitlab execute a configuração sempre que o usuário realizar um commit.&lt;br /&gt;
&lt;br /&gt;
=== '''Conclusão''' ===&lt;br /&gt;
             Neste tutorial foi apresentado uma metodologia de automação de redes baseada na integração de ferramentas open source, Ansible e gitlab. Onde através da utilização da abstração de modelos de dados e roles, é possível entregar ao administrador de redes uma interface de configuração agnóstica a fabricantes e com um mecanismo de aprovação característico de metodologias de desenvolvimento de software, com commits e processos de aprovação.&lt;br /&gt;
&lt;br /&gt;
Por fim toda a configuração demonstrada neste artigo pode ser acessada no seguinte repositório do github [10], e a demonstração deste cenário poderá ser assistido em um vídeo no YouTube que será publicado em breve.&lt;br /&gt;
&lt;br /&gt;
Muito obrigado pela atenção, espero que tenham gostado do conteúdo, e assim que possível estarei disponibilizando um vídeo no YouTube demonstrando e dando maiores explicações sobre a metodologia&lt;br /&gt;
&lt;br /&gt;
=== '''REFERÊNCIAS''' ===&lt;br /&gt;
[1]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/runner/register/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[2]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/quick_start/README.html#creating-a-gitlab-ciyml-file&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[3]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/yaml/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[4]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[5]     (&amp;lt;nowiki&amp;gt;https://galaxy.ansible.com/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[6]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/routeros_command_module.html#routeros-command-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[7]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/ios_config_module.html#ios-config-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[8]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/vault.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[9]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
'''AUTOR:''' [[Usuário:Renato.Oliveira]]&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1933</id>
		<title>Orquestrando sua rede com Ansible e Gitlab</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Orquestrando_sua_rede_com_Ansible_e_Gitlab&amp;diff=1933"/>
		<updated>2020-01-09T21:39:51Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: Adição de conteúdo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== '''Introdução''' ===&lt;br /&gt;
Neste artigo será apresentado uma metodologia de automação de redes baseada em GitLab e Ansible, onde, utilizando templates em Jinja2, será possível entregar ao operador uma estrutura de configurações baseada em modelos de dados. As peculiaridades de cada fabricante estarão encapsuladas através de templates que podem abstrair desde a CLI específica o equipamento até modelos YANG. Este artigo será divido em 5 seções, sendo elas:&lt;br /&gt;
* A instalação do ambiente que para simplificação será monolítica, com o Ansible e o GitLab instalado no mesmo servidor;&lt;br /&gt;
&lt;br /&gt;
* A apresentação da metodologia CI/CD com o GitLab e a criação de um workflow de implantação, com sua respectiva configuração no GitLab-Runner;&lt;br /&gt;
&lt;br /&gt;
* A descrição do funcionamento do Ansible-playbook, em conjunto com uma proposta de estrutura de diretório.&lt;br /&gt;
&lt;br /&gt;
* A criação uma abstração de modelos de dados utilizando Jinja2.&lt;br /&gt;
&lt;br /&gt;
* Integrando a solução e realização de testes.&lt;br /&gt;
&lt;br /&gt;
=== '''Instalação''' ===&lt;br /&gt;
O ambiente que será demostrado neste artigo utiliza como sistema operacional o CentOS 7 &amp;lt;!-- Atenção o CentoOS 7 é a versão mais recente suportada pelo GitLab --&amp;gt;, instalado a partir da imagem: CentOS-7-x86_64-DVD-1908, que pode ser encontrada no repositório da distribuição. Neste ambiente, todos os componentes foram instalados em conjunto, porém, para um ambiente de produção, pode ser recomendado separar os componentes GitLab-Runner e Ansible em outro servidor.&lt;br /&gt;
&lt;br /&gt;
             Para realizar a instalação dos componentes pode-se utilizar o script fornecido ou realizar a instalação via repositórios, devendo tomar o cuidado de atualizar a versão do git padrão da distribuição pois ela é incompatível com git-fetch que é utilizado pelo gitlab-runner, realizar a instalação via pip do ncclient e netmiko e criar um domínio em DNS para o gitlab. Caso deseje utilizar o script fornecido, atualize a url “gitlab.local” para o domínio registrado.&lt;br /&gt;
&lt;br /&gt;
             Finalizado o processo de instalação das ferramentas, execute o procedimento de registro do gitlab-runner conforme esta url da referência [1] .&lt;br /&gt;
&lt;br /&gt;
=== '''GitLab''' ===&lt;br /&gt;
O GitLab é um gerenciador de repositório de software baseado em git com suporte à Wiki, gerenciamento de tarefas e CI/CD. GitLab é similar ao GitHub, mas o GitLab permite que os desenvolvedores armazenem o código em seus próprios servidores, ao invés de servidores de terceiros. Ele é um software livre, distribuído pela Licença MIT. (wikipedia)&lt;br /&gt;
&lt;br /&gt;
             E com todas essas funcionalidades pode agregar valor à operação, sendo capaz de prover uma base de conhecimento com sua wiki e, através do gitlab-runner, é possível criar um ciclo onde o técnico escreve a configuração desejada e faz um commit no repositório, que automaticamente executa as tarefas de compilação e validação de sintaxe, podendo inclusive realizar o deploy das configurações em um ambiente de laboratório como o EVE-NG.&lt;br /&gt;
&lt;br /&gt;
=== '''Configurando a pipeline''' ===&lt;br /&gt;
Uma vez que o gitlab-runner foi instalado e configurado, é necessário adicionar no repositório o arquivo .gitlab-ci.yml que irá descrever todo o fluxo da pipeline [2].&lt;br /&gt;
&lt;br /&gt;
             Durante a execução de cada tarefa, o gitlab-runner executa uma operação ''git fetch'' dentro da sua pasta home o que, para o contexto deste artigo e outras aplicações, pode ser problemático, já que todo os arquivos gerados pelas tarefas anteriores serão perdidos.&lt;br /&gt;
&lt;br /&gt;
             Para a solução deste problema é necessário realizar um cache dos arquivos de configuração compilados, conforme sintaxe abaixo:&amp;lt;blockquote&amp;gt;''cache:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  key: ${CI_COMMIT_REF_SLUG}''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  paths:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  - cfg/tmp''&amp;lt;/blockquote&amp;gt;Após a configuração do cache, pode ser configurado os estágios da automação onde o gitlab-runner irá executar todas as suas tarefas em paralelo, porém,  somente irá executar as tarefas do próximo estágio, quando todas as tarefas anteriores forem concluídas com êxito. Para a configuração dos estágios, basta adicionar uma seção os relacionando conforme sintaxe abaixo:&amp;lt;blockquote&amp;gt;''stages:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''- deploy''&amp;lt;/blockquote&amp;gt;Por fim, são configuradas as tarefas que cada estágio executa, para o cenário apresentado nesse tutorial iremos configurar apenas o script a ser executado, o estágio que a tarefa pertence e quando ela deve ser executada, conforme script abaixo, porém existem diversas opções de configuração e customizações que podem ser feitas e estão documentadas no link da referência [3]&amp;lt;blockquote&amp;gt;''Setup:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;''  stage: build''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''script:''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''  - ansible-playbook parse.yaml''&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt; ''when: always''&amp;lt;/blockquote&amp;gt;              Ao término da configuração do .gitlab-ci.yml, a cada commit realizado pelo técnico será executada a pipeline que, para este tutorial, terá a forma da Figura 1:&lt;br /&gt;
[[Arquivo:Ciclo de execução.png|centro|miniaturadaimagem|800x800px|Figura 1. Ciclo de execução]]&lt;br /&gt;
&lt;br /&gt;
=== '''Ansible''' ===&lt;br /&gt;
O Ansible é uma ferramenta open-source para gerenciamento de configuração e provisionamento, que utiliza uma comunicação com os nós baseadas em SSH sem a necessidade da instalação de agentes.&lt;br /&gt;
&lt;br /&gt;
             Para a utilização da ferramenta é necessário criar um arquivo ansible.cfg, que contém as configurações básicas do ansible, criar um arquivo contendo a relação dos dispositivos, e criar um arquivo contendo as instruções a serem executadas.&lt;br /&gt;
&lt;br /&gt;
              Com os três arquivos citados anteriormente já é possível realizar alguns testes de acesso com o Ansible, porém para aplicações mais complexas é conveniente utilizar uma estrutura de diretórios para dois propósitos, o primeiro é melhorar a usabilidade e semântica da automação, e a segunda é criar um ambiente flexível e que possa ser reutilizado para diversos propósitos.&lt;br /&gt;
&lt;br /&gt;
             Com este propósito a partir da versão 1.2 o Ansible introduziu o conceito de Roles, que através de uma estrutura de diretórios possibilita o carregamento automático de diversos arquivos e o agrupamento de configurações conforme sua semelhança e necessidade específica, a documentação a respeito de roles pode ser encontrada no link da referência [4], outra vantagem da utilização de roles reside no seu compartilhamento, onde pelo link da referência [5] podem ser encontrados diversos roles prontos para uso.&lt;br /&gt;
&lt;br /&gt;
             Neste tutorial iremos criar roles de acordo com o software que roda nos equipamentos, por exemplo RouterOS, IOS, IOS-XR, Junos e etc, pois cada software possui uma sintaxe própria que ao final da implementação devem ser encapsuladas, outra vantagem desta escolha reside na possibilidade de separação de equipes de modo que a equipe com experiencia em RouteOS, não precisa se preocupar com particularidades do IOS, ou seja a única preocupação dessa equipe é considerando o modelo de dados de entrada que é padrão para todas as implementações gerar a configuração correspondente, conforme Figura 2.&lt;br /&gt;
[[Arquivo:Roles.png|centro|miniaturadaimagem|800x800px|Figura 2. Metologia de utilização dos Roles]]&lt;br /&gt;
Com a estrutura de diretórios pronta é necessário criar as abstrações das configurações o que é dependente de cada modelo e dos módulos disponíveis, para esse tutorial como configuraremos um mikrotik (RouterOS), e um cisco (IOS) iremos utilizar os seguintes módulos routeros_command [6] ios_config [7], e a linguagem de template Jinja2 para criar as abstrações, e devido as diferenças entre os módulos do ios_config e do routeros_command as etapas para a configuração serão diferentes conforme Figuras 3 e 4 &lt;br /&gt;
[[Arquivo:RoleCisco.png|centro|miniaturadaimagem|795x795px|Figura 3. Implementação de um Role para IOS]]&lt;br /&gt;
[[Arquivo:Renato-MikrotikRoles.png|centro|miniaturadaimagem|800x800px|Figura 4. Implementação de um Role para RouterOS]]&lt;br /&gt;
&lt;br /&gt;
=== '''Criando templates com Jinja2''' ===&lt;br /&gt;
Neste tutorial irei demonstrar a criação dos templates apenas para o IOS, mas para o RouterOS a implementação é análoga.&lt;br /&gt;
&lt;br /&gt;
             O primeiro passo é conceber a estrutura de dados do modelo, será utilizado uma interface como base. Abstraindo toda a sintaxe os dados que são inseridos em uma interface em geral são nome da interface, endereço IP, máscara, estado ( shut ou no shut), velocidade, encapsulamento e etc, um exemplo de modelo seria o apresentado abaixo: &amp;lt;blockquote&amp;gt;Interfaces:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: Loopback0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.0.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description: LDP Loopback&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.255&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- interface:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;name: GigabitEthernet0/0&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;address: 10.0.1.1&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;mask: 255.255.255.252&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;enabled: True&amp;lt;/blockquote&amp;gt;Os arquivos contendo estes modelos seriam armazenados dentro da pasta ''roles/models/files/interfaces/&amp;lt;hostname&amp;gt;.yml''. Percebe que neste momento estamos fazendo duas associações implícitas, a primeira é utilizar a palavra '''interfaces''' no caminho que será utilizada posteriormente para acessar todos os arquivos de configuração relativos a configuração das interfaces, e a segunda associação está no nome do arquivo '''&amp;lt;hostname&amp;gt;.yml''', que será utilizado em tempo de execução para associar dada configuração ao ativo.&lt;br /&gt;
&lt;br /&gt;
             Com o modelo pronto precisamos escrever o template, que no caso do IOS ficará em ''roles/ios/templates/interfaces.j2'', e iremos criar um template para cada funcionalidade que desejarmos automatizar.&lt;br /&gt;
&lt;br /&gt;
             Para a criação do template é necessário conhecer algumas estruturas de controle que nos permitirão realizar testes, e executar laços dentro da execução. A primeira estrutura que será apresentada é o laço '''{% for iterador in variável %} ... {% endfor %}'''. Ao observar o modelo que criamos acima pode se perceber que ele forma uma lista de interfaces, e será carregado dentro do Ansible como uma variável de nome interfaces, então para montar o laço iremos utilizar:&amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;              Outra estrutura que será usada extensivamente é condicional IF que possui a seguinte estrutura: &amp;lt;blockquote&amp;gt;{% if confição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;..&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% elif condição %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% else %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;...&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;             E para acessar as variáveis basta utilizar a seguinte sintaxe &amp;lt;nowiki&amp;gt;{{ nome da variável }}&amp;lt;/nowiki&amp;gt;.  O próximo passo é escrever a configuração que se deseja aplicar tomando muito cuidado com espaços, e sem a necessidade de se utilizar end ao final, pois o módulo executa uma comparação textual com a configuração em produção antes de configurar, no final a configuração do template será semelhando a abaixo:&amp;lt;blockquote&amp;gt;{% for interface in interfaces %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;interface &amp;lt;nowiki&amp;gt;{{ interface.name }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.description is defined %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;description &amp;lt;nowiki&amp;gt;{{ interface.description}}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if (interface.address is defined ) and (interface.mask is defined ) %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ip address &amp;lt;nowiki&amp;gt;{{ interface.address }}&amp;lt;/nowiki&amp;gt; &amp;lt;nowiki&amp;gt;{{ interface.mask }}&amp;lt;/nowiki&amp;gt;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == True %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;no shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% if interface.enabled == False %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;shutdown&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endif %}&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;exit&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;{% endfor %}&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== '''Integrando a solução''' ===&lt;br /&gt;
Com os modelos prontos e todos os templates está na hora de criar os playbooks, que serão utilizados pelo Ansible para guiar a automação. O primeiro playbook a ser criado fica na raiz do diretório e será responsável por “chamar” os playbooks de cada role, o que é entregue automaticamente, bastando se incluir o role no playbook, para esse primeiro playbook que chamarei de principal, será necessário criar um “Play” para cada grupo de ativos e neste play será incluído a role desejada, conforme exemplo abaixo:&amp;lt;blockquote&amp;gt;- name: Cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - cisco&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;- name: MikroTik&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;hosts: routeros&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;roles:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  - routeros&amp;lt;/blockquote&amp;gt;A relação de hosts para cada grupo é definida dentro do arquivo hosts, que tem a seguinte sintaxe:&amp;lt;blockquote&amp;gt;[cisco]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE7 ansible_host=192.168.237.206&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE4 ansible_host=192.168.237.202&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P2  ansible_host=192.168.237.203&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P1  ansible_host=192.168.237.205&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;PE5 ansible_host=192.168.237.207&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;CPE6 ansible_host=192.168.237.204&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;[routeros]&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;P3  ansible_host=192.168.237.183&amp;lt;/blockquote&amp;gt;              Neste arquivo os grupos são definidos dentro dos colchetes, [cisco] e [routeros], enquanto os membros do grupo são definidos individualmente abaixo com a seguinte sintaxe: HOSTNAME  ansible_host=&amp;lt;endereço IP&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
             Adicionalmente ao endereço é necessário prover as credenciais de acesso ao equipamento e o sistema que roda em cada um conforme [3], neste tutorial será utilizado a mesma credencial de acesso a todos os equipamentos e tal configuração ficará dentro do arquivo group_vars/all.yml que tem a seguinte forma:&amp;lt;blockquote&amp;gt;ansible_connection: network_cli&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_become_method: enable&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_user: 'renato'&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;ansible_ssh_pass: '123456'&amp;lt;/blockquote&amp;gt;Note que nesse tutorial estou usando uma senha em claro dentro de um arquivo de configuração o que não é uma boa prática, para encriptar esta senha utilize os procedimentos descritos em [8].&lt;br /&gt;
&lt;br /&gt;
E para as configurações específicas de cada plataforma será criado um arquivo com o mesmo nome do groupo na pasta group_vars, estas configurações podem ser visualizadas em [9].&lt;br /&gt;
&lt;br /&gt;
             Finalizado estas configurações, criação do playbook principal, do inventário e das variáveis, vamos aos arquivos específicos de cada modelo. Para isso deverá ser criado um arquivo com o nome main.yml na pasta roles/&amp;lt;role&amp;gt;/tasks. Para a configuração no cisco, conforme Figura 3 precisamos primeiro ler o arquivo com o modelo e transformar ele em variável, porém é importante notar que cada tarefa é executada para todos os equipamentos do grupo, assim para evitar erros de execução iremos pesquisar pelo modelo na sua pasta respectiva:&amp;lt;blockquote&amp;gt;- name: List interface directory&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;find:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  paths: roles/models/files/interfaces&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  patterns: &amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  recurse: yes&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file_type: file&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;register: Files&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;              &lt;br /&gt;
&lt;br /&gt;
Perceba que a tarefa acima pesquisa na pasta /roles/models/files/interfaces todos os arquivos com o seguinte padrão ''&amp;quot;*&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;quot;'', note a sintaxe ''&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;'', vista anteriormente nos templates em jinja2, que  faz referência ao equipamento que está sendo processado, registra o resultado de sua busca na variável Files e por fim executa esse procedimento localmente, sem a necessidade de se conectar via ssh no host.&lt;br /&gt;
&lt;br /&gt;
Com os arquivos identificados o próximo passo é importar as variáveis que será feito utilizando o módulo template, conforme descrito abaixo:&amp;lt;blockquote&amp;gt;- name: Include interface vars&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  include_vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  file: roles/models/files/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;             Com o modelo importado o próximo passo é a criação dos arquivos de configuração, nesta etapa é fundamental que na sua estrutura de diretórios já exista uma pasta destinada a estes arquivos, e para a sua configuração basta seguir o modelo abaixo:&amp;lt;blockquote&amp;gt;- name: Make Config&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;template:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  src: interface.j2&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  dest: cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  mode: 0777&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: Files.files != []&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;delegate_to: localhost&amp;lt;/blockquote&amp;gt;             Finalmente com todos os arquivos de configuração prontos, está na hora de aplicar as configurações nos equipamentos que no caso do ios é feito utilizando o módulo ios_config, conforme sintaxe abaixo:&amp;lt;blockquote&amp;gt;  - name: Configure&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  ios_config:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;    src:  “cfg/interfaces/&amp;lt;nowiki&amp;gt;{{ inventory_hostname }}&amp;lt;/nowiki&amp;gt;.cfg”&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  when: configFiles.files != []&amp;lt;/blockquote&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Finalizadas estas configurações basta repetir o processo para cada funcionalidade que se deseja implementar em sua automação, e caso seja de interesse é possível simplificar ainda mais a criação dos playbooks, realizando a separação da configuração das tarefas por escopos, ou seja dentro da pasta roles/&amp;lt;role&amp;gt;/tasks existirá um arquivo main.yml que é responsável por importar as tarefas de cada uma das funcionalidades e cada funcionalidade terá um arquivo próprio como por exemplor interfaces.yml, ospf.yml , mpls.yml e etc, desta forma as configurações apresentadas acima residirão dentro de cada um dos playbooks de funcionalidades e o playbook main.yml irá apenas instanciar usando a seguinte sintaxe:&amp;lt;blockquote&amp;gt;- import_tasks: interfaces.yml&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;vars:&amp;lt;/blockquote&amp;gt;&amp;lt;blockquote&amp;gt;  scope: interfaces&amp;lt;/blockquote&amp;gt;             &lt;br /&gt;
&lt;br /&gt;
             Observe no código acima que foi introduzido uma variável durante a inclusão, e ao observar as configurações realizadas anteriormente é possível perceber que em nenhum momento foi utilizado alguma especificidade de alguma funcionalidade, portanto com é possível apenas com a alteração da variável scope, recém introduzida, replicar todo o código que criamos sem a necessidade de escreve-lo novamente.&lt;br /&gt;
&lt;br /&gt;
             Finalizado as configurações dos outros roles, para executar a automação basta executar o comando ansible-playbook &amp;lt;playbook).yaml na pasta raiz do projeto, comando este que deve ser inserido no .gitlab-ci.yml para que o gitlab execute a configuração sempre que o usuário realizar um commit.&lt;br /&gt;
&lt;br /&gt;
=== '''Conclusão''' ===&lt;br /&gt;
             Neste tutorial foi apresentado uma metodologia de automação de redes baseada na integração de ferramentas open source, Ansible e gitlab. Onde através da utilização da abstração de modelos de dados e roles, é possível entregar ao administrador de redes uma interface de configuração agnóstica a fabricantes e com um mecanismo de aprovação característico de metodologias de desenvolvimento de software, com commits e processos de aprovação.&lt;br /&gt;
&lt;br /&gt;
Por fim toda a configuração demonstrada neste artigo pode ser acessada no seguinte repositório do github [10], e a demonstração deste cenário poderá ser assistido em um vídeo no YouTube que será publicado em breve.&lt;br /&gt;
&lt;br /&gt;
Muito obrigado pela atenção, espero que tenham gostado do conteúdo, e assim que possível estarei disponibilizando um vídeo no YouTube demonstrando e dando maiores explicações sobre a metodologia&lt;br /&gt;
&lt;br /&gt;
=== REFERÊNCIAS ===&lt;br /&gt;
[1]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/runner/register/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[2]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/quick_start/README.html#creating-a-gitlab-ciyml-file&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[3]     (&amp;lt;nowiki&amp;gt;https://docs.gitlab.com/ee/ci/yaml/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[4]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[5]     (&amp;lt;nowiki&amp;gt;https://galaxy.ansible.com/&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[6]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/routeros_command_module.html#routeros-command-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[7]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/modules/ios_config_module.html#ios-config-module&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[8]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/user_guide/vault.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
[9]     (&amp;lt;nowiki&amp;gt;https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
'''AUTOR:''' [[Usuário:Renato.Oliveira]]&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Arquivo:Renato-MikrotikRoles.png&amp;diff=1932</id>
		<title>Arquivo:Renato-MikrotikRoles.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Arquivo:Renato-MikrotikRoles.png&amp;diff=1932"/>
		<updated>2020-01-09T21:22:58Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;.&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Arquivo:RoleCisco.png&amp;diff=1931</id>
		<title>Arquivo:RoleCisco.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Arquivo:RoleCisco.png&amp;diff=1931"/>
		<updated>2020-01-09T21:18:37Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;.&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Arquivo:Roles.png&amp;diff=1930</id>
		<title>Arquivo:Roles.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Arquivo:Roles.png&amp;diff=1930"/>
		<updated>2020-01-09T21:15:16Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;.&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Arquivo:Ciclo_de_execu%C3%A7%C3%A3o.png&amp;diff=1929</id>
		<title>Arquivo:Ciclo de execução.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Arquivo:Ciclo_de_execu%C3%A7%C3%A3o.png&amp;diff=1929"/>
		<updated>2020-01-09T21:09:30Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;.&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
	<entry>
		<id>https://wiki.brasilpeeringforum.org/index.php?title=Usu%C3%A1rio:Renato.Oliveira&amp;diff=1874</id>
		<title>Usuário:Renato.Oliveira</title>
		<link rel="alternate" type="text/html" href="https://wiki.brasilpeeringforum.org/index.php?title=Usu%C3%A1rio:Renato.Oliveira&amp;diff=1874"/>
		<updated>2020-01-06T02:23:56Z</updated>

		<summary type="html">&lt;p&gt;Renato.Oliveira: Página pessoal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Perfil do Profissional ===&lt;br /&gt;
Renato Almeida de Oliveira é um engenheiro de telecomunicações formado pelo instituto militar de engenharia (IME).&lt;br /&gt;
&lt;br /&gt;
Atua como engenheiro militar no Exército Brasileiro tendo contribuído com os seguintes projetos:&lt;br /&gt;
* Criação do NOC do 2º CTA situado no Rio de Janeiro, responsável pelo monitoramento da a infraestrutura de redes dedica aos centros de operações em atuação nos jogos olímpicos Rio 2016;&lt;br /&gt;
&lt;br /&gt;
* Desenvolvimento de software para autenticação e registro de usuários da rede coorporativa do exército, entregando as unidades da área do Rio de Janeiro uma plataforma self-service com provimento automático de serviços;&lt;br /&gt;
&lt;br /&gt;
* Mapeamento da infraestrutura legada de Brasília para a realização do moving entre o datacenter antigo para o recém construído data center Ricardo Franco (TIER III);&lt;br /&gt;
&lt;br /&gt;
* Configuração da infraestrutura de redes do backbone nacional do Exército Brasileiro, e integração da rede MPLS legada com a novo backbone;&lt;br /&gt;
&lt;br /&gt;
=== Contato ===&lt;br /&gt;
Para contatos referentes a serviços de consultoria técnica especializada, fornecimento de soluções, projetos, suporte e treinamentos:&lt;br /&gt;
&lt;br /&gt;
'''Linkedin: https://www.linkedin.com/in/renato-oliveira-2b5b4094/'''&lt;br /&gt;
&lt;br /&gt;
'''Telegram''': https://t.me/RenatoAOliveira&lt;/div&gt;</summary>
		<author><name>Renato.Oliveira</name></author>
	</entry>
</feed>